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