1 /* $NetBSD: uaudio.c,v 1.91 2004/11/05 17:46:14 kent Exp $ */
2 /* $FreeBSD$: */
3
4 /*-
5 * Copyright (c) 1999 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Lennart Augustsson (lennart@augustsson.net) at
10 * Carlstedt Research & Technology.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by the NetBSD
23 * Foundation, Inc. and its contributors.
24 * 4. Neither the name of The NetBSD Foundation nor the names of its
25 * contributors may be used to endorse or promote products derived
26 * from this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 */
40
41 /*
42 * USB audio specs: http://www.usb.org/developers/devclass_docs/audio10.pdf
43 * http://www.usb.org/developers/devclass_docs/frmts10.pdf
44 * http://www.usb.org/developers/devclass_docs/termt10.pdf
45 */
46
47 #include <sys/cdefs.h>
48 #if defined(__NetBSD__) || defined(__OpenBSD__)
49 __KERNEL_RCSID(0, "$NetBSD: uaudio.c,v 1.91 2004/11/05 17:46:14 kent Exp $");
50 #endif
51
52 #include <sys/param.h>
53 #include <sys/systm.h>
54 #include <sys/kernel.h>
55 #include <sys/malloc.h>
56 #if defined(__NetBSD__) || defined(__OpenBSD__)
57 #include <sys/device.h>
58 #include <sys/ioctl.h>
59 #endif
60 #include <sys/tty.h>
61 #include <sys/file.h>
62 #include <sys/reboot.h> /* for bootverbose */
63 #include <sys/select.h>
64 #include <sys/proc.h>
65 #include <sys/vnode.h>
66 #if defined(__NetBSD__) || defined(__OpenBSD__)
67 #include <sys/device.h>
68 #elif defined(__FreeBSD__)
69 #include <sys/module.h>
70 #include <sys/bus.h>
71 #include <sys/conf.h>
72 #endif
73 #include <sys/poll.h>
74 #if defined(__FreeBSD__)
75 #include <sys/sysctl.h>
76 #endif
77
78 #if defined(__NetBSD__) || defined(__OpenBSD__)
79 #include <sys/audioio.h>
80 #include <dev/audio_if.h>
81 #include <dev/audiovar.h>
82 #include <dev/mulaw.h>
83 #include <dev/auconv.h>
84 #elif defined(__FreeBSD__)
85 #include <dev/sound/pcm/sound.h> /* XXXXX */
86 #include <dev/sound/chip.h>
87 #endif
88
89 #include <dev/usb/usb.h>
90 #include <dev/usb/usbdi.h>
91 #include <dev/usb/usbdi_util.h>
92 #include <dev/usb/usb_quirks.h>
93
94 #if defined(__NetBSD__) || defined(__OpenBSD__)
95 #include <dev/usb/uaudioreg.h>
96 #elif defined(__FreeBSD__)
97 #include <dev/sound/usb/uaudioreg.h>
98 #include <dev/sound/usb/uaudio.h>
99 #endif
100
101 #if defined(__NetBSD__) || defined(__OpenBSD__)
102 /* #define UAUDIO_DEBUG */
103 #else
104 /* #define USB_DEBUG */
105 #endif
106 /* #define UAUDIO_MULTIPLE_ENDPOINTS */
107 #ifdef USB_DEBUG
108 #define DPRINTF(x) do { if (uaudiodebug) logprintf x; } while (0)
109 #define DPRINTFN(n,x) do { if (uaudiodebug>(n)) logprintf x; } while (0)
110 int uaudiodebug = 0;
111 #if defined(__FreeBSD__)
112 SYSCTL_NODE(_hw_usb, OID_AUTO, uaudio, CTLFLAG_RW, 0, "USB uaudio");
113 SYSCTL_INT(_hw_usb_uaudio, OID_AUTO, debug, CTLFLAG_RW,
114 &uaudiodebug, 0, "uaudio debug level");
115 #endif
116 #else
117 #define DPRINTF(x)
118 #define DPRINTFN(n,x)
119 #endif
120
121 #define UAUDIO_NCHANBUFS 6 /* number of outstanding request */
122 #if defined(__NetBSD__) || defined(__OpenBSD__)
123 #define UAUDIO_NFRAMES 10 /* ms of sound in each request */
124 #elif defined(__FreeBSD__)
125 #define UAUDIO_NFRAMES 20 /* ms of sound in each request */
126 #endif
127
128
129 #define MIX_MAX_CHAN 8
130 struct mixerctl {
131 u_int16_t wValue[MIX_MAX_CHAN]; /* using nchan */
132 u_int16_t wIndex;
133 u_int8_t nchan;
134 u_int8_t type;
135 #define MIX_ON_OFF 1
136 #define MIX_SIGNED_16 2
137 #define MIX_UNSIGNED_16 3
138 #define MIX_SIGNED_8 4
139 #define MIX_SELECTOR 5
140 #define MIX_SIZE(n) ((n) == MIX_SIGNED_16 || (n) == MIX_UNSIGNED_16 ? 2 : 1)
141 #define MIX_UNSIGNED(n) ((n) == MIX_UNSIGNED_16)
142 int minval, maxval;
143 u_int delta;
144 u_int mul;
145 #if defined(__FreeBSD__) /* XXXXX */
146 unsigned ctl;
147 #define MAX_SELECTOR_INPUT_PIN 256
148 u_int8_t slctrtype[MAX_SELECTOR_INPUT_PIN];
149 #endif
150 u_int8_t class;
151 #if !defined(__FreeBSD__)
152 char ctlname[MAX_AUDIO_DEV_LEN];
153 char *ctlunit;
154 #endif
155 };
156 #define MAKE(h,l) (((h) << 8) | (l))
157
158 struct as_info {
159 u_int8_t alt;
160 u_int8_t encoding;
161 u_int8_t attributes; /* Copy of bmAttributes of
162 * usb_audio_streaming_endpoint_descriptor
163 */
164 usbd_interface_handle ifaceh;
165 const usb_interface_descriptor_t *idesc;
166 const usb_endpoint_descriptor_audio_t *edesc;
167 const usb_endpoint_descriptor_audio_t *edesc1;
168 const struct usb_audio_streaming_type1_descriptor *asf1desc;
169 int sc_busy; /* currently used */
170 };
171
172 struct chan {
173 #if defined(__NetBSD__) || defined(__OpenBSD__)
174 void (*intr)(void *); /* DMA completion intr handler */
175 void *arg; /* arg for intr() */
176 #else
177 struct pcm_channel *pcm_ch;
178 #endif
179 usbd_pipe_handle pipe;
180 usbd_pipe_handle sync_pipe;
181
182 u_int sample_size;
183 u_int sample_rate;
184 u_int bytes_per_frame;
185 u_int fraction; /* fraction/1000 is the extra samples/frame */
186 u_int residue; /* accumulates the fractional samples */
187
188 u_char *start; /* upper layer buffer start */
189 u_char *end; /* upper layer buffer end */
190 u_char *cur; /* current position in upper layer buffer */
191 int blksize; /* chunk size to report up */
192 int transferred; /* transferred bytes not reported up */
193
194 int altidx; /* currently used altidx */
195
196 int curchanbuf;
197 struct chanbuf {
198 struct chan *chan;
199 usbd_xfer_handle xfer;
200 u_char *buffer;
201 u_int16_t sizes[UAUDIO_NFRAMES];
202 u_int16_t offsets[UAUDIO_NFRAMES];
203 u_int16_t size;
204 } chanbufs[UAUDIO_NCHANBUFS];
205
206 struct uaudio_softc *sc; /* our softc */
207 #if defined(__FreeBSD__)
208 u_int32_t format;
209 int precision;
210 int channels;
211 #endif
212 };
213
214 struct uaudio_softc {
215 USBBASEDEVICE sc_dev; /* base device */
216 usbd_device_handle sc_udev; /* USB device */
217 int sc_ac_iface; /* Audio Control interface */
218 usbd_interface_handle sc_ac_ifaceh;
219 struct chan sc_playchan; /* play channel */
220 struct chan sc_recchan; /* record channel */
221 int sc_nullalt;
222 int sc_audio_rev;
223 struct as_info *sc_alts; /* alternate settings */
224 int sc_nalts; /* # of alternate settings */
225 int sc_altflags;
226 #define HAS_8 0x01
227 #define HAS_16 0x02
228 #define HAS_8U 0x04
229 #define HAS_ALAW 0x08
230 #define HAS_MULAW 0x10
231 #define UA_NOFRAC 0x20 /* don't do sample rate adjustment */
232 #define HAS_24 0x40
233 int sc_mode; /* play/record capability */
234 struct mixerctl *sc_ctls; /* mixer controls */
235 int sc_nctls; /* # of mixer controls */
236 device_ptr_t sc_audiodev;
237 char sc_dying;
238 };
239
240 struct terminal_list {
241 int size;
242 uint16_t terminals[1];
243 };
244 #define TERMINAL_LIST_SIZE(N) (offsetof(struct terminal_list, terminals) \
245 + sizeof(uint16_t) * (N))
246
247 struct io_terminal {
248 union {
249 const usb_descriptor_t *desc;
250 const struct usb_audio_input_terminal *it;
251 const struct usb_audio_output_terminal *ot;
252 const struct usb_audio_mixer_unit *mu;
253 const struct usb_audio_selector_unit *su;
254 const struct usb_audio_feature_unit *fu;
255 const struct usb_audio_processing_unit *pu;
256 const struct usb_audio_extension_unit *eu;
257 } d;
258 int inputs_size;
259 struct terminal_list **inputs; /* list of source input terminals */
260 struct terminal_list *output; /* list of destination output terminals */
261 int direct; /* directly connected to an output terminal */
262 };
263
264 #define UAC_OUTPUT 0
265 #define UAC_INPUT 1
266 #define UAC_EQUAL 2
267 #define UAC_RECORD 3
268 #define UAC_NCLASSES 4
269 #ifdef USB_DEBUG
270 #if defined(__FreeBSD__)
271 #define AudioCinputs "inputs"
272 #define AudioCoutputs "outputs"
273 #define AudioCrecord "record"
274 #define AudioCequalization "equalization"
275 #endif
276 Static const char *uac_names[] = {
277 AudioCoutputs, AudioCinputs, AudioCequalization, AudioCrecord,
278 };
279 #endif
280
281 Static usbd_status uaudio_identify_ac
282 (struct uaudio_softc *, const usb_config_descriptor_t *);
283 Static usbd_status uaudio_identify_as
284 (struct uaudio_softc *, const usb_config_descriptor_t *);
285 Static usbd_status uaudio_process_as
286 (struct uaudio_softc *, const char *, int *, int,
287 const usb_interface_descriptor_t *);
288
289 Static void uaudio_add_alt(struct uaudio_softc *, const struct as_info *);
290
291 Static const usb_interface_descriptor_t *uaudio_find_iface
292 (const char *, int, int *, int);
293
294 Static void uaudio_mixer_add_ctl(struct uaudio_softc *, struct mixerctl *);
295
296 #if defined(__NetBSD__) || defined(__OpenBSD__)
297 Static char *uaudio_id_name
298 (struct uaudio_softc *, const struct io_terminal *, int);
299 #endif
300
301 #ifdef USB_DEBUG
302 Static void uaudio_dump_cluster(const struct usb_audio_cluster *);
303 #endif
304 Static struct usb_audio_cluster uaudio_get_cluster
305 (int, const struct io_terminal *);
306 Static void uaudio_add_input
307 (struct uaudio_softc *, const struct io_terminal *, int);
308 Static void uaudio_add_output
309 (struct uaudio_softc *, const struct io_terminal *, int);
310 Static void uaudio_add_mixer
311 (struct uaudio_softc *, const struct io_terminal *, int);
312 Static void uaudio_add_selector
313 (struct uaudio_softc *, const struct io_terminal *, int);
314 #ifdef USB_DEBUG
315 Static const char *uaudio_get_terminal_name(int);
316 #endif
317 Static int uaudio_determine_class
318 (const struct io_terminal *, struct mixerctl *);
319 #if defined(__FreeBSD__)
320 Static const int uaudio_feature_name(const struct io_terminal *,
321 struct mixerctl *);
322 #else
323 Static const char *uaudio_feature_name
324 (const struct io_terminal *, struct mixerctl *);
325 #endif
326 Static void uaudio_add_feature
327 (struct uaudio_softc *, const struct io_terminal *, int);
328 Static void uaudio_add_processing_updown
329 (struct uaudio_softc *, const struct io_terminal *, int);
330 Static void uaudio_add_processing
331 (struct uaudio_softc *, const struct io_terminal *, int);
332 Static void uaudio_add_extension
333 (struct uaudio_softc *, const struct io_terminal *, int);
334 Static struct terminal_list *uaudio_merge_terminal_list
335 (const struct io_terminal *);
336 Static struct terminal_list *uaudio_io_terminaltype
337 (int, struct io_terminal *, int);
338 Static usbd_status uaudio_identify
339 (struct uaudio_softc *, const usb_config_descriptor_t *);
340
341 Static int uaudio_signext(int, int);
342 #if defined(__NetBSD__) || defined(__OpenBSD__)
343 Static int uaudio_value2bsd(struct mixerctl *, int);
344 #endif
345 Static int uaudio_bsd2value(struct mixerctl *, int);
346 Static int uaudio_get(struct uaudio_softc *, int, int, int, int, int);
347 #if defined(__NetBSD__) || defined(__OpenBSD__)
348 Static int uaudio_ctl_get
349 (struct uaudio_softc *, int, struct mixerctl *, int);
350 #endif
351 Static void uaudio_set
352 (struct uaudio_softc *, int, int, int, int, int, int);
353 Static void uaudio_ctl_set
354 (struct uaudio_softc *, int, struct mixerctl *, int, int);
355
356 Static usbd_status uaudio_set_speed(struct uaudio_softc *, int, u_int);
357
358 Static usbd_status uaudio_chan_open(struct uaudio_softc *, struct chan *);
359 Static void uaudio_chan_close(struct uaudio_softc *, struct chan *);
360 Static usbd_status uaudio_chan_alloc_buffers
361 (struct uaudio_softc *, struct chan *);
362 Static void uaudio_chan_free_buffers(struct uaudio_softc *, struct chan *);
363
364 #if defined(__NetBSD__) || defined(__OpenBSD__)
365 Static void uaudio_chan_init
366 (struct chan *, int, const struct audio_params *, int);
367 Static void uaudio_chan_set_param(struct chan *, u_char *, u_char *, int);
368 #endif
369
370 Static void uaudio_chan_ptransfer(struct chan *);
371 Static void uaudio_chan_pintr
372 (usbd_xfer_handle, usbd_private_handle, usbd_status);
373
374 Static void uaudio_chan_rtransfer(struct chan *);
375 Static void uaudio_chan_rintr
376 (usbd_xfer_handle, usbd_private_handle, usbd_status);
377
378 #if defined(__NetBSD__) || defined(__OpenBSD__)
379 Static int uaudio_open(void *, int);
380 Static void uaudio_close(void *);
381 Static int uaudio_drain(void *);
382 Static int uaudio_query_encoding(void *, struct audio_encoding *);
383 Static void uaudio_get_minmax_rates
384 (int, const struct as_info *, const struct audio_params *,
385 int, u_long *, u_long *);
386 Static int uaudio_match_alt_sub
387 (int, const struct as_info *, const struct audio_params *, int, u_long);
388 Static int uaudio_match_alt_chan
389 (int, const struct as_info *, struct audio_params *, int);
390 Static int uaudio_match_alt
391 (int, const struct as_info *, struct audio_params *, int);
392 Static int uaudio_set_params
393 (void *, int, int, struct audio_params *, struct audio_params *);
394 Static int uaudio_round_blocksize(void *, int);
395 Static int uaudio_trigger_output
396 (void *, void *, void *, int, void (*)(void *), void *,
397 struct audio_params *);
398 Static int uaudio_trigger_input
399 (void *, void *, void *, int, void (*)(void *), void *,
400 struct audio_params *);
401 Static int uaudio_halt_in_dma(void *);
402 Static int uaudio_halt_out_dma(void *);
403 Static int uaudio_getdev(void *, struct audio_device *);
404 Static int uaudio_mixer_set_port(void *, mixer_ctrl_t *);
405 Static int uaudio_mixer_get_port(void *, mixer_ctrl_t *);
406 Static int uaudio_query_devinfo(void *, mixer_devinfo_t *);
407 Static int uaudio_get_props(void *);
408
409 Static const struct audio_hw_if uaudio_hw_if = {
410 uaudio_open,
411 uaudio_close,
412 uaudio_drain,
413 uaudio_query_encoding,
414 uaudio_set_params,
415 uaudio_round_blocksize,
416 NULL,
417 NULL,
418 NULL,
419 NULL,
420 NULL,
421 uaudio_halt_out_dma,
422 uaudio_halt_in_dma,
423 NULL,
424 uaudio_getdev,
425 NULL,
426 uaudio_mixer_set_port,
427 uaudio_mixer_get_port,
428 uaudio_query_devinfo,
429 NULL,
430 NULL,
431 NULL,
432 NULL,
433 uaudio_get_props,
434 uaudio_trigger_output,
435 uaudio_trigger_input,
436 NULL,
437 };
438
439 Static struct audio_device uaudio_device = {
440 "USB audio",
441 "",
442 "uaudio"
443 };
444
445 #elif defined(__FreeBSD__)
446 Static int audio_attach_mi(device_t);
447 Static int uaudio_init_params(struct uaudio_softc * sc, struct chan *ch, int mode);
448
449 /* for NetBSD compatibirity */
450 #define AUMODE_PLAY 0x01
451 #define AUMODE_RECORD 0x02
452
453 #define AUDIO_PROP_FULLDUPLEX 0x01
454
455 #define AUDIO_ENCODING_ULAW 1
456 #define AUDIO_ENCODING_ALAW 2
457 #define AUDIO_ENCODING_SLINEAR_LE 6
458 #define AUDIO_ENCODING_SLINEAR_BE 7
459 #define AUDIO_ENCODING_ULINEAR_LE 8
460 #define AUDIO_ENCODING_ULINEAR_BE 9
461
462 #endif /* FreeBSD */
463
464
465 #if defined(__NetBSD__) || defined(__OpenBSD__)
466
467 USB_DECLARE_DRIVER(uaudio);
468
469 #elif defined(__FreeBSD__)
470
471 USB_DECLARE_DRIVER_INIT(uaudio,
472 DEVMETHOD(device_suspend, bus_generic_suspend),
473 DEVMETHOD(device_resume, bus_generic_resume),
474 DEVMETHOD(device_shutdown, bus_generic_shutdown),
475 DEVMETHOD(bus_print_child, bus_generic_print_child)
476 );
477 #endif
478
479
480 USB_MATCH(uaudio)
481 {
482 USB_MATCH_START(uaudio, uaa);
483 usb_interface_descriptor_t *id;
484
485 if (uaa->iface == NULL)
486 return (UMATCH_NONE);
487
488 id = usbd_get_interface_descriptor(uaa->iface);
489 /* Trigger on the control interface. */
490 if (id == NULL ||
491 id->bInterfaceClass != UICLASS_AUDIO ||
492 id->bInterfaceSubClass != UISUBCLASS_AUDIOCONTROL ||
493 (usbd_get_quirks(uaa->device)->uq_flags & UQ_BAD_AUDIO))
494 return (UMATCH_NONE);
495
496 return (UMATCH_IFACECLASS_IFACESUBCLASS);
497 }
498
499 USB_ATTACH(uaudio)
500 {
501 USB_ATTACH_START(uaudio, sc, uaa);
502 usb_interface_descriptor_t *id;
503 usb_config_descriptor_t *cdesc;
504 char devinfo[1024];
505 usbd_status err;
506 int i, j, found;
507
508 #if defined(__FreeBSD__)
509 usbd_devinfo(uaa->device, 0, devinfo);
510 USB_ATTACH_SETUP;
511 #else
512 usbd_devinfo(uaa->device, 0, devinfo, sizeof(devinfo));
513 #endif
514
515 #if !defined(__FreeBSD__)
516 printf(": %s\n", devinfo);
517 #endif
518
519 sc->sc_udev = uaa->device;
520
521 cdesc = usbd_get_config_descriptor(sc->sc_udev);
522 if (cdesc == NULL) {
523 printf("%s: failed to get configuration descriptor\n",
524 USBDEVNAME(sc->sc_dev));
525 USB_ATTACH_ERROR_RETURN;
526 }
527
528 err = uaudio_identify(sc, cdesc);
529 if (err) {
530 printf("%s: audio descriptors make no sense, error=%d\n",
531 USBDEVNAME(sc->sc_dev), err);
532 USB_ATTACH_ERROR_RETURN;
533 }
534
535 sc->sc_ac_ifaceh = uaa->iface;
536 /* Pick up the AS interface. */
537 for (i = 0; i < uaa->nifaces; i++) {
538 if (uaa->ifaces[i] == NULL)
539 continue;
540 id = usbd_get_interface_descriptor(uaa->ifaces[i]);
541 if (id == NULL)
542 continue;
543 found = 0;
544 for (j = 0; j < sc->sc_nalts; j++) {
545 if (id->bInterfaceNumber ==
546 sc->sc_alts[j].idesc->bInterfaceNumber) {
547 sc->sc_alts[j].ifaceh = uaa->ifaces[i];
548 found = 1;
549 }
550 }
551 if (found)
552 uaa->ifaces[i] = NULL;
553 }
554
555 for (j = 0; j < sc->sc_nalts; j++) {
556 if (sc->sc_alts[j].ifaceh == NULL) {
557 printf("%s: alt %d missing AS interface(s)\n",
558 USBDEVNAME(sc->sc_dev), j);
559 USB_ATTACH_ERROR_RETURN;
560 }
561 }
562
563 printf("%s: audio rev %d.%02x\n", USBDEVNAME(sc->sc_dev),
564 sc->sc_audio_rev >> 8, sc->sc_audio_rev & 0xff);
565
566 sc->sc_playchan.sc = sc->sc_recchan.sc = sc;
567 sc->sc_playchan.altidx = -1;
568 sc->sc_recchan.altidx = -1;
569
570 if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_FRAC)
571 sc->sc_altflags |= UA_NOFRAC;
572
573 #ifndef USB_DEBUG
574 if (bootverbose)
575 #endif
576 printf("%s: %d mixer controls\n", USBDEVNAME(sc->sc_dev),
577 sc->sc_nctls);
578
579 #if !defined(__FreeBSD__)
580 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
581 USBDEV(sc->sc_dev));
582 #endif
583
584 DPRINTF(("uaudio_attach: doing audio_attach_mi\n"));
585 #if defined(__OpenBSD__)
586 audio_attach_mi(&uaudio_hw_if, sc, &sc->sc_dev);
587 #elif defined(__NetBSD__)
588 sc->sc_audiodev = audio_attach_mi(&uaudio_hw_if, sc, &sc->sc_dev);
589 #elif defined(__FreeBSD__)
590 sc->sc_dying = 0;
591 if (audio_attach_mi(sc->sc_dev)) {
592 printf("audio_attach_mi failed\n");
593 USB_ATTACH_ERROR_RETURN;
594 }
595 #endif
596
597 USB_ATTACH_SUCCESS_RETURN;
598 }
599
600 #if defined(__NetBSD__) || defined(__OpenBSD__)
601 int
602 uaudio_activate(device_ptr_t self, enum devact act)
603 {
604 struct uaudio_softc *sc = (struct uaudio_softc *)self;
605 int rv = 0;
606
607 switch (act) {
608 case DVACT_ACTIVATE:
609 return (EOPNOTSUPP);
610 break;
611
612 case DVACT_DEACTIVATE:
613 if (sc->sc_audiodev != NULL)
614 rv = config_deactivate(sc->sc_audiodev);
615 sc->sc_dying = 1;
616 break;
617 }
618 return (rv);
619 }
620 #endif
621
622 #if defined(__NetBSD__) || defined(__OpenBSD__)
623 int
624 uaudio_detach(device_ptr_t self, int flags)
625 {
626 struct uaudio_softc *sc = (struct uaudio_softc *)self;
627 int rv = 0;
628
629 /* Wait for outstanding requests to complete. */
630 usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES);
631
632 if (sc->sc_audiodev != NULL)
633 rv = config_detach(sc->sc_audiodev, flags);
634
635 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
636 USBDEV(sc->sc_dev));
637
638 return (rv);
639 }
640 #elif defined(__FreeBSD__)
641
642 USB_DETACH(uaudio)
643 {
644 USB_DETACH_START(uaudio, sc);
645
646 sc->sc_dying = 1;
647
648 #if 0 /* XXX */
649 /* Wait for outstanding requests to complete. */
650 usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES);
651 #endif
652
653 /* do nothing ? */
654 return bus_generic_detach(sc->sc_dev);
655 }
656 #endif
657
658 #if defined(__NetBSD__) || defined(__OpenBSD__)
659 Static int
660 uaudio_query_encoding(void *addr, struct audio_encoding *fp)
661 {
662 struct uaudio_softc *sc = addr;
663 int flags = sc->sc_altflags;
664 int idx;
665
666 if (sc->sc_dying)
667 return (EIO);
668
669 if (sc->sc_nalts == 0 || flags == 0)
670 return (ENXIO);
671
672 idx = fp->index;
673 switch (idx) {
674 case 0:
675 strlcpy(fp->name, AudioEulinear, sizeof(fp->name));
676 fp->encoding = AUDIO_ENCODING_ULINEAR;
677 fp->precision = 8;
678 fp->flags = flags&HAS_8U ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
679 return (0);
680 case 1:
681 strlcpy(fp->name, AudioEmulaw, sizeof(fp->name));
682 fp->encoding = AUDIO_ENCODING_ULAW;
683 fp->precision = 8;
684 fp->flags = flags&HAS_MULAW ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
685 return (0);
686 case 2:
687 strlcpy(fp->name, AudioEalaw, sizeof(fp->name));
688 fp->encoding = AUDIO_ENCODING_ALAW;
689 fp->precision = 8;
690 fp->flags = flags&HAS_ALAW ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
691 return (0);
692 case 3:
693 strlcpy(fp->name, AudioEslinear, sizeof(fp->name));
694 fp->encoding = AUDIO_ENCODING_SLINEAR;
695 fp->precision = 8;
696 fp->flags = flags&HAS_8 ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
697 return (0);
698 case 4:
699 strlcpy(fp->name, AudioEslinear_le, sizeof(fp->name));
700 fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
701 fp->precision = 16;
702 fp->flags = 0;
703 return (0);
704 case 5:
705 strlcpy(fp->name, AudioEulinear_le, sizeof(fp->name));
706 fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
707 fp->precision = 16;
708 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
709 return (0);
710 case 6:
711 strlcpy(fp->name, AudioEslinear_be, sizeof(fp->name));
712 fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
713 fp->precision = 16;
714 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
715 return (0);
716 case 7:
717 strlcpy(fp->name, AudioEulinear_be, sizeof(fp->name));
718 fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
719 fp->precision = 16;
720 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
721 return (0);
722 default:
723 return (EINVAL);
724 }
725 }
726 #endif
727
728 Static const usb_interface_descriptor_t *
729 uaudio_find_iface(const char *buf, int size, int *offsp, int subtype)
730 {
731 const usb_interface_descriptor_t *d;
732
733 while (*offsp < size) {
734 d = (const void *)(buf + *offsp);
735 *offsp += d->bLength;
736 if (d->bDescriptorType == UDESC_INTERFACE &&
737 d->bInterfaceClass == UICLASS_AUDIO &&
738 d->bInterfaceSubClass == subtype)
739 return (d);
740 }
741 return (NULL);
742 }
743
744 Static void
745 uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct mixerctl *mc)
746 {
747 int res;
748 size_t len;
749 struct mixerctl *nmc;
750
751 #if defined(__FreeBSD__)
752 if (mc->class < UAC_NCLASSES) {
753 DPRINTF(("%s: adding %s.%d\n",
754 __func__, uac_names[mc->class], mc->ctl));
755 } else {
756 DPRINTF(("%s: adding %d\n", __func__, mc->ctl));
757 }
758 #else
759 if (mc->class < UAC_NCLASSES) {
760 DPRINTF(("%s: adding %s.%s\n",
761 __func__, uac_names[mc->class], mc->ctlname));
762 } else {
763 DPRINTF(("%s: adding %s\n", __func__, mc->ctlname));
764 }
765 #endif
766 len = sizeof(*mc) * (sc->sc_nctls + 1);
767 nmc = malloc(len, M_USBDEV, M_NOWAIT);
768 if (nmc == NULL) {
769 printf("uaudio_mixer_add_ctl: no memory\n");
770 return;
771 }
772 /* Copy old data, if there was any */
773 if (sc->sc_nctls != 0) {
774 memcpy(nmc, sc->sc_ctls, sizeof(*mc) * (sc->sc_nctls));
775 free(sc->sc_ctls, M_USBDEV);
776 }
777 sc->sc_ctls = nmc;
778
779 mc->delta = 0;
780 if (mc->type == MIX_ON_OFF) {
781 mc->minval = 0;
782 mc->maxval = 1;
783 } else if (mc->type == MIX_SELECTOR) {
784 ;
785 } else {
786 /* Determine min and max values. */
787 mc->minval = uaudio_signext(mc->type,
788 uaudio_get(sc, GET_MIN, UT_READ_CLASS_INTERFACE,
789 mc->wValue[0], mc->wIndex,
790 MIX_SIZE(mc->type)));
791 mc->maxval = 1 + uaudio_signext(mc->type,
792 uaudio_get(sc, GET_MAX, UT_READ_CLASS_INTERFACE,
793 mc->wValue[0], mc->wIndex,
794 MIX_SIZE(mc->type)));
795 mc->mul = mc->maxval - mc->minval;
796 if (mc->mul == 0)
797 mc->mul = 1;
798 res = uaudio_get(sc, GET_RES, UT_READ_CLASS_INTERFACE,
799 mc->wValue[0], mc->wIndex,
800 MIX_SIZE(mc->type));
801 if (res > 0)
802 mc->delta = (res * 255 + mc->mul/2) / mc->mul;
803 }
804
805 sc->sc_ctls[sc->sc_nctls++] = *mc;
806
807 #ifdef USB_DEBUG
808 if (uaudiodebug > 2) {
809 int i;
810 DPRINTF(("uaudio_mixer_add_ctl: wValue=%04x",mc->wValue[0]));
811 for (i = 1; i < mc->nchan; i++)
812 DPRINTF((",%04x", mc->wValue[i]));
813 #if defined(__FreeBSD__)
814 DPRINTF((" wIndex=%04x type=%d ctl='%d' "
815 "min=%d max=%d\n",
816 mc->wIndex, mc->type, mc->ctl,
817 mc->minval, mc->maxval));
818 #else
819 DPRINTF((" wIndex=%04x type=%d name='%s' unit='%s' "
820 "min=%d max=%d\n",
821 mc->wIndex, mc->type, mc->ctlname, mc->ctlunit,
822 mc->minval, mc->maxval));
823 #endif
824 }
825 #endif
826 }
827
828 #if defined(__NetBSD__) || defined(__OpenBSD__)
829 Static char *
830 uaudio_id_name(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
831 {
832 static char buf[32];
833 snprintf(buf, sizeof(buf), "i%d", id);
834 return (buf);
835 }
836 #endif
837
838 #ifdef USB_DEBUG
839 Static void
840 uaudio_dump_cluster(const struct usb_audio_cluster *cl)
841 {
842 static const char *channel_names[16] = {
843 "LEFT", "RIGHT", "CENTER", "LFE",
844 "LEFT_SURROUND", "RIGHT_SURROUND", "LEFT_CENTER", "RIGHT_CENTER",
845 "SURROUND", "LEFT_SIDE", "RIGHT_SIDE", "TOP",
846 "RESERVED12", "RESERVED13", "RESERVED14", "RESERVED15",
847 };
848 int cc, i, first;
849
850 cc = UGETW(cl->wChannelConfig);
851 logprintf("cluster: bNrChannels=%u wChannelConfig=0x%.4x",
852 cl->bNrChannels, cc);
853 first = TRUE;
854 for (i = 0; cc != 0; i++) {
855 if (cc & 1) {
856 logprintf("%c%s", first ? '<' : ',', channel_names[i]);
857 first = FALSE;
858 }
859 cc = cc >> 1;
860 }
861 logprintf("> iChannelNames=%u", cl->iChannelNames);
862 }
863 #endif
864
865 Static struct usb_audio_cluster
866 uaudio_get_cluster(int id, const struct io_terminal *iot)
867 {
868 struct usb_audio_cluster r;
869 const usb_descriptor_t *dp;
870 int i;
871
872 for (i = 0; i < 25; i++) { /* avoid infinite loops */
873 dp = iot[id].d.desc;
874 if (dp == 0)
875 goto bad;
876 switch (dp->bDescriptorSubtype) {
877 case UDESCSUB_AC_INPUT:
878 r.bNrChannels = iot[id].d.it->bNrChannels;
879 USETW(r.wChannelConfig, UGETW(iot[id].d.it->wChannelConfig));
880 r.iChannelNames = iot[id].d.it->iChannelNames;
881 return (r);
882 case UDESCSUB_AC_OUTPUT:
883 id = iot[id].d.ot->bSourceId;
884 break;
885 case UDESCSUB_AC_MIXER:
886 r = *(const struct usb_audio_cluster *)
887 &iot[id].d.mu->baSourceId[iot[id].d.mu->bNrInPins];
888 return (r);
889 case UDESCSUB_AC_SELECTOR:
890 /* XXX This is not really right */
891 id = iot[id].d.su->baSourceId[0];
892 break;
893 case UDESCSUB_AC_FEATURE:
894 id = iot[id].d.fu->bSourceId;
895 break;
896 case UDESCSUB_AC_PROCESSING:
897 r = *(const struct usb_audio_cluster *)
898 &iot[id].d.pu->baSourceId[iot[id].d.pu->bNrInPins];
899 return (r);
900 case UDESCSUB_AC_EXTENSION:
901 r = *(const struct usb_audio_cluster *)
902 &iot[id].d.eu->baSourceId[iot[id].d.eu->bNrInPins];
903 return (r);
904 default:
905 goto bad;
906 }
907 }
908 bad:
909 printf("uaudio_get_cluster: bad data\n");
910 memset(&r, 0, sizeof r);
911 return (r);
912
913 }
914
915 Static void
916 uaudio_add_input(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
917 {
918 #ifdef USB_DEBUG
919 const struct usb_audio_input_terminal *d = iot[id].d.it;
920
921 DPRINTFN(2,("uaudio_add_input: bTerminalId=%d wTerminalType=0x%04x "
922 "bAssocTerminal=%d bNrChannels=%d wChannelConfig=%d "
923 "iChannelNames=%d iTerminal=%d\n",
924 d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal,
925 d->bNrChannels, UGETW(d->wChannelConfig),
926 d->iChannelNames, d->iTerminal));
927 #endif
928 }
929
930 Static void
931 uaudio_add_output(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
932 {
933 #ifdef USB_DEBUG
934 const struct usb_audio_output_terminal *d = iot[id].d.ot;
935
936 DPRINTFN(2,("uaudio_add_output: bTerminalId=%d wTerminalType=0x%04x "
937 "bAssocTerminal=%d bSourceId=%d iTerminal=%d\n",
938 d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal,
939 d->bSourceId, d->iTerminal));
940 #endif
941 }
942
943 Static void
944 uaudio_add_mixer(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
945 {
946 const struct usb_audio_mixer_unit *d = iot[id].d.mu;
947 const struct usb_audio_mixer_unit_1 *d1;
948 int c, chs, ichs, ochs, i, o, bno, p, mo, mc, k;
949 const uByte *bm;
950 struct mixerctl mix;
951
952 DPRINTFN(2,("uaudio_add_mixer: bUnitId=%d bNrInPins=%d\n",
953 d->bUnitId, d->bNrInPins));
954
955 /* Compute the number of input channels */
956 ichs = 0;
957 for (i = 0; i < d->bNrInPins; i++)
958 ichs += uaudio_get_cluster(d->baSourceId[i], iot).bNrChannels;
959
960 /* and the number of output channels */
961 d1 = (const struct usb_audio_mixer_unit_1 *)&d->baSourceId[d->bNrInPins];
962 ochs = d1->bNrChannels;
963 DPRINTFN(2,("uaudio_add_mixer: ichs=%d ochs=%d\n", ichs, ochs));
964
965 bm = d1->bmControls;
966 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
967 uaudio_determine_class(&iot[id], &mix);
968 mix.type = MIX_SIGNED_16;
969 #if !defined(__FreeBSD__) /* XXXXX */
970 mix.ctlunit = AudioNvolume;
971 #endif
972
973 #define BIT(bno) ((bm[bno / 8] >> (7 - bno % 8)) & 1)
974 for (p = i = 0; i < d->bNrInPins; i++) {
975 chs = uaudio_get_cluster(d->baSourceId[i], iot).bNrChannels;
976 mc = 0;
977 for (c = 0; c < chs; c++) {
978 mo = 0;
979 for (o = 0; o < ochs; o++) {
980 bno = (p + c) * ochs + o;
981 if (BIT(bno))
982 mo++;
983 }
984 if (mo == 1)
985 mc++;
986 }
987 if (mc == chs && chs <= MIX_MAX_CHAN) {
988 k = 0;
989 for (c = 0; c < chs; c++)
990 for (o = 0; o < ochs; o++) {
991 bno = (p + c) * ochs + o;
992 if (BIT(bno))
993 mix.wValue[k++] =
994 MAKE(p+c+1, o+1);
995 }
996 #if !defined(__FreeBSD__)
997 snprintf(mix.ctlname, sizeof(mix.ctlname), "mix%d-%s",
998 d->bUnitId, uaudio_id_name(sc, iot,
999 d->baSourceId[i]));
1000 #endif
1001 mix.nchan = chs;
1002 uaudio_mixer_add_ctl(sc, &mix);
1003 } else {
1004 /* XXX */
1005 }
1006 #undef BIT
1007 p += chs;
1008 }
1009
1010 }
1011
1012 Static void
1013 uaudio_add_selector(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
1014 {
1015 const struct usb_audio_selector_unit *d = iot[id].d.su;
1016 struct mixerctl mix;
1017 #if !defined(__FreeBSD__)
1018 int i, wp;
1019 #else
1020 int i;
1021 struct mixerctl dummy;
1022 #endif
1023
1024 DPRINTFN(2,("uaudio_add_selector: bUnitId=%d bNrInPins=%d\n",
1025 d->bUnitId, d->bNrInPins));
1026 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
1027 mix.wValue[0] = MAKE(0, 0);
1028 uaudio_determine_class(&iot[id], &mix);
1029 mix.nchan = 1;
1030 mix.type = MIX_SELECTOR;
1031 #if defined(__FreeBSD__)
1032 mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */
1033 mix.minval = 1;
1034 mix.maxval = d->bNrInPins;
1035 mix.mul = mix.maxval - mix.minval;
1036 for (i = 0; i < MAX_SELECTOR_INPUT_PIN; i++) {
1037 mix.slctrtype[i] = SOUND_MIXER_NRDEVICES;
1038 }
1039 for (i = mix.minval; i <= mix.maxval; i++) {
1040 mix.slctrtype[i - 1] = uaudio_feature_name(&iot[d->baSourceId[i - 1]], &dummy);
1041 }
1042 #else
1043 mix.ctlunit = "";
1044 mix.minval = 1;
1045 mix.maxval = d->bNrInPins;
1046 mix.mul = mix.maxval - mix.minval;
1047 wp = snprintf(mix.ctlname, MAX_AUDIO_DEV_LEN, "sel%d-", d->bUnitId);
1048 for (i = 1; i <= d->bNrInPins; i++) {
1049 wp += snprintf(mix.ctlname + wp, MAX_AUDIO_DEV_LEN - wp,
1050 "i%d", d->baSourceId[i - 1]);
1051 if (wp > MAX_AUDIO_DEV_LEN - 1)
1052 break;
1053 }
1054 #endif
1055 uaudio_mixer_add_ctl(sc, &mix);
1056 }
1057
1058 #ifdef USB_DEBUG
1059 Static const char *
1060 uaudio_get_terminal_name(int terminal_type)
1061 {
1062 static char buf[100];
1063
1064 switch (terminal_type) {
1065 /* USB terminal types */
1066 case UAT_UNDEFINED: return "UAT_UNDEFINED";
1067 case UAT_STREAM: return "UAT_STREAM";
1068 case UAT_VENDOR: return "UAT_VENDOR";
1069 /* input terminal types */
1070 case UATI_UNDEFINED: return "UATI_UNDEFINED";
1071 case UATI_MICROPHONE: return "UATI_MICROPHONE";
1072 case UATI_DESKMICROPHONE: return "UATI_DESKMICROPHONE";
1073 case UATI_PERSONALMICROPHONE: return "UATI_PERSONALMICROPHONE";
1074 case UATI_OMNIMICROPHONE: return "UATI_OMNIMICROPHONE";
1075 case UATI_MICROPHONEARRAY: return "UATI_MICROPHONEARRAY";
1076 case UATI_PROCMICROPHONEARR: return "UATI_PROCMICROPHONEARR";
1077 /* output terminal types */
1078 case UATO_UNDEFINED: return "UATO_UNDEFINED";
1079 case UATO_SPEAKER: return "UATO_SPEAKER";
1080 case UATO_HEADPHONES: return "UATO_HEADPHONES";
1081 case UATO_DISPLAYAUDIO: return "UATO_DISPLAYAUDIO";
1082 case UATO_DESKTOPSPEAKER: return "UATO_DESKTOPSPEAKER";
1083 case UATO_ROOMSPEAKER: return "UATO_ROOMSPEAKER";
1084 case UATO_COMMSPEAKER: return "UATO_COMMSPEAKER";
1085 case UATO_SUBWOOFER: return "UATO_SUBWOOFER";
1086 /* bidir terminal types */
1087 case UATB_UNDEFINED: return "UATB_UNDEFINED";
1088 case UATB_HANDSET: return "UATB_HANDSET";
1089 case UATB_HEADSET: return "UATB_HEADSET";
1090 case UATB_SPEAKERPHONE: return "UATB_SPEAKERPHONE";
1091 case UATB_SPEAKERPHONEESUP: return "UATB_SPEAKERPHONEESUP";
1092 case UATB_SPEAKERPHONEECANC: return "UATB_SPEAKERPHONEECANC";
1093 /* telephony terminal types */
1094 case UATT_UNDEFINED: return "UATT_UNDEFINED";
1095 case UATT_PHONELINE: return "UATT_PHONELINE";
1096 case UATT_TELEPHONE: return "UATT_TELEPHONE";
1097 case UATT_DOWNLINEPHONE: return "UATT_DOWNLINEPHONE";
1098 /* external terminal types */
1099 case UATE_UNDEFINED: return "UATE_UNDEFINED";
1100 case UATE_ANALOGCONN: return "UATE_ANALOGCONN";
1101 case UATE_LINECONN: return "UATE_LINECONN";
1102 case UATE_LEGACYCONN: return "UATE_LEGACYCONN";
1103 case UATE_DIGITALAUIFC: return "UATE_DIGITALAUIFC";
1104 case UATE_SPDIF: return "UATE_SPDIF";
1105 case UATE_1394DA: return "UATE_1394DA";
1106 case UATE_1394DV: return "UATE_1394DV";
1107 /* embedded function terminal types */
1108 case UATF_UNDEFINED: return "UATF_UNDEFINED";
1109 case UATF_CALIBNOISE: return "UATF_CALIBNOISE";
1110 case UATF_EQUNOISE: return "UATF_EQUNOISE";
1111 case UATF_CDPLAYER: return "UATF_CDPLAYER";
1112 case UATF_DAT: return "UATF_DAT";
1113 case UATF_DCC: return "UATF_DCC";
1114 case UATF_MINIDISK: return "UATF_MINIDISK";
1115 case UATF_ANALOGTAPE: return "UATF_ANALOGTAPE";
1116 case UATF_PHONOGRAPH: return "UATF_PHONOGRAPH";
1117 case UATF_VCRAUDIO: return "UATF_VCRAUDIO";
1118 case UATF_VIDEODISCAUDIO: return "UATF_VIDEODISCAUDIO";
1119 case UATF_DVDAUDIO: return "UATF_DVDAUDIO";
1120 case UATF_TVTUNERAUDIO: return "UATF_TVTUNERAUDIO";
1121 case UATF_SATELLITE: return "UATF_SATELLITE";
1122 case UATF_CABLETUNER: return "UATF_CABLETUNER";
1123 case UATF_DSS: return "UATF_DSS";
1124 case UATF_RADIORECV: return "UATF_RADIORECV";
1125 case UATF_RADIOXMIT: return "UATF_RADIOXMIT";
1126 case UATF_MULTITRACK: return "UATF_MULTITRACK";
1127 case UATF_SYNTHESIZER: return "UATF_SYNTHESIZER";
1128 default:
1129 snprintf(buf, sizeof(buf), "unknown type (0x%.4x)", terminal_type);
1130 return buf;
1131 }
1132 }
1133 #endif
1134
1135 Static int
1136 uaudio_determine_class(const struct io_terminal *iot, struct mixerctl *mix)
1137 {
1138 int terminal_type;
1139
1140 if (iot == NULL || iot->output == NULL) {
1141 mix->class = UAC_OUTPUT;
1142 return 0;
1143 }
1144 terminal_type = 0;
1145 if (iot->output->size == 1)
1146 terminal_type = iot->output->terminals[0];
1147 /*
1148 * If the only output terminal is USB,
1149 * the class is UAC_RECORD.
1150 */
1151 if ((terminal_type & 0xff00) == (UAT_UNDEFINED & 0xff00)) {
1152 mix->class = UAC_RECORD;
1153 if (iot->inputs_size == 1
1154 && iot->inputs[0] != NULL
1155 && iot->inputs[0]->size == 1)
1156 return iot->inputs[0]->terminals[0];
1157 else
1158 return 0;
1159 }
1160 /*
1161 * If the ultimate destination of the unit is just one output
1162 * terminal and the unit is connected to the output terminal
1163 * directly, the class is UAC_OUTPUT.
1164 */
1165 if (terminal_type != 0 && iot->direct) {
1166 mix->class = UAC_OUTPUT;
1167 return terminal_type;
1168 }
1169 /*
1170 * If the unit is connected to just one input terminal,
1171 * the class is UAC_INPUT.
1172 */
1173 if (iot->inputs_size == 1 && iot->inputs[0] != NULL
1174 && iot->inputs[0]->size == 1) {
1175 mix->class = UAC_INPUT;
1176 return iot->inputs[0]->terminals[0];
1177 }
1178 /*
1179 * Otherwise, the class is UAC_OUTPUT.
1180 */
1181 mix->class = UAC_OUTPUT;
1182 return terminal_type;
1183 }
1184
1185 #if defined(__FreeBSD__)
1186 const int
1187 uaudio_feature_name(const struct io_terminal *iot, struct mixerctl *mix)
1188 {
1189 int terminal_type;
1190
1191 terminal_type = uaudio_determine_class(iot, mix);
1192 if (mix->class == UAC_RECORD && terminal_type == 0)
1193 return SOUND_MIXER_IMIX;
1194 DPRINTF(("%s: terminal_type=%s\n", __func__,
1195 uaudio_get_terminal_name(terminal_type)));
1196 switch (terminal_type) {
1197 case UAT_STREAM:
1198 return SOUND_MIXER_PCM;
1199
1200 case UATI_MICROPHONE:
1201 case UATI_DESKMICROPHONE:
1202 case UATI_PERSONALMICROPHONE:
1203 case UATI_OMNIMICROPHONE:
1204 case UATI_MICROPHONEARRAY:
1205 case UATI_PROCMICROPHONEARR:
1206 return SOUND_MIXER_MIC;
1207
1208 case UATO_SPEAKER:
1209 case UATO_DESKTOPSPEAKER:
1210 case UATO_ROOMSPEAKER:
1211 case UATO_COMMSPEAKER:
1212 return SOUND_MIXER_SPEAKER;
1213
1214 case UATE_ANALOGCONN:
1215 case UATE_LINECONN:
1216 case UATE_LEGACYCONN:
1217 return SOUND_MIXER_LINE;
1218
1219 case UATE_DIGITALAUIFC:
1220 case UATE_SPDIF:
1221 case UATE_1394DA:
1222 case UATE_1394DV:
1223 return SOUND_MIXER_ALTPCM;
1224
1225 case UATF_CDPLAYER:
1226 return SOUND_MIXER_CD;
1227
1228 case UATF_SYNTHESIZER:
1229 return SOUND_MIXER_SYNTH;
1230
1231 case UATF_VIDEODISCAUDIO:
1232 case UATF_DVDAUDIO:
1233 case UATF_TVTUNERAUDIO:
1234 return SOUND_MIXER_VIDEO;
1235
1236 /* telephony terminal types */
1237 case UATT_UNDEFINED:
1238 case UATT_PHONELINE:
1239 case UATT_TELEPHONE:
1240 case UATT_DOWNLINEPHONE:
1241 return SOUND_MIXER_PHONEIN;
1242 /* return SOUND_MIXER_PHONEOUT;*/
1243
1244 case UATF_RADIORECV:
1245 case UATF_RADIOXMIT:
1246 return SOUND_MIXER_RADIO;
1247
1248 case UAT_UNDEFINED:
1249 case UAT_VENDOR:
1250 case UATI_UNDEFINED:
1251 /* output terminal types */
1252 case UATO_UNDEFINED:
1253 case UATO_DISPLAYAUDIO:
1254 case UATO_SUBWOOFER:
1255 case UATO_HEADPHONES:
1256 /* bidir terminal types */
1257 case UATB_UNDEFINED:
1258 case UATB_HANDSET:
1259 case UATB_HEADSET:
1260 case UATB_SPEAKERPHONE:
1261 case UATB_SPEAKERPHONEESUP:
1262 case UATB_SPEAKERPHONEECANC:
1263 /* external terminal types */
1264 case UATE_UNDEFINED:
1265 /* embedded function terminal types */
1266 case UATF_UNDEFINED:
1267 case UATF_CALIBNOISE:
1268 case UATF_EQUNOISE:
1269 case UATF_DAT:
1270 case UATF_DCC:
1271 case UATF_MINIDISK:
1272 case UATF_ANALOGTAPE:
1273 case UATF_PHONOGRAPH:
1274 case UATF_VCRAUDIO:
1275 case UATF_SATELLITE:
1276 case UATF_CABLETUNER:
1277 case UATF_DSS:
1278 case UATF_MULTITRACK:
1279 case 0xffff:
1280 default:
1281 DPRINTF(("%s: 'master' for 0x%.4x\n", __func__, terminal_type));
1282 return SOUND_MIXER_VOLUME;
1283 }
1284 return SOUND_MIXER_VOLUME;
1285 }
1286 #else
1287 Static const char *
1288 uaudio_feature_name(const struct io_terminal *iot, struct mixerctl *mix)
1289 {
1290 int terminal_type;
1291
1292 terminal_type = uaudio_determine_class(iot, mix);
1293 if (mix->class == UAC_RECORD && terminal_type == 0)
1294 return AudioNmixerout;
1295 DPRINTF(("%s: terminal_type=%s\n", __func__,
1296 uaudio_get_terminal_name(terminal_type)));
1297 switch (terminal_type) {
1298 case UAT_STREAM:
1299 return AudioNdac;
1300
1301 case UATI_MICROPHONE:
1302 case UATI_DESKMICROPHONE:
1303 case UATI_PERSONALMICROPHONE:
1304 case UATI_OMNIMICROPHONE:
1305 case UATI_MICROPHONEARRAY:
1306 case UATI_PROCMICROPHONEARR:
1307 return AudioNmicrophone;
1308
1309 case UATO_SPEAKER:
1310 case UATO_DESKTOPSPEAKER:
1311 case UATO_ROOMSPEAKER:
1312 case UATO_COMMSPEAKER:
1313 return AudioNspeaker;
1314
1315 case UATO_HEADPHONES:
1316 return AudioNheadphone;
1317
1318 case UATO_SUBWOOFER:
1319 return AudioNlfe;
1320
1321 /* telephony terminal types */
1322 case UATT_UNDEFINED:
1323 case UATT_PHONELINE:
1324 case UATT_TELEPHONE:
1325 case UATT_DOWNLINEPHONE:
1326 return "phone";
1327
1328 case UATE_ANALOGCONN:
1329 case UATE_LINECONN:
1330 case UATE_LEGACYCONN:
1331 return AudioNline;
1332
1333 case UATE_DIGITALAUIFC:
1334 case UATE_SPDIF:
1335 case UATE_1394DA:
1336 case UATE_1394DV:
1337 return AudioNaux;
1338
1339 case UATF_CDPLAYER:
1340 return AudioNcd;
1341
1342 case UATF_SYNTHESIZER:
1343 return AudioNfmsynth;
1344
1345 case UATF_VIDEODISCAUDIO:
1346 case UATF_DVDAUDIO:
1347 case UATF_TVTUNERAUDIO:
1348 return AudioNvideo;
1349
1350 case UAT_UNDEFINED:
1351 case UAT_VENDOR:
1352 case UATI_UNDEFINED:
1353 /* output terminal types */
1354 case UATO_UNDEFINED:
1355 case UATO_DISPLAYAUDIO:
1356 /* bidir terminal types */
1357 case UATB_UNDEFINED:
1358 case UATB_HANDSET:
1359 case UATB_HEADSET:
1360 case UATB_SPEAKERPHONE:
1361 case UATB_SPEAKERPHONEESUP:
1362 case UATB_SPEAKERPHONEECANC:
1363 /* external terminal types */
1364 case UATE_UNDEFINED:
1365 /* embedded function terminal types */
1366 case UATF_UNDEFINED:
1367 case UATF_CALIBNOISE:
1368 case UATF_EQUNOISE:
1369 case UATF_DAT:
1370 case UATF_DCC:
1371 case UATF_MINIDISK:
1372 case UATF_ANALOGTAPE:
1373 case UATF_PHONOGRAPH:
1374 case UATF_VCRAUDIO:
1375 case UATF_SATELLITE:
1376 case UATF_CABLETUNER:
1377 case UATF_DSS:
1378 case UATF_RADIORECV:
1379 case UATF_RADIOXMIT:
1380 case UATF_MULTITRACK:
1381 case 0xffff:
1382 default:
1383 DPRINTF(("%s: 'master' for 0x%.4x\n", __func__, terminal_type));
1384 return AudioNmaster;
1385 }
1386 return AudioNmaster;
1387 }
1388 #endif
1389
1390 Static void
1391 uaudio_add_feature(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
1392 {
1393 const struct usb_audio_feature_unit *d = iot[id].d.fu;
1394 uByte *ctls = d->bmaControls;
1395 int ctlsize = d->bControlSize;
1396 int nchan = (d->bLength - 7) / ctlsize;
1397 u_int fumask, mmask, cmask;
1398 struct mixerctl mix;
1399 int chan, ctl, i, unit;
1400 #if defined(__FreeBSD__)
1401 int mixernumber;
1402 #else
1403 const char *mixername;
1404 #endif
1405
1406 #define GET(i) (ctls[(i)*ctlsize] | \
1407 (ctlsize > 1 ? ctls[(i)*ctlsize+1] << 8 : 0))
1408
1409 mmask = GET(0);
1410 /* Figure out what we can control */
1411 for (cmask = 0, chan = 1; chan < nchan; chan++) {
1412 DPRINTFN(9,("uaudio_add_feature: chan=%d mask=%x\n",
1413 chan, GET(chan)));
1414 cmask |= GET(chan);
1415 }
1416
1417 #if !defined(__FreeBSD__)
1418 DPRINTFN(1,("uaudio_add_feature: bUnitId=%d, "
1419 "%d channels, mmask=0x%04x, cmask=0x%04x\n",
1420 d->bUnitId, nchan, mmask, cmask));
1421 #endif
1422
1423 if (nchan > MIX_MAX_CHAN)
1424 nchan = MIX_MAX_CHAN;
1425 unit = d->bUnitId;
1426 mix.wIndex = MAKE(unit, sc->sc_ac_iface);
1427 for (ctl = MUTE_CONTROL; ctl < LOUDNESS_CONTROL; ctl++) {
1428 fumask = FU_MASK(ctl);
1429 DPRINTFN(4,("uaudio_add_feature: ctl=%d fumask=0x%04x\n",
1430 ctl, fumask));
1431 if (mmask & fumask) {
1432 mix.nchan = 1;
1433 mix.wValue[0] = MAKE(ctl, 0);
1434 } else if (cmask & fumask) {
1435 mix.nchan = nchan - 1;
1436 for (i = 1; i < nchan; i++) {
1437 if (GET(i) & fumask)
1438 mix.wValue[i-1] = MAKE(ctl, i);
1439 else
1440 mix.wValue[i-1] = -1;
1441 }
1442 } else {
1443 continue;
1444 }
1445 #undef GET
1446
1447 #if defined(__FreeBSD__)
1448 mixernumber = uaudio_feature_name(&iot[id], &mix);
1449 #else
1450 mixername = uaudio_feature_name(&iot[id], &mix);
1451 #endif
1452 switch (ctl) {
1453 case MUTE_CONTROL:
1454 mix.type = MIX_ON_OFF;
1455 #if defined(__FreeBSD__)
1456 mix.ctl = SOUND_MIXER_NRDEVICES;
1457 #else
1458 mix.ctlunit = "";
1459 snprintf(mix.ctlname, sizeof(mix.ctlname),
1460 "%s.%s", mixername, AudioNmute);
1461 #endif
1462 break;
1463 case VOLUME_CONTROL:
1464 mix.type = MIX_SIGNED_16;
1465 #if defined(__FreeBSD__)
1466 mix.ctl = mixernumber;
1467 #else
1468 mix.ctlunit = AudioNvolume;
1469 strlcpy(mix.ctlname, mixername, sizeof(mix.ctlname));
1470 #endif
1471 break;
1472 case BASS_CONTROL:
1473 mix.type = MIX_SIGNED_8;
1474 #if defined(__FreeBSD__)
1475 mix.ctl = SOUND_MIXER_BASS;
1476 #else
1477 mix.ctlunit = AudioNbass;
1478 snprintf(mix.ctlname, sizeof(mix.ctlname),
1479 "%s.%s", mixername, AudioNbass);
1480 #endif
1481 break;
1482 case MID_CONTROL:
1483 mix.type = MIX_SIGNED_8;
1484 #if defined(__FreeBSD__)
1485 mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */
1486 #else
1487 mix.ctlunit = AudioNmid;
1488 snprintf(mix.ctlname, sizeof(mix.ctlname),
1489 "%s.%s", mixername, AudioNmid);
1490 #endif
1491 break;
1492 case TREBLE_CONTROL:
1493 mix.type = MIX_SIGNED_8;
1494 #if defined(__FreeBSD__)
1495 mix.ctl = SOUND_MIXER_TREBLE;
1496 #else
1497 mix.ctlunit = AudioNtreble;
1498 snprintf(mix.ctlname, sizeof(mix.ctlname),
1499 "%s.%s", mixername, AudioNtreble);
1500 #endif
1501 break;
1502 case GRAPHIC_EQUALIZER_CONTROL:
1503 continue; /* XXX don't add anything */
1504 break;
1505 case AGC_CONTROL:
1506 mix.type = MIX_ON_OFF;
1507 #if defined(__FreeBSD__)
1508 mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */
1509 #else
1510 mix.ctlunit = "";
1511 snprintf(mix.ctlname, sizeof(mix.ctlname), "%s.%s",
1512 mixername, AudioNagc);
1513 #endif
1514 break;
1515 case DELAY_CONTROL:
1516 mix.type = MIX_UNSIGNED_16;
1517 #if defined(__FreeBSD__)
1518 mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */
1519 #else
1520 mix.ctlunit = "4 ms";
1521 snprintf(mix.ctlname, sizeof(mix.ctlname),
1522 "%s.%s", mixername, AudioNdelay);
1523 #endif
1524 break;
1525 case BASS_BOOST_CONTROL:
1526 mix.type = MIX_ON_OFF;
1527 #if defined(__FreeBSD__)
1528 mix.ctl = SOUND_MIXER_NRDEVICES; /* XXXXX */
1529 #else
1530 mix.ctlunit = "";
1531 snprintf(mix.ctlname, sizeof(mix.ctlname),
1532 "%s.%s", mixername, AudioNbassboost);
1533 #endif
1534 break;
1535 case LOUDNESS_CONTROL:
1536 mix.type = MIX_ON_OFF;
1537 #if defined(__FreeBSD__)
1538 mix.ctl = SOUND_MIXER_LOUD; /* Is this correct ? */
1539 #else
1540 mix.ctlunit = "";
1541 snprintf(mix.ctlname, sizeof(mix.ctlname),
1542 "%s.%s", mixername, AudioNloudness);
1543 #endif
1544 break;
1545 }
1546 uaudio_mixer_add_ctl(sc, &mix);
1547 }
1548 }
1549
1550 Static void
1551 uaudio_add_processing_updown(struct uaudio_softc *sc,
1552 const struct io_terminal *iot, int id)
1553 {
1554 const struct usb_audio_processing_unit *d = iot[id].d.pu;
1555 const struct usb_audio_processing_unit_1 *d1 =
1556 (const struct usb_audio_processing_unit_1 *)&d->baSourceId[d->bNrInPins];
1557 const struct usb_audio_processing_unit_updown *ud =
1558 (const struct usb_audio_processing_unit_updown *)
1559 &d1->bmControls[d1->bControlSize];
1560 struct mixerctl mix;
1561 int i;
1562
1563 DPRINTFN(2,("uaudio_add_processing_updown: bUnitId=%d bNrModes=%d\n",
1564 d->bUnitId, ud->bNrModes));
1565
1566 if (!(d1->bmControls[0] & UA_PROC_MASK(UD_MODE_SELECT_CONTROL))) {
1567 DPRINTF(("uaudio_add_processing_updown: no mode select\n"));
1568 return;
1569 }
1570
1571 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
1572 mix.nchan = 1;
1573 mix.wValue[0] = MAKE(UD_MODE_SELECT_CONTROL, 0);
1574 uaudio_determine_class(&iot[id], &mix);
1575 mix.type = MIX_ON_OFF; /* XXX */
1576 #if !defined(__FreeBSD__)
1577 mix.ctlunit = "";
1578 snprintf(mix.ctlname, sizeof(mix.ctlname), "pro%d-mode", d->bUnitId);
1579 #endif
1580
1581 for (i = 0; i < ud->bNrModes; i++) {
1582 DPRINTFN(2,("uaudio_add_processing_updown: i=%d bm=0x%x\n",
1583 i, UGETW(ud->waModes[i])));
1584 /* XXX */
1585 }
1586 uaudio_mixer_add_ctl(sc, &mix);
1587 }
1588
1589 Static void
1590 uaudio_add_processing(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
1591 {
1592 const struct usb_audio_processing_unit *d = iot[id].d.pu;
1593 const struct usb_audio_processing_unit_1 *d1 =
1594 (const struct usb_audio_processing_unit_1 *)&d->baSourceId[d->bNrInPins];
1595 int ptype = UGETW(d->wProcessType);
1596 struct mixerctl mix;
1597
1598 DPRINTFN(2,("uaudio_add_processing: wProcessType=%d bUnitId=%d "
1599 "bNrInPins=%d\n", ptype, d->bUnitId, d->bNrInPins));
1600
1601 if (d1->bmControls[0] & UA_PROC_ENABLE_MASK) {
1602 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
1603 mix.nchan = 1;
1604 mix.wValue[0] = MAKE(XX_ENABLE_CONTROL, 0);
1605 uaudio_determine_class(&iot[id], &mix);
1606 mix.type = MIX_ON_OFF;
1607 #if !defined(__FreeBSD__)
1608 mix.ctlunit = "";
1609 snprintf(mix.ctlname, sizeof(mix.ctlname), "pro%d.%d-enable",
1610 d->bUnitId, ptype);
1611 #endif
1612 uaudio_mixer_add_ctl(sc, &mix);
1613 }
1614
1615 switch(ptype) {
1616 case UPDOWNMIX_PROCESS:
1617 uaudio_add_processing_updown(sc, iot, id);
1618 break;
1619 case DOLBY_PROLOGIC_PROCESS:
1620 case P3D_STEREO_EXTENDER_PROCESS:
1621 case REVERBATION_PROCESS:
1622 case CHORUS_PROCESS:
1623 case DYN_RANGE_COMP_PROCESS:
1624 default:
1625 #ifdef USB_DEBUG
1626 printf("uaudio_add_processing: unit %d, type=%d not impl.\n",
1627 d->bUnitId, ptype);
1628 #endif
1629 break;
1630 }
1631 }
1632
1633 Static void
1634 uaudio_add_extension(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
1635 {
1636 const struct usb_audio_extension_unit *d = iot[id].d.eu;
1637 const struct usb_audio_extension_unit_1 *d1 =
1638 (const struct usb_audio_extension_unit_1 *)&d->baSourceId[d->bNrInPins];
1639 struct mixerctl mix;
1640
1641 DPRINTFN(2,("uaudio_add_extension: bUnitId=%d bNrInPins=%d\n",
1642 d->bUnitId, d->bNrInPins));
1643
1644 if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_XU)
1645 return;
1646
1647 if (d1->bmControls[0] & UA_EXT_ENABLE_MASK) {
1648 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
1649 mix.nchan = 1;
1650 mix.wValue[0] = MAKE(UA_EXT_ENABLE, 0);
1651 uaudio_determine_class(&iot[id], &mix);
1652 mix.type = MIX_ON_OFF;
1653 #if !defined(__FreeBSD__)
1654 mix.ctlunit = "";
1655 snprintf(mix.ctlname, sizeof(mix.ctlname), "ext%d-enable",
1656 d->bUnitId);
1657 #endif
1658 uaudio_mixer_add_ctl(sc, &mix);
1659 }
1660 }
1661
1662 Static struct terminal_list*
1663 uaudio_merge_terminal_list(const struct io_terminal *iot)
1664 {
1665 struct terminal_list *tml;
1666 uint16_t *ptm;
1667 int i, len;
1668
1669 len = 0;
1670 if (iot->inputs == NULL)
1671 return NULL;
1672 for (i = 0; i < iot->inputs_size; i++) {
1673 if (iot->inputs[i] != NULL)
1674 len += iot->inputs[i]->size;
1675 }
1676 tml = malloc(TERMINAL_LIST_SIZE(len), M_TEMP, M_NOWAIT);
1677 if (tml == NULL) {
1678 printf("uaudio_merge_terminal_list: no memory\n");
1679 return NULL;
1680 }
1681 tml->size = 0;
1682 ptm = tml->terminals;
1683 for (i = 0; i < iot->inputs_size; i++) {
1684 if (iot->inputs[i] == NULL)
1685 continue;
1686 if (iot->inputs[i]->size > len)
1687 break;
1688 memcpy(ptm, iot->inputs[i]->terminals,
1689 iot->inputs[i]->size * sizeof(uint16_t));
1690 tml->size += iot->inputs[i]->size;
1691 ptm += iot->inputs[i]->size;
1692 len -= iot->inputs[i]->size;
1693 }
1694 return tml;
1695 }
1696
1697 Static struct terminal_list *
1698 uaudio_io_terminaltype(int outtype, struct io_terminal *iot, int id)
1699 {
1700 struct terminal_list *tml;
1701 struct io_terminal *it;
1702 int src_id, i;
1703
1704 it = &iot[id];
1705 if (it->output != NULL) {
1706 /* already has outtype? */
1707 for (i = 0; i < it->output->size; i++)
1708 if (it->output->terminals[i] == outtype)
1709 return uaudio_merge_terminal_list(it);
1710 tml = malloc(TERMINAL_LIST_SIZE(it->output->size + 1),
1711 M_TEMP, M_NOWAIT);
1712 if (tml == NULL) {
1713 printf("uaudio_io_terminaltype: no memory\n");
1714 return uaudio_merge_terminal_list(it);
1715 }
1716 memcpy(tml, it->output, TERMINAL_LIST_SIZE(it->output->size));
1717 tml->terminals[it->output->size] = outtype;
1718 tml->size++;
1719 free(it->output, M_TEMP);
1720 it->output = tml;
1721 if (it->inputs != NULL) {
1722 for (i = 0; i < it->inputs_size; i++)
1723 if (it->inputs[i] != NULL)
1724 free(it->inputs[i], M_TEMP);
1725 free(it->inputs, M_TEMP);
1726 }
1727 it->inputs_size = 0;
1728 it->inputs = NULL;
1729 } else { /* end `iot[id] != NULL' */
1730 it->inputs_size = 0;
1731 it->inputs = NULL;
1732 it->output = malloc(TERMINAL_LIST_SIZE(1), M_TEMP, M_NOWAIT);
1733 if (it->output == NULL) {
1734 printf("uaudio_io_terminaltype: no memory\n");
1735 return NULL;
1736 }
1737 it->output->terminals[0] = outtype;
1738 it->output->size = 1;
1739 it->direct = FALSE;
1740 }
1741
1742 switch (it->d.desc->bDescriptorSubtype) {
1743 case UDESCSUB_AC_INPUT:
1744 it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT);
1745 if (it->inputs == NULL) {
1746 printf("uaudio_io_terminaltype: no memory\n");
1747 return NULL;
1748 }
1749 tml = malloc(TERMINAL_LIST_SIZE(1), M_TEMP, M_NOWAIT);
1750 if (tml == NULL) {
1751 printf("uaudio_io_terminaltype: no memory\n");
1752 free(it->inputs, M_TEMP);
1753 it->inputs = NULL;
1754 return NULL;
1755 }
1756 it->inputs[0] = tml;
1757 tml->terminals[0] = UGETW(it->d.it->wTerminalType);
1758 tml->size = 1;
1759 it->inputs_size = 1;
1760 return uaudio_merge_terminal_list(it);
1761 case UDESCSUB_AC_FEATURE:
1762 src_id = it->d.fu->bSourceId;
1763 it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT);
1764 if (it->inputs == NULL) {
1765 printf("uaudio_io_terminaltype: no memory\n");
1766 return uaudio_io_terminaltype(outtype, iot, src_id);
1767 }
1768 it->inputs[0] = uaudio_io_terminaltype(outtype, iot, src_id);
1769 it->inputs_size = 1;
1770 return uaudio_merge_terminal_list(it);
1771 case UDESCSUB_AC_OUTPUT:
1772 it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT);
1773 if (it->inputs == NULL) {
1774 printf("uaudio_io_terminaltype: no memory\n");
1775 return NULL;
1776 }
1777 src_id = it->d.ot->bSourceId;
1778 it->inputs[0] = uaudio_io_terminaltype(outtype, iot, src_id);
1779 it->inputs_size = 1;
1780 iot[src_id].direct = TRUE;
1781 return NULL;
1782 case UDESCSUB_AC_MIXER:
1783 it->inputs_size = 0;
1784 it->inputs = malloc(sizeof(struct terminal_list *)
1785 * it->d.mu->bNrInPins, M_TEMP, M_NOWAIT);
1786 if (it->inputs == NULL) {
1787 printf("uaudio_io_terminaltype: no memory\n");
1788 return NULL;
1789 }
1790 for (i = 0; i < it->d.mu->bNrInPins; i++) {
1791 src_id = it->d.mu->baSourceId[i];
1792 it->inputs[i] = uaudio_io_terminaltype(outtype, iot,
1793 src_id);
1794 it->inputs_size++;
1795 }
1796 return uaudio_merge_terminal_list(it);
1797 case UDESCSUB_AC_SELECTOR:
1798 it->inputs_size = 0;
1799 it->inputs = malloc(sizeof(struct terminal_list *)
1800 * it->d.su->bNrInPins, M_TEMP, M_NOWAIT);
1801 if (it->inputs == NULL) {
1802 printf("uaudio_io_terminaltype: no memory\n");
1803 return NULL;
1804 }
1805 for (i = 0; i < it->d.su->bNrInPins; i++) {
1806 src_id = it->d.su->baSourceId[i];
1807 it->inputs[i] = uaudio_io_terminaltype(outtype, iot,
1808 src_id);
1809 it->inputs_size++;
1810 }
1811 return uaudio_merge_terminal_list(it);
1812 case UDESCSUB_AC_PROCESSING:
1813 it->inputs_size = 0;
1814 it->inputs = malloc(sizeof(struct terminal_list *)
1815 * it->d.pu->bNrInPins, M_TEMP, M_NOWAIT);
1816 if (it->inputs == NULL) {
1817 printf("uaudio_io_terminaltype: no memory\n");
1818 return NULL;
1819 }
1820 for (i = 0; i < it->d.pu->bNrInPins; i++) {
1821 src_id = it->d.pu->baSourceId[i];
1822 it->inputs[i] = uaudio_io_terminaltype(outtype, iot,
1823 src_id);
1824 it->inputs_size++;
1825 }
1826 return uaudio_merge_terminal_list(it);
1827 case UDESCSUB_AC_EXTENSION:
1828 it->inputs_size = 0;
1829 it->inputs = malloc(sizeof(struct terminal_list *)
1830 * it->d.eu->bNrInPins, M_TEMP, M_NOWAIT);
1831 if (it->inputs == NULL) {
1832 printf("uaudio_io_terminaltype: no memory\n");
1833 return NULL;
1834 }
1835 for (i = 0; i < it->d.eu->bNrInPins; i++) {
1836 src_id = it->d.eu->baSourceId[i];
1837 it->inputs[i] = uaudio_io_terminaltype(outtype, iot,
1838 src_id);
1839 it->inputs_size++;
1840 }
1841 return uaudio_merge_terminal_list(it);
1842 case UDESCSUB_AC_HEADER:
1843 default:
1844 return NULL;
1845 }
1846 }
1847
1848 Static usbd_status
1849 uaudio_identify(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc)
1850 {
1851 usbd_status err;
1852
1853 err = uaudio_identify_ac(sc, cdesc);
1854 if (err)
1855 return (err);
1856 return (uaudio_identify_as(sc, cdesc));
1857 }
1858
1859 Static void
1860 uaudio_add_alt(struct uaudio_softc *sc, const struct as_info *ai)
1861 {
1862 size_t len;
1863 struct as_info *nai;
1864
1865 len = sizeof(*ai) * (sc->sc_nalts + 1);
1866 nai = malloc(len, M_USBDEV, M_NOWAIT);
1867 if (nai == NULL) {
1868 printf("uaudio_add_alt: no memory\n");
1869 return;
1870 }
1871 /* Copy old data, if there was any */
1872 if (sc->sc_nalts != 0) {
1873 memcpy(nai, sc->sc_alts, sizeof(*ai) * (sc->sc_nalts));
1874 free(sc->sc_alts, M_USBDEV);
1875 }
1876 sc->sc_alts = nai;
1877 DPRINTFN(2,("uaudio_add_alt: adding alt=%d, enc=%d\n",
1878 ai->alt, ai->encoding));
1879 sc->sc_alts[sc->sc_nalts++] = *ai;
1880 }
1881
1882 Static usbd_status
1883 uaudio_process_as(struct uaudio_softc *sc, const char *buf, int *offsp,
1884 int size, const usb_interface_descriptor_t *id)
1885 #define offs (*offsp)
1886 {
1887 const struct usb_audio_streaming_interface_descriptor *asid;
1888 const struct usb_audio_streaming_type1_descriptor *asf1d;
1889 const usb_endpoint_descriptor_audio_t *ed;
1890 const usb_endpoint_descriptor_audio_t *epdesc1;
1891 const struct usb_audio_streaming_endpoint_descriptor *sed;
1892 int format, chan, prec, enc;
1893 int dir, type, sync;
1894 struct as_info ai;
1895 const char *format_str;
1896
1897 asid = (const void *)(buf + offs);
1898 if (asid->bDescriptorType != UDESC_CS_INTERFACE ||
1899 asid->bDescriptorSubtype != AS_GENERAL)
1900 return (USBD_INVAL);
1901 DPRINTF(("uaudio_process_as: asid: bTerminakLink=%d wFormatTag=%d\n",
1902 asid->bTerminalLink, UGETW(asid->wFormatTag)));
1903 offs += asid->bLength;
1904 if (offs > size)
1905 return (USBD_INVAL);
1906
1907 asf1d = (const void *)(buf + offs);
1908 if (asf1d->bDescriptorType != UDESC_CS_INTERFACE ||
1909 asf1d->bDescriptorSubtype != FORMAT_TYPE)
1910 return (USBD_INVAL);
1911 offs += asf1d->bLength;
1912 if (offs > size)
1913 return (USBD_INVAL);
1914
1915 if (asf1d->bFormatType != FORMAT_TYPE_I) {
1916 printf("%s: ignored setting with type %d format\n",
1917 USBDEVNAME(sc->sc_dev), UGETW(asid->wFormatTag));
1918 return (USBD_NORMAL_COMPLETION);
1919 }
1920
1921 ed = (const void *)(buf + offs);
1922 if (ed->bDescriptorType != UDESC_ENDPOINT)
1923 return (USBD_INVAL);
1924 DPRINTF(("uaudio_process_as: endpoint[0] bLength=%d bDescriptorType=%d "
1925 "bEndpointAddress=%d bmAttributes=0x%x wMaxPacketSize=%d "
1926 "bInterval=%d bRefresh=%d bSynchAddress=%d\n",
1927 ed->bLength, ed->bDescriptorType, ed->bEndpointAddress,
1928 ed->bmAttributes, UGETW(ed->wMaxPacketSize),
1929 ed->bInterval, ed->bRefresh, ed->bSynchAddress));
1930 offs += ed->bLength;
1931 if (offs > size)
1932 return (USBD_INVAL);
1933 if (UE_GET_XFERTYPE(ed->bmAttributes) != UE_ISOCHRONOUS)
1934 return (USBD_INVAL);
1935
1936 dir = UE_GET_DIR(ed->bEndpointAddress);
1937 type = UE_GET_ISO_TYPE(ed->bmAttributes);
1938 if ((usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_INP_ASYNC) &&
1939 dir == UE_DIR_IN && type == UE_ISO_ADAPT)
1940 type = UE_ISO_ASYNC;
1941
1942 /* We can't handle endpoints that need a sync pipe yet. */
1943 sync = FALSE;
1944 if (dir == UE_DIR_IN && type == UE_ISO_ADAPT) {
1945 sync = TRUE;
1946 #ifndef UAUDIO_MULTIPLE_ENDPOINTS
1947 printf("%s: ignored input endpoint of type adaptive\n",
1948 USBDEVNAME(sc->sc_dev));
1949 return (USBD_NORMAL_COMPLETION);
1950 #endif
1951 }
1952 if (dir != UE_DIR_IN && type == UE_ISO_ASYNC) {
1953 sync = TRUE;
1954 #ifndef UAUDIO_MULTIPLE_ENDPOINTS
1955 printf("%s: ignored output endpoint of type async\n",
1956 USBDEVNAME(sc->sc_dev));
1957 return (USBD_NORMAL_COMPLETION);
1958 #endif
1959 }
1960
1961 sed = (const void *)(buf + offs);
1962 if (sed->bDescriptorType != UDESC_CS_ENDPOINT ||
1963 sed->bDescriptorSubtype != AS_GENERAL)
1964 return (USBD_INVAL);
1965 DPRINTF((" streadming_endpoint: offset=%d bLength=%d\n", offs, sed->bLength));
1966 offs += sed->bLength;
1967 if (offs > size)
1968 return (USBD_INVAL);
1969
1970 if (sync && id->bNumEndpoints <= 1) {
1971 printf("%s: a sync-pipe endpoint but no other endpoint\n",
1972 USBDEVNAME(sc->sc_dev));
1973 return USBD_INVAL;
1974 }
1975 if (!sync && id->bNumEndpoints > 1) {
1976 printf("%s: non sync-pipe endpoint but multiple endpoints\n",
1977 USBDEVNAME(sc->sc_dev));
1978 return USBD_INVAL;
1979 }
1980 epdesc1 = NULL;
1981 if (id->bNumEndpoints > 1) {
1982 epdesc1 = (const void*)(buf + offs);
1983 if (epdesc1->bDescriptorType != UDESC_ENDPOINT)
1984 return USBD_INVAL;
1985 DPRINTF(("uaudio_process_as: endpoint[1] bLength=%d "
1986 "bDescriptorType=%d bEndpointAddress=%d "
1987 "bmAttributes=0x%x wMaxPacketSize=%d bInterval=%d "
1988 "bRefresh=%d bSynchAddress=%d\n",
1989 epdesc1->bLength, epdesc1->bDescriptorType,
1990 epdesc1->bEndpointAddress, epdesc1->bmAttributes,
1991 UGETW(epdesc1->wMaxPacketSize), epdesc1->bInterval,
1992 epdesc1->bRefresh, epdesc1->bSynchAddress));
1993 offs += epdesc1->bLength;
1994 if (offs > size)
1995 return USBD_INVAL;
1996 if (epdesc1->bSynchAddress != 0) {
1997 printf("%s: invalid endpoint: bSynchAddress=0\n",
1998 USBDEVNAME(sc->sc_dev));
1999 return USBD_INVAL;
2000 }
2001 if (UE_GET_XFERTYPE(epdesc1->bmAttributes) != UE_ISOCHRONOUS) {
2002 printf("%s: invalid endpoint: bmAttributes=0x%x\n",
2003 USBDEVNAME(sc->sc_dev), epdesc1->bmAttributes);
2004 return USBD_INVAL;
2005 }
2006 if (epdesc1->bEndpointAddress != ed->bSynchAddress) {
2007 printf("%s: invalid endpoint addresses: "
2008 "ep[0]->bSynchAddress=0x%x "
2009 "ep[1]->bEndpointAddress=0x%x\n",
2010 USBDEVNAME(sc->sc_dev), ed->bSynchAddress,
2011 epdesc1->bEndpointAddress);
2012 return USBD_INVAL;
2013 }
2014 /* UE_GET_ADDR(epdesc1->bEndpointAddress), and epdesc1->bRefresh */
2015 }
2016
2017 format = UGETW(asid->wFormatTag);
2018 chan = asf1d->bNrChannels;
2019 prec = asf1d->bBitResolution;
2020 if (prec != 8 && prec != 16 && prec != 24) {
2021 printf("%s: ignored setting with precision %d\n",
2022 USBDEVNAME(sc->sc_dev), prec);
2023 return (USBD_NORMAL_COMPLETION);
2024 }
2025 switch (format) {
2026 case UA_FMT_PCM:
2027 if (prec == 8) {
2028 sc->sc_altflags |= HAS_8;
2029 } else if (prec == 16) {
2030 sc->sc_altflags |= HAS_16;
2031 } else if (prec == 24) {
2032 sc->sc_altflags |= HAS_24;
2033 }
2034 enc = AUDIO_ENCODING_SLINEAR_LE;
2035 format_str = "pcm";
2036 break;
2037 case UA_FMT_PCM8:
2038 enc = AUDIO_ENCODING_ULINEAR_LE;
2039 sc->sc_altflags |= HAS_8U;
2040 format_str = "pcm8";
2041 break;
2042 case UA_FMT_ALAW:
2043 enc = AUDIO_ENCODING_ALAW;
2044 sc->sc_altflags |= HAS_ALAW;
2045 format_str = "alaw";
2046 break;
2047 case UA_FMT_MULAW:
2048 enc = AUDIO_ENCODING_ULAW;
2049 sc->sc_altflags |= HAS_MULAW;
2050 format_str = "mulaw";
2051 break;
2052 case UA_FMT_IEEE_FLOAT:
2053 default:
2054 printf("%s: ignored setting with format %d\n",
2055 USBDEVNAME(sc->sc_dev), format);
2056 return (USBD_NORMAL_COMPLETION);
2057 }
2058 #ifdef USB_DEBUG
2059 printf("%s: %s: %dch, %d/%dbit, %s,", USBDEVNAME(sc->sc_dev),
2060 dir == UE_DIR_IN ? "recording" : "playback",
2061 chan, prec, asf1d->bSubFrameSize * 8, format_str);
2062 if (asf1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
2063 printf(" %d-%dHz\n", UA_SAMP_LO(asf1d), UA_SAMP_HI(asf1d));
2064 } else {
2065 int r;
2066 printf(" %d", UA_GETSAMP(asf1d, 0));
2067 for (r = 1; r < asf1d->bSamFreqType; r++)
2068 printf(",%d", UA_GETSAMP(asf1d, r));
2069 printf("Hz\n");
2070 }
2071 #endif
2072 ai.alt = id->bAlternateSetting;
2073 ai.encoding = enc;
2074 ai.attributes = sed->bmAttributes;
2075 ai.idesc = id;
2076 ai.edesc = ed;
2077 ai.edesc1 = epdesc1;
2078 ai.asf1desc = asf1d;
2079 ai.sc_busy = 0;
2080 uaudio_add_alt(sc, &ai);
2081 #ifdef USB_DEBUG
2082 if (ai.attributes & UA_SED_FREQ_CONTROL)
2083 DPRINTFN(1, ("uaudio_process_as: FREQ_CONTROL\n"));
2084 if (ai.attributes & UA_SED_PITCH_CONTROL)
2085 DPRINTFN(1, ("uaudio_process_as: PITCH_CONTROL\n"));
2086 #endif
2087 sc->sc_mode |= (dir == UE_DIR_OUT) ? AUMODE_PLAY : AUMODE_RECORD;
2088
2089 return (USBD_NORMAL_COMPLETION);
2090 }
2091 #undef offs
2092
2093 Static usbd_status
2094 uaudio_identify_as(struct uaudio_softc *sc,
2095 const usb_config_descriptor_t *cdesc)
2096 {
2097 const usb_interface_descriptor_t *id;
2098 const char *buf;
2099 int size, offs;
2100
2101 size = UGETW(cdesc->wTotalLength);
2102 buf = (const char *)cdesc;
2103
2104 /* Locate the AudioStreaming interface descriptor. */
2105 offs = 0;
2106 id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOSTREAM);
2107 if (id == NULL)
2108 return (USBD_INVAL);
2109
2110 /* Loop through all the alternate settings. */
2111 while (offs <= size) {
2112 DPRINTFN(2, ("uaudio_identify: interface=%d offset=%d\n",
2113 id->bInterfaceNumber, offs));
2114 switch (id->bNumEndpoints) {
2115 case 0:
2116 DPRINTFN(2, ("uaudio_identify: AS null alt=%d\n",
2117 id->bAlternateSetting));
2118 sc->sc_nullalt = id->bAlternateSetting;
2119 break;
2120 case 1:
2121 #ifdef UAUDIO_MULTIPLE_ENDPOINTS
2122 case 2:
2123 #endif
2124 uaudio_process_as(sc, buf, &offs, size, id);
2125 break;
2126 default:
2127 printf("%s: ignored audio interface with %d "
2128 "endpoints\n",
2129 USBDEVNAME(sc->sc_dev), id->bNumEndpoints);
2130 break;
2131 }
2132 id = uaudio_find_iface(buf, size, &offs,UISUBCLASS_AUDIOSTREAM);
2133 if (id == NULL)
2134 break;
2135 }
2136 if (offs > size)
2137 return (USBD_INVAL);
2138 DPRINTF(("uaudio_identify_as: %d alts available\n", sc->sc_nalts));
2139
2140 if (sc->sc_mode == 0) {
2141 printf("%s: no usable endpoint found\n",
2142 USBDEVNAME(sc->sc_dev));
2143 return (USBD_INVAL);
2144 }
2145
2146 return (USBD_NORMAL_COMPLETION);
2147 }
2148
2149 Static usbd_status
2150 uaudio_identify_ac(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc)
2151 {
2152 struct io_terminal* iot;
2153 const usb_interface_descriptor_t *id;
2154 const struct usb_audio_control_descriptor *acdp;
2155 const usb_descriptor_t *dp;
2156 const struct usb_audio_output_terminal *pot;
2157 struct terminal_list *tml;
2158 const char *buf, *ibuf, *ibufend;
2159 int size, offs, aclen, ndps, i, j;
2160
2161 size = UGETW(cdesc->wTotalLength);
2162 buf = (const char *)cdesc;
2163
2164 /* Locate the AudioControl interface descriptor. */
2165 offs = 0;
2166 id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOCONTROL);
2167 if (id == NULL)
2168 return (USBD_INVAL);
2169 if (offs + sizeof *acdp > size)
2170 return (USBD_INVAL);
2171 sc->sc_ac_iface = id->bInterfaceNumber;
2172 DPRINTFN(2,("uaudio_identify_ac: AC interface is %d\n", sc->sc_ac_iface));
2173
2174 /* A class-specific AC interface header should follow. */
2175 ibuf = buf + offs;
2176 acdp = (const struct usb_audio_control_descriptor *)ibuf;
2177 if (acdp->bDescriptorType != UDESC_CS_INTERFACE ||
2178 acdp->bDescriptorSubtype != UDESCSUB_AC_HEADER)
2179 return (USBD_INVAL);
2180 aclen = UGETW(acdp->wTotalLength);
2181 if (offs + aclen > size)
2182 return (USBD_INVAL);
2183
2184 if (!(usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_BAD_ADC) &&
2185 UGETW(acdp->bcdADC) != UAUDIO_VERSION)
2186 return (USBD_INVAL);
2187
2188 sc->sc_audio_rev = UGETW(acdp->bcdADC);
2189 DPRINTFN(2,("uaudio_identify_ac: found AC header, vers=%03x, len=%d\n",
2190 sc->sc_audio_rev, aclen));
2191
2192 sc->sc_nullalt = -1;
2193
2194 /* Scan through all the AC specific descriptors */
2195 ibufend = ibuf + aclen;
2196 dp = (const usb_descriptor_t *)ibuf;
2197 ndps = 0;
2198 iot = malloc(sizeof(struct io_terminal) * 256, M_TEMP, M_NOWAIT | M_ZERO);
2199 if (iot == NULL) {
2200 printf("%s: no memory\n", __func__);
2201 return USBD_NOMEM;
2202 }
2203 for (;;) {
2204 ibuf += dp->bLength;
2205 if (ibuf >= ibufend)
2206 break;
2207 dp = (const usb_descriptor_t *)ibuf;
2208 if (ibuf + dp->bLength > ibufend)
2209 return (USBD_INVAL);
2210 if (dp->bDescriptorType != UDESC_CS_INTERFACE) {
2211 printf("uaudio_identify_ac: skip desc type=0x%02x\n",
2212 dp->bDescriptorType);
2213 continue;
2214 }
2215 i = ((const struct usb_audio_input_terminal *)dp)->bTerminalId;
2216 iot[i].d.desc = dp;
2217 if (i > ndps)
2218 ndps = i;
2219 }
2220 ndps++;
2221
2222 /* construct io_terminal */
2223 for (i = 0; i < ndps; i++) {
2224 dp = iot[i].d.desc;
2225 if (dp == NULL)
2226 continue;
2227 if (dp->bDescriptorSubtype != UDESCSUB_AC_OUTPUT)
2228 continue;
2229 pot = iot[i].d.ot;
2230 tml = uaudio_io_terminaltype(UGETW(pot->wTerminalType), iot, i);
2231 if (tml != NULL)
2232 free(tml, M_TEMP);
2233 }
2234
2235 #ifdef USB_DEBUG
2236 for (i = 0; i < 256; i++) {
2237 struct usb_audio_cluster cluster;
2238
2239 if (iot[i].d.desc == NULL)
2240 continue;
2241 logprintf("id %d:\t", i);
2242 switch (iot[i].d.desc->bDescriptorSubtype) {
2243 case UDESCSUB_AC_INPUT:
2244 logprintf("AC_INPUT type=%s\n", uaudio_get_terminal_name
2245 (UGETW(iot[i].d.it->wTerminalType)));
2246 logprintf("\t");
2247 cluster = uaudio_get_cluster(i, iot);
2248 uaudio_dump_cluster(&cluster);
2249 logprintf("\n");
2250 break;
2251 case UDESCSUB_AC_OUTPUT:
2252 logprintf("AC_OUTPUT type=%s ", uaudio_get_terminal_name
2253 (UGETW(iot[i].d.ot->wTerminalType)));
2254 logprintf("src=%d\n", iot[i].d.ot->bSourceId);
2255 break;
2256 case UDESCSUB_AC_MIXER:
2257 logprintf("AC_MIXER src=");
2258 for (j = 0; j < iot[i].d.mu->bNrInPins; j++)
2259 logprintf("%d ", iot[i].d.mu->baSourceId[j]);
2260 logprintf("\n\t");
2261 cluster = uaudio_get_cluster(i, iot);
2262 uaudio_dump_cluster(&cluster);
2263 logprintf("\n");
2264 break;
2265 case UDESCSUB_AC_SELECTOR:
2266 logprintf("AC_SELECTOR src=");
2267 for (j = 0; j < iot[i].d.su->bNrInPins; j++)
2268 logprintf("%d ", iot[i].d.su->baSourceId[j]);
2269 logprintf("\n");
2270 break;
2271 case UDESCSUB_AC_FEATURE:
2272 logprintf("AC_FEATURE src=%d\n", iot[i].d.fu->bSourceId);
2273 break;
2274 case UDESCSUB_AC_PROCESSING:
2275 logprintf("AC_PROCESSING src=");
2276 for (j = 0; j < iot[i].d.pu->bNrInPins; j++)
2277 logprintf("%d ", iot[i].d.pu->baSourceId[j]);
2278 logprintf("\n\t");
2279 cluster = uaudio_get_cluster(i, iot);
2280 uaudio_dump_cluster(&cluster);
2281 logprintf("\n");
2282 break;
2283 case UDESCSUB_AC_EXTENSION:
2284 logprintf("AC_EXTENSION src=");
2285 for (j = 0; j < iot[i].d.eu->bNrInPins; j++)
2286 logprintf("%d ", iot[i].d.eu->baSourceId[j]);
2287 logprintf("\n\t");
2288 cluster = uaudio_get_cluster(i, iot);
2289 uaudio_dump_cluster(&cluster);
2290 logprintf("\n");
2291 break;
2292 default:
2293 logprintf("unknown audio control (subtype=%d)\n",
2294 iot[i].d.desc->bDescriptorSubtype);
2295 }
2296 for (j = 0; j < iot[i].inputs_size; j++) {
2297 int k;
2298 logprintf("\tinput%d: ", j);
2299 tml = iot[i].inputs[j];
2300 if (tml == NULL) {
2301 logprintf("NULL\n");
2302 continue;
2303 }
2304 for (k = 0; k < tml->size; k++)
2305 logprintf("%s ", uaudio_get_terminal_name
2306 (tml->terminals[k]));
2307 logprintf("\n");
2308 }
2309 logprintf("\toutput: ");
2310 tml = iot[i].output;
2311 for (j = 0; j < tml->size; j++)
2312 logprintf("%s ", uaudio_get_terminal_name(tml->terminals[j]));
2313 logprintf("\n");
2314 }
2315 #endif
2316
2317 for (i = 0; i < ndps; i++) {
2318 dp = iot[i].d.desc;
2319 if (dp == NULL)
2320 continue;
2321 DPRINTF(("uaudio_identify_ac: id=%d subtype=%d\n",
2322 i, dp->bDescriptorSubtype));
2323 switch (dp->bDescriptorSubtype) {
2324 case UDESCSUB_AC_HEADER:
2325 printf("uaudio_identify_ac: unexpected AC header\n");
2326 break;
2327 case UDESCSUB_AC_INPUT:
2328 uaudio_add_input(sc, iot, i);
2329 break;
2330 case UDESCSUB_AC_OUTPUT:
2331 uaudio_add_output(sc, iot, i);
2332 break;
2333 case UDESCSUB_AC_MIXER:
2334 uaudio_add_mixer(sc, iot, i);
2335 break;
2336 case UDESCSUB_AC_SELECTOR:
2337 uaudio_add_selector(sc, iot, i);
2338 break;
2339 case UDESCSUB_AC_FEATURE:
2340 uaudio_add_feature(sc, iot, i);
2341 break;
2342 case UDESCSUB_AC_PROCESSING:
2343 uaudio_add_processing(sc, iot, i);
2344 break;
2345 case UDESCSUB_AC_EXTENSION:
2346 uaudio_add_extension(sc, iot, i);
2347 break;
2348 default:
2349 printf("uaudio_identify_ac: bad AC desc subtype=0x%02x\n",
2350 dp->bDescriptorSubtype);
2351 break;
2352 }
2353 }
2354
2355 /* delete io_terminal */
2356 for (i = 0; i < 256; i++) {
2357 if (iot[i].d.desc == NULL)
2358 continue;
2359 if (iot[i].inputs != NULL) {
2360 for (j = 0; j < iot[i].inputs_size; j++) {
2361 if (iot[i].inputs[j] != NULL)
2362 free(iot[i].inputs[j], M_TEMP);
2363 }
2364 free(iot[i].inputs, M_TEMP);
2365 }
2366 if (iot[i].output != NULL)
2367 free(iot[i].output, M_TEMP);
2368 iot[i].d.desc = NULL;
2369 }
2370 free(iot, M_TEMP);
2371
2372 return (USBD_NORMAL_COMPLETION);
2373 }
2374
2375 #if defined(__NetBSD__) || defined(__OpenBSD__)
2376 Static int
2377 uaudio_query_devinfo(void *addr, mixer_devinfo_t *mi)
2378 {
2379 struct uaudio_softc *sc = addr;
2380 struct mixerctl *mc;
2381 int n, nctls, i;
2382
2383 DPRINTFN(2,("uaudio_query_devinfo: index=%d\n", mi->index));
2384 if (sc->sc_dying)
2385 return (EIO);
2386
2387 n = mi->index;
2388 nctls = sc->sc_nctls;
2389
2390 switch (n) {
2391 case UAC_OUTPUT:
2392 mi->type = AUDIO_MIXER_CLASS;
2393 mi->mixer_class = UAC_OUTPUT;
2394 mi->next = mi->prev = AUDIO_MIXER_LAST;
2395 strlcpy(mi->label.name, AudioCoutputs, sizeof(mi->label.name));
2396 return (0);
2397 case UAC_INPUT:
2398 mi->type = AUDIO_MIXER_CLASS;
2399 mi->mixer_class = UAC_INPUT;
2400 mi->next = mi->prev = AUDIO_MIXER_LAST;
2401 strlcpy(mi->label.name, AudioCinputs, sizeof(mi->label.name));
2402 return (0);
2403 case UAC_EQUAL:
2404 mi->type = AUDIO_MIXER_CLASS;
2405 mi->mixer_class = UAC_EQUAL;
2406 mi->next = mi->prev = AUDIO_MIXER_LAST;
2407 strlcpy(mi->label.name, AudioCequalization,
2408 sizeof(mi->label.name));
2409 return (0);
2410 case UAC_RECORD:
2411 mi->type = AUDIO_MIXER_CLASS;
2412 mi->mixer_class = UAC_RECORD;
2413 mi->next = mi->prev = AUDIO_MIXER_LAST;
2414 strlcpy(mi->label.name, AudioCrecord, sizeof(mi->label.name));
2415 return 0;
2416 default:
2417 break;
2418 }
2419
2420 n -= UAC_NCLASSES;
2421 if (n < 0 || n >= nctls)
2422 return (ENXIO);
2423
2424 mc = &sc->sc_ctls[n];
2425 strlcpy(mi->label.name, mc->ctlname, sizeof(mi->label.name));
2426 mi->mixer_class = mc->class;
2427 mi->next = mi->prev = AUDIO_MIXER_LAST; /* XXX */
2428 switch (mc->type) {
2429 case MIX_ON_OFF:
2430 mi->type = AUDIO_MIXER_ENUM;
2431 mi->un.e.num_mem = 2;
2432 strlcpy(mi->un.e.member[0].label.name, AudioNoff,
2433 sizeof(mi->un.e.member[0].label.name));
2434 mi->un.e.member[0].ord = 0;
2435 strlcpy(mi->un.e.member[1].label.name, AudioNon,
2436 sizeof(mi->un.e.member[1].label.name));
2437 mi->un.e.member[1].ord = 1;
2438 break;
2439 case MIX_SELECTOR:
2440 mi->type = AUDIO_MIXER_ENUM;
2441 mi->un.e.num_mem = mc->maxval - mc->minval + 1;
2442 for (i = 0; i <= mc->maxval - mc->minval; i++) {
2443 snprintf(mi->un.e.member[i].label.name,
2444 sizeof(mi->un.e.member[i].label.name),
2445 "%d", i + mc->minval);
2446 mi->un.e.member[i].ord = i + mc->minval;
2447 }
2448 break;
2449 default:
2450 mi->type = AUDIO_MIXER_VALUE;
2451 strncpy(mi->un.v.units.name, mc->ctlunit, MAX_AUDIO_DEV_LEN);
2452 mi->un.v.num_channels = mc->nchan;
2453 mi->un.v.delta = mc->delta;
2454 break;
2455 }
2456 return (0);
2457 }
2458
2459 Static int
2460 uaudio_open(void *addr, int flags)
2461 {
2462 struct uaudio_softc *sc = addr;
2463
2464 DPRINTF(("uaudio_open: sc=%p\n", sc));
2465 if (sc->sc_dying)
2466 return (EIO);
2467
2468 if ((flags & FWRITE) && !(sc->sc_mode & AUMODE_PLAY))
2469 return (EACCES);
2470 if ((flags & FREAD) && !(sc->sc_mode & AUMODE_RECORD))
2471 return (EACCES);
2472
2473 return (0);
2474 }
2475
2476 /*
2477 * Close function is called at splaudio().
2478 */
2479 Static void
2480 uaudio_close(void *addr)
2481 {
2482 }
2483
2484 Static int
2485 uaudio_drain(void *addr)
2486 {
2487 struct uaudio_softc *sc = addr;
2488
2489 usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES);
2490
2491 return (0);
2492 }
2493
2494 Static int
2495 uaudio_halt_out_dma(void *addr)
2496 {
2497 struct uaudio_softc *sc = addr;
2498
2499 if (sc->sc_dying)
2500 return (EIO);
2501
2502 DPRINTF(("uaudio_halt_out_dma: enter\n"));
2503 if (sc->sc_playchan.pipe != NULL) {
2504 uaudio_chan_close(sc, &sc->sc_playchan);
2505 sc->sc_playchan.pipe = NULL;
2506 uaudio_chan_free_buffers(sc, &sc->sc_playchan);
2507 sc->sc_playchan.intr = NULL;
2508 }
2509 return (0);
2510 }
2511
2512 Static int
2513 uaudio_halt_in_dma(void *addr)
2514 {
2515 struct uaudio_softc *sc = addr;
2516
2517 DPRINTF(("uaudio_halt_in_dma: enter\n"));
2518 if (sc->sc_recchan.pipe != NULL) {
2519 uaudio_chan_close(sc, &sc->sc_recchan);
2520 sc->sc_recchan.pipe = NULL;
2521 uaudio_chan_free_buffers(sc, &sc->sc_recchan);
2522 sc->sc_recchan.intr = NULL;
2523 }
2524 return (0);
2525 }
2526
2527 Static int
2528 uaudio_getdev(void *addr, struct audio_device *retp)
2529 {
2530 struct uaudio_softc *sc = addr;
2531
2532 DPRINTF(("uaudio_mixer_getdev:\n"));
2533 if (sc->sc_dying)
2534 return (EIO);
2535
2536 *retp = uaudio_device;
2537 return (0);
2538 }
2539
2540 /*
2541 * Make sure the block size is large enough to hold all outstanding transfers.
2542 */
2543 Static int
2544 uaudio_round_blocksize(void *addr, int blk)
2545 {
2546 struct uaudio_softc *sc = addr;
2547 int bpf;
2548
2549 DPRINTF(("uaudio_round_blocksize: p.bpf=%d r.bpf=%d\n",
2550 sc->sc_playchan.bytes_per_frame,
2551 sc->sc_recchan.bytes_per_frame));
2552 if (sc->sc_playchan.bytes_per_frame > sc->sc_recchan.bytes_per_frame) {
2553 bpf = sc->sc_playchan.bytes_per_frame
2554 + sc->sc_playchan.sample_size;
2555 } else {
2556 bpf = sc->sc_recchan.bytes_per_frame
2557 + sc->sc_recchan.sample_size;
2558 }
2559 /* XXX */
2560 bpf *= UAUDIO_NFRAMES * UAUDIO_NCHANBUFS;
2561
2562 bpf = (bpf + 15) &~ 15;
2563
2564 if (blk < bpf)
2565 blk = bpf;
2566
2567 #ifdef DIAGNOSTIC
2568 if (blk <= 0) {
2569 printf("uaudio_round_blocksize: blk=%d\n", blk);
2570 blk = 512;
2571 }
2572 #endif
2573
2574 DPRINTFN(1,("uaudio_round_blocksize: blk=%d\n", blk));
2575 return (blk);
2576 }
2577
2578 Static int
2579 uaudio_get_props(void *addr)
2580 {
2581 return (AUDIO_PROP_FULLDUPLEX | AUDIO_PROP_INDEPENDENT);
2582
2583 }
2584 #endif /* NetBSD or OpenBSD */
2585
2586 Static int
2587 uaudio_get(struct uaudio_softc *sc, int which, int type, int wValue,
2588 int wIndex, int len)
2589 {
2590 usb_device_request_t req;
2591 u_int8_t data[4];
2592 usbd_status err;
2593 int val;
2594
2595 #if defined(__FreeBSD__)
2596 if (sc->sc_dying)
2597 return (EIO);
2598 #endif
2599
2600 if (wValue == -1)
2601 return (0);
2602
2603 req.bmRequestType = type;
2604 req.bRequest = which;
2605 USETW(req.wValue, wValue);
2606 USETW(req.wIndex, wIndex);
2607 USETW(req.wLength, len);
2608 DPRINTFN(2,("uaudio_get: type=0x%02x req=0x%02x wValue=0x%04x "
2609 "wIndex=0x%04x len=%d\n",
2610 type, which, wValue, wIndex, len));
2611 err = usbd_do_request(sc->sc_udev, &req, data);
2612 if (err) {
2613 DPRINTF(("uaudio_get: err=%s\n", usbd_errstr(err)));
2614 return (-1);
2615 }
2616 switch (len) {
2617 case 1:
2618 val = data[0];
2619 break;
2620 case 2:
2621 val = data[0] | (data[1] << 8);
2622 break;
2623 default:
2624 DPRINTF(("uaudio_get: bad length=%d\n", len));
2625 return (-1);
2626 }
2627 DPRINTFN(2,("uaudio_get: val=%d\n", val));
2628 return (val);
2629 }
2630
2631 Static void
2632 uaudio_set(struct uaudio_softc *sc, int which, int type, int wValue,
2633 int wIndex, int len, int val)
2634 {
2635 usb_device_request_t req;
2636 u_int8_t data[4];
2637 usbd_status err;
2638
2639 #if defined(__FreeBSD__)
2640 if (sc->sc_dying)
2641 return;
2642 #endif
2643
2644 if (wValue == -1)
2645 return;
2646
2647 req.bmRequestType = type;
2648 req.bRequest = which;
2649 USETW(req.wValue, wValue);
2650 USETW(req.wIndex, wIndex);
2651 USETW(req.wLength, len);
2652 switch (len) {
2653 case 1:
2654 data[0] = val;
2655 break;
2656 case 2:
2657 data[0] = val;
2658 data[1] = val >> 8;
2659 break;
2660 default:
2661 return;
2662 }
2663 DPRINTFN(2,("uaudio_set: type=0x%02x req=0x%02x wValue=0x%04x "
2664 "wIndex=0x%04x len=%d, val=%d\n",
2665 type, which, wValue, wIndex, len, val & 0xffff));
2666 err = usbd_do_request(sc->sc_udev, &req, data);
2667 #ifdef USB_DEBUG
2668 if (err)
2669 DPRINTF(("uaudio_set: err=%d\n", err));
2670 #endif
2671 }
2672
2673 Static int
2674 uaudio_signext(int type, int val)
2675 {
2676 if (!MIX_UNSIGNED(type)) {
2677 if (MIX_SIZE(type) == 2)
2678 val = (int16_t)val;
2679 else
2680 val = (int8_t)val;
2681 }
2682 return (val);
2683 }
2684
2685 #if defined(__NetBSD__) || defined(__OpenBSD__)
2686 Static int
2687 uaudio_value2bsd(struct mixerctl *mc, int val)
2688 {
2689 DPRINTFN(5, ("uaudio_value2bsd: type=%03x val=%d min=%d max=%d ",
2690 mc->type, val, mc->minval, mc->maxval));
2691 if (mc->type == MIX_ON_OFF) {
2692 val = (val != 0);
2693 } else if (mc->type == MIX_SELECTOR) {
2694 if (val < mc->minval || val > mc->maxval)
2695 val = mc->minval;
2696 } else
2697 val = ((uaudio_signext(mc->type, val) - mc->minval) * 255
2698 + mc->mul/2) / mc->mul;
2699 DPRINTFN(5, ("val'=%d\n", val));
2700 return (val);
2701 }
2702 #endif
2703
2704 int
2705 uaudio_bsd2value(struct mixerctl *mc, int val)
2706 {
2707 DPRINTFN(5,("uaudio_bsd2value: type=%03x val=%d min=%d max=%d ",
2708 mc->type, val, mc->minval, mc->maxval));
2709 if (mc->type == MIX_ON_OFF) {
2710 val = (val != 0);
2711 } else if (mc->type == MIX_SELECTOR) {
2712 if (val < mc->minval || val > mc->maxval)
2713 val = mc->minval;
2714 } else
2715 val = (val + mc->delta/2) * mc->mul / 255 + mc->minval;
2716 DPRINTFN(5, ("val'=%d\n", val));
2717 return (val);
2718 }
2719
2720 #if defined(__NetBSD__) || defined(__OpenBSD__)
2721 Static int
2722 uaudio_ctl_get(struct uaudio_softc *sc, int which, struct mixerctl *mc,
2723 int chan)
2724 {
2725 int val;
2726
2727 DPRINTFN(5,("uaudio_ctl_get: which=%d chan=%d\n", which, chan));
2728 val = uaudio_get(sc, which, UT_READ_CLASS_INTERFACE, mc->wValue[chan],
2729 mc->wIndex, MIX_SIZE(mc->type));
2730 return (uaudio_value2bsd(mc, val));
2731 }
2732 #endif
2733
2734 Static void
2735 uaudio_ctl_set(struct uaudio_softc *sc, int which, struct mixerctl *mc,
2736 int chan, int val)
2737 {
2738 val = uaudio_bsd2value(mc, val);
2739 uaudio_set(sc, which, UT_WRITE_CLASS_INTERFACE, mc->wValue[chan],
2740 mc->wIndex, MIX_SIZE(mc->type), val);
2741 }
2742
2743 #if defined(__NetBSD__) || defined(__OpenBSD__)
2744 Static int
2745 uaudio_mixer_get_port(void *addr, mixer_ctrl_t *cp)
2746 {
2747 struct uaudio_softc *sc = addr;
2748 struct mixerctl *mc;
2749 int i, n, vals[MIX_MAX_CHAN], val;
2750
2751 DPRINTFN(2,("uaudio_mixer_get_port: index=%d\n", cp->dev));
2752
2753 if (sc->sc_dying)
2754 return (EIO);
2755
2756 n = cp->dev - UAC_NCLASSES;
2757 if (n < 0 || n >= sc->sc_nctls)
2758 return (ENXIO);
2759 mc = &sc->sc_ctls[n];
2760
2761 if (mc->type == MIX_ON_OFF) {
2762 if (cp->type != AUDIO_MIXER_ENUM)
2763 return (EINVAL);
2764 cp->un.ord = uaudio_ctl_get(sc, GET_CUR, mc, 0);
2765 } else if (mc->type == MIX_SELECTOR) {
2766 if (cp->type != AUDIO_MIXER_ENUM)
2767 return (EINVAL);
2768 cp->un.ord = uaudio_ctl_get(sc, GET_CUR, mc, 0);
2769 } else {
2770 if (cp->type != AUDIO_MIXER_VALUE)
2771 return (EINVAL);
2772 if (cp->un.value.num_channels != 1 &&
2773 cp->un.value.num_channels != mc->nchan)
2774 return (EINVAL);
2775 for (i = 0; i < mc->nchan; i++)
2776 vals[i] = uaudio_ctl_get(sc, GET_CUR, mc, i);
2777 if (cp->un.value.num_channels == 1 && mc->nchan != 1) {
2778 for (val = 0, i = 0; i < mc->nchan; i++)
2779 val += vals[i];
2780 vals[0] = val / mc->nchan;
2781 }
2782 for (i = 0; i < cp->un.value.num_channels; i++)
2783 cp->un.value.level[i] = vals[i];
2784 }
2785
2786 return (0);
2787 }
2788
2789 Static int
2790 uaudio_mixer_set_port(void *addr, mixer_ctrl_t *cp)
2791 {
2792 struct uaudio_softc *sc = addr;
2793 struct mixerctl *mc;
2794 int i, n, vals[MIX_MAX_CHAN];
2795
2796 DPRINTFN(2,("uaudio_mixer_set_port: index = %d\n", cp->dev));
2797 if (sc->sc_dying)
2798 return (EIO);
2799
2800 n = cp->dev - UAC_NCLASSES;
2801 if (n < 0 || n >= sc->sc_nctls)
2802 return (ENXIO);
2803 mc = &sc->sc_ctls[n];
2804
2805 if (mc->type == MIX_ON_OFF) {
2806 if (cp->type != AUDIO_MIXER_ENUM)
2807 return (EINVAL);
2808 uaudio_ctl_set(sc, SET_CUR, mc, 0, cp->un.ord);
2809 } else if (mc->type == MIX_SELECTOR) {
2810 if (cp->type != AUDIO_MIXER_ENUM)
2811 return (EINVAL);
2812 uaudio_ctl_set(sc, SET_CUR, mc, 0, cp->un.ord);
2813 } else {
2814 if (cp->type != AUDIO_MIXER_VALUE)
2815 return (EINVAL);
2816 if (cp->un.value.num_channels == 1)
2817 for (i = 0; i < mc->nchan; i++)
2818 vals[i] = cp->un.value.level[0];
2819 else if (cp->un.value.num_channels == mc->nchan)
2820 for (i = 0; i < mc->nchan; i++)
2821 vals[i] = cp->un.value.level[i];
2822 else
2823 return (EINVAL);
2824 for (i = 0; i < mc->nchan; i++)
2825 uaudio_ctl_set(sc, SET_CUR, mc, i, vals[i]);
2826 }
2827 return (0);
2828 }
2829
2830 Static int
2831 uaudio_trigger_input(void *addr, void *start, void *end, int blksize,
2832 void (*intr)(void *), void *arg,
2833 struct audio_params *param)
2834 {
2835 struct uaudio_softc *sc = addr;
2836 struct chan *ch = &sc->sc_recchan;
2837 usbd_status err;
2838 int i, s;
2839
2840 if (sc->sc_dying)
2841 return (EIO);
2842
2843 DPRINTFN(3,("uaudio_trigger_input: sc=%p start=%p end=%p "
2844 "blksize=%d\n", sc, start, end, blksize));
2845
2846 uaudio_chan_set_param(ch, start, end, blksize);
2847 DPRINTFN(3,("uaudio_trigger_input: sample_size=%d bytes/frame=%d "
2848 "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame,
2849 ch->fraction));
2850
2851 err = uaudio_chan_alloc_buffers(sc, ch);
2852 if (err)
2853 return (EIO);
2854
2855 err = uaudio_chan_open(sc, ch);
2856 if (err) {
2857 uaudio_chan_free_buffers(sc, ch);
2858 return (EIO);
2859 }
2860
2861 ch->intr = intr;
2862 ch->arg = arg;
2863
2864 s = splusb();
2865 for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX -1 shouldn't be needed */
2866 uaudio_chan_rtransfer(ch);
2867 splx(s);
2868
2869 return (0);
2870 }
2871
2872 Static int
2873 uaudio_trigger_output(void *addr, void *start, void *end, int blksize,
2874 void (*intr)(void *), void *arg,
2875 struct audio_params *param)
2876 {
2877 struct uaudio_softc *sc = addr;
2878 struct chan *ch = &sc->sc_playchan;
2879 usbd_status err;
2880 int i, s;
2881
2882 if (sc->sc_dying)
2883 return (EIO);
2884
2885 DPRINTFN(3,("uaudio_trigger_output: sc=%p start=%p end=%p "
2886 "blksize=%d\n", sc, start, end, blksize));
2887
2888 uaudio_chan_set_param(ch, start, end, blksize);
2889 DPRINTFN(3,("uaudio_trigger_output: sample_size=%d bytes/frame=%d "
2890 "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame,
2891 ch->fraction));
2892
2893 err = uaudio_chan_alloc_buffers(sc, ch);
2894 if (err)
2895 return (EIO);
2896
2897 err = uaudio_chan_open(sc, ch);
2898 if (err) {
2899 uaudio_chan_free_buffers(sc, ch);
2900 return (EIO);
2901 }
2902
2903 ch->intr = intr;
2904 ch->arg = arg;
2905
2906 s = splusb();
2907 for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX */
2908 uaudio_chan_ptransfer(ch);
2909 splx(s);
2910
2911 return (0);
2912 }
2913 #endif /* NetBSD or OpenBSD */
2914
2915 /* Set up a pipe for a channel. */
2916 Static usbd_status
2917 uaudio_chan_open(struct uaudio_softc *sc, struct chan *ch)
2918 {
2919 struct as_info *as = &sc->sc_alts[ch->altidx];
2920 int endpt = as->edesc->bEndpointAddress;
2921 usbd_status err;
2922
2923 #if defined(__FreeBSD__)
2924 if (sc->sc_dying)
2925 return (EIO);
2926 #endif
2927
2928 DPRINTF(("uaudio_chan_open: endpt=0x%02x, speed=%d, alt=%d\n",
2929 endpt, ch->sample_rate, as->alt));
2930
2931 /* Set alternate interface corresponding to the mode. */
2932 err = usbd_set_interface(as->ifaceh, as->alt);
2933 if (err)
2934 return (err);
2935
2936 /*
2937 * If just one sampling rate is supported,
2938 * no need to call uaudio_set_speed().
2939 * Roland SD-90 freezes by a SAMPLING_FREQ_CONTROL request.
2940 */
2941 if (as->asf1desc->bSamFreqType != 1) {
2942 err = uaudio_set_speed(sc, endpt, ch->sample_rate);
2943 if (err)
2944 DPRINTF(("uaudio_chan_open: set_speed failed err=%s\n",
2945 usbd_errstr(err)));
2946 }
2947
2948 ch->pipe = 0;
2949 ch->sync_pipe = 0;
2950 DPRINTF(("uaudio_chan_open: create pipe to 0x%02x\n", endpt));
2951 err = usbd_open_pipe(as->ifaceh, endpt, 0, &ch->pipe);
2952 if (err)
2953 return err;
2954 if (as->edesc1 != NULL) {
2955 endpt = as->edesc1->bEndpointAddress;
2956 DPRINTF(("uaudio_chan_open: create sync-pipe to 0x%02x\n", endpt));
2957 err = usbd_open_pipe(as->ifaceh, endpt, 0, &ch->sync_pipe);
2958 }
2959 return err;
2960 }
2961
2962 Static void
2963 uaudio_chan_close(struct uaudio_softc *sc, struct chan *ch)
2964 {
2965 struct as_info *as = &sc->sc_alts[ch->altidx];
2966
2967 #if defined(__FreeBSD__)
2968 if (sc->sc_dying)
2969 return ;
2970 #endif
2971
2972 as->sc_busy = 0;
2973 if (sc->sc_nullalt >= 0) {
2974 DPRINTF(("uaudio_chan_close: set null alt=%d\n",
2975 sc->sc_nullalt));
2976 usbd_set_interface(as->ifaceh, sc->sc_nullalt);
2977 }
2978 if (ch->pipe) {
2979 usbd_abort_pipe(ch->pipe);
2980 usbd_close_pipe(ch->pipe);
2981 }
2982 if (ch->sync_pipe) {
2983 usbd_abort_pipe(ch->sync_pipe);
2984 usbd_close_pipe(ch->sync_pipe);
2985 }
2986 }
2987
2988 Static usbd_status
2989 uaudio_chan_alloc_buffers(struct uaudio_softc *sc, struct chan *ch)
2990 {
2991 usbd_xfer_handle xfer;
2992 void *buf;
2993 int i, size;
2994
2995 size = (ch->bytes_per_frame + ch->sample_size) * UAUDIO_NFRAMES;
2996 for (i = 0; i < UAUDIO_NCHANBUFS; i++) {
2997 xfer = usbd_alloc_xfer(sc->sc_udev);
2998 if (xfer == 0)
2999 goto bad;
3000 ch->chanbufs[i].xfer = xfer;
3001 buf = usbd_alloc_buffer(xfer, size);
3002 if (buf == 0) {
3003 i++;
3004 goto bad;
3005 }
3006 ch->chanbufs[i].buffer = buf;
3007 ch->chanbufs[i].chan = ch;
3008 }
3009
3010 return (USBD_NORMAL_COMPLETION);
3011
3012 bad:
3013 while (--i >= 0)
3014 /* implicit buffer free */
3015 usbd_free_xfer(ch->chanbufs[i].xfer);
3016 return (USBD_NOMEM);
3017 }
3018
3019 Static void
3020 uaudio_chan_free_buffers(struct uaudio_softc *sc, struct chan *ch)
3021 {
3022 int i;
3023
3024 for (i = 0; i < UAUDIO_NCHANBUFS; i++)
3025 usbd_free_xfer(ch->chanbufs[i].xfer);
3026 }
3027
3028 /* Called at splusb() */
3029 Static void
3030 uaudio_chan_ptransfer(struct chan *ch)
3031 {
3032 struct chanbuf *cb;
3033 int i, n, size, residue, total;
3034
3035 if (ch->sc->sc_dying)
3036 return;
3037
3038 /* Pick the next channel buffer. */
3039 cb = &ch->chanbufs[ch->curchanbuf];
3040 if (++ch->curchanbuf >= UAUDIO_NCHANBUFS)
3041 ch->curchanbuf = 0;
3042
3043 /* Compute the size of each frame in the next transfer. */
3044 residue = ch->residue;
3045 total = 0;
3046 for (i = 0; i < UAUDIO_NFRAMES; i++) {
3047 size = ch->bytes_per_frame;
3048 residue += ch->fraction;
3049 if (residue >= USB_FRAMES_PER_SECOND) {
3050 if ((ch->sc->sc_altflags & UA_NOFRAC) == 0)
3051 size += ch->sample_size;
3052 residue -= USB_FRAMES_PER_SECOND;
3053 }
3054 cb->sizes[i] = size;
3055 total += size;
3056 }
3057 ch->residue = residue;
3058 cb->size = total;
3059
3060 /*
3061 * Transfer data from upper layer buffer to channel buffer, taking
3062 * care of wrapping the upper layer buffer.
3063 */
3064 n = min(total, ch->end - ch->cur);
3065 memcpy(cb->buffer, ch->cur, n);
3066 ch->cur += n;
3067 if (ch->cur >= ch->end)
3068 ch->cur = ch->start;
3069 if (total > n) {
3070 total -= n;
3071 memcpy(cb->buffer + n, ch->cur, total);
3072 ch->cur += total;
3073 }
3074
3075 #ifdef USB_DEBUG
3076 if (uaudiodebug > 8) {
3077 DPRINTF(("uaudio_chan_ptransfer: buffer=%p, residue=0.%03d\n",
3078 cb->buffer, ch->residue));
3079 for (i = 0; i < UAUDIO_NFRAMES; i++) {
3080 DPRINTF((" [%d] length %d\n", i, cb->sizes[i]));
3081 }
3082 }
3083 #endif
3084
3085 DPRINTFN(5,("uaudio_chan_transfer: ptransfer xfer=%p\n", cb->xfer));
3086 /* Fill the request */
3087 usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes,
3088 UAUDIO_NFRAMES, USBD_NO_COPY,
3089 uaudio_chan_pintr);
3090
3091 (void)usbd_transfer(cb->xfer);
3092 }
3093
3094 Static void
3095 uaudio_chan_pintr(usbd_xfer_handle xfer, usbd_private_handle priv,
3096 usbd_status status)
3097 {
3098 struct chanbuf *cb = priv;
3099 struct chan *ch = cb->chan;
3100 u_int32_t count;
3101 int s;
3102
3103 /* Return if we are aborting. */
3104 if (status == USBD_CANCELLED)
3105 return;
3106
3107 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
3108 DPRINTFN(5,("uaudio_chan_pintr: count=%d, transferred=%d\n",
3109 count, ch->transferred));
3110 #ifdef DIAGNOSTIC
3111 if (count != cb->size) {
3112 printf("uaudio_chan_pintr: count(%d) != size(%d)\n",
3113 count, cb->size);
3114 }
3115 #endif
3116
3117 ch->transferred += cb->size;
3118 #if defined(__FreeBSD__)
3119 /* s = spltty(); */
3120 s = splhigh();
3121 chn_intr(ch->pcm_ch);
3122 splx(s);
3123 #else
3124 s = splaudio();
3125 /* Call back to upper layer */
3126 while (ch->transferred >= ch->blksize) {
3127 ch->transferred -= ch->blksize;
3128 DPRINTFN(5,("uaudio_chan_pintr: call %p(%p)\n",
3129 ch->intr, ch->arg));
3130 ch->intr(ch->arg);
3131 }
3132 splx(s);
3133 #endif
3134
3135 /* start next transfer */
3136 uaudio_chan_ptransfer(ch);
3137 }
3138
3139 /* Called at splusb() */
3140 Static void
3141 uaudio_chan_rtransfer(struct chan *ch)
3142 {
3143 struct chanbuf *cb;
3144 int i, size, residue, total;
3145
3146 if (ch->sc->sc_dying)
3147 return;
3148
3149 /* Pick the next channel buffer. */
3150 cb = &ch->chanbufs[ch->curchanbuf];
3151 if (++ch->curchanbuf >= UAUDIO_NCHANBUFS)
3152 ch->curchanbuf = 0;
3153
3154 /* Compute the size of each frame in the next transfer. */
3155 residue = ch->residue;
3156 total = 0;
3157 for (i = 0; i < UAUDIO_NFRAMES; i++) {
3158 size = ch->bytes_per_frame;
3159 cb->sizes[i] = size;
3160 cb->offsets[i] = total;
3161 total += size;
3162 }
3163 ch->residue = residue;
3164 cb->size = total;
3165
3166 #ifdef USB_DEBUG
3167 if (uaudiodebug > 8) {
3168 DPRINTF(("uaudio_chan_rtransfer: buffer=%p, residue=0.%03d\n",
3169 cb->buffer, ch->residue));
3170 for (i = 0; i < UAUDIO_NFRAMES; i++) {
3171 DPRINTF((" [%d] length %d\n", i, cb->sizes[i]));
3172 }
3173 }
3174 #endif
3175
3176 DPRINTFN(5,("uaudio_chan_rtransfer: transfer xfer=%p\n", cb->xfer));
3177 /* Fill the request */
3178 usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes,
3179 UAUDIO_NFRAMES, USBD_NO_COPY,
3180 uaudio_chan_rintr);
3181
3182 (void)usbd_transfer(cb->xfer);
3183 }
3184
3185 Static void
3186 uaudio_chan_rintr(usbd_xfer_handle xfer, usbd_private_handle priv,
3187 usbd_status status)
3188 {
3189 struct chanbuf *cb = priv;
3190 struct chan *ch = cb->chan;
3191 u_int32_t count;
3192 int s, i, n, frsize;
3193
3194 /* Return if we are aborting. */
3195 if (status == USBD_CANCELLED)
3196 return;
3197
3198 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
3199 DPRINTFN(5,("uaudio_chan_rintr: count=%d, transferred=%d\n",
3200 count, ch->transferred));
3201
3202 /* count < cb->size is normal for asynchronous source */
3203 #ifdef DIAGNOSTIC
3204 if (count > cb->size) {
3205 printf("uaudio_chan_rintr: count(%d) > size(%d)\n",
3206 count, cb->size);
3207 }
3208 #endif
3209
3210 /*
3211 * Transfer data from channel buffer to upper layer buffer, taking
3212 * care of wrapping the upper layer buffer.
3213 */
3214 for(i = 0; i < UAUDIO_NFRAMES; i++) {
3215 frsize = cb->sizes[i];
3216 n = min(frsize, ch->end - ch->cur);
3217 memcpy(ch->cur, cb->buffer + cb->offsets[i], n);
3218 ch->cur += n;
3219 if (ch->cur >= ch->end)
3220 ch->cur = ch->start;
3221 if (frsize > n) {
3222 memcpy(ch->cur, cb->buffer + cb->offsets[i] + n,
3223 frsize - n);
3224 ch->cur += frsize - n;
3225 }
3226 }
3227
3228 /* Call back to upper layer */
3229 ch->transferred += count;
3230 #if defined(__FreeBSD__)
3231 s = spltty();
3232 chn_intr(ch->pcm_ch);
3233 splx(s);
3234 #else
3235 s = splaudio();
3236 while (ch->transferred >= ch->blksize) {
3237 ch->transferred -= ch->blksize;
3238 DPRINTFN(5,("uaudio_chan_rintr: call %p(%p)\n",
3239 ch->intr, ch->arg));
3240 ch->intr(ch->arg);
3241 }
3242 splx(s);
3243 #endif
3244
3245 /* start next transfer */
3246 uaudio_chan_rtransfer(ch);
3247 }
3248
3249 #if defined(__NetBSD__) || defined(__OpenBSD__)
3250 Static void
3251 uaudio_chan_init(struct chan *ch, int altidx, const struct audio_params *param,
3252 int maxpktsize)
3253 {
3254 int samples_per_frame, sample_size;
3255
3256 ch->altidx = altidx;
3257 sample_size = param->precision * param->factor * param->hw_channels / 8;
3258 samples_per_frame = param->hw_sample_rate / USB_FRAMES_PER_SECOND;
3259 ch->sample_size = sample_size;
3260 ch->sample_rate = param->hw_sample_rate;
3261 if (maxpktsize == 0) {
3262 ch->fraction = param->hw_sample_rate % USB_FRAMES_PER_SECOND;
3263 ch->bytes_per_frame = samples_per_frame * sample_size;
3264 } else {
3265 ch->fraction = 0;
3266 ch->bytes_per_frame = maxpktsize;
3267 }
3268 ch->residue = 0;
3269 }
3270
3271 Static void
3272 uaudio_chan_set_param(struct chan *ch, u_char *start, u_char *end, int blksize)
3273 {
3274 ch->start = start;
3275 ch->end = end;
3276 ch->cur = start;
3277 ch->blksize = blksize;
3278 ch->transferred = 0;
3279
3280 ch->curchanbuf = 0;
3281 }
3282
3283 Static void
3284 uaudio_get_minmax_rates(int nalts, const struct as_info *alts,
3285 const struct audio_params *p, int mode,
3286 u_long *min, u_long *max)
3287 {
3288 const struct usb_audio_streaming_type1_descriptor *a1d;
3289 int i, j;
3290
3291 *min = ULONG_MAX;
3292 *max = 0;
3293 for (i = 0; i < nalts; i++) {
3294 a1d = alts[i].asf1desc;
3295 if (alts[i].sc_busy)
3296 continue;
3297 if (p->hw_channels != a1d->bNrChannels)
3298 continue;
3299 if (p->hw_precision != a1d->bBitResolution)
3300 continue;
3301 if (p->hw_encoding != alts[i].encoding)
3302 continue;
3303 if (mode != UE_GET_DIR(alts[i].edesc->bEndpointAddress))
3304 continue;
3305 if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
3306 DPRINTFN(2,("uaudio_get_minmax_rates: cont %d-%d\n",
3307 UA_SAMP_LO(a1d), UA_SAMP_HI(a1d)));
3308 if (UA_SAMP_LO(a1d) < *min)
3309 *min = UA_SAMP_LO(a1d);
3310 if (UA_SAMP_HI(a1d) > *max)
3311 *max = UA_SAMP_HI(a1d);
3312 } else {
3313 for (j = 0; j < a1d->bSamFreqType; j++) {
3314 DPRINTFN(2,("uaudio_get_minmax_rates: disc #%d: %d\n",
3315 j, UA_GETSAMP(a1d, j)));
3316 if (UA_GETSAMP(a1d, j) < *min)
3317 *min = UA_GETSAMP(a1d, j);
3318 if (UA_GETSAMP(a1d, j) > *max)
3319 *max = UA_GETSAMP(a1d, j);
3320 }
3321 }
3322 }
3323 }
3324
3325 Static int
3326 uaudio_match_alt_sub(int nalts, const struct as_info *alts,
3327 const struct audio_params *p, int mode, u_long rate)
3328 {
3329 const struct usb_audio_streaming_type1_descriptor *a1d;
3330 int i, j;
3331
3332 DPRINTF(("uaudio_match_alt_sub: search for %luHz %dch\n",
3333 rate, p->hw_channels));
3334 for (i = 0; i < nalts; i++) {
3335 a1d = alts[i].asf1desc;
3336 if (alts[i].sc_busy)
3337 continue;
3338 if (p->hw_channels != a1d->bNrChannels)
3339 continue;
3340 if (p->hw_precision != a1d->bBitResolution)
3341 continue;
3342 if (p->hw_encoding != alts[i].encoding)
3343 continue;
3344 if (mode != UE_GET_DIR(alts[i].edesc->bEndpointAddress))
3345 continue;
3346 if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
3347 DPRINTFN(3,("uaudio_match_alt_sub: cont %d-%d\n",
3348 UA_SAMP_LO(a1d), UA_SAMP_HI(a1d)));
3349 if (UA_SAMP_LO(a1d) <= rate && rate <= UA_SAMP_HI(a1d))
3350 return i;
3351 } else {
3352 for (j = 0; j < a1d->bSamFreqType; j++) {
3353 DPRINTFN(3,("uaudio_match_alt_sub: disc #%d: %d\n",
3354 j, UA_GETSAMP(a1d, j)));
3355 /* XXX allow for some slack */
3356 if (UA_GETSAMP(a1d, j) == rate)
3357 return i;
3358 }
3359 }
3360 }
3361 return -1;
3362 }
3363
3364 Static int
3365 uaudio_match_alt_chan(int nalts, const struct as_info *alts,
3366 struct audio_params *p, int mode)
3367 {
3368 int i, n;
3369 u_long min, max;
3370 u_long rate;
3371
3372 /* Exact match */
3373 DPRINTF(("uaudio_match_alt_chan: examine %ldHz %dch %dbit.\n",
3374 p->sample_rate, p->hw_channels, p->hw_precision));
3375 i = uaudio_match_alt_sub(nalts, alts, p, mode, p->sample_rate);
3376 if (i >= 0)
3377 return i;
3378
3379 uaudio_get_minmax_rates(nalts, alts, p, mode, &min, &max);
3380 DPRINTF(("uaudio_match_alt_chan: min=%lu max=%lu\n", min, max));
3381 if (max <= 0)
3382 return -1;
3383 /* Search for biggers */
3384 n = 2;
3385 while ((rate = p->sample_rate * n++) <= max) {
3386 i = uaudio_match_alt_sub(nalts, alts, p, mode, rate);
3387 if (i >= 0) {
3388 p->hw_sample_rate = rate;
3389 return i;
3390 }
3391 }
3392 if (p->sample_rate >= min) {
3393 i = uaudio_match_alt_sub(nalts, alts, p, mode, max);
3394 if (i >= 0) {
3395 p->hw_sample_rate = max;
3396 return i;
3397 }
3398 } else {
3399 i = uaudio_match_alt_sub(nalts, alts, p, mode, min);
3400 if (i >= 0) {
3401 p->hw_sample_rate = min;
3402 return i;
3403 }
3404 }
3405 return -1;
3406 }
3407
3408 Static int
3409 uaudio_match_alt(int nalts, const struct as_info *alts,
3410 struct audio_params *p, int mode)
3411 {
3412 int i, n;
3413
3414 mode = mode == AUMODE_PLAY ? UE_DIR_OUT : UE_DIR_IN;
3415 i = uaudio_match_alt_chan(nalts, alts, p, mode);
3416 if (i >= 0)
3417 return i;
3418
3419 for (n = p->channels + 1; n <= AUDIO_MAX_CHANNELS; n++) {
3420 p->hw_channels = n;
3421 i = uaudio_match_alt_chan(nalts, alts, p, mode);
3422 if (i >= 0)
3423 return i;
3424 }
3425
3426 if (p->channels != 2)
3427 return -1;
3428 p->hw_channels = 1;
3429 return uaudio_match_alt_chan(nalts, alts, p, mode);
3430 }
3431
3432 Static int
3433 uaudio_set_params(void *addr, int setmode, int usemode,
3434 struct audio_params *play, struct audio_params *rec)
3435 {
3436 struct uaudio_softc *sc = addr;
3437 int flags = sc->sc_altflags;
3438 int factor;
3439 int enc, i;
3440 int paltidx=-1, raltidx=-1;
3441 void (*swcode)(void *, u_char *buf, int cnt);
3442 struct audio_params *p;
3443 int mode;
3444
3445 if (sc->sc_dying)
3446 return (EIO);
3447
3448 if (((usemode & AUMODE_PLAY) && sc->sc_playchan.pipe != NULL) ||
3449 ((usemode & AUMODE_RECORD) && sc->sc_recchan.pipe != NULL))
3450 return (EBUSY);
3451
3452 if ((usemode & AUMODE_PLAY) && sc->sc_playchan.altidx != -1)
3453 sc->sc_alts[sc->sc_playchan.altidx].sc_busy = 0;
3454 if ((usemode & AUMODE_RECORD) && sc->sc_recchan.altidx != -1)
3455 sc->sc_alts[sc->sc_recchan.altidx].sc_busy = 0;
3456
3457 /* Some uaudio devices are unidirectional. Don't try to find a
3458 matching mode for the unsupported direction. */
3459 setmode &= sc->sc_mode;
3460
3461 for (mode = AUMODE_RECORD; mode != -1;
3462 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
3463 if ((setmode & mode) == 0)
3464 continue;
3465
3466 p = (mode == AUMODE_PLAY) ? play : rec;
3467
3468 factor = 1;
3469 swcode = 0;
3470 enc = p->encoding;
3471 switch (enc) {
3472 case AUDIO_ENCODING_SLINEAR_BE:
3473 /* FALLTHROUGH */
3474 case AUDIO_ENCODING_SLINEAR_LE:
3475 if (enc == AUDIO_ENCODING_SLINEAR_BE
3476 && p->precision == 16 && (flags & HAS_16)) {
3477 swcode = swap_bytes;
3478 enc = AUDIO_ENCODING_SLINEAR_LE;
3479 } else if (p->precision == 8) {
3480 if (flags & HAS_8) {
3481 /* No conversion */
3482 } else if (flags & HAS_8U) {
3483 swcode = change_sign8;
3484 enc = AUDIO_ENCODING_ULINEAR_LE;
3485 } else if (flags & HAS_16) {
3486 factor = 2;
3487 p->hw_precision = 16;
3488 if (mode == AUMODE_PLAY)
3489 swcode = linear8_to_linear16_le;
3490 else
3491 swcode = linear16_to_linear8_le;
3492 }
3493 }
3494 break;
3495 case AUDIO_ENCODING_ULINEAR_BE:
3496 /* FALLTHROUGH */
3497 case AUDIO_ENCODING_ULINEAR_LE:
3498 if (p->precision == 16) {
3499 if (enc == AUDIO_ENCODING_ULINEAR_LE)
3500 swcode = change_sign16_le;
3501 else if (mode == AUMODE_PLAY)
3502 swcode = swap_bytes_change_sign16_le;
3503 else
3504 swcode = change_sign16_swap_bytes_le;
3505 enc = AUDIO_ENCODING_SLINEAR_LE;
3506 } else if (p->precision == 8) {
3507 if (flags & HAS_8U) {
3508 /* No conversion */
3509 } else if (flags & HAS_8) {
3510 swcode = change_sign8;
3511 enc = AUDIO_ENCODING_SLINEAR_LE;
3512 } else if (flags & HAS_16) {
3513 factor = 2;
3514 p->hw_precision = 16;
3515 enc = AUDIO_ENCODING_SLINEAR_LE;
3516 if (mode == AUMODE_PLAY)
3517 swcode = ulinear8_to_slinear16_le;
3518 else
3519 swcode = slinear16_to_ulinear8_le;
3520 }
3521 }
3522 break;
3523 case AUDIO_ENCODING_ULAW:
3524 if (flags & HAS_MULAW)
3525 break;
3526 if (flags & HAS_16) {
3527 if (mode == AUMODE_PLAY)
3528 swcode = mulaw_to_slinear16_le;
3529 else
3530 swcode = slinear16_to_mulaw_le;
3531 factor = 2;
3532 enc = AUDIO_ENCODING_SLINEAR_LE;
3533 p->hw_precision = 16;
3534 } else if (flags & HAS_8U) {
3535 if (mode == AUMODE_PLAY)
3536 swcode = mulaw_to_ulinear8;
3537 else
3538 swcode = ulinear8_to_mulaw;
3539 enc = AUDIO_ENCODING_ULINEAR_LE;
3540 } else if (flags & HAS_8) {
3541 if (mode == AUMODE_PLAY)
3542 swcode = mulaw_to_slinear8;
3543 else
3544 swcode = slinear8_to_mulaw;
3545 enc = AUDIO_ENCODING_SLINEAR_LE;
3546 } else
3547 return (EINVAL);
3548 break;
3549 case AUDIO_ENCODING_ALAW:
3550 if (flags & HAS_ALAW)
3551 break;
3552 if (mode == AUMODE_PLAY && (flags & HAS_16)) {
3553 swcode = alaw_to_slinear16_le;
3554 factor = 2;
3555 enc = AUDIO_ENCODING_SLINEAR_LE;
3556 p->hw_precision = 16;
3557 } else if (flags & HAS_8U) {
3558 if (mode == AUMODE_PLAY)
3559 swcode = alaw_to_ulinear8;
3560 else
3561 swcode = ulinear8_to_alaw;
3562 enc = AUDIO_ENCODING_ULINEAR_LE;
3563 } else if (flags & HAS_8) {
3564 if (mode == AUMODE_PLAY)
3565 swcode = alaw_to_slinear8;
3566 else
3567 swcode = slinear8_to_alaw;
3568 enc = AUDIO_ENCODING_SLINEAR_LE;
3569 } else
3570 return (EINVAL);
3571 break;
3572 default:
3573 return (EINVAL);
3574 }
3575 /* XXX do some other conversions... */
3576
3577 DPRINTF(("uaudio_set_params: chan=%d prec=%d enc=%d rate=%ld\n",
3578 p->channels, p->hw_precision, enc, p->sample_rate));
3579
3580 p->hw_encoding = enc;
3581 i = uaudio_match_alt(sc->sc_nalts, sc->sc_alts, p, mode);
3582 if (i < 0)
3583 return (EINVAL);
3584
3585 p->sw_code = swcode;
3586 p->factor = factor;
3587
3588 if (mode == AUMODE_PLAY)
3589 paltidx = i;
3590 else
3591 raltidx = i;
3592 }
3593
3594 if ((setmode & AUMODE_PLAY)) {
3595 /* XXX abort transfer if currently happening? */
3596 uaudio_chan_init(&sc->sc_playchan, paltidx, play, 0);
3597 }
3598 if ((setmode & AUMODE_RECORD)) {
3599 /* XXX abort transfer if currently happening? */
3600 uaudio_chan_init(&sc->sc_recchan, raltidx, rec,
3601 UGETW(sc->sc_alts[raltidx].edesc->wMaxPacketSize));
3602 }
3603
3604 if ((usemode & AUMODE_PLAY) && sc->sc_playchan.altidx != -1)
3605 sc->sc_alts[sc->sc_playchan.altidx].sc_busy = 1;
3606 if ((usemode & AUMODE_RECORD) && sc->sc_recchan.altidx != -1)
3607 sc->sc_alts[sc->sc_recchan.altidx].sc_busy = 1;
3608
3609 DPRINTF(("uaudio_set_params: use altidx=p%d/r%d, altno=p%d/r%d\n",
3610 sc->sc_playchan.altidx, sc->sc_recchan.altidx,
3611 (sc->sc_playchan.altidx >= 0)
3612 ?sc->sc_alts[sc->sc_playchan.altidx].idesc->bAlternateSetting
3613 : -1,
3614 (sc->sc_recchan.altidx >= 0)
3615 ? sc->sc_alts[sc->sc_recchan.altidx].idesc->bAlternateSetting
3616 : -1));
3617
3618 return (0);
3619 }
3620 #endif /* NetBSD or OpenBSD */
3621
3622 Static usbd_status
3623 uaudio_set_speed(struct uaudio_softc *sc, int endpt, u_int speed)
3624 {
3625 usb_device_request_t req;
3626 u_int8_t data[3];
3627
3628 DPRINTFN(5,("uaudio_set_speed: endpt=%d speed=%u\n", endpt, speed));
3629 req.bmRequestType = UT_WRITE_CLASS_ENDPOINT;
3630 req.bRequest = SET_CUR;
3631 USETW2(req.wValue, SAMPLING_FREQ_CONTROL, 0);
3632 USETW(req.wIndex, endpt);
3633 USETW(req.wLength, 3);
3634 data[0] = speed;
3635 data[1] = speed >> 8;
3636 data[2] = speed >> 16;
3637
3638 return (usbd_do_request(sc->sc_udev, &req, data));
3639 }
3640
3641
3642 #if defined(__FreeBSD__)
3643 /************************************************************/
3644 int
3645 uaudio_init_params(struct uaudio_softc *sc, struct chan *ch, int mode)
3646 {
3647 int i, j, enc;
3648 int samples_per_frame, sample_size;
3649
3650 if ((sc->sc_playchan.pipe != NULL) || (sc->sc_recchan.pipe != NULL))
3651 return (-1);
3652
3653 switch(ch->format & 0x0000FFFF) {
3654 case AFMT_U8:
3655 enc = AUDIO_ENCODING_ULINEAR_LE;
3656 ch->precision = 8;
3657 break;
3658 case AFMT_S8:
3659 enc = AUDIO_ENCODING_SLINEAR_LE;
3660 ch->precision = 8;
3661 break;
3662 case AFMT_A_LAW: /* ? */
3663 enc = AUDIO_ENCODING_ALAW;
3664 ch->precision = 8;
3665 break;
3666 case AFMT_MU_LAW: /* ? */
3667 enc = AUDIO_ENCODING_ULAW;
3668 ch->precision = 8;
3669 break;
3670 case AFMT_S16_LE:
3671 enc = AUDIO_ENCODING_SLINEAR_LE;
3672 ch->precision = 16;
3673 break;
3674 case AFMT_S16_BE:
3675 enc = AUDIO_ENCODING_SLINEAR_BE;
3676 ch->precision = 16;
3677 break;
3678 case AFMT_U16_LE:
3679 enc = AUDIO_ENCODING_ULINEAR_LE;
3680 ch->precision = 16;
3681 break;
3682 case AFMT_U16_BE:
3683 enc = AUDIO_ENCODING_ULINEAR_BE;
3684 ch->precision = 16;
3685 break;
3686 default:
3687 enc = 0;
3688 ch->precision = 16;
3689 printf("Unknown format %x\n", ch->format);
3690 }
3691
3692 if (ch->format & AFMT_STEREO) {
3693 ch->channels = 2;
3694 } else {
3695 ch->channels = 1;
3696 }
3697
3698 /* for (mode = ...... */
3699 for (i = 0; i < sc->sc_nalts; i++) {
3700 const struct usb_audio_streaming_type1_descriptor *a1d =
3701 sc->sc_alts[i].asf1desc;
3702 if (ch->channels == a1d->bNrChannels &&
3703 ch->precision == a1d->bBitResolution &&
3704 #if 0
3705 enc == sc->sc_alts[i].encoding) {
3706 #else
3707 enc == sc->sc_alts[i].encoding &&
3708 (mode == AUMODE_PLAY ? UE_DIR_OUT : UE_DIR_IN) ==
3709 UE_GET_DIR(sc->sc_alts[i].edesc->bEndpointAddress)) {
3710 #endif
3711 if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
3712 DPRINTFN(2,("uaudio_set_params: cont %d-%d\n",
3713 UA_SAMP_LO(a1d), UA_SAMP_HI(a1d)));
3714 if (UA_SAMP_LO(a1d) < ch->sample_rate &&
3715 ch->sample_rate < UA_SAMP_HI(a1d)) {
3716 if (mode == AUMODE_PLAY)
3717 sc->sc_playchan.altidx = i;
3718 else
3719 sc->sc_recchan.altidx = i;
3720 goto found;
3721 }
3722 } else {
3723 for (j = 0; j < a1d->bSamFreqType; j++) {
3724 DPRINTFN(2,("uaudio_set_params: disc #"
3725 "%d: %d\n", j, UA_GETSAMP(a1d, j)));
3726 /* XXX allow for some slack */
3727 if (UA_GETSAMP(a1d, j) ==
3728 ch->sample_rate) {
3729 if (mode == AUMODE_PLAY)
3730 sc->sc_playchan.altidx = i;
3731 else
3732 sc->sc_recchan.altidx = i;
3733 goto found;
3734 }
3735 }
3736 }
3737 }
3738 }
3739 /* return (EINVAL); */
3740 if (mode == AUMODE_PLAY)
3741 printf("uaudio: This device can't play in rate=%d.\n", ch->sample_rate);
3742 else
3743 printf("uaudio: This device can't record in rate=%d.\n", ch->sample_rate);
3744 return (-1);
3745
3746 found:
3747 #if 0 /* XXX */
3748 p->sw_code = swcode;
3749 p->factor = factor;
3750 if (usemode == mode)
3751 sc->sc_curaltidx = i;
3752 #endif
3753 /* } */
3754
3755 sample_size = ch->precision * ch->channels / 8;
3756 samples_per_frame = ch->sample_rate / USB_FRAMES_PER_SECOND;
3757 ch->fraction = ch->sample_rate % USB_FRAMES_PER_SECOND;
3758 ch->sample_size = sample_size;
3759 ch->bytes_per_frame = samples_per_frame * sample_size;
3760 ch->residue = 0;
3761
3762 ch->cur = ch->start;
3763 ch->transferred = 0;
3764 ch->curchanbuf = 0;
3765 return (0);
3766 }
3767
3768 void
3769 uaudio_query_formats(device_t dev, u_int32_t *pfmt, u_int32_t *rfmt)
3770 {
3771 int i, pn=0, rn=0;
3772 int prec, dir;
3773 u_int32_t fmt;
3774 struct uaudio_softc *sc;
3775
3776 const struct usb_audio_streaming_type1_descriptor *a1d;
3777
3778 sc = device_get_softc(dev);
3779
3780 for (i = 0; i < sc->sc_nalts; i++) {
3781 fmt = 0;
3782 a1d = sc->sc_alts[i].asf1desc;
3783 prec = a1d->bBitResolution; /* precision */
3784
3785 switch (sc->sc_alts[i].encoding) {
3786 case AUDIO_ENCODING_ULINEAR_LE:
3787 if (prec == 8) {
3788 fmt = AFMT_U8;
3789 } else if (prec == 16) {
3790 fmt = AFMT_U16_LE;
3791 }
3792 break;
3793 case AUDIO_ENCODING_SLINEAR_LE:
3794 if (prec == 8) {
3795 fmt = AFMT_S8;
3796 } else if (prec == 16) {
3797 fmt = AFMT_S16_LE;
3798 }
3799 break;
3800 case AUDIO_ENCODING_ULINEAR_BE:
3801 if (prec == 16) {
3802 fmt = AFMT_U16_BE;
3803 }
3804 break;
3805 case AUDIO_ENCODING_SLINEAR_BE:
3806 if (prec == 16) {
3807 fmt = AFMT_S16_BE;
3808 }
3809 break;
3810 case AUDIO_ENCODING_ALAW:
3811 if (prec == 8) {
3812 fmt = AFMT_A_LAW;
3813 }
3814 break;
3815 case AUDIO_ENCODING_ULAW:
3816 if (prec == 8) {
3817 fmt = AFMT_MU_LAW;
3818 }
3819 break;
3820 }
3821
3822 if (fmt != 0) {
3823 if (a1d->bNrChannels == 2) { /* stereo/mono */
3824 fmt |= AFMT_STEREO;
3825 } else if (a1d->bNrChannels != 1) {
3826 fmt = 0;
3827 }
3828 }
3829
3830 if (fmt != 0) {
3831 dir= UE_GET_DIR(sc->sc_alts[i].edesc->bEndpointAddress);
3832 if (dir == UE_DIR_OUT) {
3833 pfmt[pn++] = fmt;
3834 } else if (dir == UE_DIR_IN) {
3835 rfmt[rn++] = fmt;
3836 }
3837 }
3838
3839 if ((pn > 8*2) || (rn > 8*2))
3840 break;
3841 }
3842 pfmt[pn] = 0;
3843 rfmt[rn] = 0;
3844 return;
3845 }
3846
3847 void
3848 uaudio_chan_set_param_pcm_dma_buff(device_t dev, u_char *start, u_char *end,
3849 struct pcm_channel *pc, int dir)
3850 {
3851 struct uaudio_softc *sc;
3852 struct chan *ch;
3853
3854 sc = device_get_softc(dev);
3855 #ifndef NO_RECORDING
3856 if (dir == PCMDIR_PLAY)
3857 ch = &sc->sc_playchan;
3858 else
3859 ch = &sc->sc_recchan;
3860 #else
3861 ch = &sc->sc_playchan;
3862 #endif
3863
3864 ch->start = start;
3865 ch->end = end;
3866
3867 ch->pcm_ch = pc;
3868
3869 return;
3870 }
3871
3872 void
3873 uaudio_chan_set_param_blocksize(device_t dev, u_int32_t blocksize, int dir)
3874 {
3875 struct uaudio_softc *sc;
3876 struct chan *ch;
3877
3878 sc = device_get_softc(dev);
3879 #ifndef NO_RECORDING
3880 if (dir == PCMDIR_PLAY)
3881 ch = &sc->sc_playchan;
3882 else
3883 ch = &sc->sc_recchan;
3884 #else
3885 ch = &sc->sc_playchan;
3886 #endif
3887
3888 ch->blksize = blocksize;
3889
3890 return;
3891 }
3892
3893 void
3894 uaudio_chan_set_param_speed(device_t dev, u_int32_t speed, int dir)
3895 {
3896 struct uaudio_softc *sc;
3897 struct chan *ch;
3898
3899 sc = device_get_softc(dev);
3900 #ifndef NO_RECORDING
3901 if (dir == PCMDIR_PLAY)
3902 ch = &sc->sc_playchan;
3903 else
3904 ch = &sc->sc_recchan;
3905 #else
3906 ch = &sc->sc_playchan;
3907 #endif
3908
3909 ch->sample_rate = speed;
3910
3911 return;
3912 }
3913
3914 int
3915 uaudio_chan_getptr(device_t dev, int dir)
3916 {
3917 struct uaudio_softc *sc;
3918 struct chan *ch;
3919 int ptr;
3920
3921 sc = device_get_softc(dev);
3922 #ifndef NO_RECORDING
3923 if (dir == PCMDIR_PLAY)
3924 ch = &sc->sc_playchan;
3925 else
3926 ch = &sc->sc_recchan;
3927 #else
3928 ch = &sc->sc_playchan;
3929 #endif
3930
3931 ptr = ch->cur - ch->start;
3932
3933 return ptr;
3934 }
3935
3936 void
3937 uaudio_chan_set_param_format(device_t dev, u_int32_t format, int dir)
3938 {
3939 struct uaudio_softc *sc;
3940 struct chan *ch;
3941
3942 sc = device_get_softc(dev);
3943 #ifndef NO_RECORDING
3944 if (dir == PCMDIR_PLAY)
3945 ch = &sc->sc_playchan;
3946 else
3947 ch = &sc->sc_recchan;
3948 #else
3949 ch = &sc->sc_playchan;
3950 #endif
3951
3952 ch->format = format;
3953
3954 return;
3955 }
3956
3957 int
3958 uaudio_halt_out_dma(device_t dev)
3959 {
3960 struct uaudio_softc *sc;
3961
3962 sc = device_get_softc(dev);
3963
3964 DPRINTF(("uaudio_halt_out_dma: enter\n"));
3965 if (sc->sc_playchan.pipe != NULL) {
3966 uaudio_chan_close(sc, &sc->sc_playchan);
3967 sc->sc_playchan.pipe = 0;
3968 uaudio_chan_free_buffers(sc, &sc->sc_playchan);
3969 }
3970 return (0);
3971 }
3972
3973 int
3974 uaudio_halt_in_dma(device_t dev)
3975 {
3976 struct uaudio_softc *sc;
3977
3978 sc = device_get_softc(dev);
3979
3980 if (sc->sc_dying)
3981 return (EIO);
3982
3983 DPRINTF(("uaudio_halt_in_dma: enter\n"));
3984 if (sc->sc_recchan.pipe != NULL) {
3985 uaudio_chan_close(sc, &sc->sc_recchan);
3986 sc->sc_recchan.pipe = NULL;
3987 uaudio_chan_free_buffers(sc, &sc->sc_recchan);
3988 /* sc->sc_recchan.intr = NULL; */
3989 }
3990 return (0);
3991 }
3992
3993 int
3994 uaudio_trigger_input(device_t dev)
3995 {
3996 struct uaudio_softc *sc;
3997 struct chan *ch;
3998 usbd_status err;
3999 int i, s;
4000
4001 sc = device_get_softc(dev);
4002 ch = &sc->sc_recchan;
4003
4004 if (sc->sc_dying)
4005 return (EIO);
4006
4007 /* uaudio_chan_set_param(ch, start, end, blksize) */
4008 if (uaudio_init_params(sc, ch, AUMODE_RECORD))
4009 return (EIO);
4010
4011 err = uaudio_chan_alloc_buffers(sc, ch);
4012 if (err)
4013 return (EIO);
4014
4015 err = uaudio_chan_open(sc, ch);
4016 if (err) {
4017 uaudio_chan_free_buffers(sc, ch);
4018 return (EIO);
4019 }
4020
4021 /* ch->intr = intr;
4022 ch->arg = arg; */
4023
4024 s = splusb();
4025 for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX -1 shouldn't be needed */
4026 uaudio_chan_rtransfer(ch);
4027 splx(s);
4028
4029 return (0);
4030 }
4031
4032 int
4033 uaudio_trigger_output(device_t dev)
4034 {
4035 struct uaudio_softc *sc;
4036 struct chan *ch;
4037 usbd_status err;
4038 int i, s;
4039
4040 sc = device_get_softc(dev);
4041 ch = &sc->sc_playchan;
4042
4043 if (sc->sc_dying)
4044 return (EIO);
4045
4046 if (uaudio_init_params(sc, ch, AUMODE_PLAY))
4047 return (EIO);
4048
4049 err = uaudio_chan_alloc_buffers(sc, ch);
4050 if (err)
4051 return (EIO);
4052
4053 err = uaudio_chan_open(sc, ch);
4054 if (err) {
4055 uaudio_chan_free_buffers(sc, ch);
4056 return (EIO);
4057 }
4058
4059 s = splusb();
4060 for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX */
4061 uaudio_chan_ptransfer(ch);
4062 splx(s);
4063
4064 return (0);
4065 }
4066
4067 u_int32_t
4068 uaudio_query_mix_info(device_t dev)
4069 {
4070 int i;
4071 u_int32_t mask = 0;
4072 struct uaudio_softc *sc;
4073 struct mixerctl *mc;
4074
4075 sc = device_get_softc(dev);
4076 for (i=0; i < sc->sc_nctls; i++) {
4077 mc = &sc->sc_ctls[i];
4078 if (mc->ctl != SOUND_MIXER_NRDEVICES) {
4079 /* Set device mask bits.
4080 See /usr/include/machine/soundcard.h */
4081 mask |= (1 << mc->ctl);
4082 }
4083 }
4084 return mask;
4085 }
4086
4087 u_int32_t
4088 uaudio_query_recsrc_info(device_t dev)
4089 {
4090 int i, rec_selector_id;
4091 u_int32_t mask = 0;
4092 struct uaudio_softc *sc;
4093 struct mixerctl *mc;
4094
4095 sc = device_get_softc(dev);
4096 rec_selector_id = -1;
4097 for (i=0; i < sc->sc_nctls; i++) {
4098 mc = &sc->sc_ctls[i];
4099 if (mc->ctl == SOUND_MIXER_NRDEVICES &&
4100 mc->type == MIX_SELECTOR && mc->class == UAC_RECORD) {
4101 if (rec_selector_id == -1) {
4102 rec_selector_id = i;
4103 } else {
4104 printf("There are many selectors. Can't recognize which selector is a record source selector.\n");
4105 return mask;
4106 }
4107 }
4108 }
4109 if (rec_selector_id == -1)
4110 return mask;
4111 mc = &sc->sc_ctls[rec_selector_id];
4112 for (i = mc->minval; i <= mc->maxval; i++) {
4113 if (mc->slctrtype[i - 1] == SOUND_MIXER_NRDEVICES)
4114 continue;
4115 mask |= 1 << mc->slctrtype[i - 1];
4116 }
4117 return mask;
4118 }
4119
4120 void
4121 uaudio_mixer_set(device_t dev, unsigned type, unsigned left, unsigned right)
4122 {
4123 int i;
4124 struct uaudio_softc *sc;
4125 struct mixerctl *mc;
4126
4127 sc = device_get_softc(dev);
4128 for (i=0; i < sc->sc_nctls; i++) {
4129 mc = &sc->sc_ctls[i];
4130 if (mc->ctl == type) {
4131 if (mc->nchan == 2) {
4132 /* set Right */
4133 uaudio_ctl_set(sc, SET_CUR, mc, 1, (int)(right*256)/100);
4134 }
4135 /* set Left or Mono */
4136 uaudio_ctl_set(sc, SET_CUR, mc, 0, (int)(left*256)/100);
4137 }
4138 }
4139 return;
4140 }
4141
4142 u_int32_t
4143 uaudio_mixer_setrecsrc(device_t dev, u_int32_t src)
4144 {
4145 int i, rec_selector_id;
4146 struct uaudio_softc *sc;
4147 struct mixerctl *mc;
4148
4149 sc = device_get_softc(dev);
4150 rec_selector_id = -1;
4151 for (i=0; i < sc->sc_nctls; i++) {
4152 mc = &sc->sc_ctls[i];
4153 if (mc->ctl == SOUND_MIXER_NRDEVICES &&
4154 mc->type == MIX_SELECTOR && mc->class == UAC_RECORD) {
4155 if (rec_selector_id == -1) {
4156 rec_selector_id = i;
4157 } else {
4158 return src; /* Can't recognize which selector is record source selector */
4159 }
4160 }
4161 }
4162 if (rec_selector_id == -1)
4163 return src;
4164 mc = &sc->sc_ctls[rec_selector_id];
4165 for (i = mc->minval; i <= mc->maxval; i++) {
4166 if (src != (1 << mc->slctrtype[i - 1]))
4167 continue;
4168 uaudio_ctl_set(sc, SET_CUR, mc, 0, i);
4169 return (1 << mc->slctrtype[i - 1]);
4170 }
4171 uaudio_ctl_set(sc, SET_CUR, mc, 0, mc->minval);
4172 return (1 << mc->slctrtype[mc->minval - 1]);
4173 }
4174
4175 Static int
4176 audio_attach_mi(device_t dev)
4177 {
4178 device_t child;
4179 struct sndcard_func *func;
4180
4181 /* Attach the children. */
4182 /* PCM Audio */
4183 func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT);
4184 if (func == NULL)
4185 return (ENOMEM);
4186 bzero(func, sizeof(*func));
4187 func->func = SCF_PCM;
4188 child = device_add_child(dev, "pcm", -1);
4189 device_set_ivars(child, func);
4190
4191 bus_generic_attach(dev);
4192
4193 return 0; /* XXXXX */
4194 }
4195
4196 DRIVER_MODULE(uaudio, uhub, uaudio_driver, uaudio_devclass, usbd_driver_load, 0);
4197 MODULE_VERSION(uaudio, 1);
4198
4199 #endif
Cache object: da17e133a4641e52d8d705f517e32701
|