ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/src/trunk/sys/dev/sound/usb/uaudio.c
Revision: 12246
Committed: Fri Aug 9 02:52:56 2019 UTC (4 years, 8 months ago) by laffer1
Content type: text/plain
File size: 156143 byte(s)
Log Message:
extend the vendor class USB audio quirk to cover devices without the control descriptor

File Contents

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

Properties

Name Value
svn:keywords MidnightBSD=%H