]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - sys/dev/sound/usb/uaudio.c
MFC: r227309 (partial)
[FreeBSD/stable/9.git] / sys / dev / sound / usb / uaudio.c
1 /*      $NetBSD: uaudio.c,v 1.91 2004/11/05 17:46:14 kent Exp $ */
2 /*      $FreeBSD$ */
3
4 /*-
5  * Copyright (c) 1999 The NetBSD Foundation, Inc.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to The NetBSD Foundation
9  * by Lennart Augustsson (lennart@augustsson.net) at
10  * Carlstedt Research & Technology.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
36
37 /*
38  * USB audio specs: http://www.usb.org/developers/devclass_docs/audio10.pdf
39  *                  http://www.usb.org/developers/devclass_docs/frmts10.pdf
40  *                  http://www.usb.org/developers/devclass_docs/termt10.pdf
41  */
42
43 /*
44  * Also merged:
45  *  $NetBSD: uaudio.c,v 1.94 2005/01/15 15:19:53 kent Exp $
46  *  $NetBSD: uaudio.c,v 1.95 2005/01/16 06:02:19 dsainty Exp $
47  *  $NetBSD: uaudio.c,v 1.96 2005/01/16 12:46:00 kent Exp $
48  *  $NetBSD: uaudio.c,v 1.97 2005/02/24 08:19:38 martin Exp $
49  */
50
51 #include <sys/stdint.h>
52 #include <sys/stddef.h>
53 #include <sys/param.h>
54 #include <sys/queue.h>
55 #include <sys/types.h>
56 #include <sys/systm.h>
57 #include <sys/kernel.h>
58 #include <sys/bus.h>
59 #include <sys/module.h>
60 #include <sys/lock.h>
61 #include <sys/mutex.h>
62 #include <sys/condvar.h>
63 #include <sys/sysctl.h>
64 #include <sys/sx.h>
65 #include <sys/unistd.h>
66 #include <sys/callout.h>
67 #include <sys/malloc.h>
68 #include <sys/priv.h>
69
70 #include "usbdevs.h"
71 #include <dev/usb/usb.h>
72 #include <dev/usb/usbdi.h>
73 #include <dev/usb/usbdi_util.h>
74 #include <dev/usb/usbhid.h>
75 #include <dev/usb/usb_request.h>
76
77 #define USB_DEBUG_VAR uaudio_debug
78 #include <dev/usb/usb_debug.h>
79
80 #include <dev/usb/quirk/usb_quirk.h>
81
82 #include <sys/reboot.h>                 /* for bootverbose */
83
84 #ifdef HAVE_KERNEL_OPTION_HEADERS
85 #include "opt_snd.h"
86 #endif
87
88 #include <dev/sound/pcm/sound.h>
89 #include <dev/sound/usb/uaudioreg.h>
90 #include <dev/sound/usb/uaudio.h>
91 #include <dev/sound/chip.h>
92 #include "feeder_if.h"
93
94 static int uaudio_default_rate = 0;             /* use rate list */
95 static int uaudio_default_bits = 32;
96 static int uaudio_default_channels = 0;         /* use default */
97
98 #ifdef USB_DEBUG
99 static int uaudio_debug = 0;
100
101 static SYSCTL_NODE(_hw_usb, OID_AUTO, uaudio, CTLFLAG_RW, 0, "USB uaudio");
102
103 SYSCTL_INT(_hw_usb_uaudio, OID_AUTO, debug, CTLFLAG_RW,
104     &uaudio_debug, 0, "uaudio debug level");
105
106 TUNABLE_INT("hw.usb.uaudio.default_rate", &uaudio_default_rate);
107 SYSCTL_INT(_hw_usb_uaudio, OID_AUTO, default_rate, CTLFLAG_RW,
108     &uaudio_default_rate, 0, "uaudio default sample rate");
109
110 TUNABLE_INT("hw.usb.uaudio.default_bits", &uaudio_default_bits);
111 SYSCTL_INT(_hw_usb_uaudio, OID_AUTO, default_bits, CTLFLAG_RW,
112     &uaudio_default_bits, 0, "uaudio default sample bits");
113
114 TUNABLE_INT("hw.usb.uaudio.default_channels", &uaudio_default_channels);
115 SYSCTL_INT(_hw_usb_uaudio, OID_AUTO, default_channels, CTLFLAG_RW,
116     &uaudio_default_channels, 0, "uaudio default sample channels");
117 #endif
118
119 #define UAUDIO_NFRAMES          64      /* must be factor of 8 due HS-USB */
120 #define UAUDIO_NCHANBUFS        2       /* number of outstanding request */
121 #define UAUDIO_RECURSE_LIMIT    255     /* rounds */
122
123 #define MAKE_WORD(h,l) (((h) << 8) | (l))
124 #define BIT_TEST(bm,bno) (((bm)[(bno) / 8] >> (7 - ((bno) % 8))) & 1)
125 #define UAUDIO_MAX_CHAN(x) (x)
126 #define MIX(sc) ((sc)->sc_mixer_node)
127
128 union uaudio_asid {
129         const struct usb_audio_streaming_interface_descriptor *v1;
130         const struct usb_audio20_streaming_interface_descriptor *v2;
131 };
132
133 union uaudio_asf1d {
134         const struct usb_audio_streaming_type1_descriptor *v1;
135         const struct usb_audio20_streaming_type1_descriptor *v2;
136 };
137
138 union uaudio_sed {
139         const struct usb_audio_streaming_endpoint_descriptor *v1;
140         const struct usb_audio20_streaming_endpoint_descriptor *v2;
141 };
142
143 struct uaudio_mixer_node {
144         const char *name;
145
146         int32_t minval;
147         int32_t maxval;
148 #define MIX_MAX_CHAN 16
149         int32_t wValue[MIX_MAX_CHAN];   /* using nchan */
150         uint32_t mul;
151         uint32_t ctl;
152
153         int wData[MIX_MAX_CHAN];        /* using nchan */
154         uint16_t wIndex;
155
156         uint8_t update[(MIX_MAX_CHAN + 7) / 8];
157         uint8_t nchan;
158         uint8_t type;
159 #define MIX_ON_OFF      1
160 #define MIX_SIGNED_16   2
161 #define MIX_UNSIGNED_16 3
162 #define MIX_SIGNED_8    4
163 #define MIX_SELECTOR    5
164 #define MIX_UNKNOWN     6
165 #define MIX_SIZE(n) ((((n) == MIX_SIGNED_16) || \
166                       ((n) == MIX_UNSIGNED_16)) ? 2 : 1)
167 #define MIX_UNSIGNED(n) ((n) == MIX_UNSIGNED_16)
168
169 #define MAX_SELECTOR_INPUT_PIN 256
170         uint8_t slctrtype[MAX_SELECTOR_INPUT_PIN];
171         uint8_t class;
172         uint8_t val_default;
173
174         uint8_t desc[64];
175
176         struct uaudio_mixer_node *next;
177 };
178
179 struct uaudio_chan {
180         struct pcmchan_caps pcm_cap;    /* capabilities */
181
182         struct snd_dbuf *pcm_buf;
183         const struct usb_config *usb_cfg;
184         struct mtx *pcm_mtx;            /* lock protecting this structure */
185         struct uaudio_softc *priv_sc;
186         struct pcm_channel *pcm_ch;
187         struct usb_xfer *xfer[UAUDIO_NCHANBUFS + 1];
188         union uaudio_asf1d p_asf1d;
189         union uaudio_sed p_sed;
190         const usb_endpoint_descriptor_audio_t *p_ed1;
191         const struct uaudio_format *p_fmt;
192
193         uint8_t *buf;                   /* pointer to buffer */
194         uint8_t *start;                 /* upper layer buffer start */
195         uint8_t *end;                   /* upper layer buffer end */
196         uint8_t *cur;                   /* current position in upper layer
197                                          * buffer */
198
199         uint32_t intr_size;             /* in bytes */
200         uint32_t intr_frames;           /* in units */
201         uint32_t sample_rate;
202         uint32_t frames_per_second;
203         uint32_t sample_rem;
204         uint32_t sample_curr;
205
206         uint32_t format;
207         uint32_t pcm_format[2];
208
209         uint16_t bytes_per_frame[2];
210
211         uint16_t sample_size;
212
213         uint8_t valid;
214         uint8_t iface_index;
215         uint8_t iface_alt_index;
216         uint8_t channels;
217
218         uint8_t last_sync_time;
219         uint8_t last_sync_state;
220 #define UAUDIO_SYNC_NONE 0
221 #define UAUDIO_SYNC_MORE 1
222 #define UAUDIO_SYNC_LESS 2
223 };
224
225 #define UMIDI_CABLES_MAX   16           /* units */
226 #define UMIDI_TX_FRAMES    256          /* units */
227 #define UMIDI_TX_BUFFER    (UMIDI_TX_FRAMES * 4)        /* bytes */
228
229 enum {
230         UMIDI_TX_TRANSFER,
231         UMIDI_RX_TRANSFER,
232         UMIDI_N_TRANSFER,
233 };
234
235 struct umidi_sub_chan {
236         struct usb_fifo_sc fifo;
237         uint8_t *temp_cmd;
238         uint8_t temp_0[4];
239         uint8_t temp_1[4];
240         uint8_t state;
241 #define UMIDI_ST_UNKNOWN   0            /* scan for command */
242 #define UMIDI_ST_1PARAM    1
243 #define UMIDI_ST_2PARAM_1  2
244 #define UMIDI_ST_2PARAM_2  3
245 #define UMIDI_ST_SYSEX_0   4
246 #define UMIDI_ST_SYSEX_1   5
247 #define UMIDI_ST_SYSEX_2   6
248
249         uint8_t read_open:1;
250         uint8_t write_open:1;
251         uint8_t unused:6;
252 };
253
254 struct umidi_chan {
255
256         struct umidi_sub_chan sub[UMIDI_CABLES_MAX];
257         struct mtx mtx;
258
259         struct usb_xfer *xfer[UMIDI_N_TRANSFER];
260
261         uint8_t iface_index;
262         uint8_t iface_alt_index;
263
264         uint8_t read_open_refcount;
265         uint8_t write_open_refcount;
266
267         uint8_t curr_cable;
268         uint8_t max_cable;
269         uint8_t valid;
270         uint8_t single_command;
271 };
272
273 struct uaudio_search_result {
274         uint8_t bit_input[(256 + 7) / 8];
275         uint8_t bit_output[(256 + 7) / 8];
276         uint8_t recurse_level;
277         uint8_t id_max;
278         uint8_t is_input;
279 };
280
281 enum {
282         UAUDIO_HID_RX_TRANSFER,
283         UAUDIO_HID_N_TRANSFER,
284 };
285
286 struct uaudio_hid {
287         struct usb_xfer *xfer[UAUDIO_HID_N_TRANSFER];
288         struct hid_location volume_up_loc;
289         struct hid_location volume_down_loc;
290         struct hid_location mute_loc;
291         uint32_t flags;
292 #define UAUDIO_HID_VALID                0x0001
293 #define UAUDIO_HID_HAS_ID               0x0002
294 #define UAUDIO_HID_HAS_VOLUME_UP        0x0004
295 #define UAUDIO_HID_HAS_VOLUME_DOWN      0x0008
296 #define UAUDIO_HID_HAS_MUTE             0x0010
297         uint8_t iface_index;
298         uint8_t volume_up_id;
299         uint8_t volume_down_id;
300         uint8_t mute_id;
301 };
302
303 struct uaudio_softc {
304         struct sbuf sc_sndstat;
305         struct sndcard_func sc_sndcard_func;
306         struct uaudio_chan sc_rec_chan;
307         struct uaudio_chan sc_play_chan;
308         struct umidi_chan sc_midi_chan;
309         struct uaudio_hid sc_hid;
310         struct uaudio_search_result sc_mixer_clocks;
311         struct uaudio_mixer_node sc_mixer_node;
312
313         struct mtx *sc_mixer_lock;
314         struct snd_mixer *sc_mixer_dev;
315         struct usb_device *sc_udev;
316         struct usb_xfer *sc_mixer_xfer[1];
317         struct uaudio_mixer_node *sc_mixer_root;
318         struct uaudio_mixer_node *sc_mixer_curr;
319
320         uint32_t sc_mix_info;
321         uint32_t sc_recsrc_info;
322
323         uint16_t sc_audio_rev;
324         uint16_t sc_mixer_count;
325
326         uint8_t sc_sndstat_valid;
327         uint8_t sc_mixer_iface_index;
328         uint8_t sc_mixer_iface_no;
329         uint8_t sc_mixer_chan;
330         uint8_t sc_pcm_registered:1;
331         uint8_t sc_mixer_init:1;
332         uint8_t sc_uq_audio_swap_lr:1;
333         uint8_t sc_uq_au_inp_async:1;
334         uint8_t sc_uq_au_no_xu:1;
335         uint8_t sc_uq_bad_adc:1;
336         uint8_t sc_uq_au_vendor_class:1;
337 };
338
339 struct uaudio_terminal_node {
340         union {
341                 const struct usb_descriptor *desc;
342                 const struct usb_audio_input_terminal *it_v1;
343                 const struct usb_audio_output_terminal *ot_v1;
344                 const struct usb_audio_mixer_unit_0 *mu_v1;
345                 const struct usb_audio_selector_unit *su_v1;
346                 const struct usb_audio_feature_unit *fu_v1;
347                 const struct usb_audio_processing_unit_0 *pu_v1;
348                 const struct usb_audio_extension_unit_0 *eu_v1;
349                 const struct usb_audio20_clock_source_unit *csrc_v2;
350                 const struct usb_audio20_clock_selector_unit_0 *csel_v2;
351                 const struct usb_audio20_clock_multiplier_unit *cmul_v2;
352                 const struct usb_audio20_input_terminal *it_v2;
353                 const struct usb_audio20_output_terminal *ot_v2;
354                 const struct usb_audio20_mixer_unit_0 *mu_v2;
355                 const struct usb_audio20_selector_unit *su_v2;
356                 const struct usb_audio20_feature_unit *fu_v2;
357                 const struct usb_audio20_sample_rate_unit *ru_v2;
358                 const struct usb_audio20_processing_unit_0 *pu_v2;
359                 const struct usb_audio20_extension_unit_0 *eu_v2;
360                 const struct usb_audio20_effect_unit *ef_v2;
361         }       u;
362         struct uaudio_search_result usr;
363         struct uaudio_terminal_node *root;
364 };
365
366 struct uaudio_format {
367         uint16_t wFormat;
368         uint8_t bPrecision;
369         uint32_t freebsd_fmt;
370         const char *description;
371 };
372
373 static const struct uaudio_format uaudio10_formats[] = {
374
375         {UA_FMT_PCM8, 8, AFMT_U8, "8-bit U-LE PCM"},
376         {UA_FMT_PCM8, 16, AFMT_U16_LE, "16-bit U-LE PCM"},
377         {UA_FMT_PCM8, 24, AFMT_U24_LE, "24-bit U-LE PCM"},
378         {UA_FMT_PCM8, 32, AFMT_U32_LE, "32-bit U-LE PCM"},
379
380         {UA_FMT_PCM, 8, AFMT_S8, "8-bit S-LE PCM"},
381         {UA_FMT_PCM, 16, AFMT_S16_LE, "16-bit S-LE PCM"},
382         {UA_FMT_PCM, 24, AFMT_S24_LE, "24-bit S-LE PCM"},
383         {UA_FMT_PCM, 32, AFMT_S32_LE, "32-bit S-LE PCM"},
384
385         {UA_FMT_ALAW, 8, AFMT_A_LAW, "8-bit A-Law"},
386         {UA_FMT_MULAW, 8, AFMT_MU_LAW, "8-bit mu-Law"},
387
388         {0, 0, 0, NULL}
389 };
390
391 static const struct uaudio_format uaudio20_formats[] = {
392
393         {UA20_FMT_PCM, 8, AFMT_S8, "8-bit S-LE PCM"},
394         {UA20_FMT_PCM, 16, AFMT_S16_LE, "16-bit S-LE PCM"},
395         {UA20_FMT_PCM, 24, AFMT_S24_LE, "24-bit S-LE PCM"},
396         {UA20_FMT_PCM, 32, AFMT_S32_LE, "32-bit S-LE PCM"},
397
398         {UA20_FMT_PCM8, 8, AFMT_U8, "8-bit U-LE PCM"},
399         {UA20_FMT_PCM8, 16, AFMT_U16_LE, "16-bit U-LE PCM"},
400         {UA20_FMT_PCM8, 24, AFMT_U24_LE, "24-bit U-LE PCM"},
401         {UA20_FMT_PCM8, 32, AFMT_U32_LE, "32-bit U-LE PCM"},
402
403         {UA20_FMT_ALAW, 8, AFMT_A_LAW, "8-bit A-Law"},
404         {UA20_FMT_MULAW, 8, AFMT_MU_LAW, "8-bit mu-Law"},
405
406         {0, 0, 0, NULL}
407 };
408
409 #define UAC_OUTPUT      0
410 #define UAC_INPUT       1
411 #define UAC_EQUAL       2
412 #define UAC_RECORD      3
413 #define UAC_NCLASSES    4
414
415 #ifdef USB_DEBUG
416 static const char *uac_names[] = {
417         "outputs", "inputs", "equalization", "record"
418 };
419
420 #endif
421
422 /* prototypes */
423
424 static device_probe_t uaudio_probe;
425 static device_attach_t uaudio_attach;
426 static device_detach_t uaudio_detach;
427
428 static usb_callback_t uaudio_chan_play_callback;
429 static usb_callback_t uaudio_chan_play_sync_callback;
430 static usb_callback_t uaudio_chan_record_callback;
431 static usb_callback_t uaudio_chan_record_sync_callback;
432 static usb_callback_t uaudio_mixer_write_cfg_callback;
433 static usb_callback_t umidi_bulk_read_callback;
434 static usb_callback_t umidi_bulk_write_callback;
435 static usb_callback_t uaudio_hid_rx_callback;
436
437 /* ==== USB mixer ==== */
438
439 static int uaudio_mixer_sysctl_handler(SYSCTL_HANDLER_ARGS);
440 static void uaudio_mixer_ctl_free(struct uaudio_softc *);
441 static void uaudio_mixer_register_sysctl(struct uaudio_softc *, device_t);
442 static void uaudio_mixer_reload_all(struct uaudio_softc *);
443 static void uaudio_mixer_controls_create_ftu(struct uaudio_softc *);
444
445 /* ==== USB audio v1.0 ==== */
446
447 static void     uaudio_mixer_add_mixer(struct uaudio_softc *,
448                     const struct uaudio_terminal_node *, int);
449 static void     uaudio_mixer_add_selector(struct uaudio_softc *,
450                     const struct uaudio_terminal_node *, int);
451 static uint32_t uaudio_mixer_feature_get_bmaControls(
452                     const struct usb_audio_feature_unit *, uint8_t);
453 static void     uaudio_mixer_add_feature(struct uaudio_softc *,
454                     const struct uaudio_terminal_node *, int);
455 static void     uaudio_mixer_add_processing_updown(struct uaudio_softc *,
456                     const struct uaudio_terminal_node *, int);
457 static void     uaudio_mixer_add_processing(struct uaudio_softc *,
458                     const struct uaudio_terminal_node *, int);
459 static void     uaudio_mixer_add_extension(struct uaudio_softc *,
460                     const struct uaudio_terminal_node *, int);
461 static struct   usb_audio_cluster uaudio_mixer_get_cluster(uint8_t,
462                     const struct uaudio_terminal_node *);
463 static uint16_t uaudio_mixer_determine_class(const struct uaudio_terminal_node *,
464                     struct uaudio_mixer_node *);
465 static uint16_t uaudio_mixer_feature_name(const struct uaudio_terminal_node *,
466                     struct uaudio_mixer_node *);
467 static void     uaudio_mixer_find_inputs_sub(struct uaudio_terminal_node *,
468                     const uint8_t *, uint8_t, struct uaudio_search_result *);
469 static const void *uaudio_mixer_verify_desc(const void *, uint32_t);
470 static usb_error_t uaudio_set_speed(struct usb_device *, uint8_t, uint32_t);
471 static int      uaudio_mixer_get(struct usb_device *, uint16_t, uint8_t,
472                     struct uaudio_mixer_node *);
473
474 /* ==== USB audio v2.0 ==== */
475
476 static void     uaudio20_mixer_add_mixer(struct uaudio_softc *,
477                     const struct uaudio_terminal_node *, int);
478 static void     uaudio20_mixer_add_selector(struct uaudio_softc *,
479                     const struct uaudio_terminal_node *, int);
480 static void     uaudio20_mixer_add_feature(struct uaudio_softc *,
481                     const struct uaudio_terminal_node *, int);
482 static struct   usb_audio20_cluster uaudio20_mixer_get_cluster(uint8_t,
483                     const struct uaudio_terminal_node *);
484 static uint16_t uaudio20_mixer_determine_class(const struct uaudio_terminal_node *,
485                     struct uaudio_mixer_node *);
486 static uint16_t uaudio20_mixer_feature_name(const struct uaudio_terminal_node *,
487                     struct uaudio_mixer_node *);
488 static void     uaudio20_mixer_find_inputs_sub(struct uaudio_terminal_node *,
489                     const uint8_t *, uint8_t, struct uaudio_search_result *);
490 static const void *uaudio20_mixer_verify_desc(const void *, uint32_t);
491 static usb_error_t uaudio20_set_speed(struct usb_device *, uint8_t,
492                     uint8_t, uint32_t);
493
494 /* USB audio v1.0 and v2.0 */
495
496 static void     uaudio_chan_fill_info_sub(struct uaudio_softc *,
497                     struct usb_device *, uint32_t, uint8_t, uint8_t);
498 static void     uaudio_chan_fill_info(struct uaudio_softc *,
499                     struct usb_device *);
500 static void     uaudio_mixer_add_ctl_sub(struct uaudio_softc *,
501                     struct uaudio_mixer_node *);
502 static void     uaudio_mixer_add_ctl(struct uaudio_softc *,
503                     struct uaudio_mixer_node *);
504 static void     uaudio_mixer_fill_info(struct uaudio_softc *,
505                     struct usb_device *, void *);
506 static void     uaudio_mixer_ctl_set(struct uaudio_softc *,
507                     struct uaudio_mixer_node *, uint8_t, int32_t val);
508 static int      uaudio_mixer_signext(uint8_t, int);
509 static int      uaudio_mixer_bsd2value(struct uaudio_mixer_node *, int32_t val);
510 static void     uaudio_mixer_init(struct uaudio_softc *);
511 static const struct uaudio_terminal_node *uaudio_mixer_get_input(
512                     const struct uaudio_terminal_node *, uint8_t);
513 static const struct uaudio_terminal_node *uaudio_mixer_get_output(
514                     const struct uaudio_terminal_node *, uint8_t);
515 static void     uaudio_mixer_find_outputs_sub(struct uaudio_terminal_node *,
516                     uint8_t, uint8_t, struct uaudio_search_result *);
517 static uint8_t  umidi_convert_to_usb(struct umidi_sub_chan *, uint8_t, uint8_t);
518 static struct   umidi_sub_chan *umidi_sub_by_fifo(struct usb_fifo *);
519 static void     umidi_start_read(struct usb_fifo *);
520 static void     umidi_stop_read(struct usb_fifo *);
521 static void     umidi_start_write(struct usb_fifo *);
522 static void     umidi_stop_write(struct usb_fifo *);
523 static int      umidi_open(struct usb_fifo *, int);
524 static int      umidi_ioctl(struct usb_fifo *, u_long cmd, void *, int);
525 static void     umidi_close(struct usb_fifo *, int);
526 static void     umidi_init(device_t dev);
527 static int      umidi_probe(device_t dev);
528 static int      umidi_detach(device_t dev);
529 static int      uaudio_hid_probe(struct uaudio_softc *sc,
530                     struct usb_attach_arg *uaa);
531 static void     uaudio_hid_detach(struct uaudio_softc *sc);
532
533 #ifdef USB_DEBUG
534 static void     uaudio_chan_dump_ep_desc(
535                     const usb_endpoint_descriptor_audio_t *);
536 #endif
537
538 static const struct usb_config
539         uaudio_cfg_record[UAUDIO_NCHANBUFS + 1] = {
540         [0] = {
541                 .type = UE_ISOCHRONOUS,
542                 .endpoint = UE_ADDR_ANY,
543                 .direction = UE_DIR_IN,
544                 .bufsize = 0,   /* use "wMaxPacketSize * frames" */
545                 .frames = UAUDIO_NFRAMES,
546                 .flags = {.short_xfer_ok = 1,},
547                 .callback = &uaudio_chan_record_callback,
548         },
549
550         [1] = {
551                 .type = UE_ISOCHRONOUS,
552                 .endpoint = UE_ADDR_ANY,
553                 .direction = UE_DIR_IN,
554                 .bufsize = 0,   /* use "wMaxPacketSize * frames" */
555                 .frames = UAUDIO_NFRAMES,
556                 .flags = {.short_xfer_ok = 1,},
557                 .callback = &uaudio_chan_record_callback,
558         },
559
560         [2] = {
561                 .type = UE_ISOCHRONOUS,
562                 .endpoint = UE_ADDR_ANY,
563                 .direction = UE_DIR_OUT,
564                 .bufsize = 0,   /* use "wMaxPacketSize * frames" */
565                 .frames = 1,
566                 .flags = {.no_pipe_ok = 1,.short_xfer_ok = 1,},
567                 .callback = &uaudio_chan_record_sync_callback,
568         },
569 };
570
571 static const struct usb_config
572         uaudio_cfg_play[UAUDIO_NCHANBUFS + 1] = {
573         [0] = {
574                 .type = UE_ISOCHRONOUS,
575                 .endpoint = UE_ADDR_ANY,
576                 .direction = UE_DIR_OUT,
577                 .bufsize = 0,   /* use "wMaxPacketSize * frames" */
578                 .frames = UAUDIO_NFRAMES,
579                 .flags = {.short_xfer_ok = 1,},
580                 .callback = &uaudio_chan_play_callback,
581         },
582
583         [1] = {
584                 .type = UE_ISOCHRONOUS,
585                 .endpoint = UE_ADDR_ANY,
586                 .direction = UE_DIR_OUT,
587                 .bufsize = 0,   /* use "wMaxPacketSize * frames" */
588                 .frames = UAUDIO_NFRAMES,
589                 .flags = {.short_xfer_ok = 1,},
590                 .callback = &uaudio_chan_play_callback,
591         },
592
593         [2] = {
594                 .type = UE_ISOCHRONOUS,
595                 .endpoint = UE_ADDR_ANY,
596                 .direction = UE_DIR_IN,
597                 .bufsize = 0,   /* use "wMaxPacketSize * frames" */
598                 .frames = 1,
599                 .flags = {.no_pipe_ok = 1,.short_xfer_ok = 1,},
600                 .callback = &uaudio_chan_play_sync_callback,
601         },
602 };
603
604 static const struct usb_config
605         uaudio_mixer_config[1] = {
606         [0] = {
607                 .type = UE_CONTROL,
608                 .endpoint = 0x00,       /* Control pipe */
609                 .direction = UE_DIR_ANY,
610                 .bufsize = (sizeof(struct usb_device_request) + 4),
611                 .callback = &uaudio_mixer_write_cfg_callback,
612                 .timeout = 1000,        /* 1 second */
613         },
614 };
615
616 static const
617 uint8_t umidi_cmd_to_len[16] = {
618         [0x0] = 0,                      /* reserved */
619         [0x1] = 0,                      /* reserved */
620         [0x2] = 2,                      /* bytes */
621         [0x3] = 3,                      /* bytes */
622         [0x4] = 3,                      /* bytes */
623         [0x5] = 1,                      /* bytes */
624         [0x6] = 2,                      /* bytes */
625         [0x7] = 3,                      /* bytes */
626         [0x8] = 3,                      /* bytes */
627         [0x9] = 3,                      /* bytes */
628         [0xA] = 3,                      /* bytes */
629         [0xB] = 3,                      /* bytes */
630         [0xC] = 2,                      /* bytes */
631         [0xD] = 2,                      /* bytes */
632         [0xE] = 3,                      /* bytes */
633         [0xF] = 1,                      /* bytes */
634 };
635
636 static const struct usb_config
637         umidi_config[UMIDI_N_TRANSFER] = {
638         [UMIDI_TX_TRANSFER] = {
639                 .type = UE_BULK,
640                 .endpoint = UE_ADDR_ANY,
641                 .direction = UE_DIR_OUT,
642                 .bufsize = UMIDI_TX_BUFFER,
643                 .callback = &umidi_bulk_write_callback,
644         },
645
646         [UMIDI_RX_TRANSFER] = {
647                 .type = UE_BULK,
648                 .endpoint = UE_ADDR_ANY,
649                 .direction = UE_DIR_IN,
650                 .bufsize = 4,   /* bytes */
651                 .flags = {.short_xfer_ok = 1,.proxy_buffer = 1,},
652                 .callback = &umidi_bulk_read_callback,
653         },
654 };
655
656 static const struct usb_config
657         uaudio_hid_config[UAUDIO_HID_N_TRANSFER] = {
658         [UAUDIO_HID_RX_TRANSFER] = {
659                 .type = UE_INTERRUPT,
660                 .endpoint = UE_ADDR_ANY,
661                 .direction = UE_DIR_IN,
662                 .bufsize = 0,   /* use wMaxPacketSize */
663                 .flags = {.short_xfer_ok = 1,},
664                 .callback = &uaudio_hid_rx_callback,
665         },
666 };
667
668 static devclass_t uaudio_devclass;
669
670 static device_method_t uaudio_methods[] = {
671         DEVMETHOD(device_probe, uaudio_probe),
672         DEVMETHOD(device_attach, uaudio_attach),
673         DEVMETHOD(device_detach, uaudio_detach),
674         DEVMETHOD(device_suspend, bus_generic_suspend),
675         DEVMETHOD(device_resume, bus_generic_resume),
676         DEVMETHOD(device_shutdown, bus_generic_shutdown),
677
678         DEVMETHOD_END
679 };
680
681 static driver_t uaudio_driver = {
682         .name = "uaudio",
683         .methods = uaudio_methods,
684         .size = sizeof(struct uaudio_softc),
685 };
686
687 /* The following table is derived from Linux's quirks-table.h */ 
688 static const STRUCT_USB_HOST_ID uaudio_vendor_midi[] = {
689         { USB_VPI(USB_VENDOR_YAMAHA, 0x1000, 0) }, /* UX256 */
690         { USB_VPI(USB_VENDOR_YAMAHA, 0x1001, 0) }, /* MU1000 */
691         { USB_VPI(USB_VENDOR_YAMAHA, 0x1002, 0) }, /* MU2000 */
692         { USB_VPI(USB_VENDOR_YAMAHA, 0x1003, 0) }, /* MU500 */
693         { USB_VPI(USB_VENDOR_YAMAHA, 0x1004, 3) }, /* UW500 */
694         { USB_VPI(USB_VENDOR_YAMAHA, 0x1005, 0) }, /* MOTIF6 */
695         { USB_VPI(USB_VENDOR_YAMAHA, 0x1006, 0) }, /* MOTIF7 */
696         { USB_VPI(USB_VENDOR_YAMAHA, 0x1007, 0) }, /* MOTIF8 */
697         { USB_VPI(USB_VENDOR_YAMAHA, 0x1008, 0) }, /* UX96 */
698         { USB_VPI(USB_VENDOR_YAMAHA, 0x1009, 0) }, /* UX16 */
699         { USB_VPI(USB_VENDOR_YAMAHA, 0x100a, 3) }, /* EOS BX */
700         { USB_VPI(USB_VENDOR_YAMAHA, 0x100c, 0) }, /* UC-MX */
701         { USB_VPI(USB_VENDOR_YAMAHA, 0x100d, 0) }, /* UC-KX */
702         { USB_VPI(USB_VENDOR_YAMAHA, 0x100e, 0) }, /* S08 */
703         { USB_VPI(USB_VENDOR_YAMAHA, 0x100f, 0) }, /* CLP-150 */
704         { USB_VPI(USB_VENDOR_YAMAHA, 0x1010, 0) }, /* CLP-170 */
705         { USB_VPI(USB_VENDOR_YAMAHA, 0x1011, 0) }, /* P-250 */
706         { USB_VPI(USB_VENDOR_YAMAHA, 0x1012, 0) }, /* TYROS */
707         { USB_VPI(USB_VENDOR_YAMAHA, 0x1013, 0) }, /* PF-500 */
708         { USB_VPI(USB_VENDOR_YAMAHA, 0x1014, 0) }, /* S90 */
709         { USB_VPI(USB_VENDOR_YAMAHA, 0x1015, 0) }, /* MOTIF-R */
710         { USB_VPI(USB_VENDOR_YAMAHA, 0x1016, 0) }, /* MDP-5 */
711         { USB_VPI(USB_VENDOR_YAMAHA, 0x1017, 0) }, /* CVP-204 */
712         { USB_VPI(USB_VENDOR_YAMAHA, 0x1018, 0) }, /* CVP-206 */
713         { USB_VPI(USB_VENDOR_YAMAHA, 0x1019, 0) }, /* CVP-208 */
714         { USB_VPI(USB_VENDOR_YAMAHA, 0x101a, 0) }, /* CVP-210 */
715         { USB_VPI(USB_VENDOR_YAMAHA, 0x101b, 0) }, /* PSR-1100 */
716         { USB_VPI(USB_VENDOR_YAMAHA, 0x101c, 0) }, /* PSR-2100 */
717         { USB_VPI(USB_VENDOR_YAMAHA, 0x101d, 0) }, /* CLP-175 */
718         { USB_VPI(USB_VENDOR_YAMAHA, 0x101e, 0) }, /* PSR-K1 */
719         { USB_VPI(USB_VENDOR_YAMAHA, 0x101f, 0) }, /* EZ-J24 */
720         { USB_VPI(USB_VENDOR_YAMAHA, 0x1020, 0) }, /* EZ-250i */
721         { USB_VPI(USB_VENDOR_YAMAHA, 0x1021, 0) }, /* MOTIF ES 6 */
722         { USB_VPI(USB_VENDOR_YAMAHA, 0x1022, 0) }, /* MOTIF ES 7 */
723         { USB_VPI(USB_VENDOR_YAMAHA, 0x1023, 0) }, /* MOTIF ES 8 */
724         { USB_VPI(USB_VENDOR_YAMAHA, 0x1024, 0) }, /* CVP-301 */
725         { USB_VPI(USB_VENDOR_YAMAHA, 0x1025, 0) }, /* CVP-303 */
726         { USB_VPI(USB_VENDOR_YAMAHA, 0x1026, 0) }, /* CVP-305 */
727         { USB_VPI(USB_VENDOR_YAMAHA, 0x1027, 0) }, /* CVP-307 */
728         { USB_VPI(USB_VENDOR_YAMAHA, 0x1028, 0) }, /* CVP-309 */
729         { USB_VPI(USB_VENDOR_YAMAHA, 0x1029, 0) }, /* CVP-309GP */
730         { USB_VPI(USB_VENDOR_YAMAHA, 0x102a, 0) }, /* PSR-1500 */
731         { USB_VPI(USB_VENDOR_YAMAHA, 0x102b, 0) }, /* PSR-3000 */
732         { USB_VPI(USB_VENDOR_YAMAHA, 0x102e, 0) }, /* ELS-01/01C */
733         { USB_VPI(USB_VENDOR_YAMAHA, 0x1030, 0) }, /* PSR-295/293 */
734         { USB_VPI(USB_VENDOR_YAMAHA, 0x1031, 0) }, /* DGX-205/203 */
735         { USB_VPI(USB_VENDOR_YAMAHA, 0x1032, 0) }, /* DGX-305 */
736         { USB_VPI(USB_VENDOR_YAMAHA, 0x1033, 0) }, /* DGX-505 */
737         { USB_VPI(USB_VENDOR_YAMAHA, 0x1034, 0) }, /* NULL */
738         { USB_VPI(USB_VENDOR_YAMAHA, 0x1035, 0) }, /* NULL */
739         { USB_VPI(USB_VENDOR_YAMAHA, 0x1036, 0) }, /* NULL */
740         { USB_VPI(USB_VENDOR_YAMAHA, 0x1037, 0) }, /* NULL */
741         { USB_VPI(USB_VENDOR_YAMAHA, 0x1038, 0) }, /* NULL */
742         { USB_VPI(USB_VENDOR_YAMAHA, 0x1039, 0) }, /* NULL */
743         { USB_VPI(USB_VENDOR_YAMAHA, 0x103a, 0) }, /* NULL */
744         { USB_VPI(USB_VENDOR_YAMAHA, 0x103b, 0) }, /* NULL */
745         { USB_VPI(USB_VENDOR_YAMAHA, 0x103c, 0) }, /* NULL */
746         { USB_VPI(USB_VENDOR_YAMAHA, 0x103d, 0) }, /* NULL */
747         { USB_VPI(USB_VENDOR_YAMAHA, 0x103e, 0) }, /* NULL */
748         { USB_VPI(USB_VENDOR_YAMAHA, 0x103f, 0) }, /* NULL */
749         { USB_VPI(USB_VENDOR_YAMAHA, 0x1040, 0) }, /* NULL */
750         { USB_VPI(USB_VENDOR_YAMAHA, 0x1041, 0) }, /* NULL */
751         { USB_VPI(USB_VENDOR_YAMAHA, 0x1042, 0) }, /* NULL */
752         { USB_VPI(USB_VENDOR_YAMAHA, 0x1043, 0) }, /* NULL */
753         { USB_VPI(USB_VENDOR_YAMAHA, 0x1044, 0) }, /* NULL */
754         { USB_VPI(USB_VENDOR_YAMAHA, 0x1045, 0) }, /* NULL */
755         { USB_VPI(USB_VENDOR_YAMAHA, 0x104e, 0) }, /* NULL */
756         { USB_VPI(USB_VENDOR_YAMAHA, 0x104f, 0) }, /* NULL */
757         { USB_VPI(USB_VENDOR_YAMAHA, 0x1050, 0) }, /* NULL */
758         { USB_VPI(USB_VENDOR_YAMAHA, 0x1051, 0) }, /* NULL */
759         { USB_VPI(USB_VENDOR_YAMAHA, 0x1052, 0) }, /* NULL */
760         { USB_VPI(USB_VENDOR_YAMAHA, 0x1053, 0) }, /* NULL */
761         { USB_VPI(USB_VENDOR_YAMAHA, 0x1054, 0) }, /* NULL */
762         { USB_VPI(USB_VENDOR_YAMAHA, 0x1055, 0) }, /* NULL */
763         { USB_VPI(USB_VENDOR_YAMAHA, 0x1056, 0) }, /* NULL */
764         { USB_VPI(USB_VENDOR_YAMAHA, 0x1057, 0) }, /* NULL */
765         { USB_VPI(USB_VENDOR_YAMAHA, 0x1058, 0) }, /* NULL */
766         { USB_VPI(USB_VENDOR_YAMAHA, 0x1059, 0) }, /* NULL */
767         { USB_VPI(USB_VENDOR_YAMAHA, 0x105a, 0) }, /* NULL */
768         { USB_VPI(USB_VENDOR_YAMAHA, 0x105b, 0) }, /* NULL */
769         { USB_VPI(USB_VENDOR_YAMAHA, 0x105c, 0) }, /* NULL */
770         { USB_VPI(USB_VENDOR_YAMAHA, 0x105d, 0) }, /* NULL */
771         { USB_VPI(USB_VENDOR_YAMAHA, 0x1503, 3) }, /* MOX6/MOX8 */
772         { USB_VPI(USB_VENDOR_YAMAHA, 0x2000, 0) }, /* DGP-7 */
773         { USB_VPI(USB_VENDOR_YAMAHA, 0x2001, 0) }, /* DGP-5 */
774         { USB_VPI(USB_VENDOR_YAMAHA, 0x2002, 0) }, /* NULL */
775         { USB_VPI(USB_VENDOR_YAMAHA, 0x2003, 0) }, /* NULL */
776         { USB_VPI(USB_VENDOR_YAMAHA, 0x5000, 0) }, /* CS1D */
777         { USB_VPI(USB_VENDOR_YAMAHA, 0x5001, 0) }, /* DSP1D */
778         { USB_VPI(USB_VENDOR_YAMAHA, 0x5002, 0) }, /* DME32 */
779         { USB_VPI(USB_VENDOR_YAMAHA, 0x5003, 0) }, /* DM2000 */
780         { USB_VPI(USB_VENDOR_YAMAHA, 0x5004, 0) }, /* 02R96 */
781         { USB_VPI(USB_VENDOR_YAMAHA, 0x5005, 0) }, /* ACU16-C */
782         { USB_VPI(USB_VENDOR_YAMAHA, 0x5006, 0) }, /* NHB32-C */
783         { USB_VPI(USB_VENDOR_YAMAHA, 0x5007, 0) }, /* DM1000 */
784         { USB_VPI(USB_VENDOR_YAMAHA, 0x5008, 0) }, /* 01V96 */
785         { USB_VPI(USB_VENDOR_YAMAHA, 0x5009, 0) }, /* SPX2000 */
786         { USB_VPI(USB_VENDOR_YAMAHA, 0x500a, 0) }, /* PM5D */
787         { USB_VPI(USB_VENDOR_YAMAHA, 0x500b, 0) }, /* DME64N */
788         { USB_VPI(USB_VENDOR_YAMAHA, 0x500c, 0) }, /* DME24N */
789         { USB_VPI(USB_VENDOR_YAMAHA, 0x500d, 0) }, /* NULL */
790         { USB_VPI(USB_VENDOR_YAMAHA, 0x500e, 0) }, /* NULL */
791         { USB_VPI(USB_VENDOR_YAMAHA, 0x500f, 0) }, /* NULL */
792         { USB_VPI(USB_VENDOR_YAMAHA, 0x7000, 0) }, /* DTX */
793         { USB_VPI(USB_VENDOR_YAMAHA, 0x7010, 0) }, /* UB99 */
794 };
795
796 static const STRUCT_USB_HOST_ID __used uaudio_devs[] = {
797         /* Generic USB audio class match */
798         {USB_IFACE_CLASS(UICLASS_AUDIO),
799          USB_IFACE_SUBCLASS(UISUBCLASS_AUDIOCONTROL),},
800         /* Generic USB MIDI class match */
801         {USB_IFACE_CLASS(UICLASS_AUDIO),
802          USB_IFACE_SUBCLASS(UISUBCLASS_MIDISTREAM),},
803 };
804
805 static int
806 uaudio_probe(device_t dev)
807 {
808         struct usb_attach_arg *uaa = device_get_ivars(dev);
809
810         if (uaa->usb_mode != USB_MODE_HOST)
811                 return (ENXIO);
812
813         /* lookup non-standard device(s) */
814
815         if (usbd_lookup_id_by_uaa(uaudio_vendor_midi,
816             sizeof(uaudio_vendor_midi), uaa) == 0) {
817                 return (BUS_PROBE_SPECIFIC);
818         }
819
820         if (uaa->info.bInterfaceClass != UICLASS_AUDIO) {
821                 if (uaa->info.bInterfaceClass != UICLASS_VENDOR ||
822                     usb_test_quirk(uaa, UQ_AU_VENDOR_CLASS) == 0)
823                         return (ENXIO);
824         }
825
826         /* check for AUDIO control interface */
827
828         if (uaa->info.bInterfaceSubClass == UISUBCLASS_AUDIOCONTROL) {
829                 if (usb_test_quirk(uaa, UQ_BAD_AUDIO))
830                         return (ENXIO);
831                 else
832                         return (BUS_PROBE_GENERIC);
833         }
834
835         /* check for MIDI stream */
836
837         if (uaa->info.bInterfaceSubClass == UISUBCLASS_MIDISTREAM) {
838                 if (usb_test_quirk(uaa, UQ_BAD_MIDI))
839                         return (ENXIO);
840                 else
841                         return (BUS_PROBE_GENERIC);
842         }
843         return (ENXIO);
844 }
845
846 static int
847 uaudio_attach(device_t dev)
848 {
849         struct usb_attach_arg *uaa = device_get_ivars(dev);
850         struct uaudio_softc *sc = device_get_softc(dev);
851         struct usb_interface_descriptor *id;
852         device_t child;
853
854         sc->sc_play_chan.priv_sc = sc;
855         sc->sc_rec_chan.priv_sc = sc;
856         sc->sc_udev = uaa->device;
857         sc->sc_mixer_iface_index = uaa->info.bIfaceIndex;
858         sc->sc_mixer_iface_no = uaa->info.bIfaceNum;
859
860         if (usb_test_quirk(uaa, UQ_AUDIO_SWAP_LR))
861                 sc->sc_uq_audio_swap_lr = 1;
862
863         if (usb_test_quirk(uaa, UQ_AU_INP_ASYNC))
864                 sc->sc_uq_au_inp_async = 1;
865
866         if (usb_test_quirk(uaa, UQ_AU_NO_XU))
867                 sc->sc_uq_au_no_xu = 1;
868
869         if (usb_test_quirk(uaa, UQ_BAD_ADC))
870                 sc->sc_uq_bad_adc = 1;
871
872         if (usb_test_quirk(uaa, UQ_AU_VENDOR_CLASS))
873                 sc->sc_uq_au_vendor_class = 1;
874
875         umidi_init(dev);
876
877         device_set_usb_desc(dev);
878
879         id = usbd_get_interface_descriptor(uaa->iface);
880
881         /* must fill mixer info before channel info */
882         uaudio_mixer_fill_info(sc, uaa->device, id);
883
884         /* fill channel info */
885         uaudio_chan_fill_info(sc, uaa->device);
886
887         DPRINTF("audio rev %d.%02x\n",
888             sc->sc_audio_rev >> 8,
889             sc->sc_audio_rev & 0xff);
890
891         if (sc->sc_mixer_count == 0) {
892                 if (uaa->info.idVendor == USB_VENDOR_MAUDIO &&
893                     (uaa->info.idProduct == USB_PRODUCT_MAUDIO_FASTTRACKULTRA ||
894                     uaa->info.idProduct == USB_PRODUCT_MAUDIO_FASTTRACKULTRA8R)) {
895                         DPRINTF("Generating mixer descriptors\n");
896                         uaudio_mixer_controls_create_ftu(sc);
897                 }
898         }
899
900         DPRINTF("%d mixer controls\n",
901             sc->sc_mixer_count);
902
903         if (sc->sc_play_chan.valid) {
904                 device_printf(dev, "Play: %d Hz, %d ch, %s format, "
905                     "2x8ms buffer.\n",
906                     sc->sc_play_chan.sample_rate,
907                     sc->sc_play_chan.channels,
908                     sc->sc_play_chan.p_fmt->description);
909         } else {
910                 device_printf(dev, "No playback.\n");
911         }
912
913         if (sc->sc_rec_chan.valid) {
914                 device_printf(dev, "Record: %d Hz, %d ch, %s format, "
915                     "2x8ms buffer.\n",
916                     sc->sc_rec_chan.sample_rate,
917                     sc->sc_rec_chan.channels,
918                     sc->sc_rec_chan.p_fmt->description);
919         } else {
920                 device_printf(dev, "No recording.\n");
921         }
922
923         if (sc->sc_midi_chan.valid == 0) {
924                 if (usbd_lookup_id_by_uaa(uaudio_vendor_midi,
925                     sizeof(uaudio_vendor_midi), uaa) == 0) {
926                         sc->sc_midi_chan.iface_index =
927                             (uint8_t)uaa->driver_info;
928                         sc->sc_midi_chan.iface_alt_index = 0;
929                         sc->sc_midi_chan.valid = 1;
930                 }
931         }
932
933         if (sc->sc_midi_chan.valid) {
934
935                 if (umidi_probe(dev)) {
936                         goto detach;
937                 }
938                 device_printf(dev, "MIDI sequencer.\n");
939         } else {
940                 device_printf(dev, "No MIDI sequencer.\n");
941         }
942
943         DPRINTF("doing child attach\n");
944
945         /* attach the children */
946
947         sc->sc_sndcard_func.func = SCF_PCM;
948
949         /*
950          * Only attach a PCM device if we have a playback, recording
951          * or mixer device present:
952          */
953         if (sc->sc_play_chan.valid ||
954             sc->sc_rec_chan.valid ||
955             sc->sc_mix_info) {
956                 child = device_add_child(dev, "pcm", -1);
957
958                 if (child == NULL) {
959                         DPRINTF("out of memory\n");
960                         goto detach;
961                 }
962                 device_set_ivars(child, &sc->sc_sndcard_func);
963         }
964
965         if (bus_generic_attach(dev)) {
966                 DPRINTF("child attach failed\n");
967                 goto detach;
968         }
969
970         if (uaudio_hid_probe(sc, uaa) == 0) {
971                 device_printf(dev, "HID volume keys found.\n");
972         } else {
973                 device_printf(dev, "No HID volume keys found.\n");
974         }
975
976         /* reload all mixer settings */
977         uaudio_mixer_reload_all(sc);
978
979         return (0);                     /* success */
980
981 detach:
982         uaudio_detach(dev);
983         return (ENXIO);
984 }
985
986 static void
987 uaudio_pcm_setflags(device_t dev, uint32_t flags)
988 {
989         pcm_setflags(dev, pcm_getflags(dev) | flags);
990 }
991
992 int
993 uaudio_attach_sub(device_t dev, kobj_class_t mixer_class, kobj_class_t chan_class)
994 {
995         struct uaudio_softc *sc = device_get_softc(device_get_parent(dev));
996         char status[SND_STATUSLEN];
997
998         uaudio_mixer_init(sc);
999
1000         if (sc->sc_uq_audio_swap_lr) {
1001                 DPRINTF("hardware has swapped left and right\n");
1002                 /* uaudio_pcm_setflags(dev, SD_F_PSWAPLR); */
1003         }
1004         if (!(sc->sc_mix_info & SOUND_MASK_PCM)) {
1005
1006                 DPRINTF("emulating master volume\n");
1007
1008                 /*
1009                  * Emulate missing pcm mixer controller
1010                  * through FEEDER_VOLUME
1011                  */
1012                 uaudio_pcm_setflags(dev, SD_F_SOFTPCMVOL);
1013         }
1014         if (mixer_init(dev, mixer_class, sc))
1015                 goto detach;
1016         sc->sc_mixer_init = 1;
1017
1018         mixer_hwvol_init(dev);
1019
1020         snprintf(status, sizeof(status), "at ? %s", PCM_KLDSTRING(snd_uaudio));
1021
1022         if (pcm_register(dev, sc,
1023             sc->sc_play_chan.valid ? 1 : 0,
1024             sc->sc_rec_chan.valid ? 1 : 0)) {
1025                 goto detach;
1026         }
1027
1028         uaudio_pcm_setflags(dev, SD_F_MPSAFE);
1029         sc->sc_pcm_registered = 1;
1030
1031         if (sc->sc_play_chan.valid) {
1032                 pcm_addchan(dev, PCMDIR_PLAY, chan_class, sc);
1033         }
1034         if (sc->sc_rec_chan.valid) {
1035                 pcm_addchan(dev, PCMDIR_REC, chan_class, sc);
1036         }
1037         pcm_setstatus(dev, status);
1038
1039         uaudio_mixer_register_sysctl(sc, dev);
1040
1041         return (0);                     /* success */
1042
1043 detach:
1044         uaudio_detach_sub(dev);
1045         return (ENXIO);
1046 }
1047
1048 int
1049 uaudio_detach_sub(device_t dev)
1050 {
1051         struct uaudio_softc *sc = device_get_softc(device_get_parent(dev));
1052         int error = 0;
1053
1054 repeat:
1055         if (sc->sc_pcm_registered) {
1056                 error = pcm_unregister(dev);
1057         } else {
1058                 if (sc->sc_mixer_init) {
1059                         error = mixer_uninit(dev);
1060                 }
1061         }
1062
1063         if (error) {
1064                 device_printf(dev, "Waiting for sound application to exit!\n");
1065                 usb_pause_mtx(NULL, 2 * hz);
1066                 goto repeat;            /* try again */
1067         }
1068         return (0);                     /* success */
1069 }
1070
1071 static int
1072 uaudio_detach(device_t dev)
1073 {
1074         struct uaudio_softc *sc = device_get_softc(dev);
1075
1076         /*
1077          * Stop USB transfers early so that any audio applications
1078          * will time out and close opened /dev/dspX.Y device(s), if
1079          * any.
1080          */
1081         if (sc->sc_play_chan.valid)
1082                 usbd_transfer_unsetup(sc->sc_play_chan.xfer, UAUDIO_NCHANBUFS + 1);
1083         if (sc->sc_rec_chan.valid)
1084                 usbd_transfer_unsetup(sc->sc_rec_chan.xfer, UAUDIO_NCHANBUFS + 1);
1085
1086         uaudio_hid_detach(sc);
1087
1088         if (bus_generic_detach(dev) != 0) {
1089                 DPRINTF("detach failed!\n");
1090         }
1091         sbuf_delete(&sc->sc_sndstat);
1092         sc->sc_sndstat_valid = 0;
1093
1094         umidi_detach(dev);
1095
1096         /* free mixer data */
1097
1098         uaudio_mixer_ctl_free(sc);
1099
1100         return (0);
1101 }
1102
1103 /*========================================================================*
1104  * AS - Audio Stream - routines
1105  *========================================================================*/
1106
1107 #ifdef USB_DEBUG
1108 static void
1109 uaudio_chan_dump_ep_desc(const usb_endpoint_descriptor_audio_t *ed)
1110 {
1111         if (ed) {
1112                 DPRINTF("endpoint=%p bLength=%d bDescriptorType=%d \n"
1113                     "bEndpointAddress=%d bmAttributes=0x%x \n"
1114                     "wMaxPacketSize=%d bInterval=%d \n"
1115                     "bRefresh=%d bSynchAddress=%d\n",
1116                     ed, ed->bLength, ed->bDescriptorType,
1117                     ed->bEndpointAddress, ed->bmAttributes,
1118                     UGETW(ed->wMaxPacketSize), ed->bInterval,
1119                     UEP_HAS_REFRESH(ed) ? ed->bRefresh : 0,
1120                     UEP_HAS_SYNCADDR(ed) ? ed->bSynchAddress : 0);
1121         }
1122 }
1123
1124 #endif
1125
1126 /*
1127  * The following is a workaround for broken no-name USB audio devices
1128  * sold by dealextreme called "3D sound". The problem is that the
1129  * manufacturer computed wMaxPacketSize is too small to hold the
1130  * actual data sent. In other words the device sometimes sends more
1131  * data than it actually reports it can send in a single isochronous
1132  * packet.
1133  */
1134 static void
1135 uaudio_record_fix_fs(usb_endpoint_descriptor_audio_t *ep,
1136     uint32_t xps, uint32_t add)
1137 {
1138         uint32_t mps;
1139
1140         mps = UGETW(ep->wMaxPacketSize);
1141
1142         /*
1143          * If the device indicates it can send more data than what the
1144          * sample rate indicates, we apply the workaround.
1145          */
1146         if (mps > xps) {
1147
1148                 /* allow additional data */
1149                 xps += add;
1150
1151                 /* check against the maximum USB 1.x length */
1152                 if (xps > 1023)
1153                         xps = 1023;
1154
1155                 /* check if we should do an update */
1156                 if (mps < xps) {
1157                         /* simply update the wMaxPacketSize field */
1158                         USETW(ep->wMaxPacketSize, xps);
1159                         DPRINTF("Workaround: Updated wMaxPacketSize "
1160                             "from %d to %d bytes.\n",
1161                             (int)mps, (int)xps);
1162                 }
1163         }
1164 }
1165
1166 static usb_error_t
1167 uaudio20_check_rate(struct usb_device *udev, uint8_t iface_no,
1168     uint8_t clockid, uint32_t rate)
1169 {
1170         struct usb_device_request req;
1171         usb_error_t error;
1172         uint8_t data[255];
1173         uint16_t actlen;
1174         uint16_t rates;
1175         uint16_t x;
1176
1177         DPRINTFN(6, "ifaceno=%d clockid=%d rate=%u\n",
1178             iface_no, clockid, rate);
1179
1180         req.bmRequestType = UT_READ_CLASS_INTERFACE;
1181         req.bRequest = UA20_CS_RANGE;
1182         USETW2(req.wValue, UA20_CS_SAM_FREQ_CONTROL, 0);
1183         USETW2(req.wIndex, clockid, iface_no);
1184         USETW(req.wLength, 255);
1185
1186         error = usbd_do_request_flags(udev, NULL, &req, data,
1187             USB_SHORT_XFER_OK, &actlen, USB_DEFAULT_TIMEOUT);
1188
1189         if (error != 0 || actlen < 2)
1190                 return (USB_ERR_INVAL);
1191
1192         rates = data[0] | (data[1] << 8);
1193         actlen = (actlen - 2) / 12;
1194
1195         if (rates > actlen) {
1196                 DPRINTF("Too many rates\n");
1197                 rates = actlen;
1198         }
1199
1200         for (x = 0; x != rates; x++) {
1201                 uint32_t min = UGETDW(data + 2 + (12 * x));
1202                 uint32_t max = UGETDW(data + 6 + (12 * x));
1203                 uint32_t res = UGETDW(data + 10 + (12 * x));
1204
1205                 if (res == 0) {
1206                         DPRINTF("Zero residue\n");
1207                         res = 1;
1208                 }
1209
1210                 if (min > max) {
1211                         DPRINTF("Swapped max and min\n");
1212                         uint32_t temp;
1213                         temp = min;
1214                         min = max;
1215                         max = temp;
1216                 }
1217
1218                 if (rate >= min && rate <= max &&
1219                     (((rate - min) % res) == 0)) {
1220                         return (0);
1221                 }
1222         }
1223         return (USB_ERR_INVAL);
1224 }
1225
1226 static void
1227 uaudio_chan_fill_info_sub(struct uaudio_softc *sc, struct usb_device *udev,
1228     uint32_t rate, uint8_t channels, uint8_t bit_resolution)
1229 {
1230         struct usb_descriptor *desc = NULL;
1231         union uaudio_asid asid = { NULL };
1232         union uaudio_asf1d asf1d = { NULL };
1233         union uaudio_sed sed = { NULL };
1234         usb_endpoint_descriptor_audio_t *ed1 = NULL;
1235         const struct usb_audio_control_descriptor *acdp = NULL;
1236         struct usb_config_descriptor *cd = usbd_get_config_descriptor(udev);
1237         struct usb_interface_descriptor *id;
1238         const struct uaudio_format *p_fmt = NULL;
1239         struct uaudio_chan *chan;
1240         uint16_t curidx = 0xFFFF;
1241         uint16_t lastidx = 0xFFFF;
1242         uint16_t alt_index = 0;
1243         uint16_t audio_rev = 0;
1244         uint16_t x;
1245         uint8_t ep_dir;
1246         uint8_t bChannels;
1247         uint8_t bBitResolution;
1248         uint8_t audio_if = 0;
1249         uint8_t uma_if_class;
1250
1251         while ((desc = usb_desc_foreach(cd, desc))) {
1252
1253                 if ((desc->bDescriptorType == UDESC_INTERFACE) &&
1254                     (desc->bLength >= sizeof(*id))) {
1255
1256                         id = (void *)desc;
1257
1258                         if (id->bInterfaceNumber != lastidx) {
1259                                 lastidx = id->bInterfaceNumber;
1260                                 curidx++;
1261                                 alt_index = 0;
1262
1263                         } else {
1264                                 alt_index++;
1265                         }
1266
1267                         if ((!(sc->sc_hid.flags & UAUDIO_HID_VALID)) &&
1268                             (id->bInterfaceClass == UICLASS_HID) &&
1269                             (id->bInterfaceSubClass == 0) &&
1270                             (id->bInterfaceProtocol == 0) &&
1271                             (alt_index == 0) &&
1272                             usbd_get_iface(udev, curidx) != NULL) {
1273                                 DPRINTF("Found HID interface at %d\n",
1274                                     curidx);
1275                                 sc->sc_hid.flags |= UAUDIO_HID_VALID;
1276                                 sc->sc_hid.iface_index = curidx;
1277                         }
1278
1279                         uma_if_class =
1280                             ((id->bInterfaceClass == UICLASS_AUDIO) ||
1281                             ((id->bInterfaceClass == UICLASS_VENDOR) &&
1282                             (sc->sc_uq_au_vendor_class != 0)));
1283
1284                         if ((uma_if_class != 0) && (id->bInterfaceSubClass == UISUBCLASS_AUDIOSTREAM)) {
1285                                 audio_if = 1;
1286                         } else {
1287                                 audio_if = 0;
1288                         }
1289
1290                         if ((uma_if_class != 0) &&
1291                             (id->bInterfaceSubClass == UISUBCLASS_MIDISTREAM)) {
1292
1293                                 /*
1294                                  * XXX could allow multiple MIDI interfaces
1295                                  */
1296
1297                                 if ((sc->sc_midi_chan.valid == 0) &&
1298                                     usbd_get_iface(udev, curidx)) {
1299                                         sc->sc_midi_chan.iface_index = curidx;
1300                                         sc->sc_midi_chan.iface_alt_index = alt_index;
1301                                         sc->sc_midi_chan.valid = 1;
1302                                 }
1303                         }
1304                         asid.v1 = NULL;
1305                         asf1d.v1 = NULL;
1306                         ed1 = NULL;
1307                         sed.v1 = NULL;
1308                 }
1309
1310                 if (audio_if == 0) {
1311                         if ((acdp == NULL) &&
1312                             (desc->bDescriptorType == UDESC_CS_INTERFACE) &&
1313                             (desc->bDescriptorSubtype == UDESCSUB_AC_HEADER) &&
1314                             (desc->bLength >= sizeof(*acdp))) {
1315                                 acdp = (void *)desc;
1316                                 audio_rev = UGETW(acdp->bcdADC);
1317                         }
1318
1319                         /*
1320                          * Don't collect any USB audio descriptors if
1321                          * this is not an USB audio stream interface.
1322                          */
1323                         continue;
1324                 }
1325
1326                 if ((acdp != NULL) &&
1327                     (desc->bDescriptorType == UDESC_CS_INTERFACE) &&
1328                     (desc->bDescriptorSubtype == AS_GENERAL) &&
1329                     (asid.v1 == NULL)) {
1330                         if (audio_rev >= UAUDIO_VERSION_30) {
1331                                 /* FALLTHROUGH */
1332                         } else if (audio_rev >= UAUDIO_VERSION_20) {
1333                                 if (desc->bLength >= sizeof(*asid.v2)) {
1334                                         asid.v2 = (void *)desc;
1335                                 }
1336                         } else {
1337                                 if (desc->bLength >= sizeof(*asid.v1)) {
1338                                         asid.v1 = (void *)desc;
1339                                 }
1340                         }
1341                 }
1342                 if ((acdp != NULL) &&
1343                     (desc->bDescriptorType == UDESC_CS_INTERFACE) &&
1344                     (desc->bDescriptorSubtype == FORMAT_TYPE) &&
1345                     (asf1d.v1 == NULL)) {
1346                         if (audio_rev >= UAUDIO_VERSION_30) {
1347                                 /* FALLTHROUGH */
1348                         } else if (audio_rev >= UAUDIO_VERSION_20) {
1349                                 if (desc->bLength >= sizeof(*asf1d.v2))
1350                                         asf1d.v2 = (void *)desc;
1351                         } else {
1352                                 if (desc->bLength >= sizeof(*asf1d.v1)) {
1353                                         asf1d.v1 = (void *)desc;
1354
1355                                         if (asf1d.v1->bFormatType != FORMAT_TYPE_I) {
1356                                                 DPRINTFN(11, "ignored bFormatType = %d\n",
1357                                                     asf1d.v1->bFormatType);
1358                                                 asf1d.v1 = NULL;
1359                                                 continue;
1360                                         }
1361                                         if (desc->bLength < (sizeof(*asf1d.v1) +
1362                                             ((asf1d.v1->bSamFreqType == 0) ? 6 :
1363                                             (asf1d.v1->bSamFreqType * 3)))) {
1364                                                 DPRINTFN(11, "invalid descriptor, "
1365                                                     "too short\n");
1366                                                 asf1d.v1 = NULL;
1367                                                 continue;
1368                                         }
1369                                 }
1370                         }
1371                 }
1372                 if ((desc->bDescriptorType == UDESC_ENDPOINT) &&
1373                     (desc->bLength >= UEP_MINSIZE) &&
1374                     (ed1 == NULL)) {
1375                         ed1 = (void *)desc;
1376                         if (UE_GET_XFERTYPE(ed1->bmAttributes) != UE_ISOCHRONOUS) {
1377                                 ed1 = NULL;
1378                                 continue;
1379                         }
1380                 }
1381                 if ((acdp != NULL) &&
1382                     (desc->bDescriptorType == UDESC_CS_ENDPOINT) &&
1383                     (desc->bDescriptorSubtype == AS_GENERAL) &&
1384                     (sed.v1 == NULL)) {
1385                         if (audio_rev >= UAUDIO_VERSION_30) {
1386                                 /* FALLTHROUGH */
1387                         } else if (audio_rev >= UAUDIO_VERSION_20) {
1388                                 if (desc->bLength >= sizeof(*sed.v2))
1389                                         sed.v2 = (void *)desc;
1390                         } else {
1391                                 if (desc->bLength >= sizeof(*sed.v1))
1392                                         sed.v1 = (void *)desc;
1393                         }
1394                 }
1395                 if (asid.v1 == NULL || asf1d.v1 == NULL ||
1396                     ed1 == NULL || sed.v1 == NULL) {
1397                         /* need more descriptors */
1398                         continue;
1399                 }
1400
1401                 ep_dir = UE_GET_DIR(ed1->bEndpointAddress);
1402
1403                 /* We ignore sync endpoint information until further. */
1404
1405                 if (audio_rev >= UAUDIO_VERSION_30) {
1406                         goto next_ep;
1407                 } else if (audio_rev >= UAUDIO_VERSION_20) {
1408
1409                         uint32_t dwFormat;
1410                         uint8_t bSubslotSize;
1411
1412                         dwFormat = UGETDW(asid.v2->bmFormats);
1413                         bChannels = asid.v2->bNrChannels;
1414                         bBitResolution = asf1d.v2->bBitResolution;
1415                         bSubslotSize = asf1d.v2->bSubslotSize;
1416
1417                         if (bBitResolution != (bSubslotSize * 8)) {
1418                                 DPRINTF("Invalid bSubslotSize\n");
1419                                 goto next_ep;
1420                         }
1421
1422                         if ((bChannels != channels) ||
1423                             (bBitResolution != bit_resolution)) {
1424                                 DPRINTF("Wrong number of channels\n");
1425                                 goto next_ep;
1426                         }
1427
1428                         for (p_fmt = uaudio20_formats;
1429                             p_fmt->wFormat != 0; p_fmt++) {
1430                                 if ((p_fmt->wFormat & dwFormat) &&
1431                                     (p_fmt->bPrecision == bBitResolution))
1432                                         break;
1433                         }
1434
1435                         if (p_fmt->wFormat == 0) {
1436                                 DPRINTF("Unsupported audio format\n");
1437                                 goto next_ep;
1438                         }
1439
1440                         for (x = 0; x != 256; x++) {
1441                                 if (ep_dir == UE_DIR_OUT) {
1442                                         if (!(sc->sc_mixer_clocks.bit_output[x / 8] &
1443                                             (1 << (x % 8)))) {
1444                                                 continue;
1445                                         }
1446                                 } else {
1447                                         if (!(sc->sc_mixer_clocks.bit_input[x / 8] &
1448                                             (1 << (x % 8)))) {
1449                                                 continue;
1450                                         }
1451                                 }
1452
1453                                 DPRINTF("Checking clock ID=%d\n", x);
1454
1455                                 if (uaudio20_check_rate(udev,
1456                                     sc->sc_mixer_iface_no, x, rate)) {
1457                                         DPRINTF("Unsupported sampling "
1458                                             "rate, id=%d\n", x);
1459                                         goto next_ep;
1460                                 }
1461                         }
1462                 } else {
1463                         uint16_t wFormat;
1464
1465                         wFormat = UGETW(asid.v1->wFormatTag);
1466                         bChannels = UAUDIO_MAX_CHAN(asf1d.v1->bNrChannels);
1467                         bBitResolution = asf1d.v1->bBitResolution;
1468
1469                         if (asf1d.v1->bSamFreqType == 0) {
1470                                 DPRINTFN(16, "Sample rate: %d-%dHz\n",
1471                                     UA_SAMP_LO(asf1d.v1),
1472                                     UA_SAMP_HI(asf1d.v1));
1473
1474                                 if ((rate >= UA_SAMP_LO(asf1d.v1)) &&
1475                                     (rate <= UA_SAMP_HI(asf1d.v1)))
1476                                         goto found_rate;
1477                         } else {
1478
1479                                 for (x = 0; x < asf1d.v1->bSamFreqType; x++) {
1480                                         DPRINTFN(16, "Sample rate = %dHz\n",
1481                                             UA_GETSAMP(asf1d.v1, x));
1482
1483                                         if (rate == UA_GETSAMP(asf1d.v1, x))
1484                                                 goto found_rate;
1485                                 }
1486                         }
1487                         goto next_ep;
1488
1489         found_rate:
1490                         for (p_fmt = uaudio10_formats;
1491                             p_fmt->wFormat != 0; p_fmt++) {
1492                                 if ((p_fmt->wFormat == wFormat) &&
1493                                     (p_fmt->bPrecision == bBitResolution))
1494                                         break;
1495                         }
1496                         if (p_fmt->wFormat == 0) {
1497                                 DPRINTF("Unsupported audio format\n");
1498                                 goto next_ep;
1499                         }
1500
1501                         if ((bChannels != channels) ||
1502                             (bBitResolution != bit_resolution)) {
1503                                 DPRINTF("Wrong number of channels\n");
1504                                 goto next_ep;
1505                         }
1506                 }
1507
1508                 chan = (ep_dir == UE_DIR_IN) ?
1509                     &sc->sc_rec_chan : &sc->sc_play_chan;
1510
1511                 if (chan->valid != 0 ||
1512                     usbd_get_iface(udev, curidx) == NULL) {
1513                         DPRINTF("Channel already exists or "
1514                             "interface is not valid\n");
1515                         goto next_ep;
1516                 }
1517
1518                 chan->valid = 1;
1519 #ifdef USB_DEBUG
1520                 uaudio_chan_dump_ep_desc(ed1);
1521 #endif
1522                 DPRINTF("Sample rate = %dHz, channels = %d, "
1523                     "bits = %d, format = %s\n", rate, channels,
1524                     bit_resolution, p_fmt->description);
1525
1526                 chan->sample_rate = rate;
1527                 chan->p_asf1d = asf1d;
1528                 chan->p_ed1 = ed1;
1529                 chan->p_fmt = p_fmt;
1530                 chan->p_sed = sed;
1531                 chan->iface_index = curidx;
1532                 chan->iface_alt_index = alt_index;
1533
1534                 if (ep_dir == UE_DIR_IN)
1535                         chan->usb_cfg = uaudio_cfg_record;
1536                 else
1537                         chan->usb_cfg = uaudio_cfg_play;
1538
1539                 chan->sample_size = (UAUDIO_MAX_CHAN(channels) *
1540                     p_fmt->bPrecision) / 8;
1541                 chan->channels = channels;
1542
1543                 if (ep_dir == UE_DIR_IN &&
1544                     usbd_get_speed(udev) == USB_SPEED_FULL) {
1545                         uaudio_record_fix_fs(ed1,
1546                             chan->sample_size * (rate / 1000),
1547                             chan->sample_size * (rate / 4000));
1548                 }
1549
1550                 if (sc->sc_sndstat_valid != 0) {
1551                         sbuf_printf(&sc->sc_sndstat, "\n\t"
1552                             "mode %d.%d:(%s) %dch, %dbit, %s, %dHz",
1553                             curidx, alt_index,
1554                             (ep_dir == UE_DIR_IN) ? "input" : "output",
1555                                     channels, p_fmt->bPrecision,
1556                                     p_fmt->description, rate);
1557                 }
1558
1559         next_ep:
1560                 sed.v1 = NULL;
1561                 ed1 = NULL;
1562         }
1563 }
1564
1565 /* This structure defines all the supported rates. */
1566
1567 static const uint32_t uaudio_rate_list[] = {
1568         96000,
1569         88000,
1570         80000,
1571         72000,
1572         64000,
1573         56000,
1574         48000,
1575         44100,
1576         40000,
1577         32000,
1578         24000,
1579         22050,
1580         16000,
1581         11025,
1582         8000,
1583         0
1584 };
1585
1586 static void
1587 uaudio_chan_fill_info(struct uaudio_softc *sc, struct usb_device *udev)
1588 {
1589         uint32_t rate = uaudio_default_rate;
1590         uint8_t z;
1591         uint8_t bits = uaudio_default_bits;
1592         uint8_t y;
1593         uint8_t channels = uaudio_default_channels;
1594         uint8_t x;
1595
1596         bits -= (bits % 8);
1597         if ((bits == 0) || (bits > 32)) {
1598                 /* set a valid value */
1599                 bits = 32;
1600         }
1601         if (channels == 0) {
1602                 switch (usbd_get_speed(udev)) {
1603                 case USB_SPEED_LOW:
1604                 case USB_SPEED_FULL:
1605                         /*
1606                          * Due to high bandwidth usage and problems
1607                          * with HIGH-speed split transactions we
1608                          * disable surround setups on FULL-speed USB
1609                          * by default
1610                          */
1611                         channels = 4;
1612                         break;
1613                 default:
1614                         channels = 16;
1615                         break;
1616                 }
1617         } else if (channels > 16) {
1618                 channels = 16;
1619         }
1620         if (sbuf_new(&sc->sc_sndstat, NULL, 4096, SBUF_AUTOEXTEND)) {
1621                 sc->sc_sndstat_valid = 1;
1622         }
1623         /* try to search for a valid config */
1624
1625         for (x = channels; x; x--) {
1626                 for (y = bits; y; y -= 8) {
1627
1628                         /* try user defined rate, if any */
1629                         if (rate != 0)
1630                                 uaudio_chan_fill_info_sub(sc, udev, rate, x, y);
1631
1632                         /* try find a matching rate, if any */
1633                         for (z = 0; uaudio_rate_list[z]; z++) {
1634                                 uaudio_chan_fill_info_sub(sc, udev, uaudio_rate_list[z], x, y);
1635
1636                                 if (sc->sc_rec_chan.valid &&
1637                                     sc->sc_play_chan.valid) {
1638                                         goto done;
1639                                 }
1640                         }
1641                 }
1642         }
1643
1644 done:
1645         if (sc->sc_sndstat_valid) {
1646                 sbuf_finish(&sc->sc_sndstat);
1647         }
1648 }
1649
1650 static void
1651 uaudio_chan_play_sync_callback(struct usb_xfer *xfer, usb_error_t error)
1652 {
1653         struct uaudio_chan *ch = usbd_xfer_softc(xfer);
1654         struct usb_page_cache *pc;
1655         uint8_t buf[4];
1656         uint64_t temp;
1657         int len;
1658         int actlen;
1659         int nframes;
1660
1661         usbd_xfer_status(xfer, &actlen, NULL, NULL, &nframes);
1662
1663         switch (USB_GET_STATE(xfer)) {
1664         case USB_ST_TRANSFERRED:
1665
1666                 DPRINTFN(6, "transferred %d bytes\n", actlen);
1667
1668                 if (nframes == 0)
1669                         break;
1670                 len = usbd_xfer_frame_len(xfer, 0);
1671                 if (len == 0)
1672                         break;
1673                 if (len > sizeof(buf))
1674                         len = sizeof(buf);
1675
1676                 memset(buf, 0, sizeof(buf));
1677
1678                 pc = usbd_xfer_get_frame(xfer, 0);
1679                 usbd_copy_out(pc, 0, buf, len);
1680
1681                 temp = UGETDW(buf);
1682
1683                 DPRINTF("Value = 0x%08x\n", (int)temp);
1684
1685                 /* auto-detect SYNC format */
1686
1687                 if (len == 4)
1688                         temp &= 0x0fffffff;
1689
1690                 /* check for no data */
1691
1692                 if (temp == 0)
1693                         break;
1694
1695                 /* correctly scale value */
1696
1697                 temp = (temp * 125ULL) - 64;
1698
1699                 /* auto adjust */
1700
1701                 while (temp < (ch->sample_rate - (ch->sample_rate / 4)))
1702                         temp *= 2;
1703
1704                 while (temp > (ch->sample_rate + (ch->sample_rate / 2)))
1705                         temp /= 2;
1706
1707                 /* bias */
1708
1709                 temp += (ch->sample_rate + 1999) / 2000;
1710
1711                 /* compare */
1712
1713                 DPRINTF("Comparing %d < %d\n",
1714                     (int)temp, (int)ch->sample_rate);
1715
1716                 if (temp == ch->sample_rate)
1717                         ch->last_sync_state = UAUDIO_SYNC_NONE;
1718                 else if (temp > ch->sample_rate)
1719                         ch->last_sync_state = UAUDIO_SYNC_MORE;
1720                 else
1721                         ch->last_sync_state = UAUDIO_SYNC_LESS;
1722                 break;
1723
1724         case USB_ST_SETUP:
1725                 usbd_xfer_set_frames(xfer, 1);
1726                 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_framelen(xfer));
1727                 usbd_transfer_submit(xfer);
1728                 break;
1729
1730         default:                        /* Error */
1731                 break;
1732         }
1733 }
1734
1735 static void
1736 uaudio_chan_play_callback(struct usb_xfer *xfer, usb_error_t error)
1737 {
1738         struct uaudio_chan *ch = usbd_xfer_softc(xfer);
1739         struct usb_page_cache *pc;
1740         uint32_t mfl;
1741         uint32_t total;
1742         uint32_t blockcount;
1743         uint32_t n;
1744         uint32_t offset;
1745         int actlen;
1746         int sumlen;
1747
1748         usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL);
1749
1750         if (ch->end == ch->start) {
1751                 DPRINTF("no buffer!\n");
1752                 return;
1753         }
1754
1755         switch (USB_GET_STATE(xfer)) {
1756         case USB_ST_TRANSFERRED:
1757 tr_transferred:
1758                 if (actlen < sumlen) {
1759                         DPRINTF("short transfer, "
1760                             "%d of %d bytes\n", actlen, sumlen);
1761                 }
1762                 chn_intr(ch->pcm_ch);
1763
1764                 /* start SYNC transfer, if any */
1765                 if ((ch->last_sync_time++ & 7) == 0)
1766                         usbd_transfer_start(ch->xfer[UAUDIO_NCHANBUFS]);
1767
1768         case USB_ST_SETUP:
1769                 mfl = usbd_xfer_max_framelen(xfer);
1770
1771                 if (ch->bytes_per_frame[1] > mfl) {
1772                         DPRINTF("bytes per transfer, %d, "
1773                             "exceeds maximum, %d!\n",
1774                             ch->bytes_per_frame[1],
1775                             mfl);
1776                         break;
1777                 }
1778
1779                 blockcount = ch->intr_frames;
1780
1781                 /* setup number of frames */
1782                 usbd_xfer_set_frames(xfer, blockcount);
1783
1784                 /* reset total length */
1785                 total = 0;
1786
1787                 /* setup frame lengths */
1788                 for (n = 0; n != blockcount; n++) {
1789                         uint32_t frame_len;
1790
1791                         ch->sample_curr += ch->sample_rem;
1792                         if (ch->sample_curr >= ch->frames_per_second) {
1793                                 ch->sample_curr -= ch->frames_per_second;
1794                                 frame_len = ch->bytes_per_frame[1];
1795                         } else {
1796                                 frame_len = ch->bytes_per_frame[0];
1797                         }
1798
1799                         if (n == (blockcount - 1)) {
1800                                 switch (ch->last_sync_state) {
1801                                 case UAUDIO_SYNC_MORE:
1802                                         DPRINTFN(6, "sending one sample more\n");
1803                                         if ((frame_len + ch->sample_size) <= mfl)
1804                                                 frame_len += ch->sample_size;
1805                                         ch->last_sync_state = UAUDIO_SYNC_NONE;
1806                                         break;
1807                                 case UAUDIO_SYNC_LESS:
1808                                         DPRINTFN(6, "sending one sample less\n");
1809                                         if (frame_len >= ch->sample_size)
1810                                                 frame_len -= ch->sample_size;
1811                                         ch->last_sync_state = UAUDIO_SYNC_NONE;
1812                                         break;
1813                                 default:
1814                                         break;
1815                                 }
1816                         }
1817
1818                         usbd_xfer_set_frame_len(xfer, n, frame_len);
1819                         total += frame_len;
1820                 }
1821
1822                 DPRINTFN(6, "transfer %d bytes\n", total);
1823
1824                 offset = 0;
1825
1826                 pc = usbd_xfer_get_frame(xfer, 0);
1827                 while (total > 0) {
1828
1829                         n = (ch->end - ch->cur);
1830                         if (n > total) {
1831                                 n = total;
1832                         }
1833                         usbd_copy_in(pc, offset, ch->cur, n);
1834
1835                         total -= n;
1836                         ch->cur += n;
1837                         offset += n;
1838
1839                         if (ch->cur >= ch->end) {
1840                                 ch->cur = ch->start;
1841                         }
1842                 }
1843
1844                 usbd_transfer_submit(xfer);
1845                 break;
1846
1847         default:                        /* Error */
1848                 if (error == USB_ERR_CANCELLED) {
1849                         break;
1850                 }
1851                 goto tr_transferred;
1852         }
1853 }
1854
1855 static void
1856 uaudio_chan_record_sync_callback(struct usb_xfer *xfer, usb_error_t error)
1857 {
1858         /* TODO */
1859 }
1860
1861 static void
1862 uaudio_chan_record_callback(struct usb_xfer *xfer, usb_error_t error)
1863 {
1864         struct uaudio_chan *ch = usbd_xfer_softc(xfer);
1865         struct usb_page_cache *pc;
1866         uint32_t offset0;
1867         uint32_t offset1;
1868         uint32_t mfl;
1869         int m;
1870         int n;
1871         int len;
1872         int actlen;
1873         int nframes;
1874         int blockcount;
1875
1876         usbd_xfer_status(xfer, &actlen, NULL, NULL, &nframes);
1877         mfl = usbd_xfer_max_framelen(xfer);
1878
1879         if (ch->end == ch->start) {
1880                 DPRINTF("no buffer!\n");
1881                 return;
1882         }
1883
1884         switch (USB_GET_STATE(xfer)) {
1885         case USB_ST_TRANSFERRED:
1886
1887                 DPRINTFN(6, "transferred %d bytes\n", actlen);
1888
1889                 offset0 = 0;
1890                 pc = usbd_xfer_get_frame(xfer, 0);
1891
1892                 for (n = 0; n != nframes; n++) {
1893
1894                         offset1 = offset0;
1895                         len = usbd_xfer_frame_len(xfer, n);
1896
1897                         while (len > 0) {
1898
1899                                 m = (ch->end - ch->cur);
1900
1901                                 if (m > len)
1902                                         m = len;
1903
1904                                 usbd_copy_out(pc, offset1, ch->cur, m);
1905
1906                                 len -= m;
1907                                 offset1 += m;
1908                                 ch->cur += m;
1909
1910                                 if (ch->cur >= ch->end) {
1911                                         ch->cur = ch->start;
1912                                 }
1913                         }
1914
1915                         offset0 += mfl;
1916                 }
1917
1918                 chn_intr(ch->pcm_ch);
1919
1920         case USB_ST_SETUP:
1921 tr_setup:
1922                 blockcount = ch->intr_frames;
1923
1924                 usbd_xfer_set_frames(xfer, blockcount);
1925                 for (n = 0; n < blockcount; n++) {
1926                         usbd_xfer_set_frame_len(xfer, n, mfl);
1927                 }
1928
1929                 usbd_transfer_submit(xfer);
1930                 break;
1931
1932         default:                        /* Error */
1933                 if (error == USB_ERR_CANCELLED) {
1934                         break;
1935                 }
1936                 goto tr_setup;
1937         }
1938 }
1939
1940 void   *
1941 uaudio_chan_init(struct uaudio_softc *sc, struct snd_dbuf *b,
1942     struct pcm_channel *c, int dir)
1943 {
1944         struct uaudio_chan *ch = ((dir == PCMDIR_PLAY) ?
1945             &sc->sc_play_chan : &sc->sc_rec_chan);
1946         uint32_t buf_size;
1947         uint32_t frames;
1948         uint32_t format;
1949         uint16_t fps;
1950         uint8_t endpoint;
1951         uint8_t blocks;
1952         uint8_t iface_index;
1953         uint8_t alt_index;
1954         uint8_t fps_shift;
1955         usb_error_t err;
1956
1957         fps = usbd_get_isoc_fps(sc->sc_udev);
1958
1959         if (fps < 8000) {
1960                 /* FULL speed USB */
1961                 frames = 8;
1962         } else {
1963                 /* HIGH speed USB */
1964                 frames = UAUDIO_NFRAMES;
1965         }
1966
1967         /* setup play/record format */
1968
1969         ch->pcm_cap.fmtlist = ch->pcm_format;
1970
1971         ch->pcm_format[0] = 0;
1972         ch->pcm_format[1] = 0;
1973
1974         ch->pcm_cap.minspeed = ch->sample_rate;
1975         ch->pcm_cap.maxspeed = ch->sample_rate;
1976
1977         /* setup mutex and PCM channel */
1978
1979         ch->pcm_ch = c;
1980         ch->pcm_mtx = c->lock;
1981
1982         format = ch->p_fmt->freebsd_fmt;
1983
1984         switch (ch->channels) {
1985         case 2:
1986                 /* stereo */
1987                 format = SND_FORMAT(format, 2, 0);
1988                 break;
1989         case 1:
1990                 /* mono */
1991                 format = SND_FORMAT(format, 1, 0);
1992                 break;
1993         default:
1994                 /* surround and more */
1995                 format = feeder_matrix_default_format(
1996                     SND_FORMAT(format, ch->channels, 0));
1997                 break;
1998         }
1999
2000         ch->pcm_cap.fmtlist[0] = format;
2001         ch->pcm_cap.fmtlist[1] = 0;
2002
2003         /* check if format is not supported */
2004
2005         if (format == 0) {
2006                 DPRINTF("The selected audio format is not supported\n");
2007                 goto error;
2008         }
2009
2010         /* set alternate interface corresponding to the mode */
2011
2012         endpoint = ch->p_ed1->bEndpointAddress;
2013         iface_index = ch->iface_index;
2014         alt_index = ch->iface_alt_index;
2015
2016         DPRINTF("endpoint=0x%02x, speed=%d, iface=%d alt=%d\n",
2017             endpoint, ch->sample_rate, iface_index, alt_index);
2018
2019         err = usbd_set_alt_interface_index(sc->sc_udev, iface_index, alt_index);
2020         if (err) {
2021                 DPRINTF("setting of alternate index failed: %s!\n",
2022                     usbd_errstr(err));
2023                 goto error;
2024         }
2025         usbd_set_parent_iface(sc->sc_udev, iface_index,
2026             sc->sc_mixer_iface_index);
2027
2028         /*
2029          * Only set the sample rate if the channel reports that it
2030          * supports the frequency control.
2031          */
2032
2033         if (sc->sc_audio_rev >= UAUDIO_VERSION_30) {
2034                 /* FALLTHROUGH */
2035         } else if (sc->sc_audio_rev >= UAUDIO_VERSION_20) {
2036                 unsigned int x;
2037           
2038                 for (x = 0; x != 256; x++) {
2039                         if (dir == PCMDIR_PLAY) {
2040                                 if (!(sc->sc_mixer_clocks.bit_output[x / 8] &
2041                                     (1 << (x % 8)))) {
2042                                         continue;
2043                                 }
2044                         } else {
2045                                 if (!(sc->sc_mixer_clocks.bit_input[x / 8] &
2046                                     (1 << (x % 8)))) {
2047                                         continue;
2048                                 }
2049                         }
2050
2051                         if (uaudio20_set_speed(sc->sc_udev,
2052                             sc->sc_mixer_iface_no, x, ch->sample_rate)) {
2053                                 /*
2054                                  * If the endpoint is adaptive setting
2055                                  * the speed may fail.
2056                                  */
2057                                 DPRINTF("setting of sample rate failed! "
2058                                     "(continuing anyway)\n");
2059                         }
2060                 }
2061         } else if (ch->p_sed.v1->bmAttributes & UA_SED_FREQ_CONTROL) {
2062                 if (uaudio_set_speed(sc->sc_udev, endpoint, ch->sample_rate)) {
2063                         /*
2064                          * If the endpoint is adaptive setting the
2065                          * speed may fail.
2066                          */
2067                         DPRINTF("setting of sample rate failed! "
2068                             "(continuing anyway)\n");
2069                 }
2070         }
2071         if (usbd_transfer_setup(sc->sc_udev, &iface_index, ch->xfer,
2072             ch->usb_cfg, UAUDIO_NCHANBUFS + 1, ch, ch->pcm_mtx)) {
2073                 DPRINTF("could not allocate USB transfers!\n");
2074                 goto error;
2075         }
2076
2077         fps_shift = usbd_xfer_get_fps_shift(ch->xfer[0]);
2078
2079         /* down shift number of frames per second, if any */
2080         fps >>= fps_shift;
2081         frames >>= fps_shift;
2082
2083         /* bytes per frame should not be zero */
2084         ch->bytes_per_frame[0] = ((ch->sample_rate / fps) * ch->sample_size);
2085         ch->bytes_per_frame[1] = (((ch->sample_rate + fps - 1) / fps) * ch->sample_size);
2086
2087         /* setup data rate dithering, if any */
2088         ch->frames_per_second = fps;
2089         ch->sample_rem = ch->sample_rate % fps;
2090         ch->sample_curr = 0;
2091         ch->frames_per_second = fps;
2092
2093         /* compute required buffer size */
2094         buf_size = (ch->bytes_per_frame[1] * frames);
2095
2096         ch->intr_size = buf_size;
2097         ch->intr_frames = frames;
2098
2099         DPRINTF("fps=%d sample_rem=%d\n", fps, ch->sample_rem);
2100
2101         if (ch->intr_frames == 0) {
2102                 DPRINTF("frame shift is too high!\n");
2103                 goto error;
2104         }
2105
2106         /* setup double buffering */
2107         buf_size *= 2;
2108         blocks = 2;
2109
2110         ch->buf = malloc(buf_size, M_DEVBUF, M_WAITOK | M_ZERO);
2111         if (ch->buf == NULL)
2112                 goto error;
2113         if (sndbuf_setup(b, ch->buf, buf_size) != 0)
2114                 goto error;
2115         if (sndbuf_resize(b, blocks, ch->intr_size)) 
2116                 goto error;
2117
2118         ch->start = ch->buf;
2119         ch->end = ch->buf + buf_size;
2120         ch->cur = ch->buf;
2121         ch->pcm_buf = b;
2122
2123         if (ch->pcm_mtx == NULL) {
2124                 DPRINTF("ERROR: PCM channels does not have a mutex!\n");
2125                 goto error;
2126         }
2127
2128         return (ch);
2129
2130 error:
2131         uaudio_chan_free(ch);
2132         return (NULL);
2133 }
2134
2135 int
2136 uaudio_chan_free(struct uaudio_chan *ch)
2137 {
2138         if (ch->buf != NULL) {
2139                 free(ch->buf, M_DEVBUF);
2140                 ch->buf = NULL;
2141         }
2142         usbd_transfer_unsetup(ch->xfer, UAUDIO_NCHANBUFS + 1);
2143
2144         ch->valid = 0;
2145
2146         return (0);
2147 }
2148
2149 int
2150 uaudio_chan_set_param_blocksize(struct uaudio_chan *ch, uint32_t blocksize)
2151 {
2152         return (ch->intr_size);
2153 }
2154
2155 int
2156 uaudio_chan_set_param_fragments(struct uaudio_chan *ch, uint32_t blocksize,
2157     uint32_t blockcount)
2158 {
2159         return (1);
2160 }
2161
2162 int
2163 uaudio_chan_set_param_speed(struct uaudio_chan *ch, uint32_t speed)
2164 {
2165         if (speed != ch->sample_rate) {
2166                 DPRINTF("rate conversion required\n");
2167         }
2168         return (ch->sample_rate);
2169 }
2170
2171 int
2172 uaudio_chan_getptr(struct uaudio_chan *ch)
2173 {
2174         return (ch->cur - ch->start);
2175 }
2176
2177 struct pcmchan_caps *
2178 uaudio_chan_getcaps(struct uaudio_chan *ch)
2179 {
2180         return (&ch->pcm_cap);
2181 }
2182
2183 static struct pcmchan_matrix uaudio_chan_matrix_swap_2_0 = {
2184         .id = SND_CHN_MATRIX_DRV,
2185         .channels = 2,
2186         .ext = 0,
2187         .map = {
2188                 /* Right */
2189                 [0] = {
2190                         .type = SND_CHN_T_FR,
2191                         .members =
2192                             SND_CHN_T_MASK_FR | SND_CHN_T_MASK_FC |
2193                             SND_CHN_T_MASK_LF | SND_CHN_T_MASK_BR |
2194                             SND_CHN_T_MASK_BC | SND_CHN_T_MASK_SR
2195                 },
2196                 /* Left */
2197                 [1] = {
2198                         .type = SND_CHN_T_FL,
2199                         .members =
2200                             SND_CHN_T_MASK_FL | SND_CHN_T_MASK_FC |
2201                             SND_CHN_T_MASK_LF | SND_CHN_T_MASK_BL |
2202                             SND_CHN_T_MASK_BC | SND_CHN_T_MASK_SL
2203                 },
2204                 [2] = {
2205                         .type = SND_CHN_T_MAX,
2206                         .members = 0
2207                 }
2208         },
2209         .mask = SND_CHN_T_MASK_FR | SND_CHN_T_MASK_FL,
2210         .offset = {  1,  0, -1, -1, -1, -1, -1, -1, -1,
2211                     -1, -1, -1, -1, -1, -1, -1, -1, -1  }
2212 };
2213
2214 struct pcmchan_matrix *
2215 uaudio_chan_getmatrix(struct uaudio_chan *ch, uint32_t format)
2216 {
2217         struct uaudio_softc *sc;
2218
2219         sc = ch->priv_sc;
2220
2221         if (sc != NULL && sc->sc_uq_audio_swap_lr != 0 &&
2222             AFMT_CHANNEL(format) == 2)
2223                 return (&uaudio_chan_matrix_swap_2_0);
2224
2225         return (feeder_matrix_format_map(format));
2226 }
2227
2228 int
2229 uaudio_chan_set_param_format(struct uaudio_chan *ch, uint32_t format)
2230 {
2231         ch->format = format;
2232         return (0);
2233 }
2234
2235 int
2236 uaudio_chan_start(struct uaudio_chan *ch)
2237 {
2238         ch->cur = ch->start;
2239
2240 #if (UAUDIO_NCHANBUFS != 2)
2241 #error "please update code"
2242 #endif
2243         usbd_transfer_start(ch->xfer[0]);
2244         usbd_transfer_start(ch->xfer[1]);
2245         return (0);
2246 }
2247
2248 int
2249 uaudio_chan_stop(struct uaudio_chan *ch)
2250 {
2251 #if (UAUDIO_NCHANBUFS != 2)
2252 #error "please update code"
2253 #endif
2254         usbd_transfer_stop(ch->xfer[0]);
2255         usbd_transfer_stop(ch->xfer[1]);
2256         return (0);
2257 }
2258
2259 /*========================================================================*
2260  * AC - Audio Controller - routines
2261  *========================================================================*/
2262
2263 static int
2264 uaudio_mixer_sysctl_handler(SYSCTL_HANDLER_ARGS)
2265 {
2266         struct uaudio_softc *sc;
2267         struct uaudio_mixer_node *pmc;
2268         int hint;
2269         int error;
2270         int temp = 0;
2271         int chan = 0;
2272
2273         sc = (struct uaudio_softc *)oidp->oid_arg1;
2274         hint = oidp->oid_arg2;
2275
2276         if (sc->sc_mixer_lock == NULL)
2277                 return (ENXIO);
2278
2279         /* lookup mixer node */
2280
2281         mtx_lock(sc->sc_mixer_lock);
2282         for (pmc = sc->sc_mixer_root; pmc != NULL; pmc = pmc->next) {
2283                 for (chan = 0; chan != (int)pmc->nchan; chan++) {
2284                         if (pmc->wValue[chan] != -1 &&
2285                             pmc->wValue[chan] == hint) {
2286                                 temp = pmc->wData[chan];
2287                                 goto found;
2288                         }
2289                 }
2290         }
2291 found:
2292         mtx_unlock(sc->sc_mixer_lock);
2293
2294         error = sysctl_handle_int(oidp, &temp, 0, req);
2295         if (error != 0 || req->newptr == NULL)
2296                 return (error);
2297
2298         /* update mixer value */
2299
2300         mtx_lock(sc->sc_mixer_lock);
2301         if (pmc != NULL &&
2302             temp >= pmc->minval &&
2303             temp <= pmc->maxval) {
2304
2305                 pmc->wData[chan] = temp;
2306                 pmc->update[(chan / 8)] |= (1 << (chan % 8));
2307
2308                 /* start the transfer, if not already started */
2309                 usbd_transfer_start(sc->sc_mixer_xfer[0]);
2310         }
2311         mtx_unlock(sc->sc_mixer_lock);
2312
2313         return (0);
2314 }
2315
2316 static void
2317 uaudio_mixer_ctl_free(struct uaudio_softc *sc)
2318 {
2319         struct uaudio_mixer_node *p_mc;
2320
2321         while ((p_mc = sc->sc_mixer_root) != NULL) {
2322                 sc->sc_mixer_root = p_mc->next;
2323                 free(p_mc, M_USBDEV);
2324         }
2325 }
2326
2327 static void
2328 uaudio_mixer_register_sysctl(struct uaudio_softc *sc, device_t dev)
2329 {
2330         struct uaudio_mixer_node *pmc;
2331         struct sysctl_oid *mixer_tree;
2332         struct sysctl_oid *control_tree;
2333         char buf[32];
2334         int chan;
2335         int n;
2336
2337         mixer_tree = SYSCTL_ADD_NODE(device_get_sysctl_ctx(dev),
2338             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "mixer",
2339             CTLFLAG_RD, NULL, "");
2340
2341         if (mixer_tree == NULL)
2342                 return;
2343
2344         for (n = 0, pmc = sc->sc_mixer_root; pmc != NULL;
2345             pmc = pmc->next, n++) {
2346
2347                 for (chan = 0; chan < pmc->nchan; chan++) {
2348
2349                         if (pmc->nchan > 1) {
2350                                 snprintf(buf, sizeof(buf), "%s_%d_%d",
2351                                     pmc->name, n, chan);
2352                         } else {
2353                                 snprintf(buf, sizeof(buf), "%s_%d",
2354                                     pmc->name, n);
2355                         }
2356
2357                         control_tree = SYSCTL_ADD_NODE(device_get_sysctl_ctx(dev),
2358                             SYSCTL_CHILDREN(mixer_tree), OID_AUTO, buf,
2359                             CTLFLAG_RD, NULL, "Mixer control nodes");
2360
2361                         if (control_tree == NULL)
2362                                 continue;
2363
2364                         SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
2365                             SYSCTL_CHILDREN(control_tree),
2366                             OID_AUTO, "val", CTLTYPE_INT | CTLFLAG_RW, sc,
2367                             pmc->wValue[chan],
2368                             uaudio_mixer_sysctl_handler, "I", "Current value");
2369
2370                         SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
2371                             SYSCTL_CHILDREN(control_tree),
2372                             OID_AUTO, "min", CTLFLAG_RD, 0, pmc->minval,
2373                             "Minimum value");
2374
2375                         SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
2376                             SYSCTL_CHILDREN(control_tree),
2377                             OID_AUTO, "max", CTLFLAG_RD, 0, pmc->maxval,
2378                             "Maximum value");
2379
2380                         SYSCTL_ADD_STRING(device_get_sysctl_ctx(dev),
2381                             SYSCTL_CHILDREN(control_tree),
2382                             OID_AUTO, "desc", CTLFLAG_RD, pmc->desc, 0,
2383                             "Description");
2384                 }
2385         }
2386 }
2387
2388 /* M-Audio FastTrack Ultra Mixer Description */
2389 /* Origin: Linux USB Audio driver */
2390 static void
2391 uaudio_mixer_controls_create_ftu(struct uaudio_softc *sc)
2392 {
2393         int chx;
2394         int chy;
2395
2396         memset(&MIX(sc), 0, sizeof(MIX(sc)));
2397         MIX(sc).wIndex = MAKE_WORD(6, sc->sc_mixer_iface_no);
2398         MIX(sc).wValue[0] = MAKE_WORD(8, 0);
2399         MIX(sc).class = UAC_OUTPUT;
2400         MIX(sc).type = MIX_UNSIGNED_16;
2401         MIX(sc).ctl = SOUND_MIXER_NRDEVICES;
2402         MIX(sc).name = "effect";
2403         MIX(sc).minval = 0;
2404         MIX(sc).maxval = 7;
2405         MIX(sc).mul = 7;
2406         MIX(sc).nchan = 1;
2407         MIX(sc).update[0] = 1;
2408         strlcpy(MIX(sc).desc, "Room1,2,3,Hall1,2,Plate,Delay,Echo", sizeof(MIX(sc).desc));
2409         uaudio_mixer_add_ctl_sub(sc, &MIX(sc));
2410
2411         memset(&MIX(sc), 0, sizeof(MIX(sc)));
2412         MIX(sc).wIndex = MAKE_WORD(5, sc->sc_mixer_iface_no);
2413
2414         for (chx = 0; chx != 8; chx++) {
2415                 for (chy = 0; chy != 8; chy++) {
2416
2417                         MIX(sc).wValue[0] = MAKE_WORD(chx + 1, chy + 1);
2418                         MIX(sc).type = MIX_SIGNED_16;
2419                         MIX(sc).ctl = SOUND_MIXER_NRDEVICES;
2420                         MIX(sc).name = "mix_rec";
2421                         MIX(sc).nchan = 1;
2422                         MIX(sc).update[0] = 1;
2423                         MIX(sc).val_default = 0;
2424                         snprintf(MIX(sc).desc, sizeof(MIX(sc).desc),
2425                             "AIn%d - Out%d Record Volume", chy + 1, chx + 1);
2426
2427                         uaudio_mixer_add_ctl(sc, &MIX(sc));
2428
2429                         MIX(sc).wValue[0] = MAKE_WORD(chx + 1, chy + 1 + 8);
2430                         MIX(sc).type = MIX_SIGNED_16;
2431                         MIX(sc).ctl = SOUND_MIXER_NRDEVICES;
2432                         MIX(sc).name = "mix_play";
2433                         MIX(sc).nchan = 1;
2434                         MIX(sc).update[0] = 1;
2435                         MIX(sc).val_default = (chx == chy) ? 2 : 0;
2436                         snprintf(MIX(sc).desc, sizeof(MIX(sc).desc),
2437                             "DIn%d - Out%d Playback Volume", chy + 1, chx + 1);
2438
2439                         uaudio_mixer_add_ctl(sc, &MIX(sc));
2440                 }
2441         }
2442
2443         memset(&MIX(sc), 0, sizeof(MIX(sc)));
2444         MIX(sc).wIndex = MAKE_WORD(6, sc->sc_mixer_iface_no);
2445         MIX(sc).wValue[0] = MAKE_WORD(2, 0);
2446         MIX(sc).class = UAC_OUTPUT;
2447         MIX(sc).type = MIX_SIGNED_8;
2448         MIX(sc).ctl = SOUND_MIXER_NRDEVICES;
2449         MIX(sc).name = "effect_vol";
2450         MIX(sc).nchan = 1;
2451         MIX(sc).update[0] = 1;
2452         MIX(sc).minval = 0;
2453         MIX(sc).maxval = 0x7f;
2454         MIX(sc).mul = 0x7f;
2455         MIX(sc).nchan = 1;
2456         MIX(sc).update[0] = 1;
2457         strlcpy(MIX(sc).desc, "Effect Volume", sizeof(MIX(sc).desc));
2458         uaudio_mixer_add_ctl_sub(sc, &MIX(sc));
2459
2460         memset(&MIX(sc), 0, sizeof(MIX(sc)));
2461         MIX(sc).wIndex = MAKE_WORD(6, sc->sc_mixer_iface_no);
2462         MIX(sc).wValue[0] = MAKE_WORD(3, 0);
2463         MIX(sc).class = UAC_OUTPUT;
2464         MIX(sc).type = MIX_SIGNED_16;
2465         MIX(sc).ctl = SOUND_MIXER_NRDEVICES;
2466         MIX(sc).name = "effect_dur";
2467         MIX(sc).nchan = 1;
2468         MIX(sc).update[0] = 1;
2469         MIX(sc).minval = 0;
2470         MIX(sc).maxval = 0x7f00;
2471         MIX(sc).mul = 0x7f00;
2472         MIX(sc).nchan = 1;
2473         MIX(sc).update[0] = 1;
2474         strlcpy(MIX(sc).desc, "Effect Duration", sizeof(MIX(sc).desc));
2475         uaudio_mixer_add_ctl_sub(sc, &MIX(sc));
2476
2477         memset(&MIX(sc), 0, sizeof(MIX(sc)));
2478         MIX(sc).wIndex = MAKE_WORD(6, sc->sc_mixer_iface_no);
2479         MIX(sc).wValue[0] = MAKE_WORD(4, 0);
2480         MIX(sc).class = UAC_OUTPUT;
2481         MIX(sc).type = MIX_SIGNED_8;
2482         MIX(sc).ctl = SOUND_MIXER_NRDEVICES;
2483         MIX(sc).name = "effect_fb";
2484         MIX(sc).nchan = 1;
2485         MIX(sc).update[0] = 1;
2486         MIX(sc).minval = 0;
2487         MIX(sc).maxval = 0x7f;
2488         MIX(sc).mul = 0x7f;
2489         MIX(sc).nchan = 1;
2490         MIX(sc).update[0] = 1;
2491         strlcpy(MIX(sc).desc, "Effect Feedback Volume", sizeof(MIX(sc).desc));
2492         uaudio_mixer_add_ctl_sub(sc, &MIX(sc));
2493
2494         memset(&MIX(sc), 0, sizeof(MIX(sc)));
2495         MIX(sc).wIndex = MAKE_WORD(7, sc->sc_mixer_iface_no);
2496         for (chy = 0; chy != 4; chy++) {
2497
2498                 MIX(sc).wValue[0] = MAKE_WORD(7, chy + 1);
2499                 MIX(sc).type = MIX_SIGNED_16;
2500                 MIX(sc).ctl = SOUND_MIXER_NRDEVICES;
2501                 MIX(sc).name = "effect_ret";
2502                 MIX(sc).nchan = 1;
2503                 MIX(sc).update[0] = 1;
2504                 snprintf(MIX(sc).desc, sizeof(MIX(sc).desc),
2505                     "Effect Return %d Volume", chy + 1);
2506
2507                 uaudio_mixer_add_ctl(sc, &MIX(sc));
2508         }
2509
2510         memset(&MIX(sc), 0, sizeof(MIX(sc)));
2511         MIX(sc).wIndex = MAKE_WORD(5, sc->sc_mixer_iface_no);
2512
2513         for (chy = 0; chy != 8; chy++) {
2514                 MIX(sc).wValue[0] = MAKE_WORD(9, chy + 1);
2515                 MIX(sc).type = MIX_SIGNED_16;
2516                 MIX(sc).ctl = SOUND_MIXER_NRDEVICES;
2517                 MIX(sc).name = "effect_send";
2518                 MIX(sc).nchan = 1;
2519                 MIX(sc).update[0] = 1;
2520                 snprintf(MIX(sc).desc, sizeof(MIX(sc).desc),
2521                     "Effect Send AIn%d Volume", chy + 1);
2522
2523                 uaudio_mixer_add_ctl(sc, &MIX(sc));
2524
2525                 MIX(sc).wValue[0] = MAKE_WORD(9, chy + 1);
2526                 MIX(sc).type = MIX_SIGNED_16;
2527                 MIX(sc).ctl = SOUND_MIXER_NRDEVICES;
2528                 MIX(sc).name = "effect_send";
2529                 MIX(sc).nchan = 1;
2530                 MIX(sc).update[0] = 1;
2531                 snprintf(MIX(sc).desc, sizeof(MIX(sc).desc),
2532                     "Effect Send DIn%d Volume", chy + 1 + 8);
2533
2534                 uaudio_mixer_add_ctl(sc, &MIX(sc));
2535         }
2536 }
2537
2538 static void
2539 uaudio_mixer_reload_all(struct uaudio_softc *sc)
2540 {
2541         struct uaudio_mixer_node *pmc;
2542         int chan;
2543
2544         if (sc->sc_mixer_lock == NULL)
2545                 return;
2546
2547         mtx_lock(sc->sc_mixer_lock);
2548         for (pmc = sc->sc_mixer_root; pmc != NULL; pmc = pmc->next) {
2549                 /* use reset defaults for non-oss controlled settings */
2550                 if (pmc->ctl == SOUND_MIXER_NRDEVICES)
2551                         continue;
2552                 for (chan = 0; chan < pmc->nchan; chan++)
2553                         pmc->update[chan / 8] |= (1 << (chan % 8));
2554         }
2555         usbd_transfer_start(sc->sc_mixer_xfer[0]);
2556
2557         /* start HID volume keys, if any */
2558         usbd_transfer_start(sc->sc_hid.xfer[0]);
2559         mtx_unlock(sc->sc_mixer_lock);
2560 }
2561
2562 static void
2563 uaudio_mixer_add_ctl_sub(struct uaudio_softc *sc, struct uaudio_mixer_node *mc)
2564 {
2565         struct uaudio_mixer_node *p_mc_new =
2566             malloc(sizeof(*p_mc_new), M_USBDEV, M_WAITOK);
2567         int ch;
2568
2569         if (p_mc_new != NULL) {
2570                 memcpy(p_mc_new, mc, sizeof(*p_mc_new));
2571                 p_mc_new->next = sc->sc_mixer_root;
2572                 sc->sc_mixer_root = p_mc_new;
2573                 sc->sc_mixer_count++;
2574
2575                 /* set default value for all channels */
2576                 for (ch = 0; ch < p_mc_new->nchan; ch++) {
2577                         switch (p_mc_new->val_default) {
2578                         case 1:
2579                                 /* 50% */
2580                                 p_mc_new->wData[ch] = (p_mc_new->maxval + p_mc_new->minval) / 2;
2581                                 break;
2582                         case 2:
2583                                 /* 100% */
2584                                 p_mc_new->wData[ch] = p_mc_new->maxval;
2585                                 break;
2586                         default:
2587                                 /* 0% */
2588                                 p_mc_new->wData[ch] = p_mc_new->minval;
2589                                 break;
2590                         }
2591                 }
2592         } else {
2593                 DPRINTF("out of memory\n");
2594         }
2595 }
2596
2597 static void
2598 uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct uaudio_mixer_node *mc)
2599 {
2600         int32_t res;
2601
2602         if (mc->class < UAC_NCLASSES) {
2603                 DPRINTF("adding %s.%d\n",
2604                     uac_names[mc->class], mc->ctl);
2605         } else {
2606                 DPRINTF("adding %d\n", mc->ctl);
2607         }
2608
2609         if (mc->type == MIX_ON_OFF) {
2610                 mc->minval = 0;
2611                 mc->maxval = 1;
2612         } else if (mc->type == MIX_SELECTOR) {
2613         } else {
2614
2615                 /* determine min and max values */
2616
2617                 mc->minval = uaudio_mixer_get(sc->sc_udev,
2618                     sc->sc_audio_rev, GET_MIN, mc);
2619                 mc->maxval = uaudio_mixer_get(sc->sc_udev,
2620                     sc->sc_audio_rev, GET_MAX, mc);
2621
2622                 /* check if max and min was swapped */
2623
2624                 if (mc->maxval < mc->minval) {
2625                         res = mc->maxval;
2626                         mc->maxval = mc->minval;
2627                         mc->minval = res;
2628                 }
2629
2630                 /* compute value range */
2631                 mc->mul = mc->maxval - mc->minval;
2632                 if (mc->mul == 0)
2633                         mc->mul = 1;
2634
2635                 /* compute value alignment */
2636                 res = uaudio_mixer_get(sc->sc_udev,
2637                     sc->sc_audio_rev, GET_RES, mc);
2638
2639                 DPRINTF("Resolution = %d\n", (int)res);
2640         }
2641
2642         uaudio_mixer_add_ctl_sub(sc, mc);
2643
2644 #ifdef USB_DEBUG
2645         if (uaudio_debug > 2) {
2646                 uint8_t i;
2647
2648                 for (i = 0; i < mc->nchan; i++) {
2649                         DPRINTF("[mix] wValue=%04x\n", mc->wValue[0]);
2650                 }
2651                 DPRINTF("[mix] wIndex=%04x type=%d ctl='%d' "
2652                     "min=%d max=%d\n",
2653                     mc->wIndex, mc->type, mc->ctl,
2654                     mc->minval, mc->maxval);
2655         }
2656 #endif
2657 }
2658
2659 static void
2660 uaudio_mixer_add_mixer(struct uaudio_softc *sc,
2661     const struct uaudio_terminal_node *iot, int id)
2662 {
2663         const struct usb_audio_mixer_unit_0 *d0 = iot[id].u.mu_v1;
2664         const struct usb_audio_mixer_unit_1 *d1;
2665
2666         uint32_t bno;                   /* bit number */
2667         uint32_t p;                     /* bit number accumulator */
2668         uint32_t mo;                    /* matching outputs */
2669         uint32_t mc;                    /* matching channels */
2670         uint32_t ichs;                  /* input channels */
2671         uint32_t ochs;                  /* output channels */
2672         uint32_t c;
2673         uint32_t chs;                   /* channels */
2674         uint32_t i;
2675         uint32_t o;
2676
2677         DPRINTFN(3, "bUnitId=%d bNrInPins=%d\n",
2678             d0->bUnitId, d0->bNrInPins);
2679
2680         /* compute the number of input channels */
2681
2682         ichs = 0;
2683         for (i = 0; i < d0->bNrInPins; i++) {
2684                 ichs += uaudio_mixer_get_cluster(
2685                     d0->baSourceId[i], iot).bNrChannels;
2686         }
2687
2688         d1 = (const void *)(d0->baSourceId + d0->bNrInPins);
2689
2690         /* and the number of output channels */
2691
2692         ochs = d1->bNrChannels;
2693
2694         DPRINTFN(3, "ichs=%d ochs=%d\n", ichs, ochs);
2695
2696         memset(&MIX(sc), 0, sizeof(MIX(sc)));
2697
2698         MIX(sc).wIndex = MAKE_WORD(d0->bUnitId, sc->sc_mixer_iface_no);
2699         uaudio_mixer_determine_class(&iot[id], &MIX(sc));
2700         MIX(sc).type = MIX_SIGNED_16;
2701
2702         if (uaudio_mixer_verify_desc(d0, ((ichs * ochs) + 7) / 8) == NULL)
2703                 return;
2704
2705         for (p = i = 0; i < d0->bNrInPins; i++) {
2706                 chs = uaudio_mixer_get_cluster(
2707                     d0->baSourceId[i], iot).bNrChannels;
2708                 mc = 0;
2709                 for (c = 0; c < chs; c++) {
2710                         mo = 0;
2711                         for (o = 0; o < ochs; o++) {
2712                                 bno = ((p + c) * ochs) + o;
2713                                 if (BIT_TEST(d1->bmControls, bno))
2714                                         mo++;
2715                         }
2716                         if (mo == 1)
2717                                 mc++;
2718                 }
2719                 if ((mc == chs) && (chs <= MIX_MAX_CHAN)) {
2720
2721                         /* repeat bit-scan */
2722
2723                         mc = 0;
2724                         for (c = 0; c < chs; c++) {
2725                                 for (o = 0; o < ochs; o++) {
2726                                         bno = ((p + c) * ochs) + o;
2727                                         if (BIT_TEST(d1->bmControls, bno))
2728                                                 MIX(sc).wValue[mc++] = MAKE_WORD(p + c + 1, o + 1);
2729                                 }
2730                         }
2731                         MIX(sc).nchan = chs;
2732                         uaudio_mixer_add_ctl(sc, &MIX(sc));
2733                 }
2734                 p += chs;
2735         }
2736 }
2737
2738 static void
2739 uaudio20_mixer_add_mixer(struct uaudio_softc *sc,
2740     const struct uaudio_terminal_node *iot, int id)
2741 {
2742         const struct usb_audio20_mixer_unit_0 *d0 = iot[id].u.mu_v2;
2743         const struct usb_audio20_mixer_unit_1 *d1;
2744
2745         uint32_t bno;                   /* bit number */
2746         uint32_t p;                     /* bit number accumulator */
2747         uint32_t mo;                    /* matching outputs */
2748         uint32_t mc;                    /* matching channels */
2749         uint32_t ichs;                  /* input channels */
2750         uint32_t ochs;                  /* output channels */
2751         uint32_t c;
2752         uint32_t chs;                   /* channels */
2753         uint32_t i;
2754         uint32_t o;
2755
2756         DPRINTFN(3, "bUnitId=%d bNrInPins=%d\n",
2757             d0->bUnitId, d0->bNrInPins);
2758
2759         /* compute the number of input channels */
2760
2761         ichs = 0;
2762         for (i = 0; i < d0->bNrInPins; i++) {
2763                 ichs += uaudio20_mixer_get_cluster(
2764                     d0->baSourceId[i], iot).bNrChannels;
2765         }
2766
2767         d1 = (const void *)(d0->baSourceId + d0->bNrInPins);
2768
2769         /* and the number of output channels */
2770
2771         ochs = d1->bNrChannels;
2772
2773         DPRINTFN(3, "ichs=%d ochs=%d\n", ichs, ochs);
2774
2775         memset(&MIX(sc), 0, sizeof(MIX(sc)));
2776
2777         MIX(sc).wIndex = MAKE_WORD(d0->bUnitId, sc->sc_mixer_iface_no);
2778         uaudio20_mixer_determine_class(&iot[id], &MIX(sc));
2779         MIX(sc).type = MIX_SIGNED_16;
2780
2781         if (uaudio20_mixer_verify_desc(d0, ((ichs * ochs) + 7) / 8) == NULL)
2782                 return;
2783
2784         for (p = i = 0; i < d0->bNrInPins; i++) {
2785                 chs = uaudio20_mixer_get_cluster(
2786                     d0->baSourceId[i], iot).bNrChannels;
2787                 mc = 0;
2788                 for (c = 0; c < chs; c++) {
2789                         mo = 0;
2790                         for (o = 0; o < ochs; o++) {
2791                                 bno = ((p + c) * ochs) + o;
2792                                 if (BIT_TEST(d1->bmControls, bno))
2793                                         mo++;
2794                         }
2795                         if (mo == 1)
2796                                 mc++;
2797                 }
2798                 if ((mc == chs) && (chs <= MIX_MAX_CHAN)) {
2799
2800                         /* repeat bit-scan */
2801
2802                         mc = 0;
2803                         for (c = 0; c < chs; c++) {
2804                                 for (o = 0; o < ochs; o++) {
2805                                         bno = ((p + c) * ochs) + o;
2806                                         if (BIT_TEST(d1->bmControls, bno))
2807                                                 MIX(sc).wValue[mc++] = MAKE_WORD(p + c + 1, o + 1);
2808                                 }
2809                         }
2810                         MIX(sc).nchan = chs;
2811                         uaudio_mixer_add_ctl(sc, &MIX(sc));
2812                 }
2813                 p += chs;
2814         }
2815 }
2816
2817 static void
2818 uaudio_mixer_add_selector(struct uaudio_softc *sc,
2819     const struct uaudio_terminal_node *iot, int id)
2820 {
2821         const struct usb_audio_selector_unit *d = iot[id].u.su_v1;
2822         uint16_t i;
2823
2824         DPRINTFN(3, "bUnitId=%d bNrInPins=%d\n",
2825             d->bUnitId, d->bNrInPins);
2826
2827         if (d->bNrInPins == 0)
2828                 return;
2829
2830         memset(&MIX(sc), 0, sizeof(MIX(sc)));
2831
2832         MIX(sc).wIndex = MAKE_WORD(d->bUnitId, sc->sc_mixer_iface_no);
2833         MIX(sc).wValue[0] = MAKE_WORD(0, 0);
2834         uaudio_mixer_determine_class(&iot[id], &MIX(sc));
2835         MIX(sc).nchan = 1;
2836         MIX(sc).type = MIX_SELECTOR;
2837         MIX(sc).ctl = SOUND_MIXER_NRDEVICES;
2838         MIX(sc).minval = 1;
2839         MIX(sc).maxval = d->bNrInPins;
2840         MIX(sc).name = "selector";
2841
2842         i = d->baSourceId[d->bNrInPins];
2843         if (i == 0 ||
2844             usbd_req_get_string_any(sc->sc_udev, NULL,
2845             MIX(sc).desc, sizeof(MIX(sc).desc), i) != 0) {
2846                 MIX(sc).desc[0] = 0;
2847         }
2848
2849         if (MIX(sc).maxval > MAX_SELECTOR_INPUT_PIN) {
2850                 MIX(sc).maxval = MAX_SELECTOR_INPUT_PIN;
2851         }
2852         MIX(sc).mul = (MIX(sc).maxval - MIX(sc).minval);
2853         for (i = 0; i < MAX_SELECTOR_INPUT_PIN; i++) {
2854                 MIX(sc).slctrtype[i] = SOUND_MIXER_NRDEVICES;
2855         }
2856
2857         for (i = 0; i < MIX(sc).maxval; i++) {
2858                 MIX(sc).slctrtype[i] = uaudio_mixer_feature_name(
2859                     &iot[d->baSourceId[i]], &MIX(sc));
2860         }
2861
2862         MIX(sc).class = 0;                      /* not used */
2863
2864         uaudio_mixer_add_ctl(sc, &MIX(sc));
2865 }
2866
2867 static void
2868 uaudio20_mixer_add_selector(struct uaudio_softc *sc,
2869     const struct uaudio_terminal_node *iot, int id)
2870 {
2871         const struct usb_audio20_selector_unit *d = iot[id].u.su_v2;
2872         uint16_t i;
2873
2874         DPRINTFN(3, "bUnitId=%d bNrInPins=%d\n",
2875             d->bUnitId, d->bNrInPins);
2876
2877         if (d->bNrInPins == 0)
2878                 return;
2879
2880         memset(&MIX(sc), 0, sizeof(MIX(sc)));
2881
2882         MIX(sc).wIndex = MAKE_WORD(d->bUnitId, sc->sc_mixer_iface_no);
2883         MIX(sc).wValue[0] = MAKE_WORD(0, 0);
2884         uaudio20_mixer_determine_class(&iot[id], &MIX(sc));
2885         MIX(sc).nchan = 1;
2886         MIX(sc).type = MIX_SELECTOR;
2887         MIX(sc).ctl = SOUND_MIXER_NRDEVICES;
2888         MIX(sc).minval = 1;
2889         MIX(sc).maxval = d->bNrInPins;
2890         MIX(sc).name = "selector";
2891
2892         i = d->baSourceId[d->bNrInPins];
2893         if (i == 0 ||
2894             usbd_req_get_string_any(sc->sc_udev, NULL,
2895             MIX(sc).desc, sizeof(MIX(sc).desc), i) != 0) {
2896                 MIX(sc).desc[0] = 0;
2897         }
2898
2899         if (MIX(sc).maxval > MAX_SELECTOR_INPUT_PIN)
2900                 MIX(sc).maxval = MAX_SELECTOR_INPUT_PIN;
2901
2902         MIX(sc).mul = (MIX(sc).maxval - MIX(sc).minval);
2903         for (i = 0; i < MAX_SELECTOR_INPUT_PIN; i++)
2904                 MIX(sc).slctrtype[i] = SOUND_MIXER_NRDEVICES;
2905
2906         for (i = 0; i < MIX(sc).maxval; i++) {
2907                 MIX(sc).slctrtype[i] = uaudio20_mixer_feature_name(
2908                     &iot[d->baSourceId[i]], &MIX(sc));
2909         }
2910
2911         MIX(sc).class = 0;                      /* not used */
2912
2913         uaudio_mixer_add_ctl(sc, &MIX(sc));
2914 }
2915
2916 static uint32_t
2917 uaudio_mixer_feature_get_bmaControls(const struct usb_audio_feature_unit *d,
2918     uint8_t i)
2919 {
2920         uint32_t temp = 0;
2921         uint32_t offset = (i * d->bControlSize);
2922
2923         if (d->bControlSize > 0) {
2924                 temp |= d->bmaControls[offset];
2925                 if (d->bControlSize > 1) {
2926                         temp |= d->bmaControls[offset + 1] << 8;
2927                         if (d->bControlSize > 2) {
2928                                 temp |= d->bmaControls[offset + 2] << 16;
2929                                 if (d->bControlSize > 3) {
2930                                         temp |= d->bmaControls[offset + 3] << 24;
2931                                 }
2932                         }
2933                 }
2934         }
2935         return (temp);
2936 }
2937
2938 static void
2939 uaudio_mixer_add_feature(struct uaudio_softc *sc,
2940     const struct uaudio_terminal_node *iot, int id)
2941 {
2942         const struct usb_audio_feature_unit *d = iot[id].u.fu_v1;
2943         uint32_t fumask;
2944         uint32_t mmask;
2945         uint32_t cmask;
2946         uint16_t mixernumber;
2947         uint8_t nchan;
2948         uint8_t chan;
2949         uint8_t ctl;
2950         uint8_t i;
2951
2952         if (d->bControlSize == 0)
2953                 return;
2954
2955         memset(&MIX(sc), 0, sizeof(MIX(sc)));
2956
2957         nchan = (d->bLength - 7) / d->bControlSize;
2958         mmask = uaudio_mixer_feature_get_bmaControls(d, 0);
2959         cmask = 0;
2960
2961         if (nchan == 0)
2962                 return;
2963
2964         /* figure out what we can control */
2965
2966         for (chan = 1; chan < nchan; chan++) {
2967                 DPRINTFN(10, "chan=%d mask=%x\n",
2968                     chan, uaudio_mixer_feature_get_bmaControls(d, chan));
2969
2970                 cmask |= uaudio_mixer_feature_get_bmaControls(d, chan);
2971         }
2972
2973         if (nchan > MIX_MAX_CHAN) {
2974                 nchan = MIX_MAX_CHAN;
2975         }
2976         MIX(sc).wIndex = MAKE_WORD(d->bUnitId, sc->sc_mixer_iface_no);
2977
2978         i = d->bmaControls[d->bControlSize];
2979         if (i == 0 ||
2980             usbd_req_get_string_any(sc->sc_udev, NULL,
2981             MIX(sc).desc, sizeof(MIX(sc).desc), i) != 0) {
2982                 MIX(sc).desc[0] = 0;
2983         }
2984
2985         for (ctl = 1; ctl <= LOUDNESS_CONTROL; ctl++) {
2986
2987                 fumask = FU_MASK(ctl);
2988
2989                 DPRINTFN(5, "ctl=%d fumask=0x%04x\n",
2990                     ctl, fumask);
2991
2992                 if (mmask & fumask) {
2993                         MIX(sc).nchan = 1;
2994                         MIX(sc).wValue[0] = MAKE_WORD(ctl, 0);
2995                 } else if (cmask & fumask) {
2996                         MIX(sc).nchan = nchan - 1;
2997                         for (i = 1; i < nchan; i++) {
2998                                 if (uaudio_mixer_feature_get_bmaControls(d, i) & fumask)
2999                                         MIX(sc).wValue[i - 1] = MAKE_WORD(ctl, i);
3000                                 else
3001                                         MIX(sc).wValue[i - 1] = -1;
3002                         }
3003                 } else {
3004                         continue;
3005                 }
3006
3007                 mixernumber = uaudio_mixer_feature_name(&iot[id], &MIX(sc));
3008
3009                 switch (ctl) {
3010                 case MUTE_CONTROL:
3011                         MIX(sc).type = MIX_ON_OFF;
3012                         MIX(sc).ctl = SOUND_MIXER_NRDEVICES;
3013                         MIX(sc).name = "mute";
3014                         break;
3015
3016                 case VOLUME_CONTROL:
3017                         MIX(sc).type = MIX_SIGNED_16;
3018                         MIX(sc).ctl = mixernumber;
3019                         MIX(sc).name = "vol";
3020                         break;
3021
3022                 case BASS_CONTROL:
3023                         MIX(sc).type = MIX_SIGNED_8;
3024                         MIX(sc).ctl = SOUND_MIXER_BASS;
3025                         MIX(sc).name = "bass";
3026                         break;
3027
3028                 case MID_CONTROL:
3029                         MIX(sc).type = MIX_SIGNED_8;
3030                         MIX(sc).ctl = SOUND_MIXER_NRDEVICES;    /* XXXXX */
3031                         MIX(sc).name = "mid";
3032                         break;
3033
3034                 case TREBLE_CONTROL:
3035                         MIX(sc).type = MIX_SIGNED_8;
3036                         MIX(sc).ctl = SOUND_MIXER_TREBLE;
3037                         MIX(sc).name = "treble";
3038                         break;
3039
3040                 case GRAPHIC_EQUALIZER_CONTROL:
3041                         continue;       /* XXX don't add anything */
3042
3043                 case AGC_CONTROL:
3044                         MIX(sc).type = MIX_ON_OFF;
3045                         MIX(sc).ctl = SOUND_MIXER_NRDEVICES;    /* XXXXX */
3046                         MIX(sc).name = "agc";
3047                         break;
3048
3049                 case DELAY_CONTROL:
3050                         MIX(sc).type = MIX_UNSIGNED_16;
3051                         MIX(sc).ctl = SOUND_MIXER_NRDEVICES;    /* XXXXX */
3052                         MIX(sc).name = "delay";
3053                         break;
3054
3055                 case BASS_BOOST_CONTROL:
3056                         MIX(sc).type = MIX_ON_OFF;
3057                         MIX(sc).ctl = SOUND_MIXER_NRDEVICES;    /* XXXXX */
3058                         MIX(sc).name = "boost";
3059                         break;
3060
3061                 case LOUDNESS_CONTROL:
3062                         MIX(sc).type = MIX_ON_OFF;
3063                         MIX(sc).ctl = SOUND_MIXER_LOUD; /* Is this correct ? */
3064                         MIX(sc).name = "loudness";
3065                         break;
3066
3067                 default:
3068                         MIX(sc).type = MIX_UNKNOWN;
3069                         break;
3070                 }
3071
3072                 if (MIX(sc).type != MIX_UNKNOWN)
3073                         uaudio_mixer_add_ctl(sc, &MIX(sc));
3074         }
3075 }
3076
3077 static void
3078 uaudio20_mixer_add_feature(struct uaudio_softc *sc,
3079     const struct uaudio_terminal_node *iot, int id)
3080 {
3081         const struct usb_audio20_feature_unit *d = iot[id].u.fu_v2;
3082         uint32_t ctl;
3083         uint32_t mmask;
3084         uint32_t cmask;
3085         uint16_t mixernumber;
3086         uint8_t nchan;
3087         uint8_t chan;
3088         uint8_t i;
3089         uint8_t what;
3090
3091         if (UGETDW(d->bmaControls[0]) == 0)
3092                 return;
3093
3094         memset(&MIX(sc), 0, sizeof(MIX(sc)));
3095
3096         nchan = (d->bLength - 6) / 4;
3097         mmask = UGETDW(d->bmaControls[0]);
3098         cmask = 0;
3099
3100         if (nchan == 0)
3101                 return;
3102
3103         /* figure out what we can control */
3104
3105         for (chan = 1; chan < nchan; chan++)
3106                 cmask |= UGETDW(d->bmaControls[chan]);
3107
3108         if (nchan > MIX_MAX_CHAN)
3109                 nchan = MIX_MAX_CHAN;
3110
3111         MIX(sc).wIndex = MAKE_WORD(d->bUnitId, sc->sc_mixer_iface_no);
3112
3113         i = d->bmaControls[nchan][0];
3114         if (i == 0 ||
3115             usbd_req_get_string_any(sc->sc_udev, NULL,
3116             MIX(sc).desc, sizeof(MIX(sc).desc), i) != 0) {
3117                 MIX(sc).desc[0] = 0;
3118         }
3119
3120         for (ctl = 3; ctl != 0; ctl <<= 2) {
3121
3122                 mixernumber = uaudio20_mixer_feature_name(&iot[id], &MIX(sc));
3123
3124                 switch (ctl) {
3125                 case (3 << 0):
3126                         MIX(sc).type = MIX_ON_OFF;
3127                         MIX(sc).ctl = SOUND_MIXER_NRDEVICES;
3128                         MIX(sc).name = "mute";
3129                         what = MUTE_CONTROL;
3130                         break;
3131                 case (3 << 2): 
3132                         MIX(sc).type = MIX_SIGNED_16;
3133                         MIX(sc).ctl = mixernumber;
3134                         MIX(sc).name = "vol";
3135                         what = VOLUME_CONTROL;
3136                         break;
3137                 case (3 << 4):
3138                         MIX(sc).type = MIX_SIGNED_8;
3139                         MIX(sc).ctl = SOUND_MIXER_BASS;
3140                         MIX(sc).name = "bass";
3141                         what = BASS_CONTROL;
3142                         break;
3143                 case (3 << 6):
3144                         MIX(sc).type = MIX_SIGNED_8;
3145                         MIX(sc).ctl = SOUND_MIXER_NRDEVICES;    /* XXXXX */
3146                         MIX(sc).name = "mid";
3147                         what = MID_CONTROL;
3148                         break;
3149                 case (3 << 8):
3150                         MIX(sc).type = MIX_SIGNED_8;
3151                         MIX(sc).ctl = SOUND_MIXER_TREBLE;
3152                         MIX(sc).name = "treble";
3153                         what = TREBLE_CONTROL;
3154                         break;
3155                 case (3 << 12):
3156                         MIX(sc).type = MIX_ON_OFF;
3157                         MIX(sc).ctl = SOUND_MIXER_NRDEVICES;    /* XXXXX */
3158                         MIX(sc).name = "agc";
3159                         what = AGC_CONTROL;
3160                         break;
3161                 case (3 << 14):
3162                         MIX(sc).type = MIX_UNSIGNED_16;
3163                         MIX(sc).ctl = SOUND_MIXER_NRDEVICES;    /* XXXXX */
3164                         MIX(sc).name = "delay";
3165                         what = DELAY_CONTROL;
3166                         break;
3167                 case (3 << 16):
3168                         MIX(sc).type = MIX_ON_OFF;
3169                         MIX(sc).ctl = SOUND_MIXER_NRDEVICES;    /* XXXXX */
3170                         MIX(sc).name = "boost";
3171                         what = BASS_BOOST_CONTROL;
3172                         break;
3173                 case (3 << 18):
3174                         MIX(sc).type = MIX_ON_OFF;
3175                         MIX(sc).ctl = SOUND_MIXER_LOUD; /* Is this correct ? */
3176                         MIX(sc).name = "loudness";
3177                         what = LOUDNESS_CONTROL;
3178                         break;
3179                 case (3 << 20):
3180                         MIX(sc).type = MIX_SIGNED_16;
3181                         MIX(sc).ctl = mixernumber;
3182                         MIX(sc).name = "igain";
3183                         what = INPUT_GAIN_CONTROL;
3184                         break;
3185                 case (3 << 22):
3186                         MIX(sc).type = MIX_SIGNED_16;
3187                         MIX(sc).ctl = mixernumber;
3188                         MIX(sc).name = "igainpad";
3189                         what = INPUT_GAIN_PAD_CONTROL;
3190                         break;
3191                 default:
3192                         continue;
3193                 }
3194
3195                 if ((mmask & ctl) == ctl) {
3196                         MIX(sc).nchan = 1;
3197                         MIX(sc).wValue[0] = MAKE_WORD(what, 0);
3198                 } else if ((cmask & ctl) == ctl) {
3199                         MIX(sc).nchan = nchan - 1;
3200                         for (i = 1; i < nchan; i++) {
3201                                 if ((UGETDW(d->bmaControls[i]) & ctl) == ctl)
3202                                         MIX(sc).wValue[i - 1] = MAKE_WORD(what, i);
3203                                 else
3204                                         MIX(sc).wValue[i - 1] = -1;
3205                         }
3206                 } else {
3207                         continue;
3208                 }
3209
3210                 if (MIX(sc).type != MIX_UNKNOWN)
3211                         uaudio_mixer_add_ctl(sc, &MIX(sc));
3212         }
3213 }
3214
3215 static void
3216 uaudio_mixer_add_processing_updown(struct uaudio_softc *sc,
3217     const struct uaudio_terminal_node *iot, int id)
3218 {
3219         const struct usb_audio_processing_unit_0 *d0 = iot[id].u.pu_v1;
3220         const struct usb_audio_processing_unit_1 *d1 =
3221             (const void *)(d0->baSourceId + d0->bNrInPins);
3222         const struct usb_audio_processing_unit_updown *ud =
3223             (const void *)(d1->bmControls + d1->bControlSize);
3224         uint8_t i;
3225
3226         if (uaudio_mixer_verify_desc(d0, sizeof(*ud)) == NULL) {
3227                 return;
3228         }
3229         if (uaudio_mixer_verify_desc(d0, sizeof(*ud) + (2 * ud->bNrModes))
3230             == NULL) {
3231                 return;
3232         }
3233         DPRINTFN(3, "bUnitId=%d bNrModes=%d\n",
3234             d0->bUnitId, ud->bNrModes);
3235
3236         if (!(d1->bmControls[0] & UA_PROC_MASK(UD_MODE_SELECT_CONTROL))) {
3237                 DPRINTF("no mode select\n");
3238                 return;
3239         }
3240         memset(&MIX(sc), 0, sizeof(MIX(sc)));
3241
3242         MIX(sc).wIndex = MAKE_WORD(d0->bUnitId, sc->sc_mixer_iface_no);
3243         MIX(sc).nchan = 1;
3244         MIX(sc).wValue[0] = MAKE_WORD(UD_MODE_SELECT_CONTROL, 0);
3245         uaudio_mixer_determine_class(&iot[id], &MIX(sc));
3246         MIX(sc).type = MIX_ON_OFF;              /* XXX */
3247
3248         for (i = 0; i < ud->bNrModes; i++) {
3249                 DPRINTFN(3, "i=%d bm=0x%x\n", i, UGETW(ud->waModes[i]));
3250                 /* XXX */
3251         }
3252
3253         uaudio_mixer_add_ctl(sc, &MIX(sc));
3254 }
3255
3256 static void
3257 uaudio_mixer_add_processing(struct uaudio_softc *sc,
3258     const struct uaudio_terminal_node *iot, int id)
3259 {
3260         const struct usb_audio_processing_unit_0 *d0 = iot[id].u.pu_v1;
3261         const struct usb_audio_processing_unit_1 *d1 =
3262             (const void *)(d0->baSourceId + d0->bNrInPins);
3263         uint16_t ptype;
3264
3265         memset(&MIX(sc), 0, sizeof(MIX(sc)));
3266
3267         ptype = UGETW(d0->wProcessType);
3268
3269         DPRINTFN(3, "wProcessType=%d bUnitId=%d "
3270             "bNrInPins=%d\n", ptype, d0->bUnitId, d0->bNrInPins);
3271
3272         if (d1->bControlSize == 0) {
3273                 return;
3274         }
3275         if (d1->bmControls[0] & UA_PROC_ENABLE_MASK) {
3276                 MIX(sc).wIndex = MAKE_WORD(d0->bUnitId, sc->sc_mixer_iface_no);
3277                 MIX(sc).nchan = 1;
3278                 MIX(sc).wValue[0] = MAKE_WORD(XX_ENABLE_CONTROL, 0);
3279                 uaudio_mixer_determine_class(&iot[id], &MIX(sc));
3280                 MIX(sc).type = MIX_ON_OFF;
3281                 uaudio_mixer_add_ctl(sc, &MIX(sc));
3282         }
3283         switch (ptype) {
3284         case UPDOWNMIX_PROCESS:
3285                 uaudio_mixer_add_processing_updown(sc, iot, id);
3286                 break;
3287
3288         case DOLBY_PROLOGIC_PROCESS:
3289         case P3D_STEREO_EXTENDER_PROCESS:
3290         case REVERBATION_PROCESS:
3291         case CHORUS_PROCESS:
3292         case DYN_RANGE_COMP_PROCESS:
3293         default:
3294                 DPRINTF("unit %d, type=%d is not implemented\n",
3295                     d0->bUnitId, ptype);
3296                 break;
3297         }
3298 }
3299
3300 static void
3301 uaudio_mixer_add_extension(struct uaudio_softc *sc,
3302     const struct uaudio_terminal_node *iot, int id)
3303 {
3304         const struct usb_audio_extension_unit_0 *d0 = iot[id].u.eu_v1;
3305         const struct usb_audio_extension_unit_1 *d1 =
3306             (const void *)(d0->baSourceId + d0->bNrInPins);
3307
3308         DPRINTFN(3, "bUnitId=%d bNrInPins=%d\n",
3309             d0->bUnitId, d0->bNrInPins);
3310
3311         if (sc->sc_uq_au_no_xu) {
3312                 return;
3313         }
3314         if (d1->bControlSize == 0) {
3315                 return;
3316         }
3317         if (d1->bmControls[0] & UA_EXT_ENABLE_MASK) {
3318
3319                 memset(&MIX(sc), 0, sizeof(MIX(sc)));
3320
3321                 MIX(sc).wIndex = MAKE_WORD(d0->bUnitId, sc->sc_mixer_iface_no);
3322                 MIX(sc).nchan = 1;
3323                 MIX(sc).wValue[0] = MAKE_WORD(UA_EXT_ENABLE, 0);
3324                 uaudio_mixer_determine_class(&iot[id], &MIX(sc));
3325                 MIX(sc).type = MIX_ON_OFF;
3326
3327                 uaudio_mixer_add_ctl(sc, &MIX(sc));
3328         }
3329 }
3330
3331 static const void *
3332 uaudio_mixer_verify_desc(const void *arg, uint32_t len)
3333 {
3334         const struct usb_audio_mixer_unit_1 *d1;
3335         const struct usb_audio_extension_unit_1 *e1;
3336         const struct usb_audio_processing_unit_1 *u1;
3337
3338         union {
3339                 const struct usb_descriptor *desc;
3340                 const struct usb_audio_input_terminal *it;
3341                 const struct usb_audio_output_terminal *ot;
3342                 const struct usb_audio_mixer_unit_0 *mu;
3343                 const struct usb_audio_selector_unit *su;
3344                 const struct usb_audio_feature_unit *fu;
3345                 const struct usb_audio_processing_unit_0 *pu;
3346                 const struct usb_audio_extension_unit_0 *eu;
3347         }     u;
3348
3349         u.desc = arg;
3350
3351         if (u.desc == NULL) {
3352                 goto error;
3353         }
3354         if (u.desc->bDescriptorType != UDESC_CS_INTERFACE) {
3355                 goto error;
3356         }
3357         switch (u.desc->bDescriptorSubtype) {
3358         case UDESCSUB_AC_INPUT:
3359                 len += sizeof(*u.it);
3360                 break;
3361
3362         case UDESCSUB_AC_OUTPUT:
3363                 len += sizeof(*u.ot);
3364                 break;
3365
3366         case UDESCSUB_AC_MIXER:
3367                 len += sizeof(*u.mu);
3368
3369                 if (u.desc->bLength < len) {
3370                         goto error;
3371                 }
3372                 len += u.mu->bNrInPins;
3373
3374                 if (u.desc->bLength < len) {
3375                         goto error;
3376                 }
3377                 d1 = (const void *)(u.mu->baSourceId + u.mu->bNrInPins);
3378
3379                 len += sizeof(*d1);
3380                 break;
3381
3382         case UDESCSUB_AC_SELECTOR:
3383                 len += sizeof(*u.su);
3384
3385                 if (u.desc->bLength < len) {
3386                         goto error;
3387                 }
3388                 len += u.su->bNrInPins + 1;
3389                 break;
3390
3391         case UDESCSUB_AC_FEATURE:
3392                 len += sizeof(*u.fu) + 1;
3393
3394                 if (u.desc->bLength < len)
3395                         goto error;
3396
3397                 len += u.fu->bControlSize;
3398                 break;
3399
3400         case UDESCSUB_AC_PROCESSING:
3401                 len += sizeof(*u.pu);
3402
3403                 if (u.desc->bLength < len) {
3404                         goto error;
3405                 }
3406                 len += u.pu->bNrInPins;
3407
3408                 if (u.desc->bLength < len) {
3409                         goto error;
3410                 }
3411                 u1 = (const void *)(u.pu->baSourceId + u.pu->bNrInPins);
3412
3413                 len += sizeof(*u1);
3414
3415                 if (u.desc->bLength < len) {
3416                         goto error;
3417                 }
3418                 len += u1->bControlSize;
3419
3420                 break;
3421
3422         case UDESCSUB_AC_EXTENSION:
3423                 len += sizeof(*u.eu);
3424
3425                 if (u.desc->bLength < len) {
3426                         goto error;
3427                 }
3428                 len += u.eu->bNrInPins;
3429
3430                 if (u.desc->bLength < len) {
3431                         goto error;
3432                 }
3433                 e1 = (const void *)(u.eu->baSourceId + u.eu->bNrInPins);
3434
3435                 len += sizeof(*e1);
3436
3437                 if (u.desc->bLength < len) {
3438                         goto error;
3439                 }
3440                 len += e1->bControlSize;
3441                 break;
3442
3443         default:
3444                 goto error;
3445         }
3446
3447         if (u.desc->bLength < len) {
3448                 goto error;
3449         }
3450         return (u.desc);
3451
3452 error:
3453         if (u.desc) {
3454                 DPRINTF("invalid descriptor, type=%d, "
3455                     "sub_type=%d, len=%d of %d bytes\n",
3456                     u.desc->bDescriptorType,
3457                     u.desc->bDescriptorSubtype,
3458                     u.desc->bLength, len);
3459         }
3460         return (NULL);
3461 }
3462
3463 static const void *
3464 uaudio20_mixer_verify_desc(const void *arg, uint32_t len)
3465 {
3466         const struct usb_audio20_mixer_unit_1 *d1;
3467         const struct usb_audio20_extension_unit_1 *e1;
3468         const struct usb_audio20_processing_unit_1 *u1;
3469         const struct usb_audio20_clock_selector_unit_1 *c1;
3470
3471         union {
3472                 const struct usb_descriptor *desc;
3473                 const struct usb_audio20_clock_source_unit *csrc;
3474                 const struct usb_audio20_clock_selector_unit_0 *csel;
3475                 const struct usb_audio20_clock_multiplier_unit *cmul;
3476                 const struct usb_audio20_input_terminal *it;
3477                 const struct usb_audio20_output_terminal *ot;
3478                 const struct usb_audio20_mixer_unit_0 *mu;
3479                 const struct usb_audio20_selector_unit *su;
3480                 const struct usb_audio20_feature_unit *fu;
3481                 const struct usb_audio20_sample_rate_unit *ru;
3482                 const struct usb_audio20_processing_unit_0 *pu;
3483                 const struct usb_audio20_extension_unit_0 *eu;
3484                 const struct usb_audio20_effect_unit *ef;
3485         }     u;
3486
3487         u.desc = arg;
3488
3489         if (u.desc == NULL)
3490                 goto error;
3491
3492         if (u.desc->bDescriptorType != UDESC_CS_INTERFACE)
3493                 goto error;
3494
3495         switch (u.desc->bDescriptorSubtype) {
3496         case UDESCSUB_AC_INPUT:
3497                 len += sizeof(*u.it);
3498                 break;
3499
3500         case UDESCSUB_AC_OUTPUT:
3501                 len += sizeof(*u.ot);
3502                 break;
3503
3504         case UDESCSUB_AC_MIXER:
3505                 len += sizeof(*u.mu);
3506
3507                 if (u.desc->bLength < len)
3508                         goto error;
3509                 len += u.mu->bNrInPins;
3510
3511                 if (u.desc->bLength < len)
3512                         goto error;
3513
3514                 d1 = (const void *)(u.mu->baSourceId + u.mu->bNrInPins);
3515
3516                 len += sizeof(*d1) + d1->bNrChannels;
3517                 break;
3518
3519         case UDESCSUB_AC_SELECTOR:
3520                 len += sizeof(*u.su);
3521
3522                 if (u.desc->bLength < len)
3523                         goto error;
3524
3525                 len += u.su->bNrInPins + 1;
3526                 break;
3527
3528         case UDESCSUB_AC_FEATURE:
3529                 len += sizeof(*u.fu) + 1;
3530                 break;
3531
3532         case UDESCSUB_AC_EFFECT:
3533                 len += sizeof(*u.ef) + 4;
3534                 break;
3535
3536         case UDESCSUB_AC_PROCESSING_V2:
3537                 len += sizeof(*u.pu);
3538
3539                 if (u.desc->bLength < len)
3540                         goto error;
3541
3542                 len += u.pu->bNrInPins;
3543
3544                 if (u.desc->bLength < len)
3545                         goto error;
3546
3547                 u1 = (const void *)(u.pu->baSourceId + u.pu->bNrInPins);
3548
3549                 len += sizeof(*u1);
3550                 break;
3551
3552         case UDESCSUB_AC_EXTENSION_V2:
3553                 len += sizeof(*u.eu);
3554
3555                 if (u.desc->bLength < len)
3556                         goto error;
3557
3558                 len += u.eu->bNrInPins;
3559
3560                 if (u.desc->bLength < len)
3561                         goto error;
3562
3563                 e1 = (const void *)(u.eu->baSourceId + u.eu->bNrInPins);
3564
3565                 len += sizeof(*e1);
3566                 break;
3567
3568         case UDESCSUB_AC_CLOCK_SRC:
3569                 len += sizeof(*u.csrc);
3570                 break;
3571
3572         case UDESCSUB_AC_CLOCK_SEL:
3573                 len += sizeof(*u.csel);
3574
3575                 if (u.desc->bLength < len)
3576                         goto error;
3577
3578                 len += u.csel->bNrInPins;
3579
3580                 if (u.desc->bLength < len)
3581                         goto error;
3582
3583                 c1 = (const void *)(u.csel->baCSourceId + u.csel->bNrInPins);
3584
3585                 len += sizeof(*c1);
3586                 break;
3587
3588         case UDESCSUB_AC_CLOCK_MUL:
3589                 len += sizeof(*u.cmul);
3590                 break;
3591
3592         case UDESCSUB_AC_SAMPLE_RT:
3593                 len += sizeof(*u.ru);
3594                 break;
3595
3596         default:
3597                 goto error;
3598         }
3599
3600         if (u.desc->bLength < len)
3601                 goto error;
3602
3603         return (u.desc);
3604
3605 error:
3606         if (u.desc) {
3607                 DPRINTF("invalid descriptor, type=%d, "
3608                     "sub_type=%d, len=%d of %d bytes\n",
3609                     u.desc->bDescriptorType,
3610                     u.desc->bDescriptorSubtype,
3611                     u.desc->bLength, len);
3612         }
3613         return (NULL);
3614 }
3615
3616 static struct usb_audio_cluster
3617 uaudio_mixer_get_cluster(uint8_t id, const struct uaudio_terminal_node *iot)
3618 {
3619         struct usb_audio_cluster r;
3620         const struct usb_descriptor *dp;
3621         uint8_t i;
3622
3623         for (i = 0; i < UAUDIO_RECURSE_LIMIT; i++) {    /* avoid infinite loops */
3624                 dp = iot[id].u.desc;
3625                 if (dp == NULL) {
3626                         goto error;
3627                 }
3628                 switch (dp->bDescriptorSubtype) {
3629                 case UDESCSUB_AC_INPUT:
3630                         r.bNrChannels = iot[id].u.it_v1->bNrChannels;
3631                         r.wChannelConfig[0] = iot[id].u.it_v1->wChannelConfig[0];
3632                         r.wChannelConfig[1] = iot[id].u.it_v1->wChannelConfig[1];
3633                         r.iChannelNames = iot[id].u.it_v1->iChannelNames;
3634                         goto done;
3635
3636                 case UDESCSUB_AC_OUTPUT:
3637                         id = iot[id].u.ot_v1->bSourceId;
3638                         break;
3639
3640                 case UDESCSUB_AC_MIXER:
3641                         r = *(const struct usb_audio_cluster *)
3642                             &iot[id].u.mu_v1->baSourceId[
3643                             iot[id].u.mu_v1->bNrInPins];
3644                         goto done;
3645
3646                 case UDESCSUB_AC_SELECTOR:
3647                         if (iot[id].u.su_v1->bNrInPins > 0) {
3648                                 /* XXX This is not really right */
3649                                 id = iot[id].u.su_v1->baSourceId[0];
3650                         }
3651                         break;
3652
3653                 case UDESCSUB_AC_FEATURE:
3654                         id = iot[id].u.fu_v1->bSourceId;
3655                         break;
3656
3657                 case UDESCSUB_AC_PROCESSING:
3658                         r = *((const struct usb_audio_cluster *)
3659                             &iot[id].u.pu_v1->baSourceId[
3660                             iot[id].u.pu_v1->bNrInPins]);
3661                         goto done;
3662
3663                 case UDESCSUB_AC_EXTENSION:
3664                         r = *((const struct usb_audio_cluster *)
3665                             &iot[id].u.eu_v1->baSourceId[
3666                             iot[id].u.eu_v1->bNrInPins]);
3667                         goto done;
3668
3669                 default:
3670                         goto error;
3671                 }
3672         }
3673 error:
3674         DPRINTF("bad data\n");
3675         memset(&r, 0, sizeof(r));
3676 done:
3677         return (r);
3678 }
3679
3680 static struct usb_audio20_cluster
3681 uaudio20_mixer_get_cluster(uint8_t id, const struct uaudio_terminal_node *iot)
3682 {
3683         struct usb_audio20_cluster r;
3684         const struct usb_descriptor *dp;
3685         uint8_t i;
3686
3687         for (i = 0; i < UAUDIO_RECURSE_LIMIT; i++) {    /* avoid infinite loops */
3688                 dp = iot[id].u.desc;
3689                 if (dp == NULL)
3690                         goto error;
3691
3692                 switch (dp->bDescriptorSubtype) {
3693                 case UDESCSUB_AC_INPUT:
3694                         r.bNrChannels = iot[id].u.it_v2->bNrChannels;
3695                         r.bmChannelConfig[0] = iot[id].u.it_v2->bmChannelConfig[0];
3696                         r.bmChannelConfig[1] = iot[id].u.it_v2->bmChannelConfig[1];
3697                         r.bmChannelConfig[2] = iot[id].u.it_v2->bmChannelConfig[2];
3698                         r.bmChannelConfig[3] = iot[id].u.it_v2->bmChannelConfig[3];
3699                         r.iChannelNames = iot[id].u.it_v2->iTerminal;
3700                         goto done;
3701
3702                 case UDESCSUB_AC_OUTPUT:
3703                         id = iot[id].u.ot_v2->bSourceId;
3704                         break;
3705
3706                 case UDESCSUB_AC_MIXER:
3707                         r = *(const struct usb_audio20_cluster *)
3708                             &iot[id].u.mu_v2->baSourceId[
3709                             iot[id].u.mu_v2->bNrInPins];
3710                         goto done;
3711
3712                 case UDESCSUB_AC_SELECTOR:
3713                         if (iot[id].u.su_v2->bNrInPins > 0) {
3714                                 /* XXX This is not really right */
3715                                 id = iot[id].u.su_v2->baSourceId[0];
3716                         }
3717                         break;
3718
3719                 case UDESCSUB_AC_SAMPLE_RT:
3720                         id = iot[id].u.ru_v2->bSourceId;
3721                         break;
3722
3723                 case UDESCSUB_AC_EFFECT:
3724                         id = iot[id].u.ef_v2->bSourceId;
3725                         break;
3726
3727                 case UDESCSUB_AC_FEATURE:
3728                         id = iot[id].u.fu_v2->bSourceId;
3729                         break;
3730
3731                 case UDESCSUB_AC_PROCESSING_V2:
3732                         r = *((const struct usb_audio20_cluster *)
3733                             &iot[id].u.pu_v2->baSourceId[
3734                             iot[id].u.pu_v2->bNrInPins]);
3735                         goto done;
3736
3737                 case UDESCSUB_AC_EXTENSION_V2:
3738                         r = *((const struct usb_audio20_cluster *)
3739                             &iot[id].u.eu_v2->baSourceId[
3740                             iot[id].u.eu_v2->bNrInPins]);
3741                         goto done;
3742
3743                 default:
3744                         goto error;
3745                 }
3746         }
3747 error:
3748         DPRINTF("Bad data!\n");
3749         memset(&r, 0, sizeof(r));
3750 done:
3751         return (r);
3752 }
3753
3754 static uint16_t
3755 uaudio_mixer_determine_class(const struct uaudio_terminal_node *iot,
3756     struct uaudio_mixer_node *mix)
3757 {
3758         uint16_t terminal_type = 0x0000;
3759         const struct uaudio_terminal_node *input[2];
3760         const struct uaudio_terminal_node *output[2];
3761
3762         input[0] = uaudio_mixer_get_input(iot, 0);
3763         input[1] = uaudio_mixer_get_input(iot, 1);
3764
3765         output[0] = uaudio_mixer_get_output(iot, 0);
3766         output[1] = uaudio_mixer_get_output(iot, 1);
3767
3768         /*
3769          * check if there is only
3770          * one output terminal:
3771          */
3772         if (output[0] && (!output[1])) {
3773                 terminal_type =
3774                     UGETW(output[0]->u.ot_v1->wTerminalType);
3775         }
3776         /*
3777          * If the only output terminal is USB,
3778          * the class is UAC_RECORD.
3779          */
3780         if ((terminal_type & 0xff00) == (UAT_UNDEFINED & 0xff00)) {
3781
3782                 mix->class = UAC_RECORD;
3783                 if (input[0] && (!input[1])) {
3784                         terminal_type =
3785                             UGETW(input[0]->u.it_v1->wTerminalType);
3786                 } else {
3787                         terminal_type = 0;
3788                 }
3789                 goto done;
3790         }
3791         /*
3792          * if the unit is connected to just
3793          * one input terminal, the
3794          * class is UAC_INPUT:
3795          */
3796         if (input[0] && (!input[1])) {
3797                 mix->class = UAC_INPUT;
3798                 terminal_type =
3799                     UGETW(input[0]->u.it_v1->wTerminalType);
3800                 goto done;
3801         }
3802         /*
3803          * Otherwise, the class is UAC_OUTPUT.
3804          */
3805         mix->class = UAC_OUTPUT;
3806 done:
3807         return (terminal_type);
3808 }
3809
3810 static uint16_t
3811 uaudio20_mixer_determine_class(const struct uaudio_terminal_node *iot,
3812     struct uaudio_mixer_node *mix)
3813 {
3814         uint16_t terminal_type = 0x0000;
3815         const struct uaudio_terminal_node *input[2];
3816         const struct uaudio_terminal_node *output[2];
3817
3818         input[0] = uaudio_mixer_get_input(iot, 0);
3819         input[1] = uaudio_mixer_get_input(iot, 1);
3820
3821         output[0] = uaudio_mixer_get_output(iot, 0);
3822         output[1] = uaudio_mixer_get_output(iot, 1);
3823
3824         /*
3825          * check if there is only
3826          * one output terminal:
3827          */
3828         if (output[0] && (!output[1]))
3829                 terminal_type = UGETW(output[0]->u.ot_v2->wTerminalType);
3830         /*
3831          * If the only output terminal is USB,
3832          * the class is UAC_RECORD.
3833          */
3834         if ((terminal_type & 0xff00) == (UAT_UNDEFINED & 0xff00)) {
3835
3836                 mix->class = UAC_RECORD;
3837                 if (input[0] && (!input[1])) {
3838                         terminal_type =
3839                             UGETW(input[0]->u.it_v2->wTerminalType);
3840                 } else {
3841                         terminal_type = 0;
3842                 }
3843                 goto done;
3844         }
3845         /*
3846          * if the unit is connected to just
3847          * one input terminal, the
3848          * class is UAC_INPUT:
3849          */
3850         if (input[0] && (!input[1])) {
3851                 mix->class = UAC_INPUT;
3852                 terminal_type =
3853                     UGETW(input[0]->u.it_v2->wTerminalType);
3854                 goto done;
3855         }
3856         /*
3857          * Otherwise, the class is UAC_OUTPUT.
3858          */
3859         mix->class = UAC_OUTPUT;
3860 done:
3861         return (terminal_type);
3862 }
3863
3864 struct uaudio_tt_to_feature {
3865         uint16_t terminal_type;
3866         uint16_t feature;
3867 };
3868
3869 static const struct uaudio_tt_to_feature uaudio_tt_to_feature[] = {
3870
3871         {UAT_STREAM, SOUND_MIXER_PCM},
3872
3873         {UATI_MICROPHONE, SOUND_MIXER_MIC},
3874         {UATI_DESKMICROPHONE, SOUND_MIXER_MIC},
3875         {UATI_PERSONALMICROPHONE, SOUND_MIXER_MIC},
3876         {UATI_OMNIMICROPHONE, SOUND_MIXER_MIC},
3877         {UATI_MICROPHONEARRAY, SOUND_MIXER_MIC},
3878         {UATI_PROCMICROPHONEARR, SOUND_MIXER_MIC},
3879
3880         {UATO_SPEAKER, SOUND_MIXER_SPEAKER},
3881         {UATO_DESKTOPSPEAKER, SOUND_MIXER_SPEAKER},
3882         {UATO_ROOMSPEAKER, SOUND_MIXER_SPEAKER},
3883         {UATO_COMMSPEAKER, SOUND_MIXER_SPEAKER},
3884
3885         {UATE_ANALOGCONN, SOUND_MIXER_LINE},
3886         {UATE_LINECONN, SOUND_MIXER_LINE},
3887         {UATE_LEGACYCONN, SOUND_MIXER_LINE},
3888
3889         {UATE_DIGITALAUIFC, SOUND_MIXER_ALTPCM},
3890         {UATE_SPDIF, SOUND_MIXER_ALTPCM},
3891         {UATE_1394DA, SOUND_MIXER_ALTPCM},
3892         {UATE_1394DV, SOUND_MIXER_ALTPCM},
3893
3894         {UATF_CDPLAYER, SOUND_MIXER_CD},
3895
3896         {UATF_SYNTHESIZER, SOUND_MIXER_SYNTH},
3897
3898         {UATF_VIDEODISCAUDIO, SOUND_MIXER_VIDEO},
3899         {UATF_DVDAUDIO, SOUND_MIXER_VIDEO},
3900         {UATF_TVTUNERAUDIO, SOUND_MIXER_VIDEO},
3901
3902         /* telephony terminal types */
3903         {UATT_UNDEFINED, SOUND_MIXER_PHONEIN},  /* SOUND_MIXER_PHONEOUT */
3904         {UATT_PHONELINE, SOUND_MIXER_PHONEIN},  /* SOUND_MIXER_PHONEOUT */
3905         {UATT_TELEPHONE, SOUND_MIXER_PHONEIN},  /* SOUND_MIXER_PHONEOUT */
3906         {UATT_DOWNLINEPHONE, SOUND_MIXER_PHONEIN},      /* SOUND_MIXER_PHONEOUT */
3907
3908         {UATF_RADIORECV, SOUND_MIXER_RADIO},
3909         {UATF_RADIOXMIT, SOUND_MIXER_RADIO},
3910
3911         {UAT_UNDEFINED, SOUND_MIXER_VOLUME},
3912         {UAT_VENDOR, SOUND_MIXER_VOLUME},
3913         {UATI_UNDEFINED, SOUND_MIXER_VOLUME},
3914
3915         /* output terminal types */
3916         {UATO_UNDEFINED, SOUND_MIXER_VOLUME},
3917         {UATO_DISPLAYAUDIO, SOUND_MIXER_VOLUME},
3918         {UATO_SUBWOOFER, SOUND_MIXER_VOLUME},
3919         {UATO_HEADPHONES, SOUND_MIXER_VOLUME},
3920
3921         /* bidir terminal types */
3922         {UATB_UNDEFINED, SOUND_MIXER_VOLUME},
3923         {UATB_HANDSET, SOUND_MIXER_VOLUME},
3924         {UATB_HEADSET, SOUND_MIXER_VOLUME},
3925         {UATB_SPEAKERPHONE, SOUND_MIXER_VOLUME},
3926         {UATB_SPEAKERPHONEESUP, SOUND_MIXER_VOLUME},
3927         {UATB_SPEAKERPHONEECANC, SOUND_MIXER_VOLUME},
3928
3929         /* external terminal types */
3930         {UATE_UNDEFINED, SOUND_MIXER_VOLUME},
3931
3932         /* embedded function terminal types */
3933         {UATF_UNDEFINED, SOUND_MIXER_VOLUME},
3934         {UATF_CALIBNOISE, SOUND_MIXER_VOLUME},
3935         {UATF_EQUNOISE, SOUND_MIXER_VOLUME},
3936         {UATF_DAT, SOUND_MIXER_VOLUME},
3937         {UATF_DCC, SOUND_MIXER_VOLUME},
3938         {UATF_MINIDISK, SOUND_MIXER_VOLUME},
3939         {UATF_ANALOGTAPE, SOUND_MIXER_VOLUME},
3940         {UATF_PHONOGRAPH, SOUND_MIXER_VOLUME},
3941         {UATF_VCRAUDIO, SOUND_MIXER_VOLUME},
3942         {UATF_SATELLITE, SOUND_MIXER_VOLUME},
3943         {UATF_CABLETUNER, SOUND_MIXER_VOLUME},
3944         {UATF_DSS, SOUND_MIXER_VOLUME},
3945         {UATF_MULTITRACK, SOUND_MIXER_VOLUME},
3946         {0xffff, SOUND_MIXER_VOLUME},
3947
3948         /* default */
3949         {0x0000, SOUND_MIXER_VOLUME},
3950 };
3951
3952 static uint16_t
3953 uaudio_mixer_feature_name(const struct uaudio_terminal_node *iot,
3954     struct uaudio_mixer_node *mix)
3955 {
3956         const struct uaudio_tt_to_feature *uat = uaudio_tt_to_feature;
3957         uint16_t terminal_type = uaudio_mixer_determine_class(iot, mix);
3958
3959         if ((mix->class == UAC_RECORD) && (terminal_type == 0)) {
3960                 return (SOUND_MIXER_IMIX);
3961         }
3962         while (uat->terminal_type) {
3963                 if (uat->terminal_type == terminal_type) {
3964                         break;
3965                 }
3966                 uat++;
3967         }
3968
3969         DPRINTF("terminal_type=0x%04x -> %d\n",
3970             terminal_type, uat->feature);
3971
3972         return (uat->feature);
3973 }
3974
3975 static uint16_t
3976 uaudio20_mixer_feature_name(const struct uaudio_terminal_node *iot,
3977     struct uaudio_mixer_node *mix)
3978 {
3979         const struct uaudio_tt_to_feature *uat;
3980         uint16_t terminal_type = uaudio20_mixer_determine_class(iot, mix);
3981
3982         if ((mix->class == UAC_RECORD) && (terminal_type == 0))
3983                 return (SOUND_MIXER_IMIX);
3984         
3985         for (uat = uaudio_tt_to_feature; uat->terminal_type != 0; uat++) {
3986                 if (uat->terminal_type == terminal_type)
3987                         break;
3988         }
3989
3990         DPRINTF("terminal_type=0x%04x -> %d\n",
3991             terminal_type, uat->feature);
3992
3993         return (uat->feature);
3994 }
3995
3996 static const struct uaudio_terminal_node *
3997 uaudio_mixer_get_input(const struct uaudio_terminal_node *iot, uint8_t i)
3998 {
3999         struct uaudio_terminal_node *root = iot->root;
4000         uint8_t n;
4001
4002         n = iot->usr.id_max;
4003         do {
4004                 if (iot->usr.bit_input[n / 8] & (1 << (n % 8))) {
4005                         if (!i--)
4006                                 return (root + n);
4007                 }
4008         } while (n--);
4009
4010         return (NULL);
4011 }
4012
4013 static const struct uaudio_terminal_node *
4014 uaudio_mixer_get_output(const struct uaudio_terminal_node *iot, uint8_t i)
4015 {
4016         struct uaudio_terminal_node *root = iot->root;
4017         uint8_t n;
4018
4019         n = iot->usr.id_max;
4020         do {
4021                 if (iot->usr.bit_output[n / 8] & (1 << (n % 8))) {
4022                         if (!i--)
4023                                 return (root + n);
4024                 }
4025         } while (n--);
4026
4027         return (NULL);
4028 }
4029
4030 static void
4031 uaudio_mixer_find_inputs_sub(struct uaudio_terminal_node *root,
4032     const uint8_t *p_id, uint8_t n_id,
4033     struct uaudio_search_result *info)
4034 {
4035         struct uaudio_terminal_node *iot;
4036         uint8_t n;
4037         uint8_t i;
4038         uint8_t is_last;
4039
4040 top:
4041         for (n = 0; n < n_id; n++) {
4042
4043                 i = p_id[n];
4044
4045                 if (info->recurse_level == UAUDIO_RECURSE_LIMIT) {
4046                         DPRINTF("avoided going into a circle at id=%d!\n", i);
4047                         return;
4048                 }
4049
4050                 info->recurse_level++;
4051
4052                 iot = (root + i);
4053
4054                 if (iot->u.desc == NULL)
4055                         continue;
4056
4057                 is_last = ((n + 1) == n_id);
4058
4059                 switch (iot->u.desc->bDescriptorSubtype) {
4060                 case UDESCSUB_AC_INPUT:
4061                         info->bit_input[i / 8] |= (1 << (i % 8));
4062                         break;
4063
4064                 case UDESCSUB_AC_FEATURE:
4065                         if (is_last) {
4066                                 p_id = &iot->u.fu_v1->bSourceId;
4067                                 n_id = 1;
4068                                 goto top;
4069                         }
4070                         uaudio_mixer_find_inputs_sub(
4071                             root, &iot->u.fu_v1->bSourceId, 1, info);
4072                         break;
4073
4074                 case UDESCSUB_AC_OUTPUT:
4075                         if (is_last) {
4076                                 p_id = &iot->u.ot_v1->bSourceId;
4077                                 n_id = 1;
4078                                 goto top;
4079                         }
4080                         uaudio_mixer_find_inputs_sub(
4081                             root, &iot->u.ot_v1->bSourceId, 1, info);
4082                         break;
4083
4084                 case UDESCSUB_AC_MIXER:
4085                         if (is_last) {
4086                                 p_id = iot->u.mu_v1->baSourceId;
4087                                 n_id = iot->u.mu_v1->bNrInPins;
4088                                 goto top;
4089                         }
4090                         uaudio_mixer_find_inputs_sub(
4091                             root, iot->u.mu_v1->baSourceId,
4092                             iot->u.mu_v1->bNrInPins, info);
4093                         break;
4094
4095                 case UDESCSUB_AC_SELECTOR:
4096                         if (is_last) {
4097                                 p_id = iot->u.su_v1->baSourceId;
4098                                 n_id = iot->u.su_v1->bNrInPins;
4099                                 goto top;
4100                         }
4101                         uaudio_mixer_find_inputs_sub(
4102                             root, iot->u.su_v1->baSourceId,
4103                             iot->u.su_v1->bNrInPins, info);
4104                         break;
4105
4106                 case UDESCSUB_AC_PROCESSING:
4107                         if (is_last) {
4108                                 p_id = iot->u.pu_v1->baSourceId;
4109                                 n_id = iot->u.pu_v1->bNrInPins;
4110                                 goto top;
4111                         }
4112                         uaudio_mixer_find_inputs_sub(
4113                             root, iot->u.pu_v1->baSourceId,
4114                             iot->u.pu_v1->bNrInPins, info);
4115                         break;
4116
4117                 case UDESCSUB_AC_EXTENSION:
4118                         if (is_last) {
4119                                 p_id = iot->u.eu_v1->baSourceId;
4120                                 n_id = iot->u.eu_v1->bNrInPins;
4121                                 goto top;
4122                         }
4123                         uaudio_mixer_find_inputs_sub(
4124                             root, iot->u.eu_v1->baSourceId,
4125                             iot->u.eu_v1->bNrInPins, info);
4126                         break;
4127
4128                 default:
4129                         break;
4130                 }
4131         }
4132 }
4133
4134 static void
4135 uaudio20_mixer_find_inputs_sub(struct uaudio_terminal_node *root,
4136     const uint8_t *p_id, uint8_t n_id,
4137     struct uaudio_search_result *info)
4138 {
4139         struct uaudio_terminal_node *iot;
4140         uint8_t n;
4141         uint8_t i;
4142         uint8_t is_last;
4143
4144 top:
4145         for (n = 0; n < n_id; n++) {
4146
4147                 i = p_id[n];
4148
4149                 if (info->recurse_level == UAUDIO_RECURSE_LIMIT) {
4150                         DPRINTF("avoided going into a circle at id=%d!\n", i);
4151                         return;
4152                 }
4153
4154                 info->recurse_level++;
4155
4156                 iot = (root + i);
4157
4158                 if (iot->u.desc == NULL)
4159                         continue;
4160
4161                 is_last = ((n + 1) == n_id);
4162
4163                 switch (iot->u.desc->bDescriptorSubtype) {
4164                 case UDESCSUB_AC_INPUT:
4165                         info->bit_input[i / 8] |= (1 << (i % 8));
4166                         break;
4167
4168                 case UDESCSUB_AC_OUTPUT:
4169                         if (is_last) {
4170                                 p_id = &iot->u.ot_v2->bSourceId;
4171                                 n_id = 1;
4172                                 goto top;
4173                         }
4174                         uaudio20_mixer_find_inputs_sub(
4175                             root, &iot->u.ot_v2->bSourceId, 1, info);
4176                         break;
4177
4178                 case UDESCSUB_AC_MIXER:
4179                         if (is_last) {
4180                                 p_id = iot->u.mu_v2->baSourceId;
4181                                 n_id = iot->u.mu_v2->bNrInPins;
4182                                 goto top;
4183                         }
4184                         uaudio20_mixer_find_inputs_sub(
4185                             root, iot->u.mu_v2->baSourceId,
4186                             iot->u.mu_v2->bNrInPins, info);
4187                         break;
4188
4189                 case UDESCSUB_AC_SELECTOR:
4190                         if (is_last) {
4191                                 p_id = iot->u.su_v2->baSourceId;
4192                                 n_id = iot->u.su_v2->bNrInPins;
4193                                 goto top;
4194                         }
4195                         uaudio20_mixer_find_inputs_sub(
4196                             root, iot->u.su_v2->baSourceId,
4197                             iot->u.su_v2->bNrInPins, info);
4198                         break;
4199
4200                 case UDESCSUB_AC_SAMPLE_RT:
4201                         if (is_last) {
4202                                 p_id = &iot->u.ru_v2->bSourceId;
4203                                 n_id = 1;
4204                                 goto top;
4205                         }
4206                         uaudio20_mixer_find_inputs_sub(
4207                             root, &iot->u.ru_v2->bSourceId,
4208                             1, info);
4209                         break;
4210
4211                 case UDESCSUB_AC_EFFECT:
4212                         if (is_last) {
4213                                 p_id = &iot->u.ef_v2->bSourceId;
4214                                 n_id = 1;
4215                                 goto top;
4216                         }
4217                         uaudio20_mixer_find_inputs_sub(
4218                             root, &iot->u.ef_v2->bSourceId,
4219                             1, info);
4220                         break;
4221
4222                 case UDESCSUB_AC_FEATURE:
4223                         if (is_last) {
4224                                 p_id = &iot->u.fu_v2->bSourceId;
4225                                 n_id = 1;
4226                                 goto top;
4227                         }
4228                         uaudio20_mixer_find_inputs_sub(
4229                             root, &iot->u.fu_v2->bSourceId, 1, info);
4230                         break;
4231
4232                 case UDESCSUB_AC_PROCESSING_V2:
4233                         if (is_last) {
4234                                 p_id = iot->u.pu_v2->baSourceId;
4235                                 n_id = iot->u.pu_v2->bNrInPins;
4236                                 goto top;
4237                         }
4238                         uaudio20_mixer_find_inputs_sub(
4239                             root, iot->u.pu_v2->baSourceId,
4240                             iot->u.pu_v2->bNrInPins, info);
4241                         break;
4242
4243                 case UDESCSUB_AC_EXTENSION_V2:
4244                         if (is_last) {
4245                                 p_id = iot->u.eu_v2->baSourceId;
4246                                 n_id = iot->u.eu_v2->bNrInPins;
4247                                 goto top;
4248                         }
4249                         uaudio20_mixer_find_inputs_sub(
4250                             root, iot->u.eu_v2->baSourceId,
4251                             iot->u.eu_v2->bNrInPins, info);
4252                         break;
4253                 default:
4254                         break;
4255                 }
4256         }
4257 }
4258
4259 static void
4260 uaudio20_mixer_find_clocks_sub(struct uaudio_terminal_node *root,
4261     const uint8_t *p_id, uint8_t n_id,
4262     struct uaudio_search_result *info)
4263 {
4264         struct uaudio_terminal_node *iot;
4265         uint8_t n;
4266         uint8_t i;
4267         uint8_t is_last;
4268         uint8_t id;
4269
4270 top:
4271         for (n = 0; n < n_id; n++) {
4272
4273                 i = p_id[n];
4274
4275                 if (info->recurse_level == UAUDIO_RECURSE_LIMIT) {
4276                         DPRINTF("avoided going into a circle at id=%d!\n", i);
4277                         return;
4278                 }
4279
4280                 info->recurse_level++;
4281
4282                 iot = (root + i);
4283
4284                 if (iot->u.desc == NULL)
4285                         continue;
4286
4287                 is_last = ((n + 1) == n_id);
4288
4289                 switch (iot->u.desc->bDescriptorSubtype) {
4290                 case UDESCSUB_AC_INPUT:
4291                         info->is_input = 1;
4292                         if (is_last) {
4293                                 p_id = &iot->u.it_v2->bCSourceId;
4294                                 n_id = 1;
4295                                 goto top;
4296                         }
4297                         uaudio20_mixer_find_clocks_sub(root,
4298                             &iot->u.it_v2->bCSourceId, 1, info);
4299                         break;
4300
4301                 case UDESCSUB_AC_OUTPUT:
4302                         info->is_input = 0;
4303                         if (is_last) {
4304                                 p_id = &iot->u.ot_v2->bCSourceId;
4305                                 n_id = 1;
4306                                 goto top;
4307                         }
4308                         uaudio20_mixer_find_clocks_sub(root,
4309                             &iot->u.ot_v2->bCSourceId, 1, info);
4310                         break;
4311
4312                 case UDESCSUB_AC_CLOCK_SEL:
4313                         if (is_last) {
4314                                 p_id = iot->u.csel_v2->baCSourceId;
4315                                 n_id = iot->u.csel_v2->bNrInPins;
4316                                 goto top;
4317                         }
4318                         uaudio20_mixer_find_clocks_sub(root,
4319                             iot->u.csel_v2->baCSourceId,
4320                             iot->u.csel_v2->bNrInPins, info);
4321                         break;
4322
4323                 case UDESCSUB_AC_CLOCK_MUL:
4324                         if (is_last) {
4325                                 p_id = &iot->u.cmul_v2->bCSourceId;
4326                                 n_id = 1;
4327                                 goto top;
4328                         }
4329                         uaudio20_mixer_find_clocks_sub(root,
4330                             &iot->u.cmul_v2->bCSourceId,
4331                             1, info);
4332                         break;
4333
4334                 case UDESCSUB_AC_CLOCK_SRC:
4335
4336                         id = iot->u.csrc_v2->bClockId;
4337
4338                         switch (info->is_input) {
4339                         case 0:
4340                                 info->bit_output[id / 8] |= (1 << (id % 8));
4341                                 break;
4342                         case 1:
4343                                 info->bit_input[id / 8] |= (1 << (id % 8));
4344                                 break;
4345                         default:
4346                                 break;
4347                         }
4348                         break;
4349
4350                 default:
4351                         break;
4352                 }
4353         }
4354 }
4355
4356 static void
4357 uaudio_mixer_find_outputs_sub(struct uaudio_terminal_node *root, uint8_t id,
4358     uint8_t n_id, struct uaudio_search_result *info)
4359 {
4360         struct uaudio_terminal_node *iot = (root + id);
4361         uint8_t j;
4362
4363         j = n_id;
4364         do {
4365                 if ((j != id) && ((root + j)->u.desc) &&
4366                     ((root + j)->u.desc->bDescriptorSubtype == UDESCSUB_AC_OUTPUT)) {
4367
4368                         /*
4369                          * "j" (output) <--- virtual wire <--- "id" (input)
4370                          *
4371                          * if "j" has "id" on the input, then "id" have "j" on
4372                          * the output, because they are connected:
4373                          */
4374                         if ((root + j)->usr.bit_input[id / 8] & (1 << (id % 8))) {
4375                                 iot->usr.bit_output[j / 8] |= (1 << (j % 8));
4376                         }
4377                 }
4378         } while (j--);
4379 }
4380
4381 static void
4382 uaudio_mixer_fill_info(struct uaudio_softc *sc,
4383     struct usb_device *udev, void *desc)
4384 {
4385         const struct usb_audio_control_descriptor *acdp;
4386         struct usb_config_descriptor *cd = usbd_get_config_descriptor(udev);
4387         const struct usb_descriptor *dp;
4388         const struct usb_audio_unit *au;
4389         struct uaudio_terminal_node *iot = NULL;
4390         uint16_t wTotalLen;
4391         uint8_t ID_max = 0;             /* inclusive */
4392         uint8_t i;
4393
4394         desc = usb_desc_foreach(cd, desc);
4395
4396         if (desc == NULL) {
4397                 DPRINTF("no Audio Control header\n");
4398                 goto done;
4399         }
4400         acdp = desc;
4401
4402         if ((acdp->bLength < sizeof(*acdp)) ||
4403             (acdp->bDescriptorType != UDESC_CS_INTERFACE) ||
4404             (acdp->bDescriptorSubtype != UDESCSUB_AC_HEADER)) {
4405                 DPRINTF("invalid Audio Control header\n");
4406                 goto done;
4407         }
4408         /* "wTotalLen" is allowed to be corrupt */
4409         wTotalLen = UGETW(acdp->wTotalLength) - acdp->bLength;
4410
4411         /* get USB audio revision */
4412         sc->sc_audio_rev = UGETW(acdp->bcdADC);
4413
4414         DPRINTFN(3, "found AC header, vers=%03x, len=%d\n",
4415             sc->sc_audio_rev, wTotalLen);
4416
4417         iot = malloc(sizeof(struct uaudio_terminal_node) * 256, M_TEMP,
4418             M_WAITOK | M_ZERO);
4419
4420         if (iot == NULL) {
4421                 DPRINTF("no memory!\n");
4422                 goto done;
4423         }
4424         while ((desc = usb_desc_foreach(cd, desc))) {
4425
4426                 dp = desc;
4427
4428                 if (dp->bLength > wTotalLen) {
4429                         break;
4430                 } else {
4431                         wTotalLen -= dp->bLength;
4432                 }
4433
4434                 if (sc->sc_audio_rev >= UAUDIO_VERSION_30)
4435                         au = NULL;
4436                 else if (sc->sc_audio_rev >= UAUDIO_VERSION_20)
4437                         au = uaudio20_mixer_verify_desc(dp, 0);
4438                 else
4439                         au = uaudio_mixer_verify_desc(dp, 0);
4440
4441                 if (au) {
4442                         iot[au->bUnitId].u.desc = (const void *)au;
4443                         if (au->bUnitId > ID_max)
4444                                 ID_max = au->bUnitId;
4445                 }
4446         }
4447
4448         DPRINTF("Maximum ID=%d\n", ID_max);
4449
4450         /*
4451          * determine sourcing inputs for
4452          * all nodes in the tree:
4453          */
4454         i = ID_max;
4455         do {
4456                 if (sc->sc_audio_rev >= UAUDIO_VERSION_30) {
4457                         /* FALLTHROUGH */
4458                 } else if (sc->sc_audio_rev >= UAUDIO_VERSION_20) {
4459                         uaudio20_mixer_find_inputs_sub(iot,
4460                             &i, 1, &((iot + i)->usr));
4461
4462                         sc->sc_mixer_clocks.is_input = 255;
4463                         sc->sc_mixer_clocks.recurse_level = 0;
4464
4465                         uaudio20_mixer_find_clocks_sub(iot,
4466                             &i, 1, &sc->sc_mixer_clocks);
4467                 } else {
4468                         uaudio_mixer_find_inputs_sub(iot,
4469                             &i, 1, &((iot + i)->usr));
4470                 }
4471         } while (i--);
4472
4473         /*
4474          * determine outputs for
4475          * all nodes in the tree:
4476          */
4477         i = ID_max;
4478         do {
4479                 uaudio_mixer_find_outputs_sub(iot,
4480                     i, ID_max, &((iot + i)->usr));
4481         } while (i--);
4482
4483         /* set "id_max" and "root" */
4484
4485         i = ID_max;
4486         do {
4487                 (iot + i)->usr.id_max = ID_max;
4488                 (iot + i)->root = iot;
4489         } while (i--);
4490
4491         /*
4492          * Scan the config to create a linked list of "mixer" nodes:
4493          */
4494
4495         i = ID_max;
4496         do {
4497                 dp = iot[i].u.desc;
4498
4499                 if (dp == NULL)
4500                         continue;
4501
4502                 DPRINTFN(11, "id=%d subtype=%d\n",
4503                     i, dp->bDescriptorSubtype);
4504
4505                 if (sc->sc_audio_rev >= UAUDIO_VERSION_30) {
4506                         continue;
4507                 } else if (sc->sc_audio_rev >= UAUDIO_VERSION_20) {
4508
4509                         switch (dp->bDescriptorSubtype) {
4510                         case UDESCSUB_AC_HEADER:
4511                                 DPRINTF("unexpected AC header\n");
4512                                 break;
4513
4514                         case UDESCSUB_AC_INPUT:
4515                         case UDESCSUB_AC_OUTPUT:
4516                         case UDESCSUB_AC_PROCESSING_V2:
4517                         case UDESCSUB_AC_EXTENSION_V2:
4518                         case UDESCSUB_AC_EFFECT:
4519                         case UDESCSUB_AC_CLOCK_SRC:
4520                         case UDESCSUB_AC_CLOCK_SEL:
4521                         case UDESCSUB_AC_CLOCK_MUL:
4522                         case UDESCSUB_AC_SAMPLE_RT:
4523                                 break;
4524
4525                         case UDESCSUB_AC_MIXER:
4526                                 uaudio20_mixer_add_mixer(sc, iot, i);
4527                                 break;
4528
4529                         case UDESCSUB_AC_SELECTOR:
4530                                 uaudio20_mixer_add_selector(sc, iot, i);
4531                                 break;
4532
4533                         case UDESCSUB_AC_FEATURE:
4534                                 uaudio20_mixer_add_feature(sc, iot, i);
4535                                 break;
4536
4537                         default:
4538                                 DPRINTF("bad AC desc subtype=0x%02x\n",
4539                                     dp->bDescriptorSubtype);
4540                                 break;
4541                         }
4542                         continue;
4543                 }
4544
4545                 switch (dp->bDescriptorSubtype) {
4546                 case UDESCSUB_AC_HEADER:
4547                         DPRINTF("unexpected AC header\n");
4548                         break;
4549
4550                 case UDESCSUB_AC_INPUT:
4551                 case UDESCSUB_AC_OUTPUT:
4552                         break;
4553
4554                 case UDESCSUB_AC_MIXER:
4555                         uaudio_mixer_add_mixer(sc, iot, i);
4556                         break;
4557
4558                 case UDESCSUB_AC_SELECTOR:
4559                         uaudio_mixer_add_selector(sc, iot, i);
4560                         break;
4561
4562                 case UDESCSUB_AC_FEATURE:
4563                         uaudio_mixer_add_feature(sc, iot, i);
4564                         break;
4565
4566                 case UDESCSUB_AC_PROCESSING:
4567                         uaudio_mixer_add_processing(sc, iot, i);
4568                         break;
4569
4570                 case UDESCSUB_AC_EXTENSION:
4571                         uaudio_mixer_add_extension(sc, iot, i);
4572                         break;
4573
4574                 default:
4575                         DPRINTF("bad AC desc subtype=0x%02x\n",
4576                             dp->bDescriptorSubtype);
4577                         break;
4578                 }
4579
4580         } while (i--);
4581
4582 done:
4583         free(iot, M_TEMP);
4584 }
4585
4586 static int
4587 uaudio_mixer_get(struct usb_device *udev, uint16_t audio_rev,
4588     uint8_t what, struct uaudio_mixer_node *mc)
4589 {
4590         struct usb_device_request req;
4591         int val;
4592         uint8_t data[2 + (2 * 3)];
4593         usb_error_t err;
4594
4595         if (mc->wValue[0] == -1)
4596                 return (0);
4597
4598         if (audio_rev >= UAUDIO_VERSION_30)
4599                 return (0);
4600         else if (audio_rev >= UAUDIO_VERSION_20) {
4601                 if (what == GET_CUR) {
4602                         req.bRequest = UA20_CS_CUR;
4603                         USETW(req.wLength, 2);
4604                 } else {
4605                         req.bRequest = UA20_CS_RANGE;
4606                         USETW(req.wLength, 8);
4607                 }
4608         } else {
4609                 uint16_t len = MIX_SIZE(mc->type);
4610
4611                 req.bRequest = what;
4612                 USETW(req.wLength, len);
4613         }
4614
4615         req.bmRequestType = UT_READ_CLASS_INTERFACE;
4616         USETW(req.wValue, mc->wValue[0]);
4617         USETW(req.wIndex, mc->wIndex);
4618
4619         memset(data, 0, sizeof(data));
4620
4621         err = usbd_do_request(udev, NULL, &req, data);
4622         if (err) {
4623                 DPRINTF("err=%s\n", usbd_errstr(err));
4624                 return (0);
4625         }
4626
4627         if (audio_rev >= UAUDIO_VERSION_30) {
4628                 val = 0;
4629         } else if (audio_rev >= UAUDIO_VERSION_20) {
4630                 switch (what) {
4631                 case GET_CUR:
4632                         val = (data[0] | (data[1] << 8));
4633                         break;
4634                 case GET_MIN:
4635                         val = (data[2] | (data[3] << 8));
4636                         break;
4637                 case GET_MAX:
4638                         val = (data[4] | (data[5] << 8));
4639                         break;
4640                 case GET_RES:
4641                         val = (data[6] | (data[7] << 8));
4642                         break;
4643                 default:
4644                         val = 0;
4645                         break;
4646                 }
4647         } else {
4648                 val = (data[0] | (data[1] << 8));
4649         }
4650
4651         if (what == GET_CUR || what == GET_MIN || what == GET_MAX)
4652                 val = uaudio_mixer_signext(mc->type, val);
4653
4654         DPRINTFN(3, "val=%d\n", val);
4655
4656         return (val);
4657 }
4658
4659 static void
4660 uaudio_mixer_write_cfg_callback(struct usb_xfer *xfer, usb_error_t error)
4661 {
4662         struct usb_device_request req;
4663         struct uaudio_softc *sc = usbd_xfer_softc(xfer);
4664         struct uaudio_mixer_node *mc = sc->sc_mixer_curr;
4665         struct usb_page_cache *pc;
4666         uint16_t len;
4667         uint8_t repeat = 1;
4668         uint8_t update;
4669         uint8_t chan;
4670         uint8_t buf[2];
4671
4672         DPRINTF("\n");
4673
4674         switch (USB_GET_STATE(xfer)) {
4675         case USB_ST_TRANSFERRED:
4676 tr_transferred:
4677         case USB_ST_SETUP:
4678 tr_setup:
4679
4680                 if (mc == NULL) {
4681                         mc = sc->sc_mixer_root;
4682                         sc->sc_mixer_curr = mc;
4683                         sc->sc_mixer_chan = 0;
4684                         repeat = 0;
4685                 }
4686                 while (mc) {
4687                         while (sc->sc_mixer_chan < mc->nchan) {
4688
4689                                 chan = sc->sc_mixer_chan;
4690
4691                                 sc->sc_mixer_chan++;
4692
4693                                 update = ((mc->update[chan / 8] & (1 << (chan % 8))) &&
4694                                     (mc->wValue[chan] != -1));
4695
4696                                 mc->update[chan / 8] &= ~(1 << (chan % 8));
4697
4698                                 if (update) {
4699
4700                                         req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
4701                                         USETW(req.wValue, mc->wValue[chan]);
4702                                         USETW(req.wIndex, mc->wIndex);
4703
4704                                         if (sc->sc_audio_rev >= UAUDIO_VERSION_30) {
4705                                                 return;
4706                                         } else if (sc->sc_audio_rev >= UAUDIO_VERSION_20) {
4707                                                 len = 2;
4708                                                 req.bRequest = UA20_CS_CUR;
4709                                                 USETW(req.wLength, len);
4710                                         } else {
4711                                                 len = MIX_SIZE(mc->type);
4712                                                 req.bRequest = SET_CUR;
4713                                                 USETW(req.wLength, len);
4714                                         }
4715
4716                                         buf[0] = (mc->wData[chan] & 0xFF);
4717                                         buf[1] = (mc->wData[chan] >> 8) & 0xFF;
4718
4719                                         pc = usbd_xfer_get_frame(xfer, 0);
4720                                         usbd_copy_in(pc, 0, &req, sizeof(req));
4721                                         pc = usbd_xfer_get_frame(xfer, 1);
4722                                         usbd_copy_in(pc, 0, buf, len);
4723
4724                                         usbd_xfer_set_frame_len(xfer, 0, sizeof(req));
4725                                         usbd_xfer_set_frame_len(xfer, 1, len);
4726                                         usbd_xfer_set_frames(xfer, len ? 2 : 1);
4727                                         usbd_transfer_submit(xfer);
4728                                         return;
4729                                 }
4730                         }
4731
4732                         mc = mc->next;
4733                         sc->sc_mixer_curr = mc;
4734                         sc->sc_mixer_chan = 0;
4735                 }
4736
4737                 if (repeat) {
4738                         goto tr_setup;
4739                 }
4740                 break;
4741
4742         default:                        /* Error */
4743                 DPRINTF("error=%s\n", usbd_errstr(error));
4744                 if (error == USB_ERR_CANCELLED) {
4745                         /* do nothing - we are detaching */
4746                         break;
4747                 }
4748                 goto tr_transferred;
4749         }
4750 }
4751
4752 static usb_error_t
4753 uaudio_set_speed(struct usb_device *udev, uint8_t endpt, uint32_t speed)
4754 {
4755         struct usb_device_request req;
4756         uint8_t data[3];
4757
4758         DPRINTFN(6, "endpt=%d speed=%u\n", endpt, speed);
4759
4760         req.bmRequestType = UT_WRITE_CLASS_ENDPOINT;
4761         req.bRequest = SET_CUR;
4762         USETW2(req.wValue, SAMPLING_FREQ_CONTROL, 0);
4763         USETW(req.wIndex, endpt);
4764         USETW(req.wLength, 3);
4765         data[0] = speed;
4766         data[1] = speed >> 8;
4767         data[2] = speed >> 16;
4768
4769         return (usbd_do_request(udev, NULL, &req, data));
4770 }
4771
4772 static usb_error_t
4773 uaudio20_set_speed(struct usb_device *udev, uint8_t iface_no,
4774     uint8_t clockid, uint32_t speed)
4775 {
4776         struct usb_device_request req;
4777         uint8_t data[4];
4778
4779         DPRINTFN(6, "ifaceno=%d clockid=%d speed=%u\n",
4780             iface_no, clockid, speed);
4781
4782         req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
4783         req.bRequest = UA20_CS_CUR;
4784         USETW2(req.wValue, UA20_CS_SAM_FREQ_CONTROL, 0);
4785         USETW2(req.wIndex, clockid, iface_no);
4786         USETW(req.wLength, 4);
4787         data[0] = speed;
4788         data[1] = speed >> 8;
4789         data[2] = speed >> 16;
4790         data[3] = speed >> 24;
4791
4792         return (usbd_do_request(udev, NULL, &req, data));
4793 }
4794
4795 static int
4796 uaudio_mixer_signext(uint8_t type, int val)
4797 {
4798         if (!MIX_UNSIGNED(type)) {
4799                 if (MIX_SIZE(type) == 2) {
4800                         val = (int16_t)val;
4801                 } else {
4802                         val = (int8_t)val;
4803                 }
4804         }
4805         return (val);
4806 }
4807
4808 static int
4809 uaudio_mixer_bsd2value(struct uaudio_mixer_node *mc, int32_t val)
4810 {
4811         if (mc->type == MIX_ON_OFF) {
4812                 val = (val != 0);
4813         } else if (mc->type == MIX_SELECTOR) {
4814                 if ((val < mc->minval) ||
4815                     (val > mc->maxval)) {
4816                         val = mc->minval;
4817                 }
4818         } else {
4819
4820                 /* compute actual volume */
4821                 val = (val * mc->mul) / 255;
4822
4823                 /* add lower offset */
4824                 val = val + mc->minval;
4825
4826                 /* make sure we don't write a value out of range */
4827                 if (val > mc->maxval)
4828                         val = mc->maxval;
4829                 else if (val < mc->minval)
4830                         val = mc->minval;
4831         }
4832
4833         DPRINTFN(6, "type=0x%03x val=%d min=%d max=%d val=%d\n",
4834             mc->type, val, mc->minval, mc->maxval, val);
4835         return (val);
4836 }
4837
4838 static void
4839 uaudio_mixer_ctl_set(struct uaudio_softc *sc, struct uaudio_mixer_node *mc,
4840     uint8_t chan, int32_t val)
4841 {
4842         val = uaudio_mixer_bsd2value(mc, val);
4843
4844         mc->update[chan / 8] |= (1 << (chan % 8));
4845         mc->wData[chan] = val;
4846
4847         /* start the transfer, if not already started */
4848
4849         usbd_transfer_start(sc->sc_mixer_xfer[0]);
4850 }
4851
4852 static void
4853 uaudio_mixer_init(struct uaudio_softc *sc)
4854 {
4855         struct uaudio_mixer_node *mc;
4856         int32_t i;
4857
4858         for (mc = sc->sc_mixer_root; mc;
4859             mc = mc->next) {
4860
4861                 if (mc->ctl != SOUND_MIXER_NRDEVICES) {
4862                         /*
4863                          * Set device mask bits. See
4864                          * /usr/include/machine/soundcard.h
4865                          */
4866                         sc->sc_mix_info |= (1 << mc->ctl);
4867                 }
4868                 if ((mc->ctl == SOUND_MIXER_NRDEVICES) &&
4869                     (mc->type == MIX_SELECTOR)) {
4870
4871                         for (i = mc->minval; (i > 0) && (i <= mc->maxval); i++) {
4872                                 if (mc->slctrtype[i - 1] == SOUND_MIXER_NRDEVICES) {
4873                                         continue;
4874                                 }
4875                                 sc->sc_recsrc_info |= 1 << mc->slctrtype[i - 1];
4876                         }
4877                 }
4878         }
4879 }
4880
4881 int
4882 uaudio_mixer_init_sub(struct uaudio_softc *sc, struct snd_mixer *m)
4883 {
4884         DPRINTF("\n");
4885
4886         sc->sc_mixer_lock = mixer_get_lock(m);
4887         sc->sc_mixer_dev = m;
4888
4889         if (usbd_transfer_setup(sc->sc_udev, &sc->sc_mixer_iface_index,
4890             sc->sc_mixer_xfer, uaudio_mixer_config, 1, sc,
4891             sc->sc_mixer_lock)) {
4892                 DPRINTFN(0, "could not allocate USB "
4893                     "transfer for audio mixer!\n");
4894                 return (ENOMEM);
4895         }
4896         if (!(sc->sc_mix_info & SOUND_MASK_VOLUME)) {
4897                 mix_setparentchild(m, SOUND_MIXER_VOLUME, SOUND_MASK_PCM);
4898                 mix_setrealdev(m, SOUND_MIXER_VOLUME, SOUND_MIXER_NONE);
4899         }
4900         mix_setdevs(m, sc->sc_mix_info);
4901         mix_setrecdevs(m, sc->sc_recsrc_info);
4902         return (0);
4903 }
4904
4905 int
4906 uaudio_mixer_uninit_sub(struct uaudio_softc *sc)
4907 {
4908         DPRINTF("\n");
4909
4910         usbd_transfer_unsetup(sc->sc_mixer_xfer, 1);
4911
4912         sc->sc_mixer_lock = NULL;
4913
4914         return (0);
4915 }
4916
4917 void
4918 uaudio_mixer_set(struct uaudio_softc *sc, unsigned type,
4919     unsigned left, unsigned right)
4920 {
4921         struct uaudio_mixer_node *mc;
4922         int chan;
4923
4924         for (mc = sc->sc_mixer_root; mc != NULL; mc = mc->next) {
4925
4926                 if (mc->ctl == type) {
4927                         for (chan = 0; chan < mc->nchan; chan++) {
4928                                 uaudio_mixer_ctl_set(sc, mc, chan,
4929                                     (int)((chan == 0 ? left : right) *
4930                                     255) / 100);
4931                         }
4932                 }
4933         }
4934 }
4935
4936 uint32_t
4937 uaudio_mixer_setrecsrc(struct uaudio_softc *sc, uint32_t src)
4938 {
4939         struct uaudio_mixer_node *mc;
4940         uint32_t mask;
4941         uint32_t temp;
4942         int32_t i;
4943
4944         for (mc = sc->sc_mixer_root; mc;
4945             mc = mc->next) {
4946
4947                 if ((mc->ctl == SOUND_MIXER_NRDEVICES) &&
4948                     (mc->type == MIX_SELECTOR)) {
4949
4950                         /* compute selector mask */
4951
4952                         mask = 0;
4953                         for (i = mc->minval; (i > 0) && (i <= mc->maxval); i++) {
4954                                 mask |= (1 << mc->slctrtype[i - 1]);
4955                         }
4956
4957                         temp = mask & src;
4958                         if (temp == 0) {
4959                                 continue;
4960                         }
4961                         /* find the first set bit */
4962                         temp = (-temp) & temp;
4963
4964                         /* update "src" */
4965                         src &= ~mask;
4966                         src |= temp;
4967
4968                         for (i = mc->minval; (i > 0) && (i <= mc->maxval); i++) {
4969                                 if (temp != (1 << mc->slctrtype[i - 1])) {
4970                                         continue;
4971                                 }
4972                                 uaudio_mixer_ctl_set(sc, mc, 0, i);
4973                                 break;
4974                         }
4975                 }
4976         }
4977         return (src);
4978 }
4979
4980 /*========================================================================*
4981  * MIDI support routines
4982  *========================================================================*/
4983
4984 static void
4985 umidi_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
4986 {
4987         struct umidi_chan *chan = usbd_xfer_softc(xfer);
4988         struct umidi_sub_chan *sub;
4989         struct usb_page_cache *pc;
4990         uint8_t buf[4];
4991         uint8_t cmd_len;
4992         uint8_t cn;
4993         uint16_t pos;
4994         int actlen;
4995
4996         usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
4997
4998         switch (USB_GET_STATE(xfer)) {
4999         case USB_ST_TRANSFERRED:
5000
5001                 DPRINTF("actlen=%d bytes\n", actlen);
5002
5003                 pos = 0;
5004                 pc = usbd_xfer_get_frame(xfer, 0);
5005
5006                 while (actlen >= 4) {
5007
5008                         /* copy out the MIDI data */
5009                         usbd_copy_out(pc, pos, buf, 4);
5010                         /* command length */
5011                         cmd_len = umidi_cmd_to_len[buf[0] & 0xF];
5012                         /* cable number */
5013                         cn = buf[0] >> 4;
5014                         /*
5015                          * Lookup sub-channel. The index is range
5016                          * checked below.
5017                          */
5018                         sub = &chan->sub[cn];
5019
5020                         if ((cmd_len != 0) &&
5021                             (cn < chan->max_cable) &&
5022                             (sub->read_open != 0)) {
5023
5024                                 /* Send data to the application */
5025                                 usb_fifo_put_data_linear(
5026                                     sub->fifo.fp[USB_FIFO_RX],
5027                                     buf + 1, cmd_len, 1);
5028                         }
5029                         actlen -= 4;
5030                         pos += 4;
5031                 }
5032
5033         case USB_ST_SETUP:
5034                 DPRINTF("start\n");
5035 tr_setup:
5036                 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
5037                 usbd_transfer_submit(xfer);
5038                 break;
5039
5040         default:
5041                 DPRINTF("error=%s\n", usbd_errstr(error));
5042
5043                 if (error != USB_ERR_CANCELLED) {
5044                         /* try to clear stall first */
5045                         usbd_xfer_set_stall(xfer);
5046                         goto tr_setup;
5047                 }
5048                 break;
5049         }
5050 }
5051
5052 /*
5053  * The following statemachine, that converts MIDI commands to
5054  * USB MIDI packets, derives from Linux's usbmidi.c, which
5055  * was written by "Clemens Ladisch":
5056  *
5057  * Returns:
5058  *    0: No command
5059  * Else: Command is complete
5060  */
5061 static uint8_t
5062 umidi_convert_to_usb(struct umidi_sub_chan *sub, uint8_t cn, uint8_t b)
5063 {
5064         uint8_t p0 = (cn << 4);
5065
5066         if (b >= 0xf8) {
5067                 sub->temp_0[0] = p0 | 0x0f;
5068                 sub->temp_0[1] = b;
5069                 sub->temp_0[2] = 0;
5070                 sub->temp_0[3] = 0;
5071                 sub->temp_cmd = sub->temp_0;
5072                 return (1);
5073
5074         } else if (b >= 0xf0) {
5075                 switch (b) {
5076                 case 0xf0:              /* system exclusive begin */
5077                         sub->temp_1[1] = b;
5078                         sub->state = UMIDI_ST_SYSEX_1;
5079                         break;
5080                 case 0xf1:              /* MIDI time code */
5081                 case 0xf3:              /* song select */
5082                         sub->temp_1[1] = b;
5083                         sub->state = UMIDI_ST_1PARAM;
5084                         break;
5085                 case 0xf2:              /* song position pointer */
5086                         sub->temp_1[1] = b;
5087                         sub->state = UMIDI_ST_2PARAM_1;
5088                         break;
5089                 case 0xf4:              /* unknown */
5090                 case 0xf5:              /* unknown */
5091                         sub->state = UMIDI_ST_UNKNOWN;
5092                         break;
5093                 case 0xf6:              /* tune request */
5094                         sub->temp_1[0] = p0 | 0x05;
5095                         sub->temp_1[1] = 0xf6;
5096                         sub->temp_1[2] = 0;
5097                         sub->temp_1[3] = 0;
5098                         sub->temp_cmd = sub->temp_1;
5099                         sub->state = UMIDI_ST_UNKNOWN;
5100                         return (1);
5101
5102                 case 0xf7:              /* system exclusive end */
5103                         switch (sub->state) {
5104                         case UMIDI_ST_SYSEX_0:
5105                                 sub->temp_1[0] = p0 | 0x05;
5106                                 sub->temp_1[1] = 0xf7;
5107                                 sub->temp_1[2] = 0;
5108                                 sub->temp_1[3] = 0;
5109                                 sub->temp_cmd = sub->temp_1;
5110                                 sub->state = UMIDI_ST_UNKNOWN;
5111                                 return (1);
5112                         case UMIDI_ST_SYSEX_1:
5113                                 sub->temp_1[0] = p0 | 0x06;
5114                                 sub->temp_1[2] = 0xf7;
5115                                 sub->temp_1[3] = 0;
5116                                 sub->temp_cmd = sub->temp_1;
5117                                 sub->state = UMIDI_ST_UNKNOWN;
5118                                 return (1);
5119                         case UMIDI_ST_SYSEX_2:
5120                                 sub->temp_1[0] = p0 | 0x07;
5121                                 sub->temp_1[3] = 0xf7;
5122                                 sub->temp_cmd = sub->temp_1;
5123                                 sub->state = UMIDI_ST_UNKNOWN;
5124                                 return (1);
5125                         }
5126                         sub->state = UMIDI_ST_UNKNOWN;
5127                         break;
5128                 }
5129         } else if (b >= 0x80) {
5130                 sub->temp_1[1] = b;
5131                 if ((b >= 0xc0) && (b <= 0xdf)) {
5132                         sub->state = UMIDI_ST_1PARAM;
5133                 } else {
5134                         sub->state = UMIDI_ST_2PARAM_1;
5135                 }
5136         } else {                        /* b < 0x80 */
5137                 switch (sub->state) {
5138                 case UMIDI_ST_1PARAM:
5139                         if (sub->temp_1[1] < 0xf0) {
5140                                 p0 |= sub->temp_1[1] >> 4;
5141                         } else {
5142                                 p0 |= 0x02;
5143                                 sub->state = UMIDI_ST_UNKNOWN;
5144                         }
5145                         sub->temp_1[0] = p0;
5146                         sub->temp_1[2] = b;
5147                         sub->temp_1[3] = 0;
5148                         sub->temp_cmd = sub->temp_1;
5149                         return (1);
5150                 case UMIDI_ST_2PARAM_1:
5151                         sub->temp_1[2] = b;
5152                         sub->state = UMIDI_ST_2PARAM_2;
5153                         break;
5154                 case UMIDI_ST_2PARAM_2:
5155                         if (sub->temp_1[1] < 0xf0) {
5156                                 p0 |= sub->temp_1[1] >> 4;
5157                                 sub->state = UMIDI_ST_2PARAM_1;
5158                         } else {
5159                                 p0 |= 0x03;
5160                                 sub->state = UMIDI_ST_UNKNOWN;
5161                         }
5162                         sub->temp_1[0] = p0;
5163                         sub->temp_1[3] = b;
5164                         sub->temp_cmd = sub->temp_1;
5165                         return (1);
5166                 case UMIDI_ST_SYSEX_0:
5167                         sub->temp_1[1] = b;
5168                         sub->state = UMIDI_ST_SYSEX_1;
5169                         break;
5170                 case UMIDI_ST_SYSEX_1:
5171                         sub->temp_1[2] = b;
5172                         sub->state = UMIDI_ST_SYSEX_2;
5173                         break;
5174                 case UMIDI_ST_SYSEX_2:
5175                         sub->temp_1[0] = p0 | 0x04;
5176                         sub->temp_1[3] = b;
5177                         sub->temp_cmd = sub->temp_1;
5178                         sub->state = UMIDI_ST_SYSEX_0;
5179                         return (1);
5180                 default:
5181                         break;
5182                 }
5183         }
5184         return (0);
5185 }
5186
5187 static void
5188 umidi_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
5189 {
5190         struct umidi_chan *chan = usbd_xfer_softc(xfer);
5191         struct umidi_sub_chan *sub;
5192         struct usb_page_cache *pc;
5193         uint32_t actlen;
5194         uint16_t nframes;
5195         uint8_t buf;
5196         uint8_t start_cable;
5197         uint8_t tr_any;
5198         int len;
5199
5200         usbd_xfer_status(xfer, &len, NULL, NULL, NULL);
5201
5202         /*
5203          * NOTE: Some MIDI devices only accept 4 bytes of data per
5204          * short terminated USB transfer.
5205          */
5206         switch (USB_GET_STATE(xfer)) {
5207         case USB_ST_TRANSFERRED:
5208                 DPRINTF("actlen=%d bytes\n", len);
5209
5210         case USB_ST_SETUP:
5211 tr_setup:
5212                 DPRINTF("start\n");
5213
5214                 nframes = 0;    /* reset */
5215                 start_cable = chan->curr_cable;
5216                 tr_any = 0;
5217                 pc = usbd_xfer_get_frame(xfer, 0);
5218
5219                 while (1) {
5220
5221                         /* round robin de-queueing */
5222
5223                         sub = &chan->sub[chan->curr_cable];
5224
5225                         if (sub->write_open) {
5226                                 usb_fifo_get_data_linear(sub->fifo.fp[USB_FIFO_TX],
5227                                     &buf, 1, &actlen, 0);
5228                         } else {
5229                                 actlen = 0;
5230                         }
5231
5232                         if (actlen) {
5233
5234                                 tr_any = 1;
5235
5236                                 DPRINTF("byte=0x%02x from FIFO %u\n", buf,
5237                                     (unsigned int)chan->curr_cable);
5238
5239                                 if (umidi_convert_to_usb(sub, chan->curr_cable, buf)) {
5240
5241                                         DPRINTF("sub=0x%02x 0x%02x 0x%02x 0x%02x\n",
5242                                             sub->temp_cmd[0], sub->temp_cmd[1],
5243                                             sub->temp_cmd[2], sub->temp_cmd[3]);
5244
5245                                         usbd_copy_in(pc, nframes * 4, sub->temp_cmd, 4);
5246
5247                                         nframes++;
5248
5249                                         if ((nframes >= UMIDI_TX_FRAMES) || (chan->single_command != 0))
5250                                                 break;
5251                                 } else {
5252                                         continue;
5253                                 }
5254                         }
5255
5256                         chan->curr_cable++;
5257                         if (chan->curr_cable >= chan->max_cable)
5258                                 chan->curr_cable = 0;
5259
5260                         if (chan->curr_cable == start_cable) {
5261                                 if (tr_any == 0)
5262                                         break;
5263                                 tr_any = 0;
5264                         }
5265                 }
5266
5267                 if (nframes != 0) {
5268                         DPRINTF("Transferring %d frames\n", (int)nframes);
5269                         usbd_xfer_set_frame_len(xfer, 0, 4 * nframes);
5270                         usbd_transfer_submit(xfer);
5271                 }
5272                 break;
5273
5274         default:                        /* Error */
5275
5276                 DPRINTF("error=%s\n", usbd_errstr(error));
5277
5278                 if (error != USB_ERR_CANCELLED) {
5279                         /* try to clear stall first */
5280                         usbd_xfer_set_stall(xfer);
5281                         goto tr_setup;
5282                 }
5283                 break;
5284         }
5285 }
5286
5287 static struct umidi_sub_chan *
5288 umidi_sub_by_fifo(struct usb_fifo *fifo)
5289 {
5290         struct umidi_chan *chan = usb_fifo_softc(fifo);
5291         struct umidi_sub_chan *sub;
5292         uint32_t n;
5293
5294         for (n = 0; n < UMIDI_CABLES_MAX; n++) {
5295                 sub = &chan->sub[n];
5296                 if ((sub->fifo.fp[USB_FIFO_RX] == fifo) ||
5297                     (sub->fifo.fp[USB_FIFO_TX] == fifo)) {
5298                         return (sub);
5299                 }
5300         }
5301
5302         panic("%s:%d cannot find usb_fifo!\n",
5303             __FILE__, __LINE__);
5304
5305         return (NULL);
5306 }
5307
5308 static void
5309 umidi_start_read(struct usb_fifo *fifo)
5310 {
5311         struct umidi_chan *chan = usb_fifo_softc(fifo);
5312
5313         usbd_transfer_start(chan->xfer[UMIDI_RX_TRANSFER]);
5314 }
5315
5316 static void
5317 umidi_stop_read(struct usb_fifo *fifo)
5318 {
5319         struct umidi_chan *chan = usb_fifo_softc(fifo);
5320         struct umidi_sub_chan *sub = umidi_sub_by_fifo(fifo);
5321
5322         DPRINTF("\n");
5323
5324         sub->read_open = 0;
5325
5326         if (--(chan->read_open_refcount) == 0) {
5327                 /*
5328                  * XXX don't stop the read transfer here, hence that causes
5329                  * problems with some MIDI adapters
5330                  */
5331                 DPRINTF("(stopping read transfer)\n");
5332         }
5333 }
5334
5335 static void
5336 umidi_start_write(struct usb_fifo *fifo)
5337 {
5338         struct umidi_chan *chan = usb_fifo_softc(fifo);
5339
5340         usbd_transfer_start(chan->xfer[UMIDI_TX_TRANSFER]);
5341 }
5342
5343 static void
5344 umidi_stop_write(struct usb_fifo *fifo)
5345 {
5346         struct umidi_chan *chan = usb_fifo_softc(fifo);
5347         struct umidi_sub_chan *sub = umidi_sub_by_fifo(fifo);
5348
5349         DPRINTF("\n");
5350
5351         sub->write_open = 0;
5352
5353         if (--(chan->write_open_refcount) == 0) {
5354                 DPRINTF("(stopping write transfer)\n");
5355                 usbd_transfer_stop(chan->xfer[UMIDI_TX_TRANSFER]);
5356         }
5357 }
5358
5359 static int
5360 umidi_open(struct usb_fifo *fifo, int fflags)
5361 {
5362         struct umidi_chan *chan = usb_fifo_softc(fifo);
5363         struct umidi_sub_chan *sub = umidi_sub_by_fifo(fifo);
5364
5365         if (fflags & FREAD) {
5366                 if (usb_fifo_alloc_buffer(fifo, 4, (1024 / 4))) {
5367                         return (ENOMEM);
5368                 }
5369                 mtx_lock(&chan->mtx);
5370                 chan->read_open_refcount++;
5371                 sub->read_open = 1;
5372                 mtx_unlock(&chan->mtx);
5373         }
5374         if (fflags & FWRITE) {
5375                 if (usb_fifo_alloc_buffer(fifo, 32, (1024 / 32))) {
5376                         return (ENOMEM);
5377                 }
5378                 /* clear stall first */
5379                 mtx_lock(&chan->mtx);
5380                 usbd_xfer_set_stall(chan->xfer[UMIDI_TX_TRANSFER]);
5381                 chan->write_open_refcount++;
5382                 sub->write_open = 1;
5383
5384                 /* reset */
5385                 sub->state = UMIDI_ST_UNKNOWN;
5386                 mtx_unlock(&chan->mtx);
5387         }
5388         return (0);                     /* success */
5389 }
5390
5391 static void
5392 umidi_close(struct usb_fifo *fifo, int fflags)
5393 {
5394         if (fflags & FREAD) {
5395                 usb_fifo_free_buffer(fifo);
5396         }
5397         if (fflags & FWRITE) {
5398                 usb_fifo_free_buffer(fifo);
5399         }
5400 }
5401
5402
5403 static int
5404 umidi_ioctl(struct usb_fifo *fifo, u_long cmd, void *data,
5405     int fflags)
5406 {
5407         return (ENODEV);
5408 }
5409
5410 static void
5411 umidi_init(device_t dev)
5412 {
5413         struct uaudio_softc *sc = device_get_softc(dev);
5414         struct umidi_chan *chan = &sc->sc_midi_chan;
5415
5416         mtx_init(&chan->mtx, "umidi lock", NULL, MTX_DEF | MTX_RECURSE);
5417 }
5418
5419 static struct usb_fifo_methods umidi_fifo_methods = {
5420         .f_start_read = &umidi_start_read,
5421         .f_start_write = &umidi_start_write,
5422         .f_stop_read = &umidi_stop_read,
5423         .f_stop_write = &umidi_stop_write,
5424         .f_open = &umidi_open,
5425         .f_close = &umidi_close,
5426         .f_ioctl = &umidi_ioctl,
5427         .basename[0] = "umidi",
5428 };
5429
5430 static int
5431 umidi_probe(device_t dev)
5432 {
5433         struct uaudio_softc *sc = device_get_softc(dev);
5434         struct usb_attach_arg *uaa = device_get_ivars(dev);
5435         struct umidi_chan *chan = &sc->sc_midi_chan;
5436         struct umidi_sub_chan *sub;
5437         int unit = device_get_unit(dev);
5438         int error;
5439         uint32_t n;
5440
5441         if (usb_test_quirk(uaa, UQ_SINGLE_CMD_MIDI))
5442                 chan->single_command = 1;
5443
5444         if (usbd_set_alt_interface_index(sc->sc_udev, chan->iface_index,
5445             chan->iface_alt_index)) {
5446                 DPRINTF("setting of alternate index failed!\n");
5447                 goto detach;
5448         }
5449         usbd_set_parent_iface(sc->sc_udev, chan->iface_index,
5450             sc->sc_mixer_iface_index);
5451
5452         error = usbd_transfer_setup(uaa->device, &chan->iface_index,
5453             chan->xfer, umidi_config, UMIDI_N_TRANSFER,
5454             chan, &chan->mtx);
5455         if (error) {
5456                 DPRINTF("error=%s\n", usbd_errstr(error));
5457                 goto detach;
5458         }
5459         if ((chan->max_cable > UMIDI_CABLES_MAX) ||
5460             (chan->max_cable == 0)) {
5461                 chan->max_cable = UMIDI_CABLES_MAX;
5462         }
5463
5464         for (n = 0; n < chan->max_cable; n++) {
5465
5466                 sub = &chan->sub[n];
5467
5468                 error = usb_fifo_attach(sc->sc_udev, chan, &chan->mtx,
5469                     &umidi_fifo_methods, &sub->fifo, unit, n,
5470                     chan->iface_index,
5471                     UID_ROOT, GID_OPERATOR, 0644);
5472                 if (error) {
5473                         goto detach;
5474                 }
5475         }
5476
5477         mtx_lock(&chan->mtx);
5478
5479         /* clear stall first */
5480         usbd_xfer_set_stall(chan->xfer[UMIDI_RX_TRANSFER]);
5481
5482         /*
5483          * NOTE: At least one device will not work properly unless the
5484          * BULK IN pipe is open all the time. This might have to do
5485          * about that the internal queues of the device overflow if we
5486          * don't read them regularly.
5487          */
5488         usbd_transfer_start(chan->xfer[UMIDI_RX_TRANSFER]);
5489
5490         mtx_unlock(&chan->mtx);
5491
5492         return (0);                     /* success */
5493
5494 detach:
5495         return (ENXIO);                 /* failure */
5496 }
5497
5498 static int
5499 umidi_detach(device_t dev)
5500 {
5501         struct uaudio_softc *sc = device_get_softc(dev);
5502         struct umidi_chan *chan = &sc->sc_midi_chan;
5503         uint32_t n;
5504
5505         for (n = 0; n < UMIDI_CABLES_MAX; n++) {
5506                 usb_fifo_detach(&chan->sub[n].fifo);
5507         }
5508
5509         mtx_lock(&chan->mtx);
5510
5511         usbd_transfer_stop(chan->xfer[UMIDI_RX_TRANSFER]);
5512
5513         mtx_unlock(&chan->mtx);
5514
5515         usbd_transfer_unsetup(chan->xfer, UMIDI_N_TRANSFER);
5516
5517         mtx_destroy(&chan->mtx);
5518
5519         return (0);
5520 }
5521
5522 static void
5523 uaudio_hid_rx_callback(struct usb_xfer *xfer, usb_error_t error)
5524 {
5525         struct uaudio_softc *sc = usbd_xfer_softc(xfer);
5526         const uint8_t *buffer = usbd_xfer_get_frame_buffer(xfer, 0);
5527         struct snd_mixer *m;
5528         uint8_t id;
5529         int actlen;
5530
5531         usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
5532
5533         switch (USB_GET_STATE(xfer)) {
5534         case USB_ST_TRANSFERRED:
5535                 DPRINTF("actlen=%d\n", actlen);
5536
5537                 if (actlen != 0 &&
5538                     (sc->sc_hid.flags & UAUDIO_HID_HAS_ID)) {
5539                         id = *buffer;
5540                         buffer++;
5541                         actlen--;
5542                 } else {
5543                         id = 0;
5544                 }
5545
5546                 m = sc->sc_mixer_dev;
5547
5548                 if ((sc->sc_hid.flags & UAUDIO_HID_HAS_MUTE) &&
5549                     (sc->sc_hid.mute_id == id) &&
5550                     hid_get_data(buffer, actlen,
5551                     &sc->sc_hid.mute_loc)) {
5552
5553                         DPRINTF("Mute toggle\n");
5554
5555                         mixer_hwvol_mute_locked(m);
5556                 }
5557
5558                 if ((sc->sc_hid.flags & UAUDIO_HID_HAS_VOLUME_UP) &&
5559                     (sc->sc_hid.volume_up_id == id) &&
5560                     hid_get_data(buffer, actlen,
5561                     &sc->sc_hid.volume_up_loc)) {
5562
5563                         DPRINTF("Volume Up\n");
5564
5565                         mixer_hwvol_step_locked(m, 1, 1);
5566                 }
5567
5568                 if ((sc->sc_hid.flags & UAUDIO_HID_HAS_VOLUME_DOWN) &&
5569                     (sc->sc_hid.volume_down_id == id) &&
5570                     hid_get_data(buffer, actlen,
5571                     &sc->sc_hid.volume_down_loc)) {
5572
5573                         DPRINTF("Volume Down\n");
5574
5575                         mixer_hwvol_step_locked(m, -1, -1);
5576                 }
5577
5578         case USB_ST_SETUP:
5579 tr_setup:
5580                 /* check if we can put more data into the FIFO */
5581                 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
5582                 usbd_transfer_submit(xfer);
5583                 break;
5584
5585         default:                        /* Error */
5586                 if (error != USB_ERR_CANCELLED) {
5587                         /* try clear stall first */
5588                         usbd_xfer_set_stall(xfer);
5589                         goto tr_setup;
5590                 }
5591                 break;
5592         }
5593 }
5594
5595 static int
5596 uaudio_hid_probe(struct uaudio_softc *sc,
5597     struct usb_attach_arg *uaa)
5598 {
5599         void *d_ptr;
5600         uint32_t flags;
5601         uint16_t d_len;
5602         uint8_t id;
5603         int error;
5604
5605         if (!(sc->sc_hid.flags & UAUDIO_HID_VALID))
5606                 return (-1);
5607
5608         if (sc->sc_mixer_lock == NULL)
5609                 return (-1);
5610
5611         /* Get HID descriptor */
5612         error = usbd_req_get_hid_desc(uaa->device, NULL, &d_ptr,
5613             &d_len, M_TEMP, sc->sc_hid.iface_index);
5614
5615         if (error) {
5616                 DPRINTF("error reading report description\n");
5617                 return (-1);
5618         }
5619
5620         /* check if there is an ID byte */
5621         hid_report_size(d_ptr, d_len, hid_input, &id);
5622
5623         if (id != 0)
5624                 sc->sc_hid.flags |= UAUDIO_HID_HAS_ID;
5625
5626         if (hid_locate(d_ptr, d_len,
5627             HID_USAGE2(HUP_CONSUMER, 0xE9 /* Volume Increment */),
5628             hid_input, 0, &sc->sc_hid.volume_up_loc, &flags,
5629             &sc->sc_hid.volume_up_id)) {
5630                 if (flags & HIO_VARIABLE)
5631                         sc->sc_hid.flags |= UAUDIO_HID_HAS_VOLUME_UP;
5632                 DPRINTFN(1, "Found Volume Up key\n");
5633         }
5634
5635         if (hid_locate(d_ptr, d_len,
5636             HID_USAGE2(HUP_CONSUMER, 0xEA /* Volume Decrement */),
5637             hid_input, 0, &sc->sc_hid.volume_down_loc, &flags,
5638             &sc->sc_hid.volume_down_id)) {
5639                 if (flags & HIO_VARIABLE)
5640                         sc->sc_hid.flags |= UAUDIO_HID_HAS_VOLUME_DOWN;
5641                 DPRINTFN(1, "Found Volume Down key\n");
5642         }
5643
5644         if (hid_locate(d_ptr, d_len,
5645             HID_USAGE2(HUP_CONSUMER, 0xE2 /* Mute */),
5646             hid_input, 0, &sc->sc_hid.mute_loc, &flags,
5647             &sc->sc_hid.mute_id)) {
5648                 if (flags & HIO_VARIABLE)
5649                         sc->sc_hid.flags |= UAUDIO_HID_HAS_MUTE;
5650                 DPRINTFN(1, "Found Mute key\n");
5651         }
5652
5653         free(d_ptr, M_TEMP);
5654
5655         if (!(sc->sc_hid.flags & (UAUDIO_HID_HAS_VOLUME_UP |
5656             UAUDIO_HID_HAS_VOLUME_DOWN |
5657             UAUDIO_HID_HAS_MUTE))) {
5658                 DPRINTFN(1, "Did not find any volume related keys\n");
5659                 return (-1);
5660         }
5661
5662         /* prevent the uhid driver from attaching */
5663         usbd_set_parent_iface(uaa->device, sc->sc_hid.iface_index,
5664             sc->sc_mixer_iface_index);
5665
5666         /* allocate USB transfers */
5667         error = usbd_transfer_setup(uaa->device, &sc->sc_hid.iface_index,
5668             sc->sc_hid.xfer, uaudio_hid_config, UAUDIO_HID_N_TRANSFER,
5669             sc, sc->sc_mixer_lock);
5670         if (error) {
5671                 DPRINTF("error=%s\n", usbd_errstr(error));
5672                 return (-1);
5673         }
5674         return (0);
5675 }
5676
5677 static void
5678 uaudio_hid_detach(struct uaudio_softc *sc)
5679 {
5680         usbd_transfer_unsetup(sc->sc_hid.xfer, UAUDIO_HID_N_TRANSFER);
5681 }
5682
5683 DRIVER_MODULE(uaudio, uhub, uaudio_driver, uaudio_devclass, NULL, 0);
5684 MODULE_DEPEND(uaudio, usb, 1, 1, 1);
5685 MODULE_DEPEND(uaudio, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
5686 MODULE_VERSION(uaudio, 1);