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