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