uaudio.c revision 1.37 1 /* $NetBSD: uaudio.c,v 1.37 2001/01/04 06:20:49 mycroft Exp $ */
2
3 /*
4 * Copyright (c) 1999 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 (at) augustsson.net) at
9 * Carlstedt Research & Technology.
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 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the NetBSD
22 * Foundation, Inc. and its contributors.
23 * 4. Neither the name of The NetBSD Foundation nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40 /*
41 * USB audio specs: http://www.usb.org/developers/data/devclass/audio10.pdf
42 * http://www.usb.org/developers/data/devclass/frmts10.pdf
43 * http://www.usb.org/developers/data/devclass/termt10.pdf
44 */
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/tty.h>
53 #include <sys/file.h>
54 #include <sys/select.h>
55 #include <sys/proc.h>
56 #include <sys/vnode.h>
57 #include <sys/device.h>
58 #include <sys/poll.h>
59
60 #include <sys/audioio.h>
61 #include <dev/audio_if.h>
62 #include <dev/mulaw.h>
63 #include <dev/auconv.h>
64
65 #include <dev/usb/usb.h>
66 #include <dev/usb/usbdi.h>
67 #include <dev/usb/usbdi_util.h>
68 #include <dev/usb/usb_quirks.h>
69
70 #include <dev/usb/uaudioreg.h>
71
72 #define UAUDIO_DEBUG
73 #ifdef UAUDIO_DEBUG
74 #define DPRINTF(x) if (uaudiodebug) logprintf x
75 #define DPRINTFN(n,x) if (uaudiodebug>(n)) logprintf x
76 int uaudiodebug = 0;
77 #else
78 #define DPRINTF(x)
79 #define DPRINTFN(n,x)
80 #endif
81
82 #define UAUDIO_NCHANBUFS 6 /* number of outstanding request */
83 #define UAUDIO_NFRAMES 20 /* ms of sound in each request */
84
85
86 #define MIX_MAX_CHAN 8
87 struct mixerctl {
88 u_int16_t wValue[MIX_MAX_CHAN]; /* using nchan */
89 u_int16_t wIndex;
90 u_int8_t nchan;
91 u_int8_t type;
92 #define MIX_ON_OFF 1
93 #define MIX_SIGNED_16 2
94 #define MIX_UNSIGNED_16 3
95 #define MIX_SIGNED_8 4
96 #define MIX_SIZE(n) ((n) == MIX_SIGNED_16 || (n) == MIX_UNSIGNED_16 ? 2 : 1)
97 #define MIX_UNSIGNED(n) ((n) == MIX_UNSIGNED_16)
98 int minval, maxval;
99 u_int delta;
100 u_int mul;
101 u_int8_t class;
102 char ctlname[MAX_AUDIO_DEV_LEN];
103 char *ctlunit;
104 };
105 #define MAKE(h,l) (((h) << 8) | (l))
106
107 struct as_info {
108 u_int8_t alt;
109 u_int8_t encoding;
110 usbd_interface_handle ifaceh;
111 usb_interface_descriptor_t *idesc;
112 usb_endpoint_descriptor_audio_t *edesc;
113 struct usb_audio_streaming_type1_descriptor *asf1desc;
114 };
115
116 struct chan {
117 int terminal; /* terminal id */
118 void (*intr)(void *); /* dma completion intr handler */
119 void *arg; /* arg for intr() */
120 usbd_pipe_handle pipe;
121 int dir; /* direction */
122 #define IN 0x01
123 #define OUT 0x02
124
125 u_int sample_size;
126 u_int sample_rate;
127 u_int bytes_per_frame;
128 u_int fraction; /* fraction/1000 is the extra samples/frame */
129 u_int residue; /* accumulates the fractional samples */
130
131 u_char *start; /* upper layer buffer start */
132 u_char *end; /* upper layer buffer end */
133 u_char *cur; /* current position in upper layer buffer */
134 int blksize; /* chunk size to report up */
135 int transferred; /* transferred bytes not reported up */
136
137 char nofrac; /* don't do sample rate adjustment */
138
139 int curchanbuf;
140 struct chanbuf {
141 struct chan *chan;
142 usbd_xfer_handle xfer;
143 u_char *buffer;
144 u_int16_t sizes[UAUDIO_NFRAMES];
145 u_int16_t size;
146 } chanbufs[UAUDIO_NCHANBUFS];
147
148 struct uaudio_softc *sc; /* our softc */
149 };
150
151 struct uaudio_softc {
152 USBBASEDEVICE sc_dev; /* base device */
153 usbd_device_handle sc_udev; /* USB device */
154
155 int sc_ac_iface; /* Audio Control interface */
156 usbd_interface_handle sc_ac_ifaceh;
157
158 struct chan sc_chan;
159
160 int sc_curaltidx;
161
162 int sc_nullalt;
163
164 int sc_audio_rev;
165
166 struct as_info *sc_alts;
167 int sc_nalts;
168 int sc_props;
169
170 int sc_altflags;
171 #define HAS_8 0x01
172 #define HAS_16 0x02
173 #define HAS_8U 0x04
174 #define HAS_ALAW 0x08
175 #define HAS_MULAW 0x10
176
177 struct mixerctl *sc_ctls;
178 int sc_nctls;
179
180 device_ptr_t sc_audiodev;
181 char sc_dying;
182 };
183
184 #define UAC_OUTPUT 0
185 #define UAC_INPUT 1
186 #define UAC_EQUAL 2
187
188 Static usbd_status uaudio_identify_ac(struct uaudio_softc *sc,
189 usb_config_descriptor_t *cdesc);
190 Static usbd_status uaudio_identify_as(struct uaudio_softc *sc,
191 usb_config_descriptor_t *cdesc);
192 Static usbd_status uaudio_process_as(struct uaudio_softc *sc,
193 char *buf, int *offsp, int size,
194 usb_interface_descriptor_t *id);
195
196 Static void uaudio_add_alt(struct uaudio_softc *sc,
197 struct as_info *ai);
198
199 Static usb_interface_descriptor_t *uaudio_find_iface(char *buf,
200 int size, int *offsp, int subtype);
201
202 Static void uaudio_mixer_add_ctl(struct uaudio_softc *sc,
203 struct mixerctl *mp);
204 Static char *uaudio_id_name(struct uaudio_softc *sc,
205 usb_descriptor_t **dps, int id);
206 Static struct usb_audio_cluster uaudio_get_cluster(int id,
207 usb_descriptor_t **dps);
208 Static void uaudio_add_input(struct uaudio_softc *sc,
209 usb_descriptor_t *v, usb_descriptor_t **dps);
210 Static void uaudio_add_output(struct uaudio_softc *sc,
211 usb_descriptor_t *v, usb_descriptor_t **dps);
212 Static void uaudio_add_mixer(struct uaudio_softc *sc,
213 usb_descriptor_t *v, usb_descriptor_t **dps);
214 Static void uaudio_add_selector(struct uaudio_softc *sc,
215 usb_descriptor_t *v, usb_descriptor_t **dps);
216 Static void uaudio_add_feature(struct uaudio_softc *sc,
217 usb_descriptor_t *v, usb_descriptor_t **dps);
218 Static void uaudio_add_processing_updown(struct uaudio_softc *sc,
219 usb_descriptor_t *v, usb_descriptor_t **dps);
220 Static void uaudio_add_processing(struct uaudio_softc *sc,
221 usb_descriptor_t *v, usb_descriptor_t **dps);
222 Static void uaudio_add_extension(struct uaudio_softc *sc,
223 usb_descriptor_t *v, usb_descriptor_t **dps);
224 Static usbd_status uaudio_identify(struct uaudio_softc *sc,
225 usb_config_descriptor_t *cdesc);
226
227 Static int uaudio_signext(int type, int val);
228 Static int uaudio_value2bsd(struct mixerctl *mc, int val);
229 Static int uaudio_bsd2value(struct mixerctl *mc, int val);
230 Static int uaudio_get(struct uaudio_softc *sc, int type,
231 int which, int wValue, int wIndex, int len);
232 Static int uaudio_ctl_get(struct uaudio_softc *sc, int which,
233 struct mixerctl *mc, int chan);
234 Static void uaudio_set(struct uaudio_softc *sc, int type,
235 int which, int wValue, int wIndex, int l, int v);
236 Static void uaudio_ctl_set(struct uaudio_softc *sc, int which,
237 struct mixerctl *mc, int chan, int val);
238
239 Static usbd_status uaudio_set_speed(struct uaudio_softc *, int, u_int);
240
241 Static usbd_status uaudio_chan_open(struct uaudio_softc *sc,
242 struct chan *ch);
243 Static void uaudio_chan_close(struct uaudio_softc *sc,
244 struct chan *ch);
245 Static usbd_status uaudio_chan_alloc_buffers(struct uaudio_softc *,
246 struct chan *);
247 Static void uaudio_chan_free_buffers(struct uaudio_softc *,
248 struct chan *);
249 Static void uaudio_chan_set_param(struct chan *ch,
250 struct audio_params *param, u_char *start,
251 u_char *end, int blksize);
252 Static void uaudio_chan_ptransfer(struct chan *ch);
253 Static void uaudio_chan_pintr(usbd_xfer_handle xfer,
254 usbd_private_handle priv, usbd_status status);
255
256 Static void uaudio_chan_rtransfer(struct chan *ch);
257 Static void uaudio_chan_rintr(usbd_xfer_handle xfer,
258 usbd_private_handle priv, usbd_status status);
259
260 Static int uaudio_open(void *, int);
261 Static void uaudio_close(void *);
262 Static int uaudio_drain(void *);
263 Static int uaudio_query_encoding(void *, struct audio_encoding *);
264 Static int uaudio_set_params(void *, int, int,
265 struct audio_params *, struct audio_params *);
266 Static int uaudio_round_blocksize(void *, int);
267 Static int uaudio_trigger_output(void *, void *, void *,
268 int, void (*)(void *), void *,
269 struct audio_params *);
270 Static int uaudio_trigger_input (void *, void *, void *,
271 int, void (*)(void *), void *,
272 struct audio_params *);
273 Static int uaudio_halt_in_dma(void *);
274 Static int uaudio_halt_out_dma(void *);
275 Static int uaudio_getdev(void *, struct audio_device *);
276 Static int uaudio_mixer_set_port(void *, mixer_ctrl_t *);
277 Static int uaudio_mixer_get_port(void *, mixer_ctrl_t *);
278 Static int uaudio_query_devinfo(void *, mixer_devinfo_t *);
279 Static int uaudio_get_props(void *);
280
281 Static struct audio_hw_if uaudio_hw_if = {
282 uaudio_open,
283 uaudio_close,
284 uaudio_drain,
285 uaudio_query_encoding,
286 uaudio_set_params,
287 uaudio_round_blocksize,
288 NULL,
289 NULL,
290 NULL,
291 NULL,
292 NULL,
293 uaudio_halt_out_dma,
294 uaudio_halt_in_dma,
295 NULL,
296 uaudio_getdev,
297 NULL,
298 uaudio_mixer_set_port,
299 uaudio_mixer_get_port,
300 uaudio_query_devinfo,
301 NULL,
302 NULL,
303 NULL,
304 NULL,
305 uaudio_get_props,
306 uaudio_trigger_output,
307 uaudio_trigger_input,
308 };
309
310 Static struct audio_device uaudio_device = {
311 "USB audio",
312 "",
313 "uaudio"
314 };
315
316 USB_DECLARE_DRIVER(uaudio);
317
318 USB_MATCH(uaudio)
319 {
320 USB_MATCH_START(uaudio, uaa);
321 usb_interface_descriptor_t *id;
322
323 if (uaa->iface == NULL)
324 return (UMATCH_NONE);
325
326 id = usbd_get_interface_descriptor(uaa->iface);
327 /* Trigger on the control interface. */
328 if (id == NULL ||
329 id->bInterfaceClass != UICLASS_AUDIO ||
330 id->bInterfaceSubClass != UISUBCLASS_AUDIOCONTROL ||
331 (usbd_get_quirks(uaa->device)->uq_flags & UQ_BAD_AUDIO))
332 return (UMATCH_NONE);
333
334 return (UMATCH_IFACECLASS_IFACESUBCLASS);
335 }
336
337 USB_ATTACH(uaudio)
338 {
339 USB_ATTACH_START(uaudio, sc, uaa);
340 usb_interface_descriptor_t *id;
341 usb_config_descriptor_t *cdesc;
342 char devinfo[1024];
343 usbd_status err;
344 int i, j, found;
345
346 usbd_devinfo(uaa->device, 0, devinfo);
347 printf(": %s\n", devinfo);
348
349 sc->sc_udev = uaa->device;
350
351 cdesc = usbd_get_config_descriptor(sc->sc_udev);
352 if (cdesc == NULL) {
353 printf("%s: failed to get configuration descriptor\n",
354 USBDEVNAME(sc->sc_dev));
355 USB_ATTACH_ERROR_RETURN;
356 }
357
358 err = uaudio_identify(sc, cdesc);
359 if (err) {
360 printf("%s: audio descriptors make no sense, error=%d\n",
361 USBDEVNAME(sc->sc_dev), err);
362 USB_ATTACH_ERROR_RETURN;
363 }
364
365 sc->sc_ac_ifaceh = uaa->iface;
366 /* Pick up the AS interface. */
367 for (i = 0; i < uaa->nifaces; i++) {
368 if (uaa->ifaces[i] == NULL)
369 continue;
370 id = usbd_get_interface_descriptor(uaa->ifaces[i]);
371 if (id == NULL)
372 continue;
373 found = 0;
374 for (j = 0; j < sc->sc_nalts; j++) {
375 if (id->bInterfaceNumber ==
376 sc->sc_alts[j].idesc->bInterfaceNumber) {
377 sc->sc_alts[j].ifaceh = uaa->ifaces[i];
378 found = 1;
379 }
380 }
381 if (found)
382 uaa->ifaces[i] = NULL;
383 }
384
385 for (j = 0; j < sc->sc_nalts; j++) {
386 if (sc->sc_alts[j].ifaceh == NULL) {
387 printf("%s: alt %d missing AS interface(s)\n", USBDEVNAME(sc->sc_dev), j);
388 USB_ATTACH_ERROR_RETURN;
389 }
390 }
391
392 printf("%s: audio rev %d.%02x\n",
393 USBDEVNAME(sc->sc_dev),
394 sc->sc_audio_rev >> 8, sc->sc_audio_rev & 0xff);
395
396 sc->sc_chan.sc = sc;
397
398 if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_FRAC)
399 sc->sc_chan.nofrac = 1;
400
401 DPRINTF(("uaudio_attach: doing audio_attach_mi\n"));
402 #if defined(__OpenBSD__)
403 audio_attach_mi(&uaudio_hw_if, sc, &sc->sc_dev);
404 #else
405 sc->sc_audiodev = audio_attach_mi(&uaudio_hw_if, sc, &sc->sc_dev);
406 #endif
407
408 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
409 USBDEV(sc->sc_dev));
410
411 USB_ATTACH_SUCCESS_RETURN;
412 }
413
414 int
415 uaudio_activate(device_ptr_t self, enum devact act)
416 {
417 struct uaudio_softc *sc = (struct uaudio_softc *)self;
418 int rv = 0;
419
420 switch (act) {
421 case DVACT_ACTIVATE:
422 return (EOPNOTSUPP);
423 break;
424
425 case DVACT_DEACTIVATE:
426 if (sc->sc_audiodev)
427 rv = config_deactivate(sc->sc_audiodev);
428 sc->sc_dying = 1;
429 break;
430 }
431 return (rv);
432 }
433
434 int
435 uaudio_detach(device_ptr_t self, int flags)
436 {
437 struct uaudio_softc *sc = (struct uaudio_softc *)self;
438 int rv = 0;
439
440 /* Wait for outstanding requests to complete. */
441 usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES);
442
443 if (sc->sc_audiodev != NULL)
444 rv = config_detach(sc->sc_audiodev, flags);
445
446 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
447 USBDEV(sc->sc_dev));
448
449 return (rv);
450 }
451
452 int
453 uaudio_query_encoding(void *addr, struct audio_encoding *fp)
454 {
455 struct uaudio_softc *sc = addr;
456 int flags = sc->sc_altflags;
457 int idx;
458
459 if (sc->sc_dying)
460 return (EIO);
461
462 if (sc->sc_nalts == 0 || flags == 0)
463 return (ENXIO);
464
465 idx = fp->index;
466 switch (idx) {
467 case 0:
468 strcpy(fp->name, AudioEulinear);
469 fp->encoding = AUDIO_ENCODING_ULINEAR;
470 fp->precision = 8;
471 fp->flags = flags&HAS_8U ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
472 return (0);
473 case 1:
474 strcpy(fp->name, AudioEmulaw);
475 fp->encoding = AUDIO_ENCODING_ULAW;
476 fp->precision = 8;
477 fp->flags = flags&HAS_MULAW ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
478 return (0);
479 case 2:
480 strcpy(fp->name, AudioEalaw);
481 fp->encoding = AUDIO_ENCODING_ALAW;
482 fp->precision = 8;
483 fp->flags = flags&HAS_ALAW ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
484 return (0);
485 case 3:
486 strcpy(fp->name, AudioEslinear);
487 fp->encoding = AUDIO_ENCODING_SLINEAR;
488 fp->precision = 8;
489 fp->flags = flags&HAS_8 ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
490 return (0);
491 case 4:
492 strcpy(fp->name, AudioEslinear_le);
493 fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
494 fp->precision = 16;
495 fp->flags = 0;
496 return (0);
497 case 5:
498 strcpy(fp->name, AudioEulinear_le);
499 fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
500 fp->precision = 16;
501 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
502 return (0);
503 case 6:
504 strcpy(fp->name, AudioEslinear_be);
505 fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
506 fp->precision = 16;
507 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
508 return (0);
509 case 7:
510 strcpy(fp->name, AudioEulinear_be);
511 fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
512 fp->precision = 16;
513 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
514 return (0);
515 default:
516 return (EINVAL);
517 }
518 }
519
520 usb_interface_descriptor_t *
521 uaudio_find_iface(char *buf, int size, int *offsp, int subtype)
522 {
523 usb_interface_descriptor_t *d;
524
525 while (*offsp < size) {
526 d = (void *)(buf + *offsp);
527 *offsp += d->bLength;
528 if (d->bDescriptorType == UDESC_INTERFACE &&
529 d->bInterfaceClass == UICLASS_AUDIO &&
530 d->bInterfaceSubClass == subtype)
531 return (d);
532 }
533 return (0);
534 }
535
536 void
537 uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct mixerctl *mc)
538 {
539 int res;
540
541 if (sc->sc_nctls == 0)
542 sc->sc_ctls = malloc(sizeof *mc, M_USBDEV, M_NOWAIT);
543 else
544 sc->sc_ctls = realloc(sc->sc_ctls,
545 (sc->sc_nctls+1) * sizeof *mc,
546 M_USBDEV, M_NOWAIT);
547 if (sc->sc_ctls == NULL) {
548 printf("uaudio_mixer_add_ctl: no memory\n");
549 return;
550 }
551
552 mc->delta = 0;
553 if (mc->type != MIX_ON_OFF) {
554 /* Determine min and max values. */
555 mc->minval = uaudio_signext(mc->type,
556 uaudio_get(sc, GET_MIN, UT_READ_CLASS_INTERFACE,
557 mc->wValue[0], mc->wIndex,
558 MIX_SIZE(mc->type)));
559 mc->maxval = 1 + uaudio_signext(mc->type,
560 uaudio_get(sc, GET_MAX, UT_READ_CLASS_INTERFACE,
561 mc->wValue[0], mc->wIndex,
562 MIX_SIZE(mc->type)));
563 mc->mul = mc->maxval - mc->minval;
564 if (mc->mul == 0)
565 mc->mul = 1;
566 res = uaudio_get(sc, GET_RES, UT_READ_CLASS_INTERFACE,
567 mc->wValue[0], mc->wIndex,
568 MIX_SIZE(mc->type));
569 if (res > 0)
570 mc->delta = (res * 256 + mc->mul/2) / mc->mul;
571 } else {
572 mc->minval = 0;
573 mc->maxval = 1;
574 }
575
576 sc->sc_ctls[sc->sc_nctls++] = *mc;
577
578 #ifdef UAUDIO_DEBUG
579 if (uaudiodebug > 2) {
580 int i;
581 DPRINTF(("uaudio_mixer_add_ctl: wValue=%04x",mc->wValue[0]));
582 for (i = 1; i < mc->nchan; i++)
583 DPRINTF((",%04x", mc->wValue[i]));
584 DPRINTF((" wIndex=%04x type=%d name='%s' unit='%s' "
585 "min=%d max=%d\n",
586 mc->wIndex, mc->type, mc->ctlname, mc->ctlunit,
587 mc->minval, mc->maxval));
588 }
589 #endif
590 }
591
592 char *
593 uaudio_id_name(struct uaudio_softc *sc, usb_descriptor_t **dps, int id)
594 {
595 static char buf[32];
596 sprintf(buf, "i%d", id);
597 return (buf);
598 }
599
600 struct usb_audio_cluster
601 uaudio_get_cluster(int id, usb_descriptor_t **dps)
602 {
603 struct usb_audio_cluster r;
604 usb_descriptor_t *dp;
605 int i;
606
607 for (i = 0; i < 25; i++) { /* avoid infinite loops */
608 dp = dps[id];
609 if (dp == 0)
610 goto bad;
611 switch (dp->bDescriptorSubtype) {
612 case UDESCSUB_AC_INPUT:
613 #define p ((struct usb_audio_input_terminal *)dp)
614 r.bNrChannels = p->bNrChannels;
615 USETW(r.wChannelConfig, UGETW(p->wChannelConfig));
616 r.iChannelNames = p->iChannelNames;
617 #undef p
618 return (r);
619 case UDESCSUB_AC_OUTPUT:
620 #define p ((struct usb_audio_output_terminal *)dp)
621 id = p->bSourceId;
622 #undef p
623 break;
624 case UDESCSUB_AC_MIXER:
625 #define p ((struct usb_audio_mixer_unit *)dp)
626 r = *(struct usb_audio_cluster *)
627 &p->baSourceId[p->bNrInPins];
628 #undef p
629 return (r);
630 case UDESCSUB_AC_SELECTOR:
631 /* XXX This is not really right */
632 #define p ((struct usb_audio_selector_unit *)dp)
633 id = p->baSourceId[0];
634 #undef p
635 break;
636 case UDESCSUB_AC_FEATURE:
637 #define p ((struct usb_audio_feature_unit *)dp)
638 id = p->bSourceId;
639 #undef p
640 break;
641 case UDESCSUB_AC_PROCESSING:
642 #define p ((struct usb_audio_processing_unit *)dp)
643 r = *(struct usb_audio_cluster *)
644 &p->baSourceId[p->bNrInPins];
645 #undef p
646 return (r);
647 case UDESCSUB_AC_EXTENSION:
648 #define p ((struct usb_audio_extension_unit *)dp)
649 r = *(struct usb_audio_cluster *)
650 &p->baSourceId[p->bNrInPins];
651 #undef p
652 return (r);
653 default:
654 goto bad;
655 }
656 }
657 bad:
658 printf("uaudio_get_cluster: bad data\n");
659 memset(&r, 0, sizeof r);
660 return (r);
661
662 }
663
664 void
665 uaudio_add_input(struct uaudio_softc *sc, usb_descriptor_t *v,
666 usb_descriptor_t **dps)
667 {
668 #ifdef UAUDIO_DEBUG
669 struct usb_audio_input_terminal *d =
670 (struct usb_audio_input_terminal *)v;
671
672 DPRINTFN(2,("uaudio_add_input: bTerminalId=%d wTerminalType=0x%04x "
673 "bAssocTerminal=%d bNrChannels=%d wChannelConfig=%d "
674 "iChannelNames=%d iTerminal=%d\n",
675 d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal,
676 d->bNrChannels, UGETW(d->wChannelConfig),
677 d->iChannelNames, d->iTerminal));
678 #endif
679 }
680
681 void
682 uaudio_add_output(struct uaudio_softc *sc, usb_descriptor_t *v,
683 usb_descriptor_t **dps)
684 {
685 #ifdef UAUDIO_DEBUG
686 struct usb_audio_output_terminal *d =
687 (struct usb_audio_output_terminal *)v;
688
689 DPRINTFN(2,("uaudio_add_output: bTerminalId=%d wTerminalType=0x%04x "
690 "bAssocTerminal=%d bSourceId=%d iTerminal=%d\n",
691 d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal,
692 d->bSourceId, d->iTerminal));
693 #endif
694 }
695
696 void
697 uaudio_add_mixer(struct uaudio_softc *sc, usb_descriptor_t *v,
698 usb_descriptor_t **dps)
699 {
700 struct usb_audio_mixer_unit *d = (struct usb_audio_mixer_unit *)v;
701 struct usb_audio_mixer_unit_1 *d1;
702 int c, chs, ichs, ochs, i, o, bno, p, mo, mc, k;
703 uByte *bm;
704 struct mixerctl mix;
705
706 DPRINTFN(2,("uaudio_add_mixer: bUnitId=%d bNrInPins=%d\n",
707 d->bUnitId, d->bNrInPins));
708
709 /* Compute the number of input channels */
710 ichs = 0;
711 for (i = 0; i < d->bNrInPins; i++)
712 ichs += uaudio_get_cluster(d->baSourceId[i], dps).bNrChannels;
713
714 /* and the number of output channels */
715 d1 = (struct usb_audio_mixer_unit_1 *)&d->baSourceId[d->bNrInPins];
716 ochs = d1->bNrChannels;
717 DPRINTFN(2,("uaudio_add_mixer: ichs=%d ochs=%d\n", ichs, ochs));
718
719 bm = d1->bmControls;
720 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
721 mix.class = -1;
722 mix.type = MIX_SIGNED_16;
723 mix.ctlunit = AudioNvolume;
724 #define BIT(bno) ((bm[bno / 8] >> (7 - bno % 8)) & 1)
725 for (p = i = 0; i < d->bNrInPins; i++) {
726 chs = uaudio_get_cluster(d->baSourceId[i], dps).bNrChannels;
727 mc = 0;
728 for (c = 0; c < chs; c++) {
729 mo = 0;
730 for (o = 0; o < ochs; o++) {
731 bno = (p + c) * ochs + o;
732 if (BIT(bno))
733 mo++;
734 }
735 if (mo == 1)
736 mc++;
737 }
738 if (mc == chs && chs <= MIX_MAX_CHAN) {
739 k = 0;
740 for (c = 0; c < chs; c++)
741 for (o = 0; o < ochs; o++) {
742 bno = (p + c) * ochs + o;
743 if (BIT(bno))
744 mix.wValue[k++] =
745 MAKE(p+c+1, o+1);
746 }
747 sprintf(mix.ctlname, "mix%d-%s", d->bUnitId,
748 uaudio_id_name(sc, dps, d->baSourceId[i]));
749 mix.nchan = chs;
750 uaudio_mixer_add_ctl(sc, &mix);
751 } else {
752 /* XXX */
753 }
754 #undef BIT
755 p += chs;
756 }
757
758 }
759
760 void
761 uaudio_add_selector(struct uaudio_softc *sc, usb_descriptor_t *v,
762 usb_descriptor_t **dps)
763 {
764 #ifdef UAUDIO_DEBUG
765 struct usb_audio_selector_unit *d =
766 (struct usb_audio_selector_unit *)v;
767
768 DPRINTFN(2,("uaudio_add_selector: bUnitId=%d bNrInPins=%d\n",
769 d->bUnitId, d->bNrInPins));
770 #endif
771 printf("uaudio_add_selector: NOT IMPLEMENTED\n");
772 }
773
774 void
775 uaudio_add_feature(struct uaudio_softc *sc, usb_descriptor_t *v,
776 usb_descriptor_t **dps)
777 {
778 struct usb_audio_feature_unit *d = (struct usb_audio_feature_unit *)v;
779 uByte *ctls = d->bmaControls;
780 int ctlsize = d->bControlSize;
781 int nchan = (d->bLength - 7) / ctlsize;
782 int srcId = d->bSourceId;
783 u_int fumask, mmask, cmask;
784 struct mixerctl mix;
785 int chan, ctl, i, unit;
786
787 #define GET(i) (ctls[(i)*ctlsize] | \
788 (ctlsize > 1 ? ctls[(i)*ctlsize+1] << 8 : 0))
789
790 mmask = GET(0);
791 /* Figure out what we can control */
792 for (cmask = 0, chan = 1; chan < nchan; chan++) {
793 DPRINTFN(9,("uaudio_add_feature: chan=%d mask=%x\n",
794 chan, GET(chan)));
795 cmask |= GET(chan);
796 }
797
798 DPRINTFN(1,("uaudio_add_feature: bUnitId=%d bSourceId=%d, "
799 "%d channels, mmask=0x%04x, cmask=0x%04x\n",
800 d->bUnitId, srcId, nchan, mmask, cmask));
801
802 if (nchan > MIX_MAX_CHAN)
803 nchan = MIX_MAX_CHAN;
804 unit = d->bUnitId;
805 mix.wIndex = MAKE(unit, sc->sc_ac_iface);
806 for (ctl = MUTE_CONTROL; ctl < LOUDNESS_CONTROL; ctl++) {
807 fumask = FU_MASK(ctl);
808 DPRINTFN(4,("uaudio_add_feature: ctl=%d fumask=0x%04x\n",
809 ctl, fumask));
810 if (mmask & fumask) {
811 mix.nchan = 1;
812 mix.wValue[0] = MAKE(ctl, 0);
813 } else if (cmask & fumask) {
814 mix.nchan = nchan - 1;
815 for (i = 1; i < nchan; i++) {
816 if (GET(i) & fumask)
817 mix.wValue[i-1] = MAKE(ctl, i);
818 else
819 mix.wValue[i-1] = -1;
820 }
821 } else {
822 continue;
823 }
824 #undef GET
825 mix.class = -1; /* XXX */
826 switch (ctl) {
827 case MUTE_CONTROL:
828 mix.type = MIX_ON_OFF;
829 sprintf(mix.ctlname, "fea%d-%s-%s", unit,
830 uaudio_id_name(sc, dps, srcId),
831 AudioNmute);
832 mix.ctlunit = "";
833 break;
834 case VOLUME_CONTROL:
835 mix.type = MIX_SIGNED_16;
836 sprintf(mix.ctlname, "fea%d-%s-%s", unit,
837 uaudio_id_name(sc, dps, srcId),
838 AudioNmaster);
839 mix.ctlunit = AudioNvolume;
840 break;
841 case BASS_CONTROL:
842 mix.type = MIX_SIGNED_8;
843 sprintf(mix.ctlname, "fea%d-%s-%s", unit,
844 uaudio_id_name(sc, dps, srcId),
845 AudioNbass);
846 mix.ctlunit = AudioNbass;
847 break;
848 case MID_CONTROL:
849 mix.type = MIX_SIGNED_8;
850 sprintf(mix.ctlname, "fea%d-%s-%s", unit,
851 uaudio_id_name(sc, dps, srcId),
852 AudioNmid);
853 mix.ctlunit = AudioNmid;
854 break;
855 case TREBLE_CONTROL:
856 mix.type = MIX_SIGNED_8;
857 sprintf(mix.ctlname, "fea%d-%s-%s", unit,
858 uaudio_id_name(sc, dps, srcId),
859 AudioNtreble);
860 mix.ctlunit = AudioNtreble;
861 break;
862 case GRAPHIC_EQUALIZER_CONTROL:
863 continue; /* XXX don't add anything */
864 break;
865 case AGC_CONTROL:
866 mix.type = MIX_ON_OFF;
867 sprintf(mix.ctlname, "fea%d-%s-%s", unit,
868 uaudio_id_name(sc, dps, srcId),
869 AudioNagc);
870 mix.ctlunit = "";
871 break;
872 case DELAY_CONTROL:
873 mix.type = MIX_UNSIGNED_16;
874 sprintf(mix.ctlname, "fea%d-%s-%s", unit,
875 uaudio_id_name(sc, dps, srcId),
876 AudioNdelay);
877 mix.ctlunit = "4 ms";
878 break;
879 case BASS_BOOST_CONTROL:
880 mix.type = MIX_ON_OFF;
881 sprintf(mix.ctlname, "fea%d-%s-%s", unit,
882 uaudio_id_name(sc, dps, srcId),
883 AudioNbassboost);
884 mix.ctlunit = "";
885 break;
886 case LOUDNESS_CONTROL:
887 mix.type = MIX_ON_OFF;
888 sprintf(mix.ctlname, "fea%d-%s-%s", unit,
889 uaudio_id_name(sc, dps, srcId),
890 AudioNloudness);
891 mix.ctlunit = "";
892 break;
893 }
894 uaudio_mixer_add_ctl(sc, &mix);
895 }
896 }
897
898 void
899 uaudio_add_processing_updown(struct uaudio_softc *sc, usb_descriptor_t *v,
900 usb_descriptor_t **dps)
901 {
902 struct usb_audio_processing_unit *d =
903 (struct usb_audio_processing_unit *)v;
904 struct usb_audio_processing_unit_1 *d1 =
905 (struct usb_audio_processing_unit_1 *)&d->baSourceId[d->bNrInPins];
906 struct usb_audio_processing_unit_updown *ud =
907 (struct usb_audio_processing_unit_updown *)
908 &d1->bmControls[d1->bControlSize];
909 struct mixerctl mix;
910 int i;
911
912 DPRINTFN(2,("uaudio_add_processing_updown: bUnitId=%d bNrModes=%d\n",
913 d->bUnitId, ud->bNrModes));
914
915 if (!(d1->bmControls[0] & UA_PROC_MASK(UD_MODE_SELECT_CONTROL))) {
916 DPRINTF(("uaudio_add_processing_updown: no mode select\n"));
917 return;
918 }
919
920 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
921 mix.nchan = 1;
922 mix.wValue[0] = MAKE(UD_MODE_SELECT_CONTROL, 0);
923 mix.class = -1;
924 mix.type = MIX_ON_OFF; /* XXX */
925 mix.ctlunit = "";
926 sprintf(mix.ctlname, "pro%d-mode", d->bUnitId);
927
928 for (i = 0; i < ud->bNrModes; i++) {
929 DPRINTFN(2,("uaudio_add_processing_updown: i=%d bm=0x%x\n",
930 i, UGETW(ud->waModes[i])));
931 /* XXX */
932 }
933 uaudio_mixer_add_ctl(sc, &mix);
934 }
935
936 void
937 uaudio_add_processing(struct uaudio_softc *sc, usb_descriptor_t *v,
938 usb_descriptor_t **dps)
939 {
940 struct usb_audio_processing_unit *d =
941 (struct usb_audio_processing_unit *)v;
942 struct usb_audio_processing_unit_1 *d1 =
943 (struct usb_audio_processing_unit_1 *)&d->baSourceId[d->bNrInPins];
944 int ptype = UGETW(d->wProcessType);
945 struct mixerctl mix;
946
947 DPRINTFN(2,("uaudio_add_processing: wProcessType=%d bUnitId=%d "
948 "bNrInPins=%d\n", ptype, d->bUnitId, d->bNrInPins));
949
950 if (d1->bmControls[0] & UA_PROC_ENABLE_MASK) {
951 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
952 mix.nchan = 1;
953 mix.wValue[0] = MAKE(XX_ENABLE_CONTROL, 0);
954 mix.class = -1;
955 mix.type = MIX_ON_OFF;
956 mix.ctlunit = "";
957 sprintf(mix.ctlname, "pro%d.%d-enable", d->bUnitId, ptype);
958 uaudio_mixer_add_ctl(sc, &mix);
959 }
960
961 switch(ptype) {
962 case UPDOWNMIX_PROCESS:
963 uaudio_add_processing_updown(sc, v, dps);
964 break;
965 case DOLBY_PROLOGIC_PROCESS:
966 case P3D_STEREO_EXTENDER_PROCESS:
967 case REVERBATION_PROCESS:
968 case CHORUS_PROCESS:
969 case DYN_RANGE_COMP_PROCESS:
970 default:
971 #ifdef UAUDIO_DEBUG
972 printf("uaudio_add_processing: unit %d, type=%d not impl.\n",
973 d->bUnitId, ptype);
974 #endif
975 break;
976 }
977 }
978
979 void
980 uaudio_add_extension(struct uaudio_softc *sc, usb_descriptor_t *v,
981 usb_descriptor_t **dps)
982 {
983 struct usb_audio_extension_unit *d =
984 (struct usb_audio_extension_unit *)v;
985 struct usb_audio_extension_unit_1 *d1 =
986 (struct usb_audio_extension_unit_1 *)&d->baSourceId[d->bNrInPins];
987 struct mixerctl mix;
988
989 DPRINTFN(2,("uaudio_add_extension: bUnitId=%d bNrInPins=%d\n",
990 d->bUnitId, d->bNrInPins));
991
992 if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_XU)
993 return;
994
995 if (d1->bmControls[0] & UA_EXT_ENABLE_MASK) {
996 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
997 mix.nchan = 1;
998 mix.wValue[0] = MAKE(UA_EXT_ENABLE, 0);
999 mix.class = -1;
1000 mix.type = MIX_ON_OFF;
1001 mix.ctlunit = "";
1002 sprintf(mix.ctlname, "ext%d-enable", d->bUnitId);
1003 uaudio_mixer_add_ctl(sc, &mix);
1004 }
1005 }
1006
1007 usbd_status
1008 uaudio_identify(struct uaudio_softc *sc, usb_config_descriptor_t *cdesc)
1009 {
1010 usbd_status err;
1011
1012 err = uaudio_identify_ac(sc, cdesc);
1013 if (err)
1014 return (err);
1015 return (uaudio_identify_as(sc, cdesc));
1016 }
1017
1018 void
1019 uaudio_add_alt(struct uaudio_softc *sc, struct as_info *ai)
1020 {
1021 if (sc->sc_nalts == 0)
1022 sc->sc_alts = malloc(sizeof *ai, M_USBDEV, M_NOWAIT);
1023 else
1024 sc->sc_alts = realloc(sc->sc_alts,
1025 (sc->sc_nalts+1) * sizeof *ai,
1026 M_USBDEV, M_NOWAIT);
1027 if (sc->sc_alts == NULL) {
1028 printf("uaudio_add_alt: no memory\n");
1029 return;
1030 }
1031 DPRINTFN(2,("uaudio_add_alt: adding alt=%d, enc=%d\n",
1032 ai->alt, ai->encoding));
1033 sc->sc_alts[sc->sc_nalts++] = *ai;
1034 }
1035
1036 usbd_status
1037 uaudio_process_as(struct uaudio_softc *sc, char *buf, int *offsp,
1038 int size, usb_interface_descriptor_t *id)
1039 #define offs (*offsp)
1040 {
1041 struct usb_audio_streaming_interface_descriptor *asid;
1042 struct usb_audio_streaming_type1_descriptor *asf1d;
1043 usb_endpoint_descriptor_audio_t *ed;
1044 struct usb_audio_streaming_endpoint_descriptor *sed;
1045 int format, chan, prec, enc;
1046 int dir, type;
1047 struct as_info ai;
1048
1049 asid = (void *)(buf + offs);
1050 if (asid->bDescriptorType != UDESC_CS_INTERFACE ||
1051 asid->bDescriptorSubtype != AS_GENERAL)
1052 return (USBD_INVAL);
1053 offs += asid->bLength;
1054 if (offs > size)
1055 return (USBD_INVAL);
1056 asf1d = (void *)(buf + offs);
1057 if (asf1d->bDescriptorType != UDESC_CS_INTERFACE ||
1058 asf1d->bDescriptorSubtype != FORMAT_TYPE)
1059 return (USBD_INVAL);
1060 offs += asf1d->bLength;
1061 if (offs > size)
1062 return (USBD_INVAL);
1063
1064 if (asf1d->bFormatType != FORMAT_TYPE_I) {
1065 printf("%s: ignored setting with type %d format\n",
1066 USBDEVNAME(sc->sc_dev), UGETW(asid->wFormatTag));
1067 return (USBD_NORMAL_COMPLETION);
1068 }
1069
1070 ed = (void *)(buf + offs);
1071 if (ed->bDescriptorType != UDESC_ENDPOINT)
1072 return (USBD_INVAL);
1073 DPRINTF(("uaudio_process_as: endpoint bLength=%d bDescriptorType=%d "
1074 "bEndpointAddress=%d bmAttributes=0x%x wMaxPacketSize=%d "
1075 "bInterval=%d bRefresh=%d bSynchAddress=%d\n",
1076 ed->bLength, ed->bDescriptorType, ed->bEndpointAddress,
1077 ed->bmAttributes, UGETW(ed->wMaxPacketSize),
1078 ed->bInterval, ed->bRefresh, ed->bSynchAddress));
1079 offs += ed->bLength;
1080 if (offs > size)
1081 return (USBD_INVAL);
1082 if (UE_GET_XFERTYPE(ed->bmAttributes) != UE_ISOCHRONOUS)
1083 return (USBD_INVAL);
1084
1085 dir = UE_GET_DIR(ed->bEndpointAddress);
1086 type = UE_GET_ISO_TYPE(ed->bmAttributes);
1087 if ((usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_INP_ASYNC) &&
1088 dir == UE_DIR_IN && type == UE_ISO_ADAPT)
1089 type = UE_ISO_ASYNC;
1090
1091 /* We can't handle endpoints that need a sync pipe. */
1092 if (dir == UE_DIR_IN ? type == UE_ISO_ADAPT : type == UE_ISO_ASYNC) {
1093 printf("%s: ignored %sput endpoint of type %s\n",
1094 USBDEVNAME(sc->sc_dev),
1095 dir == UE_DIR_IN ? "in" : "out",
1096 dir == UE_DIR_IN ? "adaptive" : "async");
1097 return (USBD_NORMAL_COMPLETION);
1098 }
1099
1100 sed = (void *)(buf + offs);
1101 if (sed->bDescriptorType != UDESC_CS_ENDPOINT ||
1102 sed->bDescriptorSubtype != AS_GENERAL)
1103 return (USBD_INVAL);
1104 offs += sed->bLength;
1105 if (offs > size)
1106 return (USBD_INVAL);
1107
1108 format = UGETW(asid->wFormatTag);
1109 chan = asf1d->bNrChannels;
1110 prec = asf1d->bBitResolution;
1111 if (prec != 8 && prec != 16) {
1112 #ifdef UAUDIO_DEBUG
1113 printf("%s: ignored setting with precision %d\n",
1114 USBDEVNAME(sc->sc_dev), prec);
1115 #endif
1116 return (USBD_NORMAL_COMPLETION);
1117 }
1118 switch (format) {
1119 case UA_FMT_PCM:
1120 sc->sc_altflags |= prec == 8 ? HAS_8 : HAS_16;
1121 enc = AUDIO_ENCODING_SLINEAR_LE;
1122 break;
1123 case UA_FMT_PCM8:
1124 enc = AUDIO_ENCODING_ULINEAR_LE;
1125 sc->sc_altflags |= HAS_8U;
1126 break;
1127 case UA_FMT_ALAW:
1128 enc = AUDIO_ENCODING_ALAW;
1129 sc->sc_altflags |= HAS_ALAW;
1130 break;
1131 case UA_FMT_MULAW:
1132 enc = AUDIO_ENCODING_ULAW;
1133 sc->sc_altflags |= HAS_MULAW;
1134 break;
1135 default:
1136 printf("%s: ignored setting with format %d\n",
1137 USBDEVNAME(sc->sc_dev), format);
1138 return (USBD_NORMAL_COMPLETION);
1139 }
1140 DPRINTFN(1,("uaudio_identify: alt=%d enc=%d chan=%d prec=%d\n",
1141 id->bAlternateSetting, enc, chan, prec));
1142 ai.alt = id->bAlternateSetting;
1143 ai.encoding = enc;
1144 ai.idesc = id;
1145 ai.edesc = ed;
1146 ai.asf1desc = asf1d;
1147 uaudio_add_alt(sc, &ai);
1148 sc->sc_chan.terminal = asid->bTerminalLink; /* XXX */
1149 sc->sc_chan.dir |= dir == UE_DIR_IN ? IN : OUT;
1150 return (USBD_NORMAL_COMPLETION);
1151 }
1152 #undef offs
1153
1154 usbd_status
1155 uaudio_identify_as(struct uaudio_softc *sc, usb_config_descriptor_t *cdesc)
1156 {
1157 usb_interface_descriptor_t *id;
1158 usbd_status err;
1159 char *buf;
1160 int size, offs;
1161
1162 size = UGETW(cdesc->wTotalLength);
1163 buf = (char *)cdesc;
1164
1165 /* Locate the AudioStreaming interface descriptor. */
1166 offs = 0;
1167 id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOSTREAM);
1168 if (id == NULL)
1169 return (USBD_INVAL);
1170
1171 sc->sc_chan.terminal = -1;
1172 sc->sc_chan.dir = 0;
1173
1174 /* Loop through all the alternate settings. */
1175 while (offs <= size) {
1176 DPRINTFN(2, ("uaudio_identify: interface %d\n",
1177 id->bInterfaceNumber));
1178 switch (id->bNumEndpoints) {
1179 case 0:
1180 DPRINTFN(2, ("uaudio_identify: AS null alt=%d\n",
1181 id->bAlternateSetting));
1182 sc->sc_nullalt = id->bAlternateSetting;
1183 break;
1184 case 1:
1185 err = uaudio_process_as(sc, buf, &offs, size, id);
1186 break;
1187 default:
1188 #ifdef UAUDIO_DEBUG
1189 printf("%s: ignored audio interface with %d "
1190 "endpoints\n",
1191 USBDEVNAME(sc->sc_dev), id->bNumEndpoints);
1192 #endif
1193 break;
1194 }
1195 id = uaudio_find_iface(buf, size, &offs,UISUBCLASS_AUDIOSTREAM);
1196 if (id == NULL)
1197 break;
1198 }
1199 if (offs > size)
1200 return (USBD_INVAL);
1201 DPRINTF(("uaudio_identify_as: %d alts available\n", sc->sc_nalts));
1202 if (sc->sc_chan.terminal < 0) {
1203 printf("%s: no useable endpoint found\n",
1204 USBDEVNAME(sc->sc_dev));
1205 return (USBD_INVAL);
1206 }
1207 #if 0
1208 if (sc->sc_chan.dir == (OUT | IN))
1209 sc->sc_props |= AUDIO_PROP_FULLDUPLEX;
1210 #endif
1211 return (USBD_NORMAL_COMPLETION);
1212 }
1213
1214 usbd_status
1215 uaudio_identify_ac(struct uaudio_softc *sc, usb_config_descriptor_t *cdesc)
1216 {
1217 usb_interface_descriptor_t *id;
1218 struct usb_audio_control_descriptor *acdp;
1219 usb_descriptor_t *dp, *dps[256];
1220 char *buf, *ibuf, *ibufend;
1221 int size, offs, aclen, ndps, i;
1222
1223 size = UGETW(cdesc->wTotalLength);
1224 buf = (char *)cdesc;
1225
1226 /* Locate the AudioControl interface descriptor. */
1227 offs = 0;
1228 id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOCONTROL);
1229 if (id == NULL)
1230 return (USBD_INVAL);
1231 if (offs + sizeof *acdp > size)
1232 return (USBD_INVAL);
1233 sc->sc_ac_iface = id->bInterfaceNumber;
1234 DPRINTFN(2,("uaudio_identify: AC interface is %d\n", sc->sc_ac_iface));
1235
1236 /* A class-specific AC interface header should follow. */
1237 ibuf = buf + offs;
1238 acdp = (struct usb_audio_control_descriptor *)ibuf;
1239 if (acdp->bDescriptorType != UDESC_CS_INTERFACE ||
1240 acdp->bDescriptorSubtype != UDESCSUB_AC_HEADER)
1241 return (USBD_INVAL);
1242 aclen = UGETW(acdp->wTotalLength);
1243 if (offs + aclen > size)
1244 return (USBD_INVAL);
1245
1246 if (!(usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_BAD_ADC) &&
1247 UGETW(acdp->bcdADC) != UAUDIO_VERSION)
1248 return (USBD_INVAL);
1249
1250 sc->sc_audio_rev = UGETW(acdp->bcdADC);
1251 DPRINTFN(2,("uaudio_identify: found AC header, vers=%03x, len=%d\n",
1252 sc->sc_audio_rev, aclen));
1253
1254 sc->sc_nullalt = -1;
1255
1256 /* Scan through all the AC specific descriptors */
1257 ibufend = ibuf + aclen;
1258 dp = (usb_descriptor_t *)ibuf;
1259 ndps = 0;
1260 memset(dps, 0, sizeof dps);
1261 for (;;) {
1262 ibuf += dp->bLength;
1263 if (ibuf >= ibufend)
1264 break;
1265 dp = (usb_descriptor_t *)ibuf;
1266 if (ibuf + dp->bLength > ibufend)
1267 return (USBD_INVAL);
1268 if (dp->bDescriptorType != UDESC_CS_INTERFACE) {
1269 printf("uaudio_identify: skip desc type=0x%02x\n",
1270 dp->bDescriptorType);
1271 continue;
1272 }
1273 i = ((struct usb_audio_input_terminal *)dp)->bTerminalId;
1274 dps[i] = dp;
1275 if (i > ndps)
1276 ndps = i;
1277 }
1278 ndps++;
1279
1280 for (i = 0; i < ndps; i++) {
1281 dp = dps[i];
1282 if (dp == NULL)
1283 continue;
1284 DPRINTF(("uaudio_identify: subtype=%d\n",
1285 dp->bDescriptorSubtype));
1286 switch (dp->bDescriptorSubtype) {
1287 case UDESCSUB_AC_HEADER:
1288 printf("uaudio_identify: unexpected AC header\n");
1289 break;
1290 case UDESCSUB_AC_INPUT:
1291 uaudio_add_input(sc, dp, dps);
1292 break;
1293 case UDESCSUB_AC_OUTPUT:
1294 uaudio_add_output(sc, dp, dps);
1295 break;
1296 case UDESCSUB_AC_MIXER:
1297 uaudio_add_mixer(sc, dp, dps);
1298 break;
1299 case UDESCSUB_AC_SELECTOR:
1300 uaudio_add_selector(sc, dp, dps);
1301 break;
1302 case UDESCSUB_AC_FEATURE:
1303 uaudio_add_feature(sc, dp, dps);
1304 break;
1305 case UDESCSUB_AC_PROCESSING:
1306 uaudio_add_processing(sc, dp, dps);
1307 break;
1308 case UDESCSUB_AC_EXTENSION:
1309 uaudio_add_extension(sc, dp, dps);
1310 break;
1311 default:
1312 printf("uaudio_identify: bad AC desc subtype=0x%02x\n",
1313 dp->bDescriptorSubtype);
1314 break;
1315 }
1316 }
1317 return (USBD_NORMAL_COMPLETION);
1318 }
1319
1320 int
1321 uaudio_query_devinfo(void *addr, mixer_devinfo_t *mi)
1322 {
1323 struct uaudio_softc *sc = addr;
1324 struct mixerctl *mc;
1325 int n, nctls;
1326
1327 DPRINTFN(2,("uaudio_query_devinfo: index=%d\n", mi->index));
1328 if (sc->sc_dying)
1329 return (EIO);
1330
1331 n = mi->index;
1332 nctls = sc->sc_nctls;
1333
1334 if (n < 0 || n >= nctls) {
1335 switch (n - nctls) {
1336 case UAC_OUTPUT:
1337 mi->type = AUDIO_MIXER_CLASS;
1338 mi->mixer_class = nctls + UAC_OUTPUT;
1339 mi->next = mi->prev = AUDIO_MIXER_LAST;
1340 strcpy(mi->label.name, AudioCoutputs);
1341 return (0);
1342 case UAC_INPUT:
1343 mi->type = AUDIO_MIXER_CLASS;
1344 mi->mixer_class = nctls + UAC_INPUT;
1345 mi->next = mi->prev = AUDIO_MIXER_LAST;
1346 strcpy(mi->label.name, AudioCinputs);
1347 return (0);
1348 case UAC_EQUAL:
1349 mi->type = AUDIO_MIXER_CLASS;
1350 mi->mixer_class = nctls + UAC_EQUAL;
1351 mi->next = mi->prev = AUDIO_MIXER_LAST;
1352 strcpy(mi->label.name, AudioCequalization);
1353 return (0);
1354 default:
1355 return (ENXIO);
1356 }
1357 }
1358 mc = &sc->sc_ctls[n];
1359 strncpy(mi->label.name, mc->ctlname, MAX_AUDIO_DEV_LEN);
1360 mi->mixer_class = mc->class;
1361 mi->next = mi->prev = AUDIO_MIXER_LAST; /* XXX */
1362 switch (mc->type) {
1363 case MIX_ON_OFF:
1364 mi->type = AUDIO_MIXER_ENUM;
1365 mi->un.e.num_mem = 2;
1366 strcpy(mi->un.e.member[0].label.name, AudioNoff);
1367 mi->un.e.member[0].ord = 0;
1368 strcpy(mi->un.e.member[1].label.name, AudioNon);
1369 mi->un.e.member[1].ord = 1;
1370 break;
1371 default:
1372 mi->type = AUDIO_MIXER_VALUE;
1373 strncpy(mi->un.v.units.name, mc->ctlunit, MAX_AUDIO_DEV_LEN);
1374 mi->un.v.num_channels = mc->nchan;
1375 mi->un.v.delta = mc->delta;
1376 break;
1377 }
1378 return (0);
1379 }
1380
1381 int
1382 uaudio_open(void *addr, int flags)
1383 {
1384 struct uaudio_softc *sc = addr;
1385
1386 DPRINTF(("uaudio_open: sc=%p\n", sc));
1387 if (sc->sc_dying)
1388 return (EIO);
1389
1390 if (sc->sc_chan.terminal < 0)
1391 return (ENXIO);
1392
1393 if ((flags & FREAD) && !(sc->sc_chan.dir & IN))
1394 return (EACCES);
1395 if ((flags & FWRITE) && !(sc->sc_chan.dir & OUT))
1396 return (EACCES);
1397
1398 sc->sc_chan.intr = 0;
1399
1400 return (0);
1401 }
1402
1403 /*
1404 * Close function is called at splaudio().
1405 */
1406 void
1407 uaudio_close(void *addr)
1408 {
1409 struct uaudio_softc *sc = addr;
1410
1411 DPRINTF(("uaudio_close: sc=%p\n", sc));
1412 uaudio_halt_in_dma(sc);
1413 uaudio_halt_out_dma(sc);
1414
1415 sc->sc_chan.intr = 0;
1416 }
1417
1418 int
1419 uaudio_drain(void *addr)
1420 {
1421 struct uaudio_softc *sc = addr;
1422
1423 usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES);
1424
1425 return (0);
1426 }
1427
1428 int
1429 uaudio_halt_out_dma(void *addr)
1430 {
1431 struct uaudio_softc *sc = addr;
1432
1433 DPRINTF(("uaudio_halt_out_dma: enter\n"));
1434 if (sc->sc_chan.pipe != NULL) {
1435 uaudio_chan_close(sc, &sc->sc_chan);
1436 sc->sc_chan.pipe = 0;
1437 uaudio_chan_free_buffers(sc, &sc->sc_chan);
1438 }
1439 return (0);
1440 }
1441
1442 int
1443 uaudio_halt_in_dma(void *addr)
1444 {
1445 struct uaudio_softc *sc = addr;
1446
1447 DPRINTF(("uaudio_halt_in_dma: enter\n"));
1448 if (sc->sc_chan.pipe != NULL) {
1449 uaudio_chan_close(sc, &sc->sc_chan);
1450 sc->sc_chan.pipe = 0;
1451 uaudio_chan_free_buffers(sc, &sc->sc_chan);
1452 }
1453 return (0);
1454 }
1455
1456 int
1457 uaudio_getdev(void *addr, struct audio_device *retp)
1458 {
1459 struct uaudio_softc *sc = addr;
1460
1461 DPRINTF(("uaudio_mixer_getdev:\n"));
1462 if (sc->sc_dying)
1463 return (EIO);
1464
1465 *retp = uaudio_device;
1466 return (0);
1467 }
1468
1469 /*
1470 * Make sure the block size is large enough to hold all outstanding transfers.
1471 */
1472 int
1473 uaudio_round_blocksize(void *addr, int blk)
1474 {
1475 struct uaudio_softc *sc = addr;
1476 int bpf;
1477
1478 bpf = sc->sc_chan.bytes_per_frame + sc->sc_chan.sample_size;
1479 /* XXX */
1480 bpf *= UAUDIO_NFRAMES * UAUDIO_NCHANBUFS;
1481
1482 bpf = (bpf + 15) &~ 15;
1483
1484 if (blk < bpf)
1485 blk = bpf;
1486
1487 #ifdef DIAGNOSTIC
1488 if (blk <= 0) {
1489 printf("uaudio_round_blocksize: blk=%d\n", blk);
1490 blk = 512;
1491 }
1492 #endif
1493
1494 DPRINTFN(1,("uaudio_round_blocksize: blk=%d\n", blk));
1495 return (blk);
1496 }
1497
1498 int
1499 uaudio_get_props(void *addr)
1500 {
1501 struct uaudio_softc *sc = addr;
1502
1503 return (sc->sc_props);
1504 }
1505
1506 int
1507 uaudio_get(struct uaudio_softc *sc, int which, int type, int wValue,
1508 int wIndex, int len)
1509 {
1510 usb_device_request_t req;
1511 u_int8_t data[4];
1512 usbd_status err;
1513 int val;
1514
1515 if (wValue == -1)
1516 return (0);
1517
1518 req.bmRequestType = type;
1519 req.bRequest = which;
1520 USETW(req.wValue, wValue);
1521 USETW(req.wIndex, wIndex);
1522 USETW(req.wLength, len);
1523 DPRINTFN(2,("uaudio_get: type=0x%02x req=0x%02x wValue=0x%04x "
1524 "wIndex=0x%04x len=%d\n",
1525 type, which, wValue, wIndex, len));
1526 err = usbd_do_request(sc->sc_udev, &req, &data);
1527 if (err) {
1528 DPRINTF(("uaudio_get: err=%s\n", usbd_errstr(err)));
1529 return (-1);
1530 }
1531 switch (len) {
1532 case 1:
1533 val = data[0];
1534 break;
1535 case 2:
1536 val = data[0] | (data[1] << 8);
1537 break;
1538 default:
1539 DPRINTF(("uaudio_get: bad length=%d\n", len));
1540 return (-1);
1541 }
1542 DPRINTFN(2,("uaudio_get: val=%d\n", val));
1543 return (val);
1544 }
1545
1546 void
1547 uaudio_set(struct uaudio_softc *sc, int which, int type, int wValue,
1548 int wIndex, int len, int val)
1549 {
1550 usb_device_request_t req;
1551 u_int8_t data[4];
1552 usbd_status err;
1553
1554 if (wValue == -1)
1555 return;
1556
1557 req.bmRequestType = type;
1558 req.bRequest = which;
1559 USETW(req.wValue, wValue);
1560 USETW(req.wIndex, wIndex);
1561 USETW(req.wLength, len);
1562 switch (len) {
1563 case 1:
1564 data[0] = val;
1565 break;
1566 case 2:
1567 data[0] = val;
1568 data[1] = val >> 8;
1569 break;
1570 default:
1571 return;
1572 }
1573 DPRINTFN(2,("uaudio_set: type=0x%02x req=0x%02x wValue=0x%04x "
1574 "wIndex=0x%04x len=%d, val=%d\n",
1575 type, which, wValue, wIndex, len, val & 0xffff));
1576 err = usbd_do_request(sc->sc_udev, &req, &data);
1577 #ifdef UAUDIO_DEBUG
1578 if (err)
1579 DPRINTF(("uaudio_set: err=%d\n", err));
1580 #endif
1581 }
1582
1583 int
1584 uaudio_signext(int type, int val)
1585 {
1586 if (!MIX_UNSIGNED(type)) {
1587 if (MIX_SIZE(type) == 2)
1588 val = (int16_t)val;
1589 else
1590 val = (int8_t)val;
1591 }
1592 return (val);
1593 }
1594
1595 int
1596 uaudio_value2bsd(struct mixerctl *mc, int val)
1597 {
1598 DPRINTFN(5, ("uaudio_value2bsd: type=%03x val=%d min=%d max=%d ",
1599 mc->type, val, mc->minval, mc->maxval));
1600 if (mc->type == MIX_ON_OFF)
1601 val = val != 0;
1602 else
1603 val = ((uaudio_signext(mc->type, val) - mc->minval) * 256
1604 + mc->mul/2) / mc->mul;
1605 DPRINTFN(5, ("val'=%d\n", val));
1606 return (val);
1607 }
1608
1609 int
1610 uaudio_bsd2value(struct mixerctl *mc, int val)
1611 {
1612 DPRINTFN(5,("uaudio_bsd2value: type=%03x val=%d min=%d max=%d ",
1613 mc->type, val, mc->minval, mc->maxval));
1614 if (mc->type == MIX_ON_OFF)
1615 val = val != 0;
1616 else
1617 val = (val + mc->delta/2) * mc->mul / 256 + mc->minval;
1618 DPRINTFN(5, ("val'=%d\n", val));
1619 return (val);
1620 }
1621
1622 int
1623 uaudio_ctl_get(struct uaudio_softc *sc, int which, struct mixerctl *mc,
1624 int chan)
1625 {
1626 int val;
1627
1628 DPRINTFN(5,("uaudio_ctl_get: which=%d chan=%d\n", which, chan));
1629 val = uaudio_get(sc, which, UT_READ_CLASS_INTERFACE, mc->wValue[chan],
1630 mc->wIndex, MIX_SIZE(mc->type));
1631 return (uaudio_value2bsd(mc, val));
1632 }
1633
1634 void
1635 uaudio_ctl_set(struct uaudio_softc *sc, int which, struct mixerctl *mc,
1636 int chan, int val)
1637 {
1638 val = uaudio_bsd2value(mc, val);
1639 uaudio_set(sc, which, UT_WRITE_CLASS_INTERFACE, mc->wValue[chan],
1640 mc->wIndex, MIX_SIZE(mc->type), val);
1641 }
1642
1643 int
1644 uaudio_mixer_get_port(void *addr, mixer_ctrl_t *cp)
1645 {
1646 struct uaudio_softc *sc = addr;
1647 struct mixerctl *mc;
1648 int i, n, vals[MIX_MAX_CHAN], val;
1649
1650 DPRINTFN(2,("uaudio_mixer_get_port: index=%d\n", cp->dev));
1651
1652 if (sc->sc_dying)
1653 return (EIO);
1654
1655 n = cp->dev;
1656 if (n < 0 || n >= sc->sc_nctls)
1657 return (ENXIO);
1658 mc = &sc->sc_ctls[n];
1659
1660 if (mc->type == MIX_ON_OFF) {
1661 if (cp->type != AUDIO_MIXER_ENUM)
1662 return (EINVAL);
1663 cp->un.ord = uaudio_ctl_get(sc, GET_CUR, mc, 0);
1664 } else {
1665 if (cp->type != AUDIO_MIXER_VALUE)
1666 return (EINVAL);
1667 if (cp->un.value.num_channels != 1 &&
1668 cp->un.value.num_channels != mc->nchan)
1669 return (EINVAL);
1670 for (i = 0; i < mc->nchan; i++)
1671 vals[i] = uaudio_ctl_get(sc, GET_CUR, mc, i);
1672 if (cp->un.value.num_channels == 1 && mc->nchan != 1) {
1673 for (val = 0, i = 0; i < mc->nchan; i++)
1674 val += vals[i];
1675 vals[0] = val / mc->nchan;
1676 }
1677 for (i = 0; i < cp->un.value.num_channels; i++)
1678 cp->un.value.level[i] = vals[i];
1679 }
1680
1681 return (0);
1682 }
1683
1684 int
1685 uaudio_mixer_set_port(void *addr, mixer_ctrl_t *cp)
1686 {
1687 struct uaudio_softc *sc = addr;
1688 struct mixerctl *mc;
1689 int i, n, vals[MIX_MAX_CHAN];
1690
1691 DPRINTFN(2,("uaudio_mixer_set_port: index = %d\n", cp->dev));
1692 if (sc->sc_dying)
1693 return (EIO);
1694
1695 n = cp->dev;
1696 if (n < 0 || n >= sc->sc_nctls)
1697 return (ENXIO);
1698 mc = &sc->sc_ctls[n];
1699
1700 if (mc->type == MIX_ON_OFF) {
1701 if (cp->type != AUDIO_MIXER_ENUM)
1702 return (EINVAL);
1703 uaudio_ctl_set(sc, SET_CUR, mc, 0, cp->un.ord);
1704 } else {
1705 if (cp->type != AUDIO_MIXER_VALUE)
1706 return (EINVAL);
1707 if (cp->un.value.num_channels == 1)
1708 for (i = 0; i < mc->nchan; i++)
1709 vals[i] = cp->un.value.level[0];
1710 else if (cp->un.value.num_channels == mc->nchan)
1711 for (i = 0; i < mc->nchan; i++)
1712 vals[i] = cp->un.value.level[i];
1713 else
1714 return (EINVAL);
1715 for (i = 0; i < mc->nchan; i++)
1716 uaudio_ctl_set(sc, SET_CUR, mc, i, vals[i]);
1717 }
1718 return (0);
1719 }
1720
1721 int
1722 uaudio_trigger_input(void *addr, void *start, void *end, int blksize,
1723 void (*intr)(void *), void *arg,
1724 struct audio_params *param)
1725 {
1726 struct uaudio_softc *sc = addr;
1727 struct chan *ch = &sc->sc_chan;
1728 usbd_status err;
1729 int i, s;
1730
1731 if (sc->sc_dying)
1732 return (EIO);
1733
1734 DPRINTFN(3,("uaudio_trigger_input: sc=%p start=%p end=%p "
1735 "blksize=%d\n", sc, start, end, blksize));
1736
1737 uaudio_chan_set_param(ch, param, start, end, blksize);
1738 DPRINTFN(3,("uaudio_trigger_input: sample_size=%d bytes/frame=%d "
1739 "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame,
1740 ch->fraction));
1741
1742 err = uaudio_chan_alloc_buffers(sc, ch);
1743 if (err)
1744 return (EIO);
1745
1746 err = uaudio_chan_open(sc, ch);
1747 if (err) {
1748 uaudio_chan_free_buffers(sc, ch);
1749 return (EIO);
1750 }
1751
1752 sc->sc_chan.intr = intr;
1753 sc->sc_chan.arg = arg;
1754
1755 s = splusb();
1756 for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX -1 shouldn't be needed */
1757 uaudio_chan_rtransfer(ch);
1758 splx(s);
1759
1760 return (0);
1761 }
1762
1763 int
1764 uaudio_trigger_output(void *addr, void *start, void *end, int blksize,
1765 void (*intr)(void *), void *arg,
1766 struct audio_params *param)
1767 {
1768 struct uaudio_softc *sc = addr;
1769 struct chan *ch = &sc->sc_chan;
1770 usbd_status err;
1771 int i, s;
1772
1773 if (sc->sc_dying)
1774 return (EIO);
1775
1776 DPRINTFN(3,("uaudio_trigger_output: sc=%p start=%p end=%p "
1777 "blksize=%d\n", sc, start, end, blksize));
1778
1779 uaudio_chan_set_param(ch, param, start, end, blksize);
1780 DPRINTFN(3,("uaudio_trigger_output: sample_size=%d bytes/frame=%d "
1781 "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame,
1782 ch->fraction));
1783
1784 err = uaudio_chan_alloc_buffers(sc, ch);
1785 if (err)
1786 return (EIO);
1787
1788 err = uaudio_chan_open(sc, ch);
1789 if (err) {
1790 uaudio_chan_free_buffers(sc, ch);
1791 return (EIO);
1792 }
1793
1794 sc->sc_chan.intr = intr;
1795 sc->sc_chan.arg = arg;
1796
1797 s = splusb();
1798 for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX */
1799 uaudio_chan_ptransfer(ch);
1800 splx(s);
1801
1802 return (0);
1803 }
1804
1805 /* Set up a pipe for a channel. */
1806 usbd_status
1807 uaudio_chan_open(struct uaudio_softc *sc, struct chan *ch)
1808 {
1809 struct as_info *as = &sc->sc_alts[sc->sc_curaltidx];
1810 int endpt = as->edesc->bEndpointAddress;
1811 usbd_status err;
1812
1813 DPRINTF(("uaudio_open_chan: endpt=0x%02x, speed=%d, alt=%d\n",
1814 endpt, ch->sample_rate, as->alt));
1815
1816 /* Set alternate interface corresponding to the mode. */
1817 err = usbd_set_interface(as->ifaceh, as->alt);
1818 if (err)
1819 return (err);
1820
1821 /* Some devices do not support this request, so ignore errors. */
1822 #ifdef UAUDIO_DEBUG
1823 err = uaudio_set_speed(sc, endpt, ch->sample_rate);
1824 if (err)
1825 DPRINTF(("uaudio_chan_open: set_speed failed err=%s\n",
1826 usbd_errstr(err)));
1827 #else
1828 (void)uaudio_set_speed(sc, endpt, ch->sample_rate);
1829 #endif
1830
1831 DPRINTF(("uaudio_open_chan: create pipe to 0x%02x\n", endpt));
1832 err = usbd_open_pipe(as->ifaceh, endpt, 0, &ch->pipe);
1833 return (err);
1834 }
1835
1836 void
1837 uaudio_chan_close(struct uaudio_softc *sc, struct chan *ch)
1838 {
1839 struct as_info *as = &sc->sc_alts[sc->sc_curaltidx];
1840
1841 if (sc->sc_nullalt >= 0) {
1842 DPRINTF(("uaudio_close_chan: set null alt=%d\n",
1843 sc->sc_nullalt));
1844 usbd_set_interface(as->ifaceh, sc->sc_nullalt);
1845 }
1846 usbd_abort_pipe(ch->pipe);
1847 usbd_close_pipe(ch->pipe);
1848 }
1849
1850 usbd_status
1851 uaudio_chan_alloc_buffers(struct uaudio_softc *sc, struct chan *ch)
1852 {
1853 usbd_xfer_handle xfer;
1854 void *buf;
1855 int i, size;
1856
1857 size = (ch->bytes_per_frame + ch->sample_size) * UAUDIO_NFRAMES;
1858 for (i = 0; i < UAUDIO_NCHANBUFS; i++) {
1859 xfer = usbd_alloc_xfer(sc->sc_udev);
1860 if (xfer == 0)
1861 goto bad;
1862 ch->chanbufs[i].xfer = xfer;
1863 buf = usbd_alloc_buffer(xfer, size);
1864 if (buf == 0) {
1865 i++;
1866 goto bad;
1867 }
1868 ch->chanbufs[i].buffer = buf;
1869 ch->chanbufs[i].chan = ch;
1870 }
1871
1872 return (USBD_NORMAL_COMPLETION);
1873
1874 bad:
1875 while (--i >= 0)
1876 /* implicit buffer free */
1877 usbd_free_xfer(ch->chanbufs[i].xfer);
1878 return (USBD_NOMEM);
1879 }
1880
1881 void
1882 uaudio_chan_free_buffers(struct uaudio_softc *sc, struct chan *ch)
1883 {
1884 int i;
1885
1886 for (i = 0; i < UAUDIO_NCHANBUFS; i++)
1887 usbd_free_xfer(ch->chanbufs[i].xfer);
1888 }
1889
1890 /* Called at splusb() */
1891 void
1892 uaudio_chan_ptransfer(struct chan *ch)
1893 {
1894 struct chanbuf *cb;
1895 int i, n, size, residue, total;
1896
1897 if (ch->sc->sc_dying)
1898 return;
1899
1900 /* Pick the next channel buffer. */
1901 cb = &ch->chanbufs[ch->curchanbuf];
1902 if (++ch->curchanbuf >= UAUDIO_NCHANBUFS)
1903 ch->curchanbuf = 0;
1904
1905 /* Compute the size of each frame in the next transfer. */
1906 residue = ch->residue;
1907 total = 0;
1908 for (i = 0; i < UAUDIO_NFRAMES; i++) {
1909 size = ch->bytes_per_frame;
1910 residue += ch->fraction;
1911 if (residue >= USB_FRAMES_PER_SECOND) {
1912 if (!ch->nofrac)
1913 size += ch->sample_size;
1914 residue -= USB_FRAMES_PER_SECOND;
1915 }
1916 cb->sizes[i] = size;
1917 total += size;
1918 }
1919 ch->residue = residue;
1920 cb->size = total;
1921
1922 /*
1923 * Transfer data from upper layer buffer to channel buffer, taking
1924 * care of wrapping the upper layer buffer.
1925 */
1926 n = min(total, ch->end - ch->cur);
1927 memcpy(cb->buffer, ch->cur, n);
1928 ch->cur += n;
1929 if (ch->cur >= ch->end)
1930 ch->cur = ch->start;
1931 if (total > n) {
1932 total -= n;
1933 memcpy(cb->buffer + n, ch->cur, total);
1934 ch->cur += total;
1935 }
1936
1937 #ifdef UAUDIO_DEBUG
1938 if (uaudiodebug > 8) {
1939 DPRINTF(("uaudio_chan_ptransfer: buffer=%p, residue=0.%03d\n",
1940 cb->buffer, ch->residue));
1941 for (i = 0; i < UAUDIO_NFRAMES; i++) {
1942 DPRINTF((" [%d] length %d\n", i, cb->sizes[i]));
1943 }
1944 }
1945 #endif
1946
1947 DPRINTFN(5,("uaudio_chan_transfer: ptransfer xfer=%p\n", cb->xfer));
1948 /* Fill the request */
1949 usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes,
1950 UAUDIO_NFRAMES, USBD_NO_COPY,
1951 uaudio_chan_pintr);
1952
1953 (void)usbd_transfer(cb->xfer);
1954 }
1955
1956 void
1957 uaudio_chan_pintr(usbd_xfer_handle xfer, usbd_private_handle priv,
1958 usbd_status status)
1959 {
1960 struct chanbuf *cb = priv;
1961 struct chan *ch = cb->chan;
1962 u_int32_t count;
1963 int s;
1964
1965 /* Return if we are aborting. */
1966 if (status == USBD_CANCELLED)
1967 return;
1968
1969 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
1970 DPRINTFN(5,("uaudio_chan_pintr: count=%d, transferred=%d\n",
1971 count, ch->transferred));
1972 #ifdef DIAGNOSTIC
1973 if (count != cb->size) {
1974 printf("uaudio_chan_pintr: count(%d) != size(%d)\n",
1975 count, cb->size);
1976 }
1977 #endif
1978
1979 ch->transferred += cb->size;
1980 s = splaudio();
1981 /* Call back to upper layer */
1982 while (ch->transferred >= ch->blksize) {
1983 ch->transferred -= ch->blksize;
1984 DPRINTFN(5,("uaudio_chan_pintr: call %p(%p)\n",
1985 ch->intr, ch->arg));
1986 ch->intr(ch->arg);
1987 }
1988 splx(s);
1989
1990 /* start next transfer */
1991 uaudio_chan_ptransfer(ch);
1992 }
1993
1994 /* Called at splusb() */
1995 void
1996 uaudio_chan_rtransfer(struct chan *ch)
1997 {
1998 struct chanbuf *cb;
1999 int i, size, residue, total;
2000
2001 if (ch->sc->sc_dying)
2002 return;
2003
2004 /* Pick the next channel buffer. */
2005 cb = &ch->chanbufs[ch->curchanbuf];
2006 if (++ch->curchanbuf >= UAUDIO_NCHANBUFS)
2007 ch->curchanbuf = 0;
2008
2009 /* Compute the size of each frame in the next transfer. */
2010 residue = ch->residue;
2011 total = 0;
2012 for (i = 0; i < UAUDIO_NFRAMES; i++) {
2013 size = ch->bytes_per_frame;
2014 residue += ch->fraction;
2015 if (residue >= USB_FRAMES_PER_SECOND) {
2016 if (!ch->nofrac)
2017 size += ch->sample_size;
2018 residue -= USB_FRAMES_PER_SECOND;
2019 }
2020 cb->sizes[i] = size;
2021 total += size;
2022 }
2023 ch->residue = residue;
2024 cb->size = total;
2025
2026 #ifdef UAUDIO_DEBUG
2027 if (uaudiodebug > 8) {
2028 DPRINTF(("uaudio_chan_rtransfer: buffer=%p, residue=0.%03d\n",
2029 cb->buffer, ch->residue));
2030 for (i = 0; i < UAUDIO_NFRAMES; i++) {
2031 DPRINTF((" [%d] length %d\n", i, cb->sizes[i]));
2032 }
2033 }
2034 #endif
2035
2036 DPRINTFN(5,("uaudio_chan_rtransfer: transfer xfer=%p\n", cb->xfer));
2037 /* Fill the request */
2038 usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes,
2039 UAUDIO_NFRAMES, USBD_NO_COPY,
2040 uaudio_chan_rintr);
2041
2042 (void)usbd_transfer(cb->xfer);
2043 }
2044
2045 void
2046 uaudio_chan_rintr(usbd_xfer_handle xfer, usbd_private_handle priv,
2047 usbd_status status)
2048 {
2049 struct chanbuf *cb = priv;
2050 struct chan *ch = cb->chan;
2051 u_int32_t count;
2052 int s, n;
2053
2054 /* Return if we are aborting. */
2055 if (status == USBD_CANCELLED)
2056 return;
2057
2058 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
2059 DPRINTFN(5,("uaudio_chan_rintr: count=%d, transferred=%d\n",
2060 count, ch->transferred));
2061
2062 if (count < cb->size) {
2063 /* if the device fails to keep up, copy last byte */
2064 u_char b = count ? cb->buffer[count-1] : 0;
2065 while (count < cb->size)
2066 cb->buffer[count++] = b;
2067 }
2068
2069 #ifdef DIAGNOSTIC
2070 if (count != cb->size) {
2071 printf("uaudio_chan_rintr: count(%d) != size(%d)\n",
2072 count, cb->size);
2073 }
2074 #endif
2075
2076 /*
2077 * Transfer data from channel buffer to upper layer buffer, taking
2078 * care of wrapping the upper layer buffer.
2079 */
2080 n = min(count, ch->end - ch->cur);
2081 memcpy(ch->cur, cb->buffer, n);
2082 ch->cur += n;
2083 if (ch->cur >= ch->end)
2084 ch->cur = ch->start;
2085 if (count > n) {
2086 memcpy(ch->cur, cb->buffer + n, count - n);
2087 ch->cur += count - n;
2088 }
2089
2090 /* Call back to upper layer */
2091 ch->transferred += cb->size;
2092 s = splaudio();
2093 while (ch->transferred >= ch->blksize) {
2094 ch->transferred -= ch->blksize;
2095 DPRINTFN(5,("uaudio_chan_rintr: call %p(%p)\n",
2096 ch->intr, ch->arg));
2097 ch->intr(ch->arg);
2098 }
2099 splx(s);
2100
2101 /* start next transfer */
2102 uaudio_chan_rtransfer(ch);
2103 }
2104
2105 void
2106 uaudio_chan_set_param(struct chan *ch, struct audio_params *param,
2107 u_char *start, u_char *end, int blksize)
2108 {
2109 int samples_per_frame, sample_size;
2110
2111 sample_size = param->precision * param->channels / 8;
2112 samples_per_frame = param->sample_rate / USB_FRAMES_PER_SECOND;
2113 ch->fraction = param->sample_rate % USB_FRAMES_PER_SECOND;
2114 ch->sample_size = sample_size;
2115 ch->sample_rate = param->sample_rate;
2116 ch->bytes_per_frame = samples_per_frame * sample_size;
2117 ch->residue = 0;
2118
2119 ch->start = start;
2120 ch->end = end;
2121 ch->cur = start;
2122 ch->blksize = blksize;
2123 ch->transferred = 0;
2124
2125 ch->curchanbuf = 0;
2126 }
2127
2128 int
2129 uaudio_set_params(void *addr, int setmode, int usemode,
2130 struct audio_params *p, struct audio_params *r)
2131 {
2132 struct uaudio_softc *sc = addr;
2133 int flags = sc->sc_altflags;
2134 int pfactor, rfactor;
2135 int enc, i, j;
2136 void (*pswcode)(void *, u_char *buf, int cnt);
2137 void (*rswcode)(void *, u_char *buf, int cnt);
2138
2139 if (sc->sc_dying)
2140 return (EIO);
2141
2142 if (sc->sc_chan.pipe != NULL)
2143 return (EBUSY);
2144
2145 pswcode = rswcode = 0;
2146 pfactor = rfactor = 1;
2147 enc = p->encoding;
2148 switch (enc) {
2149 case AUDIO_ENCODING_SLINEAR_BE:
2150 if (p->precision == 16) {
2151 rswcode = pswcode = swap_bytes;
2152 enc = AUDIO_ENCODING_SLINEAR_LE;
2153 } else if (p->precision == 8 && !(flags & HAS_8)) {
2154 pswcode = rswcode = change_sign8;
2155 enc = AUDIO_ENCODING_ULINEAR_LE;
2156 }
2157 break;
2158 case AUDIO_ENCODING_SLINEAR_LE:
2159 if (p->precision == 8 && !(flags & HAS_8)) {
2160 pswcode = rswcode = change_sign8;
2161 enc = AUDIO_ENCODING_ULINEAR_LE;
2162 }
2163 break;
2164 case AUDIO_ENCODING_ULINEAR_BE:
2165 if (p->precision == 16) {
2166 pswcode = swap_bytes_change_sign16_le;
2167 rswcode = change_sign16_swap_bytes_le;
2168 enc = AUDIO_ENCODING_SLINEAR_LE;
2169 } else if (p->precision == 8 && !(flags & HAS_8U)) {
2170 pswcode = rswcode = change_sign8;
2171 enc = AUDIO_ENCODING_SLINEAR_LE;
2172 }
2173 break;
2174 case AUDIO_ENCODING_ULINEAR_LE:
2175 if (p->precision == 16) {
2176 pswcode = rswcode = change_sign16_le;
2177 enc = AUDIO_ENCODING_SLINEAR_LE;
2178 } else if (p->precision == 8 && !(flags & HAS_8U)) {
2179 pswcode = rswcode = change_sign8;
2180 enc = AUDIO_ENCODING_SLINEAR_LE;
2181 }
2182 break;
2183 case AUDIO_ENCODING_ULAW:
2184 if (!(flags & HAS_MULAW)) {
2185 if ((flags & HAS_16) &&
2186 !(setmode & AUMODE_RECORD)) {
2187 pswcode = mulaw_to_slinear16_le;
2188 pfactor = 2;
2189 enc = AUDIO_ENCODING_SLINEAR_LE;
2190 } else if (flags & HAS_8U) {
2191 pswcode = mulaw_to_ulinear8;
2192 rswcode = ulinear8_to_mulaw;
2193 enc = AUDIO_ENCODING_ULINEAR_LE;
2194 } else if (flags & HAS_8) {
2195 pswcode = mulaw_to_slinear8;
2196 rswcode = slinear8_to_mulaw;
2197 enc = AUDIO_ENCODING_SLINEAR_LE;
2198 } else
2199 return (EINVAL);
2200 }
2201 break;
2202 case AUDIO_ENCODING_ALAW:
2203 if (!(flags & HAS_ALAW)) {
2204 if ((flags & HAS_16) &&
2205 !(setmode & AUMODE_RECORD)) {
2206 pswcode = alaw_to_slinear16_le;
2207 pfactor = 2;
2208 enc = AUDIO_ENCODING_SLINEAR_LE;
2209 } else if (flags & HAS_8U) {
2210 pswcode = alaw_to_ulinear8;
2211 rswcode = ulinear8_to_alaw;
2212 enc = AUDIO_ENCODING_ULINEAR_LE;
2213 } else if (flags & HAS_8) {
2214 pswcode = alaw_to_slinear8;
2215 rswcode = slinear8_to_alaw;
2216 enc = AUDIO_ENCODING_SLINEAR_LE;
2217 } else
2218 return (EINVAL);
2219 }
2220 break;
2221 default:
2222 return (EINVAL);
2223 }
2224 /* XXX do some other conversions... */
2225
2226 DPRINTF(("uaudio_set_params: chan=%d prec=%d enc=%d rate=%ld\n",
2227 p->channels, p->precision, enc, p->sample_rate));
2228
2229 for (i = 0; i < sc->sc_nalts; i++) {
2230 struct usb_audio_streaming_type1_descriptor *a1d =
2231 sc->sc_alts[i].asf1desc;
2232 if (p->channels == a1d->bNrChannels &&
2233 p->precision == a1d->bBitResolution &&
2234 enc == sc->sc_alts[i].encoding &&
2235 (setmode == AUMODE_PLAY ? UE_DIR_OUT : UE_DIR_IN) ==
2236 UE_GET_DIR(sc->sc_alts[i].edesc->bEndpointAddress)) {
2237 if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
2238 DPRINTFN(2,("uaudio_set_params: cont %d-%d\n",
2239 UA_SAMP_LO(a1d), UA_SAMP_HI(a1d)));
2240 if (UA_SAMP_LO(a1d) < p->sample_rate &&
2241 p->sample_rate < UA_SAMP_HI(a1d))
2242 goto found;
2243 } else {
2244 for (j = 0; j < a1d->bSamFreqType; j++) {
2245 DPRINTFN(2,("uaudio_set_params: disc #"
2246 "%d: %d\n", j, UA_GETSAMP(a1d, j)));
2247 /* XXX allow for some slack */
2248 if (UA_GETSAMP(a1d, j) ==
2249 p->sample_rate)
2250 goto found;
2251 }
2252 }
2253 }
2254 }
2255 return (EINVAL);
2256
2257 found:
2258 p->sw_code = pswcode;
2259 r->sw_code = rswcode;
2260 p->factor = pfactor;
2261 r->factor = rfactor;
2262 sc->sc_curaltidx = i;
2263
2264 DPRINTF(("uaudio_set_params: use altidx=%d, altno=%d\n",
2265 sc->sc_curaltidx,
2266 sc->sc_alts[sc->sc_curaltidx].idesc->bAlternateSetting));
2267
2268 return (0);
2269 }
2270
2271 usbd_status
2272 uaudio_set_speed(struct uaudio_softc *sc, int endpt, u_int speed)
2273 {
2274 usb_device_request_t req;
2275 u_int8_t data[3];
2276
2277 DPRINTFN(5,("uaudio_set_speed: endpt=%d speed=%u\n", endpt, speed));
2278 req.bmRequestType = UT_WRITE_CLASS_ENDPOINT;
2279 req.bRequest = SET_CUR;
2280 USETW2(req.wValue, SAMPLING_FREQ_CONTROL, 0);
2281 USETW(req.wIndex, endpt);
2282 USETW(req.wLength, 3);
2283 data[0] = speed;
2284 data[1] = speed >> 8;
2285 data[2] = speed >> 16;
2286
2287 return (usbd_do_request(sc->sc_udev, &req, &data));
2288 }
2289
2290