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