1 /* $NetBSD: uaudio.c,v 1.116 2009/09/23 19:07:19 plunky Exp $ */
4 * Copyright (c) 1999 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Lennart Augustsson (lennart@augustsson.net) at
9 * Carlstedt Research & Technology.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
34 * USB audio specs: http://www.usb.org/developers/devclass_docs/audio10.pdf
35 * http://www.usb.org/developers/devclass_docs/frmts10.pdf
36 * http://www.usb.org/developers/devclass_docs/termt10.pdf
39 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: uaudio.c,v 1.116 2009/09/23 19:07:19 plunky Exp $");
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/kernel.h>
45 #include <sys/malloc.h>
46 #include <sys/device.h>
47 #include <sys/ioctl.h>
49 #include <sys/reboot.h> /* for bootverbose */
50 #include <sys/select.h>
52 #include <sys/vnode.h>
54 #include <sys/module.h>
56 #include <sys/audioio.h>
57 #include <dev/audio_if.h>
58 #include <dev/audiovar.h>
59 #include <dev/mulaw.h>
60 #include <dev/auconv.h>
62 #include <dev/usb/usb.h>
63 #include <dev/usb/usbdi.h>
64 #include <dev/usb/usbdi_util.h>
65 #include <dev/usb/usb_quirks.h>
67 #include <dev/usb/uaudioreg.h>
69 /* #define UAUDIO_DEBUG */
70 /* #define UAUDIO_MULTIPLE_ENDPOINTS */
72 #define DPRINTF(x) do { if (uaudiodebug) logprintf x; } while (0)
73 #define DPRINTFN(n,x) do { if (uaudiodebug>(n)) logprintf x; } while (0)
80 #define UAUDIO_NCHANBUFS 6 /* number of outstanding request */
81 #define UAUDIO_NFRAMES 10 /* ms of sound in each request */
84 #define MIX_MAX_CHAN 8
86 uint16_t wValue
[MIX_MAX_CHAN
]; /* using nchan */
91 #define MIX_SIGNED_16 2
92 #define MIX_UNSIGNED_16 3
93 #define MIX_SIGNED_8 4
94 #define MIX_SELECTOR 5
95 #define MIX_SIZE(n) ((n) == MIX_SIGNED_16 || (n) == MIX_UNSIGNED_16 ? 2 : 1)
96 #define MIX_UNSIGNED(n) ((n) == MIX_UNSIGNED_16)
101 char ctlname
[MAX_AUDIO_DEV_LEN
];
104 #define MAKE(h,l) (((h) << 8) | (l))
109 uint8_t attributes
; /* Copy of bmAttributes of
110 * usb_audio_streaming_endpoint_descriptor
112 usbd_interface_handle ifaceh
;
113 const usb_interface_descriptor_t
*idesc
;
114 const usb_endpoint_descriptor_audio_t
*edesc
;
115 const usb_endpoint_descriptor_audio_t
*edesc1
;
116 const struct usb_audio_streaming_type1_descriptor
*asf1desc
;
117 struct audio_format
*aformat
;
118 int sc_busy
; /* currently used */
122 void (*intr
)(void *); /* DMA completion intr handler */
123 void *arg
; /* arg for intr() */
124 usbd_pipe_handle pipe
;
125 usbd_pipe_handle sync_pipe
;
129 u_int bytes_per_frame
;
130 u_int fraction
; /* fraction/1000 is the extra samples/frame */
131 u_int residue
; /* accumulates the fractional samples */
133 u_char
*start
; /* upper layer buffer start */
134 u_char
*end
; /* upper layer buffer end */
135 u_char
*cur
; /* current position in upper layer buffer */
136 int blksize
; /* chunk size to report up */
137 int transferred
; /* transferred bytes not reported up */
139 int altidx
; /* currently used altidx */
144 usbd_xfer_handle xfer
;
146 uint16_t sizes
[UAUDIO_NFRAMES
];
147 uint16_t offsets
[UAUDIO_NFRAMES
];
149 } chanbufs
[UAUDIO_NCHANBUFS
];
151 struct uaudio_softc
*sc
; /* our softc */
154 struct uaudio_softc
{
155 USBBASEDEVICE sc_dev
; /* base device */
156 usbd_device_handle sc_udev
; /* USB device */
157 int sc_ac_iface
; /* Audio Control interface */
158 usbd_interface_handle sc_ac_ifaceh
;
159 struct chan sc_playchan
; /* play channel */
160 struct chan sc_recchan
; /* record channel */
163 struct as_info
*sc_alts
; /* alternate settings */
164 int sc_nalts
; /* # of alternate settings */
169 #define HAS_ALAW 0x08
170 #define HAS_MULAW 0x10
171 #define UA_NOFRAC 0x20 /* don't do sample rate adjustment */
173 int sc_mode
; /* play/record capability */
174 struct mixerctl
*sc_ctls
; /* mixer controls */
175 int sc_nctls
; /* # of mixer controls */
176 device_t sc_audiodev
;
177 struct audio_format
*sc_formats
;
179 struct audio_encoding_set
*sc_encodings
;
180 u_int sc_channel_config
;
184 struct terminal_list
{
186 uint16_t terminals
[1];
188 #define TERMINAL_LIST_SIZE(N) (offsetof(struct terminal_list, terminals) \
189 + sizeof(uint16_t) * (N))
193 const uaudio_cs_descriptor_t
*desc
;
194 const struct usb_audio_input_terminal
*it
;
195 const struct usb_audio_output_terminal
*ot
;
196 const struct usb_audio_mixer_unit
*mu
;
197 const struct usb_audio_selector_unit
*su
;
198 const struct usb_audio_feature_unit
*fu
;
199 const struct usb_audio_processing_unit
*pu
;
200 const struct usb_audio_extension_unit
*eu
;
203 struct terminal_list
**inputs
; /* list of source input terminals */
204 struct terminal_list
*output
; /* list of destination output terminals */
205 int direct
; /* directly connected to an output terminal */
212 #define UAC_NCLASSES 4
214 Static
const char *uac_names
[] = {
215 AudioCoutputs
, AudioCinputs
, AudioCequalization
, AudioCrecord
,
219 Static usbd_status uaudio_identify_ac
220 (struct uaudio_softc
*, const usb_config_descriptor_t
*);
221 Static usbd_status uaudio_identify_as
222 (struct uaudio_softc
*, const usb_config_descriptor_t
*);
223 Static usbd_status uaudio_process_as
224 (struct uaudio_softc
*, const char *, int *, int,
225 const usb_interface_descriptor_t
*);
227 Static
void uaudio_add_alt(struct uaudio_softc
*, const struct as_info
*);
229 Static
const usb_interface_descriptor_t
*uaudio_find_iface
230 (const char *, int, int *, int);
232 Static
void uaudio_mixer_add_ctl(struct uaudio_softc
*, struct mixerctl
*);
233 Static
char *uaudio_id_name
234 (struct uaudio_softc
*, const struct io_terminal
*, int);
236 Static
void uaudio_dump_cluster(const struct usb_audio_cluster
*);
238 Static
struct usb_audio_cluster uaudio_get_cluster
239 (int, const struct io_terminal
*);
240 Static
void uaudio_add_input
241 (struct uaudio_softc
*, const struct io_terminal
*, int);
242 Static
void uaudio_add_output
243 (struct uaudio_softc
*, const struct io_terminal
*, int);
244 Static
void uaudio_add_mixer
245 (struct uaudio_softc
*, const struct io_terminal
*, int);
246 Static
void uaudio_add_selector
247 (struct uaudio_softc
*, const struct io_terminal
*, int);
249 Static
const char *uaudio_get_terminal_name(int);
251 Static
int uaudio_determine_class
252 (const struct io_terminal
*, struct mixerctl
*);
253 Static
const char *uaudio_feature_name
254 (const struct io_terminal
*, struct mixerctl
*);
255 Static
void uaudio_add_feature
256 (struct uaudio_softc
*, const struct io_terminal
*, int);
257 Static
void uaudio_add_processing_updown
258 (struct uaudio_softc
*, const struct io_terminal
*, int);
259 Static
void uaudio_add_processing
260 (struct uaudio_softc
*, const struct io_terminal
*, int);
261 Static
void uaudio_add_extension
262 (struct uaudio_softc
*, const struct io_terminal
*, int);
263 Static
struct terminal_list
*uaudio_merge_terminal_list
264 (const struct io_terminal
*);
265 Static
struct terminal_list
*uaudio_io_terminaltype
266 (int, struct io_terminal
*, int);
267 Static usbd_status uaudio_identify
268 (struct uaudio_softc
*, const usb_config_descriptor_t
*);
270 Static
int uaudio_signext(int, int);
271 Static
int uaudio_value2bsd(struct mixerctl
*, int);
272 Static
int uaudio_bsd2value(struct mixerctl
*, int);
273 Static
int uaudio_get(struct uaudio_softc
*, int, int, int, int, int);
274 Static
int uaudio_ctl_get
275 (struct uaudio_softc
*, int, struct mixerctl
*, int);
276 Static
void uaudio_set
277 (struct uaudio_softc
*, int, int, int, int, int, int);
278 Static
void uaudio_ctl_set
279 (struct uaudio_softc
*, int, struct mixerctl
*, int, int);
281 Static usbd_status
uaudio_set_speed(struct uaudio_softc
*, int, u_int
);
283 Static usbd_status
uaudio_chan_open(struct uaudio_softc
*, struct chan
*);
284 Static
void uaudio_chan_close(struct uaudio_softc
*, struct chan
*);
285 Static usbd_status uaudio_chan_alloc_buffers
286 (struct uaudio_softc
*, struct chan
*);
287 Static
void uaudio_chan_free_buffers(struct uaudio_softc
*, struct chan
*);
288 Static
void uaudio_chan_init
289 (struct chan
*, int, const struct audio_params
*, int);
290 Static
void uaudio_chan_set_param(struct chan
*, u_char
*, u_char
*, int);
291 Static
void uaudio_chan_ptransfer(struct chan
*);
292 Static
void uaudio_chan_pintr
293 (usbd_xfer_handle
, usbd_private_handle
, usbd_status
);
295 Static
void uaudio_chan_rtransfer(struct chan
*);
296 Static
void uaudio_chan_rintr
297 (usbd_xfer_handle
, usbd_private_handle
, usbd_status
);
299 Static
int uaudio_open(void *, int);
300 Static
void uaudio_close(void *);
301 Static
int uaudio_drain(void *);
302 Static
int uaudio_query_encoding(void *, struct audio_encoding
*);
303 Static
int uaudio_set_params
304 (void *, int, int, struct audio_params
*, struct audio_params
*,
305 stream_filter_list_t
*, stream_filter_list_t
*);
306 Static
int uaudio_round_blocksize(void *, int, int, const audio_params_t
*);
307 Static
int uaudio_trigger_output
308 (void *, void *, void *, int, void (*)(void *), void *,
309 const audio_params_t
*);
310 Static
int uaudio_trigger_input
311 (void *, void *, void *, int, void (*)(void *), void *,
312 const audio_params_t
*);
313 Static
int uaudio_halt_in_dma(void *);
314 Static
int uaudio_halt_out_dma(void *);
315 Static
int uaudio_getdev(void *, struct audio_device
*);
316 Static
int uaudio_mixer_set_port(void *, mixer_ctrl_t
*);
317 Static
int uaudio_mixer_get_port(void *, mixer_ctrl_t
*);
318 Static
int uaudio_query_devinfo(void *, mixer_devinfo_t
*);
319 Static
int uaudio_get_props(void *);
321 Static
const struct audio_hw_if uaudio_hw_if
= {
325 uaudio_query_encoding
,
327 uaudio_round_blocksize
,
338 uaudio_mixer_set_port
,
339 uaudio_mixer_get_port
,
340 uaudio_query_devinfo
,
346 uaudio_trigger_output
,
347 uaudio_trigger_input
,
352 Static
struct audio_device uaudio_device
= {
358 int uaudio_match(device_t
, cfdata_t
, void *);
359 void uaudio_attach(device_t
, device_t
, void *);
360 int uaudio_detach(device_t
, int);
361 void uaudio_childdet(device_t
, device_t
);
362 int uaudio_activate(device_t
, enum devact
);
364 extern struct cfdriver uaudio_cd
;
366 CFATTACH_DECL2_NEW(uaudio
, sizeof(struct uaudio_softc
),
367 uaudio_match
, uaudio_attach
, uaudio_detach
, uaudio_activate
, NULL
,
372 USB_IFMATCH_START(uaudio
, uaa
);
374 /* Trigger on the control interface. */
375 if (uaa
->class != UICLASS_AUDIO
||
376 uaa
->subclass
!= UISUBCLASS_AUDIOCONTROL
||
377 (usbd_get_quirks(uaa
->device
)->uq_flags
& UQ_BAD_AUDIO
))
380 return UMATCH_IFACECLASS_IFACESUBCLASS
;
385 USB_IFATTACH_START(uaudio
, sc
, uaa
);
386 usb_interface_descriptor_t
*id
;
387 usb_config_descriptor_t
*cdesc
;
393 sc
->sc_udev
= uaa
->device
;
398 devinfop
= usbd_devinfo_alloc(uaa
->device
, 0);
399 aprint_normal_dev(self
, "%s\n", devinfop
);
400 usbd_devinfo_free(devinfop
);
402 cdesc
= usbd_get_config_descriptor(sc
->sc_udev
);
404 aprint_error_dev(self
,
405 "failed to get configuration descriptor\n");
406 USB_ATTACH_ERROR_RETURN
;
409 err
= uaudio_identify(sc
, cdesc
);
411 aprint_error_dev(self
,
412 "audio descriptors make no sense, error=%d\n", err
);
413 USB_ATTACH_ERROR_RETURN
;
416 sc
->sc_ac_ifaceh
= uaa
->iface
;
417 /* Pick up the AS interface. */
418 for (i
= 0; i
< uaa
->nifaces
; i
++) {
419 if (uaa
->ifaces
[i
] == NULL
)
421 id
= usbd_get_interface_descriptor(uaa
->ifaces
[i
]);
425 for (j
= 0; j
< sc
->sc_nalts
; j
++) {
426 if (id
->bInterfaceNumber
==
427 sc
->sc_alts
[j
].idesc
->bInterfaceNumber
) {
428 sc
->sc_alts
[j
].ifaceh
= uaa
->ifaces
[i
];
433 uaa
->ifaces
[i
] = NULL
;
436 for (j
= 0; j
< sc
->sc_nalts
; j
++) {
437 if (sc
->sc_alts
[j
].ifaceh
== NULL
) {
438 aprint_error_dev(self
,
439 "alt %d missing AS interface(s)\n", j
);
440 USB_ATTACH_ERROR_RETURN
;
444 aprint_normal_dev(self
, "audio rev %d.%02x\n",
445 sc
->sc_audio_rev
>> 8, sc
->sc_audio_rev
& 0xff);
447 sc
->sc_playchan
.sc
= sc
->sc_recchan
.sc
= sc
;
448 sc
->sc_playchan
.altidx
= -1;
449 sc
->sc_recchan
.altidx
= -1;
451 if (usbd_get_quirks(sc
->sc_udev
)->uq_flags
& UQ_AU_NO_FRAC
)
452 sc
->sc_altflags
|= UA_NOFRAC
;
457 aprint_normal_dev(self
, "%d mixer controls\n",
460 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH
, sc
->sc_udev
,
463 DPRINTF(("uaudio_attach: doing audio_attach_mi\n"));
464 #if defined(__OpenBSD__)
465 audio_attach_mi(&uaudio_hw_if
, sc
, &sc
->sc_dev
);
467 sc
->sc_audiodev
= audio_attach_mi(&uaudio_hw_if
, sc
, sc
->sc_dev
);
470 USB_ATTACH_SUCCESS_RETURN
;
474 uaudio_activate(device_t self
, enum devact act
)
476 struct uaudio_softc
*sc
= device_private(self
);
479 case DVACT_DEACTIVATE
:
488 uaudio_childdet(device_t self
, device_t child
)
490 struct uaudio_softc
*sc
= device_private(self
);
492 KASSERT(sc
->sc_audiodev
== child
);
493 sc
->sc_audiodev
= NULL
;
497 uaudio_detach(device_t self
, int flags
)
499 struct uaudio_softc
*sc
= device_private(self
);
503 /* Wait for outstanding requests to complete. */
504 usbd_delay_ms(sc
->sc_udev
, UAUDIO_NCHANBUFS
* UAUDIO_NFRAMES
);
506 if (sc
->sc_audiodev
!= NULL
)
507 rv
= config_detach(sc
->sc_audiodev
, flags
);
509 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH
, sc
->sc_udev
,
512 if (sc
->sc_formats
!= NULL
)
513 free(sc
->sc_formats
, M_USBDEV
);
514 auconv_delete_encodings(sc
->sc_encodings
);
519 uaudio_query_encoding(void *addr
, struct audio_encoding
*fp
)
521 struct uaudio_softc
*sc
;
525 flags
= sc
->sc_altflags
;
529 if (sc
->sc_nalts
== 0 || flags
== 0)
532 return auconv_query_encoding(sc
->sc_encodings
, fp
);
535 Static
const usb_interface_descriptor_t
*
536 uaudio_find_iface(const char *tbuf
, int size
, int *offsp
, int subtype
)
538 const usb_interface_descriptor_t
*d
;
540 while (*offsp
< size
) {
541 d
= (const void *)(tbuf
+ *offsp
);
542 *offsp
+= d
->bLength
;
543 if (d
->bDescriptorType
== UDESC_INTERFACE
&&
544 d
->bInterfaceClass
== UICLASS_AUDIO
&&
545 d
->bInterfaceSubClass
== subtype
)
552 uaudio_mixer_add_ctl(struct uaudio_softc
*sc
, struct mixerctl
*mc
)
556 struct mixerctl
*nmc
;
558 if (mc
->class < UAC_NCLASSES
) {
559 DPRINTF(("%s: adding %s.%s\n",
560 __func__
, uac_names
[mc
->class], mc
->ctlname
));
562 DPRINTF(("%s: adding %s\n", __func__
, mc
->ctlname
));
564 len
= sizeof(*mc
) * (sc
->sc_nctls
+ 1);
565 nmc
= malloc(len
, M_USBDEV
, M_NOWAIT
);
567 aprint_error("uaudio_mixer_add_ctl: no memory\n");
570 /* Copy old data, if there was any */
571 if (sc
->sc_nctls
!= 0) {
572 memcpy(nmc
, sc
->sc_ctls
, sizeof(*mc
) * (sc
->sc_nctls
));
573 free(sc
->sc_ctls
, M_USBDEV
);
578 if (mc
->type
== MIX_ON_OFF
) {
581 } else if (mc
->type
== MIX_SELECTOR
) {
584 /* Determine min and max values. */
585 mc
->minval
= uaudio_signext(mc
->type
,
586 uaudio_get(sc
, GET_MIN
, UT_READ_CLASS_INTERFACE
,
587 mc
->wValue
[0], mc
->wIndex
,
588 MIX_SIZE(mc
->type
)));
589 mc
->maxval
= 1 + uaudio_signext(mc
->type
,
590 uaudio_get(sc
, GET_MAX
, UT_READ_CLASS_INTERFACE
,
591 mc
->wValue
[0], mc
->wIndex
,
592 MIX_SIZE(mc
->type
)));
593 mc
->mul
= mc
->maxval
- mc
->minval
;
596 res
= uaudio_get(sc
, GET_RES
, UT_READ_CLASS_INTERFACE
,
597 mc
->wValue
[0], mc
->wIndex
,
600 mc
->delta
= (res
* 255 + mc
->mul
/2) / mc
->mul
;
603 sc
->sc_ctls
[sc
->sc_nctls
++] = *mc
;
606 if (uaudiodebug
> 2) {
608 DPRINTF(("uaudio_mixer_add_ctl: wValue=%04x",mc
->wValue
[0]));
609 for (i
= 1; i
< mc
->nchan
; i
++)
610 DPRINTF((",%04x", mc
->wValue
[i
]));
611 DPRINTF((" wIndex=%04x type=%d name='%s' unit='%s' "
613 mc
->wIndex
, mc
->type
, mc
->ctlname
, mc
->ctlunit
,
614 mc
->minval
, mc
->maxval
));
620 uaudio_id_name(struct uaudio_softc
*sc
,
621 const struct io_terminal
*iot
, int id
)
623 static char tbuf
[32];
625 snprintf(tbuf
, sizeof(tbuf
), "i%d", id
);
631 uaudio_dump_cluster(const struct usb_audio_cluster
*cl
)
633 static const char *channel_names
[16] = {
634 "LEFT", "RIGHT", "CENTER", "LFE",
635 "LEFT_SURROUND", "RIGHT_SURROUND", "LEFT_CENTER", "RIGHT_CENTER",
636 "SURROUND", "LEFT_SIDE", "RIGHT_SIDE", "TOP",
637 "RESERVED12", "RESERVED13", "RESERVED14", "RESERVED15",
641 cc
= UGETW(cl
->wChannelConfig
);
642 logprintf("cluster: bNrChannels=%u wChannelConfig=0x%.4x",
643 cl
->bNrChannels
, cc
);
645 for (i
= 0; cc
!= 0; i
++) {
647 logprintf("%c%s", first
? '<' : ',', channel_names
[i
]);
652 logprintf("> iChannelNames=%u", cl
->iChannelNames
);
656 Static
struct usb_audio_cluster
657 uaudio_get_cluster(int id
, const struct io_terminal
*iot
)
659 struct usb_audio_cluster r
;
660 const uaudio_cs_descriptor_t
*dp
;
663 for (i
= 0; i
< 25; i
++) { /* avoid infinite loops */
667 switch (dp
->bDescriptorSubtype
) {
668 case UDESCSUB_AC_INPUT
:
669 r
.bNrChannels
= iot
[id
].d
.it
->bNrChannels
;
670 USETW(r
.wChannelConfig
, UGETW(iot
[id
].d
.it
->wChannelConfig
));
671 r
.iChannelNames
= iot
[id
].d
.it
->iChannelNames
;
673 case UDESCSUB_AC_OUTPUT
:
674 id
= iot
[id
].d
.ot
->bSourceId
;
676 case UDESCSUB_AC_MIXER
:
677 r
= *(const struct usb_audio_cluster
*)
678 &iot
[id
].d
.mu
->baSourceId
[iot
[id
].d
.mu
->bNrInPins
];
680 case UDESCSUB_AC_SELECTOR
:
681 /* XXX This is not really right */
682 id
= iot
[id
].d
.su
->baSourceId
[0];
684 case UDESCSUB_AC_FEATURE
:
685 id
= iot
[id
].d
.fu
->bSourceId
;
687 case UDESCSUB_AC_PROCESSING
:
688 r
= *(const struct usb_audio_cluster
*)
689 &iot
[id
].d
.pu
->baSourceId
[iot
[id
].d
.pu
->bNrInPins
];
691 case UDESCSUB_AC_EXTENSION
:
692 r
= *(const struct usb_audio_cluster
*)
693 &iot
[id
].d
.eu
->baSourceId
[iot
[id
].d
.eu
->bNrInPins
];
700 aprint_error("uaudio_get_cluster: bad data\n");
701 memset(&r
, 0, sizeof r
);
707 uaudio_add_input(struct uaudio_softc
*sc
, const struct io_terminal
*iot
, int id
)
709 const struct usb_audio_input_terminal
*d
;
713 DPRINTFN(2,("uaudio_add_input: bTerminalId=%d wTerminalType=0x%04x "
714 "bAssocTerminal=%d bNrChannels=%d wChannelConfig=%d "
715 "iChannelNames=%d iTerminal=%d\n",
716 d
->bTerminalId
, UGETW(d
->wTerminalType
), d
->bAssocTerminal
,
717 d
->bNrChannels
, UGETW(d
->wChannelConfig
),
718 d
->iChannelNames
, d
->iTerminal
));
720 /* If USB input terminal, record wChannelConfig */
721 if ((UGETW(d
->wTerminalType
) & 0xff00) != 0x0100)
723 sc
->sc_channel_config
= UGETW(d
->wChannelConfig
);
727 uaudio_add_output(struct uaudio_softc
*sc
,
728 const struct io_terminal
*iot
, int id
)
731 const struct usb_audio_output_terminal
*d
;
734 DPRINTFN(2,("uaudio_add_output: bTerminalId=%d wTerminalType=0x%04x "
735 "bAssocTerminal=%d bSourceId=%d iTerminal=%d\n",
736 d
->bTerminalId
, UGETW(d
->wTerminalType
), d
->bAssocTerminal
,
737 d
->bSourceId
, d
->iTerminal
));
742 uaudio_add_mixer(struct uaudio_softc
*sc
, const struct io_terminal
*iot
, int id
)
744 const struct usb_audio_mixer_unit
*d
;
745 const struct usb_audio_mixer_unit_1
*d1
;
746 int c
, chs
, ichs
, ochs
, i
, o
, bno
, p
, mo
, mc
, k
;
751 DPRINTFN(2,("uaudio_add_mixer: bUnitId=%d bNrInPins=%d\n",
752 d
->bUnitId
, d
->bNrInPins
));
754 /* Compute the number of input channels */
756 for (i
= 0; i
< d
->bNrInPins
; i
++)
757 ichs
+= uaudio_get_cluster(d
->baSourceId
[i
], iot
).bNrChannels
;
759 /* and the number of output channels */
760 d1
= (const struct usb_audio_mixer_unit_1
*)&d
->baSourceId
[d
->bNrInPins
];
761 ochs
= d1
->bNrChannels
;
762 DPRINTFN(2,("uaudio_add_mixer: ichs=%d ochs=%d\n", ichs
, ochs
));
765 mix
.wIndex
= MAKE(d
->bUnitId
, sc
->sc_ac_iface
);
766 uaudio_determine_class(&iot
[id
], &mix
);
767 mix
.type
= MIX_SIGNED_16
;
768 mix
.ctlunit
= AudioNvolume
;
769 #define _BIT(bno) ((bm[bno / 8] >> (7 - bno % 8)) & 1)
770 for (p
= i
= 0; i
< d
->bNrInPins
; i
++) {
771 chs
= uaudio_get_cluster(d
->baSourceId
[i
], iot
).bNrChannels
;
773 for (c
= 0; c
< chs
; c
++) {
775 for (o
= 0; o
< ochs
; o
++) {
776 bno
= (p
+ c
) * ochs
+ o
;
783 if (mc
== chs
&& chs
<= MIX_MAX_CHAN
) {
785 for (c
= 0; c
< chs
; c
++)
786 for (o
= 0; o
< ochs
; o
++) {
787 bno
= (p
+ c
) * ochs
+ o
;
792 snprintf(mix
.ctlname
, sizeof(mix
.ctlname
), "mix%d-%s",
793 d
->bUnitId
, uaudio_id_name(sc
, iot
,
796 uaudio_mixer_add_ctl(sc
, &mix
);
807 uaudio_add_selector(struct uaudio_softc
*sc
, const struct io_terminal
*iot
, int id
)
809 const struct usb_audio_selector_unit
*d
;
814 DPRINTFN(2,("uaudio_add_selector: bUnitId=%d bNrInPins=%d\n",
815 d
->bUnitId
, d
->bNrInPins
));
816 mix
.wIndex
= MAKE(d
->bUnitId
, sc
->sc_ac_iface
);
817 mix
.wValue
[0] = MAKE(0, 0);
818 uaudio_determine_class(&iot
[id
], &mix
);
820 mix
.type
= MIX_SELECTOR
;
823 mix
.maxval
= d
->bNrInPins
;
824 mix
.mul
= mix
.maxval
- mix
.minval
;
825 wp
= snprintf(mix
.ctlname
, MAX_AUDIO_DEV_LEN
, "sel%d-", d
->bUnitId
);
826 for (i
= 1; i
<= d
->bNrInPins
; i
++) {
827 wp
+= snprintf(mix
.ctlname
+ wp
, MAX_AUDIO_DEV_LEN
- wp
,
828 "i%d", d
->baSourceId
[i
- 1]);
829 if (wp
> MAX_AUDIO_DEV_LEN
- 1)
832 uaudio_mixer_add_ctl(sc
, &mix
);
837 uaudio_get_terminal_name(int terminal_type
)
839 static char tbuf
[100];
841 switch (terminal_type
) {
842 /* USB terminal types */
843 case UAT_UNDEFINED
: return "UAT_UNDEFINED";
844 case UAT_STREAM
: return "UAT_STREAM";
845 case UAT_VENDOR
: return "UAT_VENDOR";
846 /* input terminal types */
847 case UATI_UNDEFINED
: return "UATI_UNDEFINED";
848 case UATI_MICROPHONE
: return "UATI_MICROPHONE";
849 case UATI_DESKMICROPHONE
: return "UATI_DESKMICROPHONE";
850 case UATI_PERSONALMICROPHONE
: return "UATI_PERSONALMICROPHONE";
851 case UATI_OMNIMICROPHONE
: return "UATI_OMNIMICROPHONE";
852 case UATI_MICROPHONEARRAY
: return "UATI_MICROPHONEARRAY";
853 case UATI_PROCMICROPHONEARR
: return "UATI_PROCMICROPHONEARR";
854 /* output terminal types */
855 case UATO_UNDEFINED
: return "UATO_UNDEFINED";
856 case UATO_SPEAKER
: return "UATO_SPEAKER";
857 case UATO_HEADPHONES
: return "UATO_HEADPHONES";
858 case UATO_DISPLAYAUDIO
: return "UATO_DISPLAYAUDIO";
859 case UATO_DESKTOPSPEAKER
: return "UATO_DESKTOPSPEAKER";
860 case UATO_ROOMSPEAKER
: return "UATO_ROOMSPEAKER";
861 case UATO_COMMSPEAKER
: return "UATO_COMMSPEAKER";
862 case UATO_SUBWOOFER
: return "UATO_SUBWOOFER";
863 /* bidir terminal types */
864 case UATB_UNDEFINED
: return "UATB_UNDEFINED";
865 case UATB_HANDSET
: return "UATB_HANDSET";
866 case UATB_HEADSET
: return "UATB_HEADSET";
867 case UATB_SPEAKERPHONE
: return "UATB_SPEAKERPHONE";
868 case UATB_SPEAKERPHONEESUP
: return "UATB_SPEAKERPHONEESUP";
869 case UATB_SPEAKERPHONEECANC
: return "UATB_SPEAKERPHONEECANC";
870 /* telephony terminal types */
871 case UATT_UNDEFINED
: return "UATT_UNDEFINED";
872 case UATT_PHONELINE
: return "UATT_PHONELINE";
873 case UATT_TELEPHONE
: return "UATT_TELEPHONE";
874 case UATT_DOWNLINEPHONE
: return "UATT_DOWNLINEPHONE";
875 /* external terminal types */
876 case UATE_UNDEFINED
: return "UATE_UNDEFINED";
877 case UATE_ANALOGCONN
: return "UATE_ANALOGCONN";
878 case UATE_LINECONN
: return "UATE_LINECONN";
879 case UATE_LEGACYCONN
: return "UATE_LEGACYCONN";
880 case UATE_DIGITALAUIFC
: return "UATE_DIGITALAUIFC";
881 case UATE_SPDIF
: return "UATE_SPDIF";
882 case UATE_1394DA
: return "UATE_1394DA";
883 case UATE_1394DV
: return "UATE_1394DV";
884 /* embedded function terminal types */
885 case UATF_UNDEFINED
: return "UATF_UNDEFINED";
886 case UATF_CALIBNOISE
: return "UATF_CALIBNOISE";
887 case UATF_EQUNOISE
: return "UATF_EQUNOISE";
888 case UATF_CDPLAYER
: return "UATF_CDPLAYER";
889 case UATF_DAT
: return "UATF_DAT";
890 case UATF_DCC
: return "UATF_DCC";
891 case UATF_MINIDISK
: return "UATF_MINIDISK";
892 case UATF_ANALOGTAPE
: return "UATF_ANALOGTAPE";
893 case UATF_PHONOGRAPH
: return "UATF_PHONOGRAPH";
894 case UATF_VCRAUDIO
: return "UATF_VCRAUDIO";
895 case UATF_VIDEODISCAUDIO
: return "UATF_VIDEODISCAUDIO";
896 case UATF_DVDAUDIO
: return "UATF_DVDAUDIO";
897 case UATF_TVTUNERAUDIO
: return "UATF_TVTUNERAUDIO";
898 case UATF_SATELLITE
: return "UATF_SATELLITE";
899 case UATF_CABLETUNER
: return "UATF_CABLETUNER";
900 case UATF_DSS
: return "UATF_DSS";
901 case UATF_RADIORECV
: return "UATF_RADIORECV";
902 case UATF_RADIOXMIT
: return "UATF_RADIOXMIT";
903 case UATF_MULTITRACK
: return "UATF_MULTITRACK";
904 case UATF_SYNTHESIZER
: return "UATF_SYNTHESIZER";
906 snprintf(tbuf
, sizeof(tbuf
), "unknown type (0x%.4x)", terminal_type
);
913 uaudio_determine_class(const struct io_terminal
*iot
, struct mixerctl
*mix
)
917 if (iot
== NULL
|| iot
->output
== NULL
) {
918 mix
->class = UAC_OUTPUT
;
922 if (iot
->output
->size
== 1)
923 terminal_type
= iot
->output
->terminals
[0];
925 * If the only output terminal is USB,
926 * the class is UAC_RECORD.
928 if ((terminal_type
& 0xff00) == (UAT_UNDEFINED
& 0xff00)) {
929 mix
->class = UAC_RECORD
;
930 if (iot
->inputs_size
== 1
931 && iot
->inputs
[0] != NULL
932 && iot
->inputs
[0]->size
== 1)
933 return iot
->inputs
[0]->terminals
[0];
938 * If the ultimate destination of the unit is just one output
939 * terminal and the unit is connected to the output terminal
940 * directly, the class is UAC_OUTPUT.
942 if (terminal_type
!= 0 && iot
->direct
) {
943 mix
->class = UAC_OUTPUT
;
944 return terminal_type
;
947 * If the unit is connected to just one input terminal,
948 * the class is UAC_INPUT.
950 if (iot
->inputs_size
== 1 && iot
->inputs
[0] != NULL
951 && iot
->inputs
[0]->size
== 1) {
952 mix
->class = UAC_INPUT
;
953 return iot
->inputs
[0]->terminals
[0];
956 * Otherwise, the class is UAC_OUTPUT.
958 mix
->class = UAC_OUTPUT
;
959 return terminal_type
;
963 uaudio_feature_name(const struct io_terminal
*iot
, struct mixerctl
*mix
)
967 terminal_type
= uaudio_determine_class(iot
, mix
);
968 if (mix
->class == UAC_RECORD
&& terminal_type
== 0)
969 return AudioNmixerout
;
970 DPRINTF(("%s: terminal_type=%s\n", __func__
,
971 uaudio_get_terminal_name(terminal_type
)));
972 switch (terminal_type
) {
976 case UATI_MICROPHONE
:
977 case UATI_DESKMICROPHONE
:
978 case UATI_PERSONALMICROPHONE
:
979 case UATI_OMNIMICROPHONE
:
980 case UATI_MICROPHONEARRAY
:
981 case UATI_PROCMICROPHONEARR
:
982 return AudioNmicrophone
;
985 case UATO_DESKTOPSPEAKER
:
986 case UATO_ROOMSPEAKER
:
987 case UATO_COMMSPEAKER
:
988 return AudioNspeaker
;
990 case UATO_HEADPHONES
:
991 return AudioNheadphone
;
996 /* telephony terminal types */
1000 case UATT_DOWNLINEPHONE
:
1003 case UATE_ANALOGCONN
:
1005 case UATE_LEGACYCONN
:
1008 case UATE_DIGITALAUIFC
:
1017 case UATF_SYNTHESIZER
:
1018 return AudioNfmsynth
;
1020 case UATF_VIDEODISCAUDIO
:
1022 case UATF_TVTUNERAUDIO
:
1027 case UATI_UNDEFINED
:
1028 /* output terminal types */
1029 case UATO_UNDEFINED
:
1030 case UATO_DISPLAYAUDIO
:
1031 /* bidir terminal types */
1032 case UATB_UNDEFINED
:
1035 case UATB_SPEAKERPHONE
:
1036 case UATB_SPEAKERPHONEESUP
:
1037 case UATB_SPEAKERPHONEECANC
:
1038 /* external terminal types */
1039 case UATE_UNDEFINED
:
1040 /* embedded function terminal types */
1041 case UATF_UNDEFINED
:
1042 case UATF_CALIBNOISE
:
1047 case UATF_ANALOGTAPE
:
1048 case UATF_PHONOGRAPH
:
1050 case UATF_SATELLITE
:
1051 case UATF_CABLETUNER
:
1053 case UATF_RADIORECV
:
1054 case UATF_RADIOXMIT
:
1055 case UATF_MULTITRACK
:
1058 DPRINTF(("%s: 'master' for 0x%.4x\n", __func__
, terminal_type
));
1059 return AudioNmaster
;
1061 return AudioNmaster
;
1065 uaudio_add_feature(struct uaudio_softc
*sc
, const struct io_terminal
*iot
, int id
)
1067 const struct usb_audio_feature_unit
*d
;
1071 u_int fumask
, mmask
, cmask
;
1072 struct mixerctl mix
;
1073 int chan
, ctl
, i
, unit
;
1074 const char *mixername
;
1076 #define GET(i) (ctls[(i)*ctlsize] | \
1077 (ctlsize > 1 ? ctls[(i)*ctlsize+1] << 8 : 0))
1079 ctls
= d
->bmaControls
;
1080 ctlsize
= d
->bControlSize
;
1081 nchan
= (d
->bLength
- 7) / ctlsize
;
1083 /* Figure out what we can control */
1084 for (cmask
= 0, chan
= 1; chan
< nchan
; chan
++) {
1085 DPRINTFN(9,("uaudio_add_feature: chan=%d mask=%x\n",
1090 DPRINTFN(1,("uaudio_add_feature: bUnitId=%d, "
1091 "%d channels, mmask=0x%04x, cmask=0x%04x\n",
1092 d
->bUnitId
, nchan
, mmask
, cmask
));
1094 if (nchan
> MIX_MAX_CHAN
)
1095 nchan
= MIX_MAX_CHAN
;
1097 mix
.wIndex
= MAKE(unit
, sc
->sc_ac_iface
);
1098 for (ctl
= MUTE_CONTROL
; ctl
< LOUDNESS_CONTROL
; ctl
++) {
1099 fumask
= FU_MASK(ctl
);
1100 DPRINTFN(4,("uaudio_add_feature: ctl=%d fumask=0x%04x\n",
1102 if (mmask
& fumask
) {
1104 mix
.wValue
[0] = MAKE(ctl
, 0);
1105 } else if (cmask
& fumask
) {
1106 mix
.nchan
= nchan
- 1;
1107 for (i
= 1; i
< nchan
; i
++) {
1108 if (GET(i
) & fumask
)
1109 mix
.wValue
[i
-1] = MAKE(ctl
, i
);
1111 mix
.wValue
[i
-1] = -1;
1117 mixername
= uaudio_feature_name(&iot
[id
], &mix
);
1120 mix
.type
= MIX_ON_OFF
;
1122 snprintf(mix
.ctlname
, sizeof(mix
.ctlname
),
1123 "%s.%s", mixername
, AudioNmute
);
1125 case VOLUME_CONTROL
:
1126 mix
.type
= MIX_SIGNED_16
;
1127 mix
.ctlunit
= AudioNvolume
;
1128 strlcpy(mix
.ctlname
, mixername
, sizeof(mix
.ctlname
));
1131 mix
.type
= MIX_SIGNED_8
;
1132 mix
.ctlunit
= AudioNbass
;
1133 snprintf(mix
.ctlname
, sizeof(mix
.ctlname
),
1134 "%s.%s", mixername
, AudioNbass
);
1137 mix
.type
= MIX_SIGNED_8
;
1138 mix
.ctlunit
= AudioNmid
;
1139 snprintf(mix
.ctlname
, sizeof(mix
.ctlname
),
1140 "%s.%s", mixername
, AudioNmid
);
1142 case TREBLE_CONTROL
:
1143 mix
.type
= MIX_SIGNED_8
;
1144 mix
.ctlunit
= AudioNtreble
;
1145 snprintf(mix
.ctlname
, sizeof(mix
.ctlname
),
1146 "%s.%s", mixername
, AudioNtreble
);
1148 case GRAPHIC_EQUALIZER_CONTROL
:
1149 continue; /* XXX don't add anything */
1152 mix
.type
= MIX_ON_OFF
;
1154 snprintf(mix
.ctlname
, sizeof(mix
.ctlname
), "%s.%s",
1155 mixername
, AudioNagc
);
1158 mix
.type
= MIX_UNSIGNED_16
;
1159 mix
.ctlunit
= "4 ms";
1160 snprintf(mix
.ctlname
, sizeof(mix
.ctlname
),
1161 "%s.%s", mixername
, AudioNdelay
);
1163 case BASS_BOOST_CONTROL
:
1164 mix
.type
= MIX_ON_OFF
;
1166 snprintf(mix
.ctlname
, sizeof(mix
.ctlname
),
1167 "%s.%s", mixername
, AudioNbassboost
);
1169 case LOUDNESS_CONTROL
:
1170 mix
.type
= MIX_ON_OFF
;
1172 snprintf(mix
.ctlname
, sizeof(mix
.ctlname
),
1173 "%s.%s", mixername
, AudioNloudness
);
1176 uaudio_mixer_add_ctl(sc
, &mix
);
1181 uaudio_add_processing_updown(struct uaudio_softc
*sc
,
1182 const struct io_terminal
*iot
, int id
)
1184 const struct usb_audio_processing_unit
*d
;
1185 const struct usb_audio_processing_unit_1
*d1
;
1186 const struct usb_audio_processing_unit_updown
*ud
;
1187 struct mixerctl mix
;
1191 d1
= (const struct usb_audio_processing_unit_1
*)
1192 &d
->baSourceId
[d
->bNrInPins
];
1193 ud
= (const struct usb_audio_processing_unit_updown
*)
1194 &d1
->bmControls
[d1
->bControlSize
];
1195 DPRINTFN(2,("uaudio_add_processing_updown: bUnitId=%d bNrModes=%d\n",
1196 d
->bUnitId
, ud
->bNrModes
));
1198 if (!(d1
->bmControls
[0] & UA_PROC_MASK(UD_MODE_SELECT_CONTROL
))) {
1199 DPRINTF(("uaudio_add_processing_updown: no mode select\n"));
1203 mix
.wIndex
= MAKE(d
->bUnitId
, sc
->sc_ac_iface
);
1205 mix
.wValue
[0] = MAKE(UD_MODE_SELECT_CONTROL
, 0);
1206 uaudio_determine_class(&iot
[id
], &mix
);
1207 mix
.type
= MIX_ON_OFF
; /* XXX */
1209 snprintf(mix
.ctlname
, sizeof(mix
.ctlname
), "pro%d-mode", d
->bUnitId
);
1211 for (i
= 0; i
< ud
->bNrModes
; i
++) {
1212 DPRINTFN(2,("uaudio_add_processing_updown: i=%d bm=0x%x\n",
1213 i
, UGETW(ud
->waModes
[i
])));
1216 uaudio_mixer_add_ctl(sc
, &mix
);
1220 uaudio_add_processing(struct uaudio_softc
*sc
, const struct io_terminal
*iot
, int id
)
1222 const struct usb_audio_processing_unit
*d
;
1223 const struct usb_audio_processing_unit_1
*d1
;
1225 struct mixerctl mix
;
1228 d1
= (const struct usb_audio_processing_unit_1
*)
1229 &d
->baSourceId
[d
->bNrInPins
];
1230 ptype
= UGETW(d
->wProcessType
);
1231 DPRINTFN(2,("uaudio_add_processing: wProcessType=%d bUnitId=%d "
1232 "bNrInPins=%d\n", ptype
, d
->bUnitId
, d
->bNrInPins
));
1234 if (d1
->bmControls
[0] & UA_PROC_ENABLE_MASK
) {
1235 mix
.wIndex
= MAKE(d
->bUnitId
, sc
->sc_ac_iface
);
1237 mix
.wValue
[0] = MAKE(XX_ENABLE_CONTROL
, 0);
1238 uaudio_determine_class(&iot
[id
], &mix
);
1239 mix
.type
= MIX_ON_OFF
;
1241 snprintf(mix
.ctlname
, sizeof(mix
.ctlname
), "pro%d.%d-enable",
1243 uaudio_mixer_add_ctl(sc
, &mix
);
1247 case UPDOWNMIX_PROCESS
:
1248 uaudio_add_processing_updown(sc
, iot
, id
);
1250 case DOLBY_PROLOGIC_PROCESS
:
1251 case P3D_STEREO_EXTENDER_PROCESS
:
1252 case REVERBATION_PROCESS
:
1253 case CHORUS_PROCESS
:
1254 case DYN_RANGE_COMP_PROCESS
:
1258 "uaudio_add_processing: unit %d, type=%d not impl.\n",
1266 uaudio_add_extension(struct uaudio_softc
*sc
, const struct io_terminal
*iot
, int id
)
1268 const struct usb_audio_extension_unit
*d
;
1269 const struct usb_audio_extension_unit_1
*d1
;
1270 struct mixerctl mix
;
1273 d1
= (const struct usb_audio_extension_unit_1
*)
1274 &d
->baSourceId
[d
->bNrInPins
];
1275 DPRINTFN(2,("uaudio_add_extension: bUnitId=%d bNrInPins=%d\n",
1276 d
->bUnitId
, d
->bNrInPins
));
1278 if (usbd_get_quirks(sc
->sc_udev
)->uq_flags
& UQ_AU_NO_XU
)
1281 if (d1
->bmControls
[0] & UA_EXT_ENABLE_MASK
) {
1282 mix
.wIndex
= MAKE(d
->bUnitId
, sc
->sc_ac_iface
);
1284 mix
.wValue
[0] = MAKE(UA_EXT_ENABLE
, 0);
1285 uaudio_determine_class(&iot
[id
], &mix
);
1286 mix
.type
= MIX_ON_OFF
;
1288 snprintf(mix
.ctlname
, sizeof(mix
.ctlname
), "ext%d-enable",
1290 uaudio_mixer_add_ctl(sc
, &mix
);
1294 Static
struct terminal_list
*
1295 uaudio_merge_terminal_list(const struct io_terminal
*iot
)
1297 struct terminal_list
*tml
;
1302 if (iot
->inputs
== NULL
)
1304 for (i
= 0; i
< iot
->inputs_size
; i
++) {
1305 if (iot
->inputs
[i
] != NULL
)
1306 len
+= iot
->inputs
[i
]->size
;
1308 tml
= malloc(TERMINAL_LIST_SIZE(len
), M_TEMP
, M_NOWAIT
);
1310 aprint_error("uaudio_merge_terminal_list: no memory\n");
1314 ptm
= tml
->terminals
;
1315 for (i
= 0; i
< iot
->inputs_size
; i
++) {
1316 if (iot
->inputs
[i
] == NULL
)
1318 if (iot
->inputs
[i
]->size
> len
)
1320 memcpy(ptm
, iot
->inputs
[i
]->terminals
,
1321 iot
->inputs
[i
]->size
* sizeof(uint16_t));
1322 tml
->size
+= iot
->inputs
[i
]->size
;
1323 ptm
+= iot
->inputs
[i
]->size
;
1324 len
-= iot
->inputs
[i
]->size
;
1329 Static
struct terminal_list
*
1330 uaudio_io_terminaltype(int outtype
, struct io_terminal
*iot
, int id
)
1332 struct terminal_list
*tml
;
1333 struct io_terminal
*it
;
1337 if (it
->output
!= NULL
) {
1338 /* already has outtype? */
1339 for (i
= 0; i
< it
->output
->size
; i
++)
1340 if (it
->output
->terminals
[i
] == outtype
)
1341 return uaudio_merge_terminal_list(it
);
1342 tml
= malloc(TERMINAL_LIST_SIZE(it
->output
->size
+ 1),
1345 aprint_error("uaudio_io_terminaltype: no memory\n");
1346 return uaudio_merge_terminal_list(it
);
1348 memcpy(tml
, it
->output
, TERMINAL_LIST_SIZE(it
->output
->size
));
1349 tml
->terminals
[it
->output
->size
] = outtype
;
1351 free(it
->output
, M_TEMP
);
1353 if (it
->inputs
!= NULL
) {
1354 for (i
= 0; i
< it
->inputs_size
; i
++)
1355 if (it
->inputs
[i
] != NULL
)
1356 free(it
->inputs
[i
], M_TEMP
);
1357 free(it
->inputs
, M_TEMP
);
1359 it
->inputs_size
= 0;
1361 } else { /* end `iot[id] != NULL' */
1362 it
->inputs_size
= 0;
1364 it
->output
= malloc(TERMINAL_LIST_SIZE(1), M_TEMP
, M_NOWAIT
);
1365 if (it
->output
== NULL
) {
1366 aprint_error("uaudio_io_terminaltype: no memory\n");
1369 it
->output
->terminals
[0] = outtype
;
1370 it
->output
->size
= 1;
1374 switch (it
->d
.desc
->bDescriptorSubtype
) {
1375 case UDESCSUB_AC_INPUT
:
1376 it
->inputs
= malloc(sizeof(struct terminal_list
*), M_TEMP
, M_NOWAIT
);
1377 if (it
->inputs
== NULL
) {
1378 aprint_error("uaudio_io_terminaltype: no memory\n");
1381 tml
= malloc(TERMINAL_LIST_SIZE(1), M_TEMP
, M_NOWAIT
);
1383 aprint_error("uaudio_io_terminaltype: no memory\n");
1384 free(it
->inputs
, M_TEMP
);
1388 it
->inputs
[0] = tml
;
1389 tml
->terminals
[0] = UGETW(it
->d
.it
->wTerminalType
);
1391 it
->inputs_size
= 1;
1392 return uaudio_merge_terminal_list(it
);
1393 case UDESCSUB_AC_FEATURE
:
1394 src_id
= it
->d
.fu
->bSourceId
;
1395 it
->inputs
= malloc(sizeof(struct terminal_list
*), M_TEMP
, M_NOWAIT
);
1396 if (it
->inputs
== NULL
) {
1397 aprint_error("uaudio_io_terminaltype: no memory\n");
1398 return uaudio_io_terminaltype(outtype
, iot
, src_id
);
1400 it
->inputs
[0] = uaudio_io_terminaltype(outtype
, iot
, src_id
);
1401 it
->inputs_size
= 1;
1402 return uaudio_merge_terminal_list(it
);
1403 case UDESCSUB_AC_OUTPUT
:
1404 it
->inputs
= malloc(sizeof(struct terminal_list
*), M_TEMP
, M_NOWAIT
);
1405 if (it
->inputs
== NULL
) {
1406 aprint_error("uaudio_io_terminaltype: no memory\n");
1409 src_id
= it
->d
.ot
->bSourceId
;
1410 it
->inputs
[0] = uaudio_io_terminaltype(outtype
, iot
, src_id
);
1411 it
->inputs_size
= 1;
1412 iot
[src_id
].direct
= TRUE
;
1414 case UDESCSUB_AC_MIXER
:
1415 it
->inputs_size
= 0;
1416 it
->inputs
= malloc(sizeof(struct terminal_list
*)
1417 * it
->d
.mu
->bNrInPins
, M_TEMP
, M_NOWAIT
);
1418 if (it
->inputs
== NULL
) {
1419 aprint_error("uaudio_io_terminaltype: no memory\n");
1422 for (i
= 0; i
< it
->d
.mu
->bNrInPins
; i
++) {
1423 src_id
= it
->d
.mu
->baSourceId
[i
];
1424 it
->inputs
[i
] = uaudio_io_terminaltype(outtype
, iot
,
1428 return uaudio_merge_terminal_list(it
);
1429 case UDESCSUB_AC_SELECTOR
:
1430 it
->inputs_size
= 0;
1431 it
->inputs
= malloc(sizeof(struct terminal_list
*)
1432 * it
->d
.su
->bNrInPins
, M_TEMP
, M_NOWAIT
);
1433 if (it
->inputs
== NULL
) {
1434 aprint_error("uaudio_io_terminaltype: no memory\n");
1437 for (i
= 0; i
< it
->d
.su
->bNrInPins
; i
++) {
1438 src_id
= it
->d
.su
->baSourceId
[i
];
1439 it
->inputs
[i
] = uaudio_io_terminaltype(outtype
, iot
,
1443 return uaudio_merge_terminal_list(it
);
1444 case UDESCSUB_AC_PROCESSING
:
1445 it
->inputs_size
= 0;
1446 it
->inputs
= malloc(sizeof(struct terminal_list
*)
1447 * it
->d
.pu
->bNrInPins
, M_TEMP
, M_NOWAIT
);
1448 if (it
->inputs
== NULL
) {
1449 aprint_error("uaudio_io_terminaltype: no memory\n");
1452 for (i
= 0; i
< it
->d
.pu
->bNrInPins
; i
++) {
1453 src_id
= it
->d
.pu
->baSourceId
[i
];
1454 it
->inputs
[i
] = uaudio_io_terminaltype(outtype
, iot
,
1458 return uaudio_merge_terminal_list(it
);
1459 case UDESCSUB_AC_EXTENSION
:
1460 it
->inputs_size
= 0;
1461 it
->inputs
= malloc(sizeof(struct terminal_list
*)
1462 * it
->d
.eu
->bNrInPins
, M_TEMP
, M_NOWAIT
);
1463 if (it
->inputs
== NULL
) {
1464 aprint_error("uaudio_io_terminaltype: no memory\n");
1467 for (i
= 0; i
< it
->d
.eu
->bNrInPins
; i
++) {
1468 src_id
= it
->d
.eu
->baSourceId
[i
];
1469 it
->inputs
[i
] = uaudio_io_terminaltype(outtype
, iot
,
1473 return uaudio_merge_terminal_list(it
);
1474 case UDESCSUB_AC_HEADER
:
1481 uaudio_identify(struct uaudio_softc
*sc
, const usb_config_descriptor_t
*cdesc
)
1485 err
= uaudio_identify_ac(sc
, cdesc
);
1488 return uaudio_identify_as(sc
, cdesc
);
1492 uaudio_add_alt(struct uaudio_softc
*sc
, const struct as_info
*ai
)
1495 struct as_info
*nai
;
1497 len
= sizeof(*ai
) * (sc
->sc_nalts
+ 1);
1498 nai
= malloc(len
, M_USBDEV
, M_NOWAIT
);
1500 aprint_error("uaudio_add_alt: no memory\n");
1503 /* Copy old data, if there was any */
1504 if (sc
->sc_nalts
!= 0) {
1505 memcpy(nai
, sc
->sc_alts
, sizeof(*ai
) * (sc
->sc_nalts
));
1506 free(sc
->sc_alts
, M_USBDEV
);
1509 DPRINTFN(2,("uaudio_add_alt: adding alt=%d, enc=%d\n",
1510 ai
->alt
, ai
->encoding
));
1511 sc
->sc_alts
[sc
->sc_nalts
++] = *ai
;
1515 uaudio_process_as(struct uaudio_softc
*sc
, const char *tbuf
, int *offsp
,
1516 int size
, const usb_interface_descriptor_t
*id
)
1517 #define offs (*offsp)
1519 const struct usb_audio_streaming_interface_descriptor
*asid
;
1520 const struct usb_audio_streaming_type1_descriptor
*asf1d
;
1521 const usb_endpoint_descriptor_audio_t
*ed
;
1522 const usb_endpoint_descriptor_audio_t
*epdesc1
;
1523 const struct usb_audio_streaming_endpoint_descriptor
*sed
;
1524 int format
, chan
, prec
, enc
;
1525 int dir
, type
, sync
;
1527 const char *format_str
;
1529 asid
= (const void *)(tbuf
+ offs
);
1530 if (asid
->bDescriptorType
!= UDESC_CS_INTERFACE
||
1531 asid
->bDescriptorSubtype
!= AS_GENERAL
)
1533 DPRINTF(("uaudio_process_as: asid: bTerminakLink=%d wFormatTag=%d\n",
1534 asid
->bTerminalLink
, UGETW(asid
->wFormatTag
)));
1535 offs
+= asid
->bLength
;
1539 asf1d
= (const void *)(tbuf
+ offs
);
1540 if (asf1d
->bDescriptorType
!= UDESC_CS_INTERFACE
||
1541 asf1d
->bDescriptorSubtype
!= FORMAT_TYPE
)
1543 offs
+= asf1d
->bLength
;
1547 if (asf1d
->bFormatType
!= FORMAT_TYPE_I
) {
1548 aprint_error_dev(sc
->sc_dev
,
1549 "ignored setting with type %d format\n", UGETW(asid
->wFormatTag
));
1550 return USBD_NORMAL_COMPLETION
;
1553 ed
= (const void *)(tbuf
+ offs
);
1554 if (ed
->bDescriptorType
!= UDESC_ENDPOINT
)
1556 DPRINTF(("uaudio_process_as: endpoint[0] bLength=%d bDescriptorType=%d "
1557 "bEndpointAddress=%d bmAttributes=0x%x wMaxPacketSize=%d "
1558 "bInterval=%d bRefresh=%d bSynchAddress=%d\n",
1559 ed
->bLength
, ed
->bDescriptorType
, ed
->bEndpointAddress
,
1560 ed
->bmAttributes
, UGETW(ed
->wMaxPacketSize
),
1561 ed
->bInterval
, ed
->bRefresh
, ed
->bSynchAddress
));
1562 offs
+= ed
->bLength
;
1565 if (UE_GET_XFERTYPE(ed
->bmAttributes
) != UE_ISOCHRONOUS
)
1568 dir
= UE_GET_DIR(ed
->bEndpointAddress
);
1569 type
= UE_GET_ISO_TYPE(ed
->bmAttributes
);
1570 if ((usbd_get_quirks(sc
->sc_udev
)->uq_flags
& UQ_AU_INP_ASYNC
) &&
1571 dir
== UE_DIR_IN
&& type
== UE_ISO_ADAPT
)
1572 type
= UE_ISO_ASYNC
;
1574 /* We can't handle endpoints that need a sync pipe yet. */
1576 if (dir
== UE_DIR_IN
&& type
== UE_ISO_ADAPT
) {
1578 #ifndef UAUDIO_MULTIPLE_ENDPOINTS
1579 aprint_error_dev(sc
->sc_dev
,
1580 "ignored input endpoint of type adaptive\n");
1581 return USBD_NORMAL_COMPLETION
;
1584 if (dir
!= UE_DIR_IN
&& type
== UE_ISO_ASYNC
) {
1586 #ifndef UAUDIO_MULTIPLE_ENDPOINTS
1587 aprint_error_dev(sc
->sc_dev
,
1588 "ignored output endpoint of type async\n");
1589 return USBD_NORMAL_COMPLETION
;
1593 sed
= (const void *)(tbuf
+ offs
);
1594 if (sed
->bDescriptorType
!= UDESC_CS_ENDPOINT
||
1595 sed
->bDescriptorSubtype
!= AS_GENERAL
)
1597 DPRINTF((" streadming_endpoint: offset=%d bLength=%d\n", offs
, sed
->bLength
));
1598 offs
+= sed
->bLength
;
1602 #ifdef UAUDIO_MULTIPLE_ENDPOINTS
1603 if (sync
&& id
->bNumEndpoints
<= 1) {
1604 aprint_error_dev(sc
->sc_dev
,
1605 "a sync-pipe endpoint but no other endpoint\n");
1609 if (!sync
&& id
->bNumEndpoints
> 1) {
1610 aprint_error_dev(sc
->sc_dev
,
1611 "non sync-pipe endpoint but multiple endpoints\n");
1615 if (id
->bNumEndpoints
> 1) {
1616 epdesc1
= (const void*)(tbuf
+ offs
);
1617 if (epdesc1
->bDescriptorType
!= UDESC_ENDPOINT
)
1619 DPRINTF(("uaudio_process_as: endpoint[1] bLength=%d "
1620 "bDescriptorType=%d bEndpointAddress=%d "
1621 "bmAttributes=0x%x wMaxPacketSize=%d bInterval=%d "
1622 "bRefresh=%d bSynchAddress=%d\n",
1623 epdesc1
->bLength
, epdesc1
->bDescriptorType
,
1624 epdesc1
->bEndpointAddress
, epdesc1
->bmAttributes
,
1625 UGETW(epdesc1
->wMaxPacketSize
), epdesc1
->bInterval
,
1626 epdesc1
->bRefresh
, epdesc1
->bSynchAddress
));
1627 offs
+= epdesc1
->bLength
;
1630 if (epdesc1
->bSynchAddress
!= 0) {
1631 aprint_error_dev(sc
->sc_dev
,
1632 "invalid endpoint: bSynchAddress=0\n");
1635 if (UE_GET_XFERTYPE(epdesc1
->bmAttributes
) != UE_ISOCHRONOUS
) {
1636 aprint_error_dev(sc
->sc_dev
,
1637 "invalid endpoint: bmAttributes=0x%x\n",
1638 epdesc1
->bmAttributes
);
1641 if (epdesc1
->bEndpointAddress
!= ed
->bSynchAddress
) {
1642 aprint_error_dev(sc
->sc_dev
,
1643 "invalid endpoint addresses: "
1644 "ep[0]->bSynchAddress=0x%x "
1645 "ep[1]->bEndpointAddress=0x%x\n",
1646 ed
->bSynchAddress
, epdesc1
->bEndpointAddress
);
1649 /* UE_GET_ADDR(epdesc1->bEndpointAddress), and epdesc1->bRefresh */
1652 format
= UGETW(asid
->wFormatTag
);
1653 chan
= asf1d
->bNrChannels
;
1654 prec
= asf1d
->bBitResolution
;
1655 if (prec
!= 8 && prec
!= 16 && prec
!= 24) {
1656 aprint_error_dev(sc
->sc_dev
,
1657 "ignored setting with precision %d\n", prec
);
1658 return USBD_NORMAL_COMPLETION
;
1663 sc
->sc_altflags
|= HAS_8
;
1664 } else if (prec
== 16) {
1665 sc
->sc_altflags
|= HAS_16
;
1666 } else if (prec
== 24) {
1667 sc
->sc_altflags
|= HAS_24
;
1669 enc
= AUDIO_ENCODING_SLINEAR_LE
;
1673 enc
= AUDIO_ENCODING_ULINEAR_LE
;
1674 sc
->sc_altflags
|= HAS_8U
;
1675 format_str
= "pcm8";
1678 enc
= AUDIO_ENCODING_ALAW
;
1679 sc
->sc_altflags
|= HAS_ALAW
;
1680 format_str
= "alaw";
1683 enc
= AUDIO_ENCODING_ULAW
;
1684 sc
->sc_altflags
|= HAS_MULAW
;
1685 format_str
= "mulaw";
1687 case UA_FMT_IEEE_FLOAT
:
1689 aprint_error_dev(sc
->sc_dev
,
1690 "ignored setting with format %d\n", format
);
1691 return USBD_NORMAL_COMPLETION
;
1694 aprint_debug_dev(sc
->sc_dev
, "%s: %dch, %d/%dbit, %s,",
1695 dir
== UE_DIR_IN
? "recording" : "playback",
1696 chan
, prec
, asf1d
->bSubFrameSize
* 8, format_str
);
1697 if (asf1d
->bSamFreqType
== UA_SAMP_CONTNUOUS
) {
1698 aprint_debug(" %d-%dHz\n", UA_SAMP_LO(asf1d
),
1702 aprint_debug(" %d", UA_GETSAMP(asf1d
, 0));
1703 for (r
= 1; r
< asf1d
->bSamFreqType
; r
++)
1704 aprint_debug(",%d", UA_GETSAMP(asf1d
, r
));
1705 aprint_debug("Hz\n");
1708 ai
.alt
= id
->bAlternateSetting
;
1710 ai
.attributes
= sed
->bmAttributes
;
1713 ai
.edesc1
= epdesc1
;
1714 ai
.asf1desc
= asf1d
;
1718 uaudio_add_alt(sc
, &ai
);
1720 if (ai
.attributes
& UA_SED_FREQ_CONTROL
)
1721 DPRINTFN(1, ("uaudio_process_as: FREQ_CONTROL\n"));
1722 if (ai
.attributes
& UA_SED_PITCH_CONTROL
)
1723 DPRINTFN(1, ("uaudio_process_as: PITCH_CONTROL\n"));
1725 sc
->sc_mode
|= (dir
== UE_DIR_OUT
) ? AUMODE_PLAY
: AUMODE_RECORD
;
1727 return USBD_NORMAL_COMPLETION
;
1732 uaudio_identify_as(struct uaudio_softc
*sc
,
1733 const usb_config_descriptor_t
*cdesc
)
1735 const usb_interface_descriptor_t
*id
;
1737 struct audio_format
*auf
;
1738 const struct usb_audio_streaming_type1_descriptor
*t1desc
;
1742 size
= UGETW(cdesc
->wTotalLength
);
1743 tbuf
= (const char *)cdesc
;
1745 /* Locate the AudioStreaming interface descriptor. */
1747 id
= uaudio_find_iface(tbuf
, size
, &offs
, UISUBCLASS_AUDIOSTREAM
);
1751 /* Loop through all the alternate settings. */
1752 while (offs
<= size
) {
1753 DPRINTFN(2, ("uaudio_identify: interface=%d offset=%d\n",
1754 id
->bInterfaceNumber
, offs
));
1755 switch (id
->bNumEndpoints
) {
1757 DPRINTFN(2, ("uaudio_identify: AS null alt=%d\n",
1758 id
->bAlternateSetting
));
1759 sc
->sc_nullalt
= id
->bAlternateSetting
;
1762 #ifdef UAUDIO_MULTIPLE_ENDPOINTS
1765 uaudio_process_as(sc
, tbuf
, &offs
, size
, id
);
1768 aprint_error_dev(sc
->sc_dev
,
1769 "ignored audio interface with %d endpoints\n",
1773 id
= uaudio_find_iface(tbuf
, size
, &offs
,UISUBCLASS_AUDIOSTREAM
);
1779 DPRINTF(("uaudio_identify_as: %d alts available\n", sc
->sc_nalts
));
1781 if (sc
->sc_mode
== 0) {
1782 aprint_error_dev(sc
->sc_dev
, "no usable endpoint found\n");
1786 /* build audio_format array */
1787 sc
->sc_formats
= malloc(sizeof(struct audio_format
) * sc
->sc_nalts
,
1788 M_USBDEV
, M_NOWAIT
);
1789 if (sc
->sc_formats
== NULL
)
1791 sc
->sc_nformats
= sc
->sc_nalts
;
1792 for (i
= 0; i
< sc
->sc_nalts
; i
++) {
1793 auf
= &sc
->sc_formats
[i
];
1794 t1desc
= sc
->sc_alts
[i
].asf1desc
;
1795 auf
->driver_data
= NULL
;
1796 if (UE_GET_DIR(sc
->sc_alts
[i
].edesc
->bEndpointAddress
) == UE_DIR_OUT
)
1797 auf
->mode
= AUMODE_PLAY
;
1799 auf
->mode
= AUMODE_RECORD
;
1800 auf
->encoding
= sc
->sc_alts
[i
].encoding
;
1801 auf
->validbits
= t1desc
->bBitResolution
;
1802 auf
->precision
= t1desc
->bSubFrameSize
* 8;
1803 auf
->channels
= t1desc
->bNrChannels
;
1804 auf
->channel_mask
= sc
->sc_channel_config
;
1805 auf
->frequency_type
= t1desc
->bSamFreqType
;
1806 if (t1desc
->bSamFreqType
== UA_SAMP_CONTNUOUS
) {
1807 auf
->frequency
[0] = UA_SAMP_LO(t1desc
);
1808 auf
->frequency
[1] = UA_SAMP_HI(t1desc
);
1810 for (j
= 0; j
< t1desc
->bSamFreqType
; j
++) {
1811 if (j
>= AUFMT_MAX_FREQUENCIES
) {
1812 aprint_error("%s: please increase "
1813 "AUFMT_MAX_FREQUENCIES to %d\n",
1814 __func__
, t1desc
->bSamFreqType
);
1817 auf
->frequency
[j
] = UA_GETSAMP(t1desc
, j
);
1820 sc
->sc_alts
[i
].aformat
= auf
;
1823 if (0 != auconv_create_encodings(sc
->sc_formats
, sc
->sc_nformats
,
1824 &sc
->sc_encodings
)) {
1825 free(sc
->sc_formats
, M_DEVBUF
);
1826 sc
->sc_formats
= NULL
;
1830 return USBD_NORMAL_COMPLETION
;
1834 uaudio_identify_ac(struct uaudio_softc
*sc
, const usb_config_descriptor_t
*cdesc
)
1836 struct io_terminal
* iot
;
1837 const usb_interface_descriptor_t
*id
;
1838 const struct usb_audio_control_descriptor
*acdp
;
1839 const uaudio_cs_descriptor_t
*dp
;
1840 const struct usb_audio_output_terminal
*pot
;
1841 struct terminal_list
*tml
;
1842 const char *tbuf
, *ibuf
, *ibufend
;
1843 int size
, offs
, aclen
, ndps
, i
, j
;
1845 size
= UGETW(cdesc
->wTotalLength
);
1846 tbuf
= (const char *)cdesc
;
1848 /* Locate the AudioControl interface descriptor. */
1850 id
= uaudio_find_iface(tbuf
, size
, &offs
, UISUBCLASS_AUDIOCONTROL
);
1853 if (offs
+ sizeof *acdp
> size
)
1855 sc
->sc_ac_iface
= id
->bInterfaceNumber
;
1856 DPRINTFN(2,("uaudio_identify_ac: AC interface is %d\n", sc
->sc_ac_iface
));
1858 /* A class-specific AC interface header should follow. */
1860 acdp
= (const struct usb_audio_control_descriptor
*)ibuf
;
1861 if (acdp
->bDescriptorType
!= UDESC_CS_INTERFACE
||
1862 acdp
->bDescriptorSubtype
!= UDESCSUB_AC_HEADER
)
1864 aclen
= UGETW(acdp
->wTotalLength
);
1865 if (offs
+ aclen
> size
)
1868 if (!(usbd_get_quirks(sc
->sc_udev
)->uq_flags
& UQ_BAD_ADC
) &&
1869 UGETW(acdp
->bcdADC
) != UAUDIO_VERSION
)
1872 sc
->sc_audio_rev
= UGETW(acdp
->bcdADC
);
1873 DPRINTFN(2,("uaudio_identify_ac: found AC header, vers=%03x, len=%d\n",
1874 sc
->sc_audio_rev
, aclen
));
1876 sc
->sc_nullalt
= -1;
1878 /* Scan through all the AC specific descriptors */
1879 ibufend
= ibuf
+ aclen
;
1880 dp
= (const uaudio_cs_descriptor_t
*)ibuf
;
1882 iot
= malloc(sizeof(struct io_terminal
) * 256, M_TEMP
, M_NOWAIT
| M_ZERO
);
1884 aprint_error("%s: no memory\n", __func__
);
1888 ibuf
+= dp
->bLength
;
1889 if (ibuf
>= ibufend
)
1891 dp
= (const uaudio_cs_descriptor_t
*)ibuf
;
1892 if (ibuf
+ dp
->bLength
> ibufend
) {
1896 if (dp
->bDescriptorType
!= UDESC_CS_INTERFACE
) {
1898 "uaudio_identify_ac: skip desc type=0x%02x\n",
1899 dp
->bDescriptorType
);
1902 i
= ((const struct usb_audio_input_terminal
*)dp
)->bTerminalId
;
1909 /* construct io_terminal */
1910 for (i
= 0; i
< ndps
; i
++) {
1914 if (dp
->bDescriptorSubtype
!= UDESCSUB_AC_OUTPUT
)
1917 tml
= uaudio_io_terminaltype(UGETW(pot
->wTerminalType
), iot
, i
);
1923 for (i
= 0; i
< 256; i
++) {
1924 struct usb_audio_cluster cluster
;
1926 if (iot
[i
].d
.desc
== NULL
)
1928 logprintf("id %d:\t", i
);
1929 switch (iot
[i
].d
.desc
->bDescriptorSubtype
) {
1930 case UDESCSUB_AC_INPUT
:
1931 logprintf("AC_INPUT type=%s\n", uaudio_get_terminal_name
1932 (UGETW(iot
[i
].d
.it
->wTerminalType
)));
1934 cluster
= uaudio_get_cluster(i
, iot
);
1935 uaudio_dump_cluster(&cluster
);
1938 case UDESCSUB_AC_OUTPUT
:
1939 logprintf("AC_OUTPUT type=%s ", uaudio_get_terminal_name
1940 (UGETW(iot
[i
].d
.ot
->wTerminalType
)));
1941 logprintf("src=%d\n", iot
[i
].d
.ot
->bSourceId
);
1943 case UDESCSUB_AC_MIXER
:
1944 logprintf("AC_MIXER src=");
1945 for (j
= 0; j
< iot
[i
].d
.mu
->bNrInPins
; j
++)
1946 logprintf("%d ", iot
[i
].d
.mu
->baSourceId
[j
]);
1948 cluster
= uaudio_get_cluster(i
, iot
);
1949 uaudio_dump_cluster(&cluster
);
1952 case UDESCSUB_AC_SELECTOR
:
1953 logprintf("AC_SELECTOR src=");
1954 for (j
= 0; j
< iot
[i
].d
.su
->bNrInPins
; j
++)
1955 logprintf("%d ", iot
[i
].d
.su
->baSourceId
[j
]);
1958 case UDESCSUB_AC_FEATURE
:
1959 logprintf("AC_FEATURE src=%d\n", iot
[i
].d
.fu
->bSourceId
);
1961 case UDESCSUB_AC_PROCESSING
:
1962 logprintf("AC_PROCESSING src=");
1963 for (j
= 0; j
< iot
[i
].d
.pu
->bNrInPins
; j
++)
1964 logprintf("%d ", iot
[i
].d
.pu
->baSourceId
[j
]);
1966 cluster
= uaudio_get_cluster(i
, iot
);
1967 uaudio_dump_cluster(&cluster
);
1970 case UDESCSUB_AC_EXTENSION
:
1971 logprintf("AC_EXTENSION src=");
1972 for (j
= 0; j
< iot
[i
].d
.eu
->bNrInPins
; j
++)
1973 logprintf("%d ", iot
[i
].d
.eu
->baSourceId
[j
]);
1975 cluster
= uaudio_get_cluster(i
, iot
);
1976 uaudio_dump_cluster(&cluster
);
1980 logprintf("unknown audio control (subtype=%d)\n",
1981 iot
[i
].d
.desc
->bDescriptorSubtype
);
1983 for (j
= 0; j
< iot
[i
].inputs_size
; j
++) {
1985 logprintf("\tinput%d: ", j
);
1986 tml
= iot
[i
].inputs
[j
];
1988 logprintf("NULL\n");
1991 for (k
= 0; k
< tml
->size
; k
++)
1992 logprintf("%s ", uaudio_get_terminal_name
1993 (tml
->terminals
[k
]));
1996 logprintf("\toutput: ");
1997 tml
= iot
[i
].output
;
1998 for (j
= 0; j
< tml
->size
; j
++)
1999 logprintf("%s ", uaudio_get_terminal_name(tml
->terminals
[j
]));
2004 for (i
= 0; i
< ndps
; i
++) {
2008 DPRINTF(("uaudio_identify_ac: id=%d subtype=%d\n",
2009 i
, dp
->bDescriptorSubtype
));
2010 switch (dp
->bDescriptorSubtype
) {
2011 case UDESCSUB_AC_HEADER
:
2012 aprint_error("uaudio_identify_ac: unexpected AC header\n");
2014 case UDESCSUB_AC_INPUT
:
2015 uaudio_add_input(sc
, iot
, i
);
2017 case UDESCSUB_AC_OUTPUT
:
2018 uaudio_add_output(sc
, iot
, i
);
2020 case UDESCSUB_AC_MIXER
:
2021 uaudio_add_mixer(sc
, iot
, i
);
2023 case UDESCSUB_AC_SELECTOR
:
2024 uaudio_add_selector(sc
, iot
, i
);
2026 case UDESCSUB_AC_FEATURE
:
2027 uaudio_add_feature(sc
, iot
, i
);
2029 case UDESCSUB_AC_PROCESSING
:
2030 uaudio_add_processing(sc
, iot
, i
);
2032 case UDESCSUB_AC_EXTENSION
:
2033 uaudio_add_extension(sc
, iot
, i
);
2037 "uaudio_identify_ac: bad AC desc subtype=0x%02x\n",
2038 dp
->bDescriptorSubtype
);
2043 /* delete io_terminal */
2044 for (i
= 0; i
< 256; i
++) {
2045 if (iot
[i
].d
.desc
== NULL
)
2047 if (iot
[i
].inputs
!= NULL
) {
2048 for (j
= 0; j
< iot
[i
].inputs_size
; j
++) {
2049 if (iot
[i
].inputs
[j
] != NULL
)
2050 free(iot
[i
].inputs
[j
], M_TEMP
);
2052 free(iot
[i
].inputs
, M_TEMP
);
2054 if (iot
[i
].output
!= NULL
)
2055 free(iot
[i
].output
, M_TEMP
);
2056 iot
[i
].d
.desc
= NULL
;
2060 return USBD_NORMAL_COMPLETION
;
2064 uaudio_query_devinfo(void *addr
, mixer_devinfo_t
*mi
)
2066 struct uaudio_softc
*sc
;
2067 struct mixerctl
*mc
;
2070 DPRINTFN(2,("uaudio_query_devinfo: index=%d\n", mi
->index
));
2076 nctls
= sc
->sc_nctls
;
2080 mi
->type
= AUDIO_MIXER_CLASS
;
2081 mi
->mixer_class
= UAC_OUTPUT
;
2082 mi
->next
= mi
->prev
= AUDIO_MIXER_LAST
;
2083 strlcpy(mi
->label
.name
, AudioCoutputs
, sizeof(mi
->label
.name
));
2086 mi
->type
= AUDIO_MIXER_CLASS
;
2087 mi
->mixer_class
= UAC_INPUT
;
2088 mi
->next
= mi
->prev
= AUDIO_MIXER_LAST
;
2089 strlcpy(mi
->label
.name
, AudioCinputs
, sizeof(mi
->label
.name
));
2092 mi
->type
= AUDIO_MIXER_CLASS
;
2093 mi
->mixer_class
= UAC_EQUAL
;
2094 mi
->next
= mi
->prev
= AUDIO_MIXER_LAST
;
2095 strlcpy(mi
->label
.name
, AudioCequalization
,
2096 sizeof(mi
->label
.name
));
2099 mi
->type
= AUDIO_MIXER_CLASS
;
2100 mi
->mixer_class
= UAC_RECORD
;
2101 mi
->next
= mi
->prev
= AUDIO_MIXER_LAST
;
2102 strlcpy(mi
->label
.name
, AudioCrecord
, sizeof(mi
->label
.name
));
2109 if (n
< 0 || n
>= nctls
)
2112 mc
= &sc
->sc_ctls
[n
];
2113 strlcpy(mi
->label
.name
, mc
->ctlname
, sizeof(mi
->label
.name
));
2114 mi
->mixer_class
= mc
->class;
2115 mi
->next
= mi
->prev
= AUDIO_MIXER_LAST
; /* XXX */
2118 mi
->type
= AUDIO_MIXER_ENUM
;
2119 mi
->un
.e
.num_mem
= 2;
2120 strlcpy(mi
->un
.e
.member
[0].label
.name
, AudioNoff
,
2121 sizeof(mi
->un
.e
.member
[0].label
.name
));
2122 mi
->un
.e
.member
[0].ord
= 0;
2123 strlcpy(mi
->un
.e
.member
[1].label
.name
, AudioNon
,
2124 sizeof(mi
->un
.e
.member
[1].label
.name
));
2125 mi
->un
.e
.member
[1].ord
= 1;
2128 mi
->type
= AUDIO_MIXER_ENUM
;
2129 mi
->un
.e
.num_mem
= mc
->maxval
- mc
->minval
+ 1;
2130 for (i
= 0; i
<= mc
->maxval
- mc
->minval
; i
++) {
2131 snprintf(mi
->un
.e
.member
[i
].label
.name
,
2132 sizeof(mi
->un
.e
.member
[i
].label
.name
),
2133 "%d", i
+ mc
->minval
);
2134 mi
->un
.e
.member
[i
].ord
= i
+ mc
->minval
;
2138 mi
->type
= AUDIO_MIXER_VALUE
;
2139 strncpy(mi
->un
.v
.units
.name
, mc
->ctlunit
, MAX_AUDIO_DEV_LEN
);
2140 mi
->un
.v
.num_channels
= mc
->nchan
;
2141 mi
->un
.v
.delta
= mc
->delta
;
2148 uaudio_open(void *addr
, int flags
)
2150 struct uaudio_softc
*sc
;
2153 DPRINTF(("uaudio_open: sc=%p\n", sc
));
2157 if ((flags
& FWRITE
) && !(sc
->sc_mode
& AUMODE_PLAY
))
2159 if ((flags
& FREAD
) && !(sc
->sc_mode
& AUMODE_RECORD
))
2166 * Close function is called at splaudio().
2169 uaudio_close(void *addr
)
2174 uaudio_drain(void *addr
)
2176 struct uaudio_softc
*sc
;
2179 usbd_delay_ms(sc
->sc_udev
, UAUDIO_NCHANBUFS
* UAUDIO_NFRAMES
);
2185 uaudio_halt_out_dma(void *addr
)
2187 struct uaudio_softc
*sc
;
2189 DPRINTF(("uaudio_halt_out_dma: enter\n"));
2191 if (sc
->sc_playchan
.pipe
!= NULL
) {
2192 uaudio_chan_close(sc
, &sc
->sc_playchan
);
2193 sc
->sc_playchan
.pipe
= NULL
;
2194 uaudio_chan_free_buffers(sc
, &sc
->sc_playchan
);
2195 sc
->sc_playchan
.intr
= NULL
;
2201 uaudio_halt_in_dma(void *addr
)
2203 struct uaudio_softc
*sc
;
2205 DPRINTF(("uaudio_halt_in_dma: enter\n"));
2207 if (sc
->sc_recchan
.pipe
!= NULL
) {
2208 uaudio_chan_close(sc
, &sc
->sc_recchan
);
2209 sc
->sc_recchan
.pipe
= NULL
;
2210 uaudio_chan_free_buffers(sc
, &sc
->sc_recchan
);
2211 sc
->sc_recchan
.intr
= NULL
;
2217 uaudio_getdev(void *addr
, struct audio_device
*retp
)
2219 struct uaudio_softc
*sc
;
2221 DPRINTF(("uaudio_mixer_getdev:\n"));
2226 *retp
= uaudio_device
;
2231 * Make sure the block size is large enough to hold all outstanding transfers.
2234 uaudio_round_blocksize(void *addr
, int blk
,
2235 int mode
, const audio_params_t
*param
)
2237 struct uaudio_softc
*sc
;
2241 DPRINTF(("uaudio_round_blocksize: blk=%d mode=%s\n", blk
,
2242 mode
== AUMODE_PLAY
? "AUMODE_PLAY" : "AUMODE_RECORD"));
2244 /* chan.bytes_per_frame can be 0. */
2245 if (mode
== AUMODE_PLAY
|| sc
->sc_recchan
.bytes_per_frame
<= 0) {
2246 b
= param
->sample_rate
* UAUDIO_NFRAMES
* UAUDIO_NCHANBUFS
;
2249 * This does not make accurate value in the case
2250 * of b % USB_FRAMES_PER_SECOND != 0
2252 b
/= USB_FRAMES_PER_SECOND
;
2254 b
*= param
->precision
/ 8 * param
->channels
;
2257 * use wMaxPacketSize in bytes_per_frame.
2258 * See uaudio_set_params() and uaudio_chan_init()
2260 b
= sc
->sc_recchan
.bytes_per_frame
2261 * UAUDIO_NFRAMES
* UAUDIO_NCHANBUFS
;
2266 blk
= blk
<= b
? b
: blk
/ b
* b
;
2270 aprint_debug("uaudio_round_blocksize: blk=%d\n", blk
);
2275 DPRINTF(("uaudio_round_blocksize: resultant blk=%d\n", blk
));
2280 uaudio_get_props(void *addr
)
2282 return AUDIO_PROP_FULLDUPLEX
| AUDIO_PROP_INDEPENDENT
;
2287 uaudio_get(struct uaudio_softc
*sc
, int which
, int type
, int wValue
,
2288 int wIndex
, int len
)
2290 usb_device_request_t req
;
2298 req
.bmRequestType
= type
;
2299 req
.bRequest
= which
;
2300 USETW(req
.wValue
, wValue
);
2301 USETW(req
.wIndex
, wIndex
);
2302 USETW(req
.wLength
, len
);
2303 DPRINTFN(2,("uaudio_get: type=0x%02x req=0x%02x wValue=0x%04x "
2304 "wIndex=0x%04x len=%d\n",
2305 type
, which
, wValue
, wIndex
, len
));
2306 err
= usbd_do_request(sc
->sc_udev
, &req
, data
);
2308 DPRINTF(("uaudio_get: err=%s\n", usbd_errstr(err
)));
2316 val
= data
[0] | (data
[1] << 8);
2319 DPRINTF(("uaudio_get: bad length=%d\n", len
));
2322 DPRINTFN(2,("uaudio_get: val=%d\n", val
));
2327 uaudio_set(struct uaudio_softc
*sc
, int which
, int type
, int wValue
,
2328 int wIndex
, int len
, int val
)
2330 usb_device_request_t req
;
2337 req
.bmRequestType
= type
;
2338 req
.bRequest
= which
;
2339 USETW(req
.wValue
, wValue
);
2340 USETW(req
.wIndex
, wIndex
);
2341 USETW(req
.wLength
, len
);
2353 DPRINTFN(2,("uaudio_set: type=0x%02x req=0x%02x wValue=0x%04x "
2354 "wIndex=0x%04x len=%d, val=%d\n",
2355 type
, which
, wValue
, wIndex
, len
, val
& 0xffff));
2356 err
= usbd_do_request(sc
->sc_udev
, &req
, data
);
2359 DPRINTF(("uaudio_set: err=%d\n", err
));
2364 uaudio_signext(int type
, int val
)
2366 if (!MIX_UNSIGNED(type
)) {
2367 if (MIX_SIZE(type
) == 2)
2376 uaudio_value2bsd(struct mixerctl
*mc
, int val
)
2378 DPRINTFN(5, ("uaudio_value2bsd: type=%03x val=%d min=%d max=%d ",
2379 mc
->type
, val
, mc
->minval
, mc
->maxval
));
2380 if (mc
->type
== MIX_ON_OFF
) {
2382 } else if (mc
->type
== MIX_SELECTOR
) {
2383 if (val
< mc
->minval
|| val
> mc
->maxval
)
2386 val
= ((uaudio_signext(mc
->type
, val
) - mc
->minval
) * 255
2387 + mc
->mul
/2) / mc
->mul
;
2388 DPRINTFN(5, ("val'=%d\n", val
));
2393 uaudio_bsd2value(struct mixerctl
*mc
, int val
)
2395 DPRINTFN(5,("uaudio_bsd2value: type=%03x val=%d min=%d max=%d ",
2396 mc
->type
, val
, mc
->minval
, mc
->maxval
));
2397 if (mc
->type
== MIX_ON_OFF
) {
2399 } else if (mc
->type
== MIX_SELECTOR
) {
2400 if (val
< mc
->minval
|| val
> mc
->maxval
)
2403 val
= (val
+ mc
->delta
/2) * mc
->mul
/ 255 + mc
->minval
;
2404 DPRINTFN(5, ("val'=%d\n", val
));
2409 uaudio_ctl_get(struct uaudio_softc
*sc
, int which
, struct mixerctl
*mc
,
2414 DPRINTFN(5,("uaudio_ctl_get: which=%d chan=%d\n", which
, chan
));
2415 val
= uaudio_get(sc
, which
, UT_READ_CLASS_INTERFACE
, mc
->wValue
[chan
],
2416 mc
->wIndex
, MIX_SIZE(mc
->type
));
2417 return uaudio_value2bsd(mc
, val
);
2421 uaudio_ctl_set(struct uaudio_softc
*sc
, int which
, struct mixerctl
*mc
,
2424 val
= uaudio_bsd2value(mc
, val
);
2425 uaudio_set(sc
, which
, UT_WRITE_CLASS_INTERFACE
, mc
->wValue
[chan
],
2426 mc
->wIndex
, MIX_SIZE(mc
->type
), val
);
2430 uaudio_mixer_get_port(void *addr
, mixer_ctrl_t
*cp
)
2432 struct uaudio_softc
*sc
;
2433 struct mixerctl
*mc
;
2434 int i
, n
, vals
[MIX_MAX_CHAN
], val
;
2436 DPRINTFN(2,("uaudio_mixer_get_port: index=%d\n", cp
->dev
));
2441 n
= cp
->dev
- UAC_NCLASSES
;
2442 if (n
< 0 || n
>= sc
->sc_nctls
)
2444 mc
= &sc
->sc_ctls
[n
];
2446 if (mc
->type
== MIX_ON_OFF
) {
2447 if (cp
->type
!= AUDIO_MIXER_ENUM
)
2449 cp
->un
.ord
= uaudio_ctl_get(sc
, GET_CUR
, mc
, 0);
2450 } else if (mc
->type
== MIX_SELECTOR
) {
2451 if (cp
->type
!= AUDIO_MIXER_ENUM
)
2453 cp
->un
.ord
= uaudio_ctl_get(sc
, GET_CUR
, mc
, 0);
2455 if (cp
->type
!= AUDIO_MIXER_VALUE
)
2457 if (cp
->un
.value
.num_channels
!= 1 &&
2458 cp
->un
.value
.num_channels
!= mc
->nchan
)
2460 for (i
= 0; i
< mc
->nchan
; i
++)
2461 vals
[i
] = uaudio_ctl_get(sc
, GET_CUR
, mc
, i
);
2462 if (cp
->un
.value
.num_channels
== 1 && mc
->nchan
!= 1) {
2463 for (val
= 0, i
= 0; i
< mc
->nchan
; i
++)
2465 vals
[0] = val
/ mc
->nchan
;
2467 for (i
= 0; i
< cp
->un
.value
.num_channels
; i
++)
2468 cp
->un
.value
.level
[i
] = vals
[i
];
2475 uaudio_mixer_set_port(void *addr
, mixer_ctrl_t
*cp
)
2477 struct uaudio_softc
*sc
;
2478 struct mixerctl
*mc
;
2479 int i
, n
, vals
[MIX_MAX_CHAN
];
2481 DPRINTFN(2,("uaudio_mixer_set_port: index = %d\n", cp
->dev
));
2486 n
= cp
->dev
- UAC_NCLASSES
;
2487 if (n
< 0 || n
>= sc
->sc_nctls
)
2489 mc
= &sc
->sc_ctls
[n
];
2491 if (mc
->type
== MIX_ON_OFF
) {
2492 if (cp
->type
!= AUDIO_MIXER_ENUM
)
2494 uaudio_ctl_set(sc
, SET_CUR
, mc
, 0, cp
->un
.ord
);
2495 } else if (mc
->type
== MIX_SELECTOR
) {
2496 if (cp
->type
!= AUDIO_MIXER_ENUM
)
2498 uaudio_ctl_set(sc
, SET_CUR
, mc
, 0, cp
->un
.ord
);
2500 if (cp
->type
!= AUDIO_MIXER_VALUE
)
2502 if (cp
->un
.value
.num_channels
== 1)
2503 for (i
= 0; i
< mc
->nchan
; i
++)
2504 vals
[i
] = cp
->un
.value
.level
[0];
2505 else if (cp
->un
.value
.num_channels
== mc
->nchan
)
2506 for (i
= 0; i
< mc
->nchan
; i
++)
2507 vals
[i
] = cp
->un
.value
.level
[i
];
2510 for (i
= 0; i
< mc
->nchan
; i
++)
2511 uaudio_ctl_set(sc
, SET_CUR
, mc
, i
, vals
[i
]);
2517 uaudio_trigger_input(void *addr
, void *start
, void *end
, int blksize
,
2518 void (*intr
)(void *), void *arg
,
2519 const audio_params_t
*param
)
2521 struct uaudio_softc
*sc
;
2530 DPRINTFN(3,("uaudio_trigger_input: sc=%p start=%p end=%p "
2531 "blksize=%d\n", sc
, start
, end
, blksize
));
2532 ch
= &sc
->sc_recchan
;
2533 uaudio_chan_set_param(ch
, start
, end
, blksize
);
2534 DPRINTFN(3,("uaudio_trigger_input: sample_size=%d bytes/frame=%d "
2535 "fraction=0.%03d\n", ch
->sample_size
, ch
->bytes_per_frame
,
2538 err
= uaudio_chan_alloc_buffers(sc
, ch
);
2542 err
= uaudio_chan_open(sc
, ch
);
2544 uaudio_chan_free_buffers(sc
, ch
);
2552 for (i
= 0; i
< UAUDIO_NCHANBUFS
-1; i
++) /* XXX -1 shouldn't be needed */
2553 uaudio_chan_rtransfer(ch
);
2560 uaudio_trigger_output(void *addr
, void *start
, void *end
, int blksize
,
2561 void (*intr
)(void *), void *arg
,
2562 const audio_params_t
*param
)
2564 struct uaudio_softc
*sc
;
2573 DPRINTFN(3,("uaudio_trigger_output: sc=%p start=%p end=%p "
2574 "blksize=%d\n", sc
, start
, end
, blksize
));
2575 ch
= &sc
->sc_playchan
;
2576 uaudio_chan_set_param(ch
, start
, end
, blksize
);
2577 DPRINTFN(3,("uaudio_trigger_output: sample_size=%d bytes/frame=%d "
2578 "fraction=0.%03d\n", ch
->sample_size
, ch
->bytes_per_frame
,
2581 err
= uaudio_chan_alloc_buffers(sc
, ch
);
2585 err
= uaudio_chan_open(sc
, ch
);
2587 uaudio_chan_free_buffers(sc
, ch
);
2595 for (i
= 0; i
< UAUDIO_NCHANBUFS
-1; i
++) /* XXX */
2596 uaudio_chan_ptransfer(ch
);
2602 /* Set up a pipe for a channel. */
2604 uaudio_chan_open(struct uaudio_softc
*sc
, struct chan
*ch
)
2610 as
= &sc
->sc_alts
[ch
->altidx
];
2611 endpt
= as
->edesc
->bEndpointAddress
;
2612 DPRINTF(("uaudio_chan_open: endpt=0x%02x, speed=%d, alt=%d\n",
2613 endpt
, ch
->sample_rate
, as
->alt
));
2615 /* Set alternate interface corresponding to the mode. */
2616 err
= usbd_set_interface(as
->ifaceh
, as
->alt
);
2621 * If just one sampling rate is supported,
2622 * no need to call uaudio_set_speed().
2623 * Roland SD-90 freezes by a SAMPLING_FREQ_CONTROL request.
2625 if (as
->asf1desc
->bSamFreqType
!= 1) {
2626 err
= uaudio_set_speed(sc
, endpt
, ch
->sample_rate
);
2628 DPRINTF(("uaudio_chan_open: set_speed failed err=%s\n",
2635 DPRINTF(("uaudio_chan_open: create pipe to 0x%02x\n", endpt
));
2636 err
= usbd_open_pipe(as
->ifaceh
, endpt
, 0, &ch
->pipe
);
2639 if (as
->edesc1
!= NULL
) {
2640 endpt
= as
->edesc1
->bEndpointAddress
;
2641 DPRINTF(("uaudio_chan_open: create sync-pipe to 0x%02x\n", endpt
));
2642 err
= usbd_open_pipe(as
->ifaceh
, endpt
, 0, &ch
->sync_pipe
);
2648 uaudio_chan_close(struct uaudio_softc
*sc
, struct chan
*ch
)
2652 as
= &sc
->sc_alts
[ch
->altidx
];
2654 AUFMT_VALIDATE(as
->aformat
);
2655 if (sc
->sc_nullalt
>= 0) {
2656 DPRINTF(("uaudio_chan_close: set null alt=%d\n",
2658 usbd_set_interface(as
->ifaceh
, sc
->sc_nullalt
);
2661 usbd_abort_pipe(ch
->pipe
);
2662 usbd_close_pipe(ch
->pipe
);
2664 if (ch
->sync_pipe
) {
2665 usbd_abort_pipe(ch
->sync_pipe
);
2666 usbd_close_pipe(ch
->sync_pipe
);
2671 uaudio_chan_alloc_buffers(struct uaudio_softc
*sc
, struct chan
*ch
)
2673 usbd_xfer_handle xfer
;
2677 size
= (ch
->bytes_per_frame
+ ch
->sample_size
) * UAUDIO_NFRAMES
;
2678 for (i
= 0; i
< UAUDIO_NCHANBUFS
; i
++) {
2679 xfer
= usbd_alloc_xfer(sc
->sc_udev
);
2682 ch
->chanbufs
[i
].xfer
= xfer
;
2683 tbuf
= usbd_alloc_buffer(xfer
, size
);
2688 ch
->chanbufs
[i
].buffer
= tbuf
;
2689 ch
->chanbufs
[i
].chan
= ch
;
2692 return USBD_NORMAL_COMPLETION
;
2696 /* implicit buffer free */
2697 usbd_free_xfer(ch
->chanbufs
[i
].xfer
);
2702 uaudio_chan_free_buffers(struct uaudio_softc
*sc
, struct chan
*ch
)
2706 for (i
= 0; i
< UAUDIO_NCHANBUFS
; i
++)
2707 usbd_free_xfer(ch
->chanbufs
[i
].xfer
);
2710 /* Called at splusb() */
2712 uaudio_chan_ptransfer(struct chan
*ch
)
2715 int i
, n
, size
, residue
, total
;
2717 if (ch
->sc
->sc_dying
)
2720 /* Pick the next channel buffer. */
2721 cb
= &ch
->chanbufs
[ch
->curchanbuf
];
2722 if (++ch
->curchanbuf
>= UAUDIO_NCHANBUFS
)
2725 /* Compute the size of each frame in the next transfer. */
2726 residue
= ch
->residue
;
2728 for (i
= 0; i
< UAUDIO_NFRAMES
; i
++) {
2729 size
= ch
->bytes_per_frame
;
2730 residue
+= ch
->fraction
;
2731 if (residue
>= USB_FRAMES_PER_SECOND
) {
2732 if ((ch
->sc
->sc_altflags
& UA_NOFRAC
) == 0)
2733 size
+= ch
->sample_size
;
2734 residue
-= USB_FRAMES_PER_SECOND
;
2736 cb
->sizes
[i
] = size
;
2739 ch
->residue
= residue
;
2743 * Transfer data from upper layer buffer to channel buffer, taking
2744 * care of wrapping the upper layer buffer.
2746 n
= min(total
, ch
->end
- ch
->cur
);
2747 memcpy(cb
->buffer
, ch
->cur
, n
);
2749 if (ch
->cur
>= ch
->end
)
2750 ch
->cur
= ch
->start
;
2753 memcpy(cb
->buffer
+ n
, ch
->cur
, total
);
2758 if (uaudiodebug
> 8) {
2759 DPRINTF(("uaudio_chan_ptransfer: buffer=%p, residue=0.%03d\n",
2760 cb
->buffer
, ch
->residue
));
2761 for (i
= 0; i
< UAUDIO_NFRAMES
; i
++) {
2762 DPRINTF((" [%d] length %d\n", i
, cb
->sizes
[i
]));
2767 DPRINTFN(5,("uaudio_chan_transfer: ptransfer xfer=%p\n", cb
->xfer
));
2768 /* Fill the request */
2769 usbd_setup_isoc_xfer(cb
->xfer
, ch
->pipe
, cb
, cb
->sizes
,
2770 UAUDIO_NFRAMES
, USBD_NO_COPY
,
2773 (void)usbd_transfer(cb
->xfer
);
2777 uaudio_chan_pintr(usbd_xfer_handle xfer
, usbd_private_handle priv
,
2787 /* Return if we are aborting. */
2788 if (status
== USBD_CANCELLED
)
2791 usbd_get_xfer_status(xfer
, NULL
, NULL
, &count
, NULL
);
2792 DPRINTFN(5,("uaudio_chan_pintr: count=%d, transferred=%d\n",
2793 count
, ch
->transferred
));
2795 if (count
!= cb
->size
) {
2796 aprint_error("uaudio_chan_pintr: count(%d) != size(%d)\n",
2801 ch
->transferred
+= cb
->size
;
2803 /* Call back to upper layer */
2804 while (ch
->transferred
>= ch
->blksize
) {
2805 ch
->transferred
-= ch
->blksize
;
2806 DPRINTFN(5,("uaudio_chan_pintr: call %p(%p)\n",
2807 ch
->intr
, ch
->arg
));
2812 /* start next transfer */
2813 uaudio_chan_ptransfer(ch
);
2816 /* Called at splusb() */
2818 uaudio_chan_rtransfer(struct chan
*ch
)
2821 int i
, size
, residue
, total
;
2823 if (ch
->sc
->sc_dying
)
2826 /* Pick the next channel buffer. */
2827 cb
= &ch
->chanbufs
[ch
->curchanbuf
];
2828 if (++ch
->curchanbuf
>= UAUDIO_NCHANBUFS
)
2831 /* Compute the size of each frame in the next transfer. */
2832 residue
= ch
->residue
;
2834 for (i
= 0; i
< UAUDIO_NFRAMES
; i
++) {
2835 size
= ch
->bytes_per_frame
;
2836 cb
->sizes
[i
] = size
;
2837 cb
->offsets
[i
] = total
;
2840 ch
->residue
= residue
;
2844 if (uaudiodebug
> 8) {
2845 DPRINTF(("uaudio_chan_rtransfer: buffer=%p, residue=0.%03d\n",
2846 cb
->buffer
, ch
->residue
));
2847 for (i
= 0; i
< UAUDIO_NFRAMES
; i
++) {
2848 DPRINTF((" [%d] length %d\n", i
, cb
->sizes
[i
]));
2853 DPRINTFN(5,("uaudio_chan_rtransfer: transfer xfer=%p\n", cb
->xfer
));
2854 /* Fill the request */
2855 usbd_setup_isoc_xfer(cb
->xfer
, ch
->pipe
, cb
, cb
->sizes
,
2856 UAUDIO_NFRAMES
, USBD_NO_COPY
,
2859 (void)usbd_transfer(cb
->xfer
);
2863 uaudio_chan_rintr(usbd_xfer_handle xfer
, usbd_private_handle priv
,
2869 int s
, i
, n
, frsize
;
2873 /* Return if we are aborting. */
2874 if (status
== USBD_CANCELLED
)
2877 usbd_get_xfer_status(xfer
, NULL
, NULL
, &count
, NULL
);
2878 DPRINTFN(5,("uaudio_chan_rintr: count=%d, transferred=%d\n",
2879 count
, ch
->transferred
));
2881 /* count < cb->size is normal for asynchronous source */
2883 if (count
> cb
->size
) {
2884 aprint_error("uaudio_chan_rintr: count(%d) > size(%d)\n",
2890 * Transfer data from channel buffer to upper layer buffer, taking
2891 * care of wrapping the upper layer buffer.
2893 for(i
= 0; i
< UAUDIO_NFRAMES
; i
++) {
2894 frsize
= cb
->sizes
[i
];
2895 n
= min(frsize
, ch
->end
- ch
->cur
);
2896 memcpy(ch
->cur
, cb
->buffer
+ cb
->offsets
[i
], n
);
2898 if (ch
->cur
>= ch
->end
)
2899 ch
->cur
= ch
->start
;
2901 memcpy(ch
->cur
, cb
->buffer
+ cb
->offsets
[i
] + n
,
2903 ch
->cur
+= frsize
- n
;
2907 /* Call back to upper layer */
2908 ch
->transferred
+= count
;
2910 while (ch
->transferred
>= ch
->blksize
) {
2911 ch
->transferred
-= ch
->blksize
;
2912 DPRINTFN(5,("uaudio_chan_rintr: call %p(%p)\n",
2913 ch
->intr
, ch
->arg
));
2918 /* start next transfer */
2919 uaudio_chan_rtransfer(ch
);
2923 uaudio_chan_init(struct chan
*ch
, int altidx
, const struct audio_params
*param
,
2926 int samples_per_frame
, sample_size
;
2928 ch
->altidx
= altidx
;
2929 sample_size
= param
->precision
* param
->channels
/ 8;
2930 samples_per_frame
= param
->sample_rate
/ USB_FRAMES_PER_SECOND
;
2931 ch
->sample_size
= sample_size
;
2932 ch
->sample_rate
= param
->sample_rate
;
2933 if (maxpktsize
== 0) {
2934 ch
->fraction
= param
->sample_rate
% USB_FRAMES_PER_SECOND
;
2935 ch
->bytes_per_frame
= samples_per_frame
* sample_size
;
2938 ch
->bytes_per_frame
= maxpktsize
;
2944 uaudio_chan_set_param(struct chan
*ch
, u_char
*start
, u_char
*end
, int blksize
)
2950 ch
->blksize
= blksize
;
2951 ch
->transferred
= 0;
2956 uaudio_set_params(void *addr
, int setmode
, int usemode
,
2957 struct audio_params
*play
, struct audio_params
*rec
,
2958 stream_filter_list_t
*pfil
, stream_filter_list_t
*rfil
)
2960 struct uaudio_softc
*sc
;
2961 int paltidx
, raltidx
;
2962 struct audio_params
*p
;
2963 stream_filter_list_t
*fil
;
2972 if (((usemode
& AUMODE_PLAY
) && sc
->sc_playchan
.pipe
!= NULL
) ||
2973 ((usemode
& AUMODE_RECORD
) && sc
->sc_recchan
.pipe
!= NULL
))
2976 if ((usemode
& AUMODE_PLAY
) && sc
->sc_playchan
.altidx
!= -1) {
2977 sc
->sc_alts
[sc
->sc_playchan
.altidx
].sc_busy
= 0;
2978 AUFMT_VALIDATE(sc
->sc_alts
[sc
->sc_playchan
.altidx
].aformat
);
2980 if ((usemode
& AUMODE_RECORD
) && sc
->sc_recchan
.altidx
!= -1) {
2981 sc
->sc_alts
[sc
->sc_recchan
.altidx
].sc_busy
= 0;
2982 AUFMT_VALIDATE(sc
->sc_alts
[sc
->sc_recchan
.altidx
].aformat
);
2985 /* Some uaudio devices are unidirectional. Don't try to find a
2986 matching mode for the unsupported direction. */
2987 setmode
&= sc
->sc_mode
;
2989 for (mode
= AUMODE_RECORD
; mode
!= -1;
2990 mode
= mode
== AUMODE_RECORD
? AUMODE_PLAY
: -1) {
2991 if ((setmode
& mode
) == 0)
2994 if (mode
== AUMODE_PLAY
) {
3001 i
= auconv_set_converter(sc
->sc_formats
, sc
->sc_nformats
,
3002 mode
, p
, TRUE
, fil
);
3006 if (mode
== AUMODE_PLAY
)
3012 if ((setmode
& AUMODE_PLAY
)) {
3013 p
= pfil
->req_size
> 0 ? &pfil
->filters
[0].param
: play
;
3014 /* XXX abort transfer if currently happening? */
3015 uaudio_chan_init(&sc
->sc_playchan
, paltidx
, p
, 0);
3017 if ((setmode
& AUMODE_RECORD
)) {
3018 p
= rfil
->req_size
> 0 ? &pfil
->filters
[0].param
: rec
;
3019 /* XXX abort transfer if currently happening? */
3020 uaudio_chan_init(&sc
->sc_recchan
, raltidx
, p
,
3021 UGETW(sc
->sc_alts
[raltidx
].edesc
->wMaxPacketSize
));
3024 if ((usemode
& AUMODE_PLAY
) && sc
->sc_playchan
.altidx
!= -1) {
3025 sc
->sc_alts
[sc
->sc_playchan
.altidx
].sc_busy
= 1;
3026 AUFMT_INVALIDATE(sc
->sc_alts
[sc
->sc_playchan
.altidx
].aformat
);
3028 if ((usemode
& AUMODE_RECORD
) && sc
->sc_recchan
.altidx
!= -1) {
3029 sc
->sc_alts
[sc
->sc_recchan
.altidx
].sc_busy
= 1;
3030 AUFMT_INVALIDATE(sc
->sc_alts
[sc
->sc_recchan
.altidx
].aformat
);
3033 DPRINTF(("uaudio_set_params: use altidx=p%d/r%d, altno=p%d/r%d\n",
3034 sc
->sc_playchan
.altidx
, sc
->sc_recchan
.altidx
,
3035 (sc
->sc_playchan
.altidx
>= 0)
3036 ?sc
->sc_alts
[sc
->sc_playchan
.altidx
].idesc
->bAlternateSetting
3038 (sc
->sc_recchan
.altidx
>= 0)
3039 ? sc
->sc_alts
[sc
->sc_recchan
.altidx
].idesc
->bAlternateSetting
3046 uaudio_set_speed(struct uaudio_softc
*sc
, int endpt
, u_int speed
)
3048 usb_device_request_t req
;
3051 DPRINTFN(5,("uaudio_set_speed: endpt=%d speed=%u\n", endpt
, speed
));
3052 req
.bmRequestType
= UT_WRITE_CLASS_ENDPOINT
;
3053 req
.bRequest
= SET_CUR
;
3054 USETW2(req
.wValue
, SAMPLING_FREQ_CONTROL
, 0);
3055 USETW(req
.wIndex
, endpt
);
3056 USETW(req
.wLength
, 3);
3058 data
[1] = speed
>> 8;
3059 data
[2] = speed
>> 16;
3061 return usbd_do_request(sc
->sc_udev
, &req
, data
);
3066 MODULE(MODULE_CLASS_DRIVER
, uaudio
, NULL
);
3068 static const struct cfiattrdata audiobuscf_iattrdata
= {
3069 "audiobus", 0, { { NULL
, NULL
, 0 }, }
3071 static const struct cfiattrdata
* const uaudio_attrs
[] = {
3072 &audiobuscf_iattrdata
, NULL
3074 CFDRIVER_DECL(uaudio
, DV_DULL
, uaudio_attrs
);
3075 extern struct cfattach uaudio_ca
;
3076 static int uaudioloc
[6/*USBIFIFCF_NLOCS*/] = {
3077 -1/*USBIFIFCF_PORT_DEFAULT*/,
3078 -1/*USBIFIFCF_CONFIGURATION_DEFAULT*/,
3079 -1/*USBIFIFCF_INTERFACE_DEFAULT*/,
3080 -1/*USBIFIFCF_VENDOR_DEFAULT*/,
3081 -1/*USBIFIFCF_PRODUCT_DEFAULT*/,
3082 -1/*USBIFIFCF_RELEASE_DEFAULT*/};
3083 static struct cfparent uhubparent
= {
3084 "usbifif", NULL
, DVUNIT_ANY
3086 static struct cfdata uaudio_cfdata
[] = {
3088 .cf_name
= "uaudio",
3089 .cf_atname
= "uaudio",
3091 .cf_fstate
= FSTATE_STAR
,
3092 .cf_loc
= uaudioloc
,
3094 .cf_pspec
= &uhubparent
,
3100 uaudio_modcmd(modcmd_t cmd
, void *arg
)
3105 case MODULE_CMD_INIT
:
3106 err
= config_cfdriver_attach(&uaudio_cd
);
3110 err
= config_cfattach_attach("uaudio", &uaudio_ca
);
3112 config_cfdriver_detach(&uaudio_cd
);
3115 err
= config_cfdata_attach(uaudio_cfdata
, 1);
3117 config_cfattach_detach("uaudio", &uaudio_ca
);
3118 config_cfdriver_detach(&uaudio_cd
);
3122 case MODULE_CMD_FINI
:
3123 err
= config_cfdata_detach(uaudio_cfdata
);
3126 config_cfattach_detach("uaudio", &uaudio_ca
);
3127 config_cfdriver_detach(&uaudio_cd
);