xref: /openbsd-src/sys/dev/audio.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /*	$OpenBSD: audio.c,v 1.28 2001/08/11 22:49:19 art Exp $	*/
2 /*	$NetBSD: audio.c,v 1.105 1998/09/27 16:43:56 christos Exp $	*/
3 
4 /*
5  * Copyright (c) 1991-1993 Regents of the University of California.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *	This product includes software developed by the Computer Systems
19  *	Engineering Group at Lawrence Berkeley Laboratory.
20  * 4. Neither the name of the University nor of the Laboratory may be used
21  *    to endorse or promote products derived from this software without
22  *    specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  */
36 
37 /*
38  * This is a (partially) SunOS-compatible /dev/audio driver for NetBSD.
39  *
40  * This code tries to do something half-way sensible with
41  * half-duplex hardware, such as with the SoundBlaster hardware.  With
42  * half-duplex hardware allowing O_RDWR access doesn't really make
43  * sense.  However, closing and opening the device to "turn around the
44  * line" is relatively expensive and costs a card reset (which can
45  * take some time, at least for the SoundBlaster hardware).  Instead
46  * we allow O_RDWR access, and provide an ioctl to set the "mode",
47  * i.e. playing or recording.
48  *
49  * If you write to a half-duplex device in record mode, the data is
50  * tossed.  If you read from the device in play mode, you get silence
51  * filled buffers at the rate at which samples are naturally
52  * generated.
53  *
54  * If you try to set both play and record mode on a half-duplex
55  * device, playing takes precedence.
56  */
57 
58 /*
59  * Todo:
60  * - Add softaudio() isr processing for wakeup, poll, signals,
61  *   and silence fill.
62  */
63 
64 #include "audio.h"
65 #if NAUDIO > 0
66 
67 #include <sys/param.h>
68 #include <sys/ioctl.h>
69 #include <sys/fcntl.h>
70 #include <sys/vnode.h>
71 #include <sys/select.h>
72 #include <sys/poll.h>
73 #include <sys/malloc.h>
74 #include <sys/proc.h>
75 #include <sys/systm.h>
76 #include <sys/syslog.h>
77 #include <sys/kernel.h>
78 #include <sys/signalvar.h>
79 #include <sys/conf.h>
80 #include <sys/audioio.h>
81 #include <sys/device.h>
82 
83 #include <dev/audio_if.h>
84 #include <dev/audiovar.h>
85 
86 #include <dev/rndvar.h>
87 
88 #include <vm/vm.h>
89 
90 #include <machine/endian.h>
91 
92 #ifdef AUDIO_DEBUG
93 #define DPRINTF(x)	if (audiodebug) printf x
94 #define DPRINTFN(n,x)	if (audiodebug>(n)) printf x
95 int	audiodebug = 0;
96 #else
97 #define DPRINTF(x)
98 #define DPRINTFN(n,x)
99 #endif
100 
101 #define ROUNDSIZE(x) x &= -16	/* round to nice boundary */
102 
103 int	audio_blk_ms = AUDIO_BLK_MS;
104 
105 int	audiosetinfo __P((struct audio_softc *, struct audio_info *));
106 int	audiogetinfo __P((struct audio_softc *, struct audio_info *));
107 
108 int	audio_open __P((dev_t, struct audio_softc *, int, int, struct proc *));
109 int	audio_close __P((dev_t, int, int, struct proc *));
110 int	audio_read __P((dev_t, struct uio *, int));
111 int	audio_write __P((dev_t, struct uio *, int));
112 int	audio_ioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
113 int	audio_select __P((dev_t, int, struct proc *));
114 int	audio_mmap __P((dev_t, int, int));
115 
116 int	mixer_open __P((dev_t, struct audio_softc *, int, int, struct proc *));
117 int	mixer_close __P((dev_t, int, int, struct proc *));
118 int	mixer_ioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
119 static	void mixer_remove __P((struct audio_softc *, struct proc *p));
120 static	void mixer_signal __P((struct audio_softc *));
121 
122 void	audio_init_record __P((struct audio_softc *));
123 void	audio_init_play __P((struct audio_softc *));
124 int	audiostartr __P((struct audio_softc *));
125 int	audiostartp __P((struct audio_softc *));
126 void	audio_rint __P((void *));
127 void	audio_pint __P((void *));
128 int	audio_check_params __P((struct audio_params *));
129 
130 void	audio_calc_blksize __P((struct audio_softc *, int));
131 void	audio_fill_silence __P((struct audio_params *, u_char *, int));
132 int	audio_silence_copyout __P((struct audio_softc *, int, struct uio *));
133 
134 void	audio_init_ringbuffer __P((struct audio_ringbuffer *));
135 int	audio_initbufs __P((struct audio_softc *));
136 void	audio_calcwater __P((struct audio_softc *));
137 static __inline int audio_sleep_timo __P((int *, char *, int));
138 static __inline int audio_sleep __P((int *, char *));
139 static __inline void audio_wakeup __P((int *));
140 int	audio_drain __P((struct audio_softc *));
141 void	audio_clear __P((struct audio_softc *));
142 static __inline void audio_pint_silence __P((struct audio_softc *, struct audio_ringbuffer *, u_char *, int));
143 
144 int	audio_alloc_ring __P((struct audio_softc *, struct audio_ringbuffer *, int, int));
145 void	audio_free_ring __P((struct audio_softc *, struct audio_ringbuffer *));
146 
147 int	audioprint __P((void *, const char *));
148 
149 #define __BROKEN_INDIRECT_CONFIG /* XXX */
150 #ifdef __BROKEN_INDIRECT_CONFIG
151 int	audioprobe __P((struct device *, void *, void *));
152 #else
153 int	audioprobe __P((struct device *, struct cfdata *, void *));
154 #endif
155 void	audioattach __P((struct device *, struct device *, void *));
156 int	audiodetach __P((struct device *, int));
157 int	audioactivate __P((struct device *, enum devact));
158 
159 struct portname {
160 	char 	*name;
161 	int 	mask;
162 };
163 static struct portname itable[] = {
164 	{ AudioNmicrophone,	AUDIO_MICROPHONE },
165 	{ AudioNline,		AUDIO_LINE_IN },
166 	{ AudioNcd,		AUDIO_CD },
167 	{ 0 }
168 };
169 static struct portname otable[] = {
170 	{ AudioNspeaker,	AUDIO_SPEAKER },
171 	{ AudioNheadphone,	AUDIO_HEADPHONE },
172 	{ AudioNline,		AUDIO_LINE_OUT },
173 	{ 0 }
174 };
175 void	au_check_ports __P((struct audio_softc *, struct au_mixer_ports *,
176 			    mixer_devinfo_t *, int, char *, char *,
177 			    struct portname *));
178 int	au_set_gain __P((struct audio_softc *, struct au_mixer_ports *,
179 			 int, int));
180 void	au_get_gain __P((struct audio_softc *, struct au_mixer_ports *,
181 			 u_int *, u_char *));
182 int	au_set_port __P((struct audio_softc *, struct au_mixer_ports *,
183 			 u_int));
184 int	au_get_port __P((struct audio_softc *, struct au_mixer_ports *));
185 int	au_get_lr_value __P((struct audio_softc *, mixer_ctrl_t *,
186 			     int *, int *r));
187 int	au_set_lr_value __P((struct audio_softc *, mixer_ctrl_t *,
188 			     int, int));
189 int	au_portof __P((struct audio_softc *, char *));
190 
191 
192 /* The default audio mode: 8 kHz mono ulaw */
193 struct audio_params audio_default =
194 	{ 8000, AUDIO_ENCODING_ULAW, 8, 1, 0, 1 };
195 
196 struct cfattach audio_ca = {
197 	sizeof(struct audio_softc), audioprobe, audioattach,
198 	audiodetach, audioactivate
199 };
200 
201 struct cfdriver audio_cd = {
202 	NULL, "audio", DV_DULL
203 };
204 
205 int
206 audioprobe(parent, match, aux)
207 	struct device *parent;
208 #ifdef __BROKEN_INDIRECT_CONFIG
209 	void *match;
210 #else
211 	struct cfdata *match;
212 #endif
213 	void *aux;
214 {
215 	struct audio_attach_args *sa = aux;
216 
217 	DPRINTF(("audioprobe: type=%d sa=%p hw=%p\n",
218 		   sa->type, sa, sa->hwif));
219 	return (sa->type == AUDIODEV_TYPE_AUDIO) ? 1 : 0;
220 }
221 
222 void
223 audioattach(parent, self, aux)
224 	struct device *parent, *self;
225 	void *aux;
226 {
227 	struct audio_softc *sc = (void *)self;
228 	struct audio_attach_args *sa = aux;
229 	struct audio_hw_if *hwp = sa->hwif;
230 	void *hdlp = sa->hdl;
231 	int error;
232 	mixer_devinfo_t mi;
233 	int iclass, oclass;
234 
235 	printf("\n");
236 
237 #ifdef DIAGNOSTIC
238 	if (hwp == 0 ||
239 	    hwp->open == 0 ||
240 	    hwp->close == 0 ||
241 	    hwp->query_encoding == 0 ||
242 	    hwp->set_params == 0 ||
243 	    (hwp->start_output == 0 && hwp->trigger_output == 0) ||
244 	    (hwp->start_input == 0 && hwp->trigger_input == 0) ||
245 	    hwp->halt_output == 0 ||
246 	    hwp->halt_input == 0 ||
247 	    hwp->getdev == 0 ||
248 	    hwp->set_port == 0 ||
249 	    hwp->get_port == 0 ||
250 	    hwp->query_devinfo == 0 ||
251 	    hwp->get_props == 0) {
252 		printf("audio: missing method\n");
253 		sc->hw_if = 0;
254 		return;
255         }
256 #endif
257 
258 	sc->hw_if = hwp;
259 	sc->hw_hdl = hdlp;
260 	sc->sc_dev = parent;
261 
262 	error = audio_alloc_ring(sc, &sc->sc_pr, AUMODE_PLAY, AU_RING_SIZE);
263 	if (error) {
264 		sc->hw_if = 0;
265 		printf("audio: could not allocate play buffer\n");
266 		return;
267 	}
268 	error = audio_alloc_ring(sc, &sc->sc_rr, AUMODE_RECORD, AU_RING_SIZE);
269 	if (error) {
270 		audio_free_ring(sc, &sc->sc_pr);
271 		sc->hw_if = 0;
272 		printf("audio: could not allocate record buffer\n");
273 		return;
274 	}
275 
276 	/*
277 	 * Set default softc params
278 	 */
279 	sc->sc_pparams = audio_default;
280 	sc->sc_rparams = audio_default;
281 
282 	/* Set up some default values */
283 	sc->sc_blkset = 0;
284 	audio_calc_blksize(sc, AUMODE_RECORD);
285 	audio_calc_blksize(sc, AUMODE_PLAY);
286 	audio_init_ringbuffer(&sc->sc_rr);
287 	audio_init_ringbuffer(&sc->sc_pr);
288 	audio_calcwater(sc);
289 
290 	iclass = oclass = -1;
291 	sc->sc_inports.index = -1;
292 	sc->sc_inports.nports = 0;
293 	sc->sc_inports.isenum = 0;
294 	sc->sc_inports.allports = 0;
295 	sc->sc_outports.index = -1;
296 	sc->sc_outports.nports = 0;
297 	sc->sc_outports.isenum = 0;
298 	sc->sc_outports.allports = 0;
299 	sc->sc_monitor_port = -1;
300 	for(mi.index = 0; ; mi.index++) {
301 		if (hwp->query_devinfo(hdlp, &mi) != 0)
302 			break;
303 		if (mi.type == AUDIO_MIXER_CLASS &&
304 		    strcmp(mi.label.name, AudioCrecord) == 0)
305 			iclass = mi.index;
306 		if (mi.type == AUDIO_MIXER_CLASS &&
307 		    strcmp(mi.label.name, AudioCmonitor) == 0)
308 			oclass = mi.index;
309 	}
310 	for(mi.index = 0; ; mi.index++) {
311 		if (hwp->query_devinfo(hdlp, &mi) != 0)
312 			break;
313 		if (mi.type == AUDIO_MIXER_CLASS)
314 			continue;
315 		au_check_ports(sc, &sc->sc_inports,  &mi, iclass,
316 			       AudioNsource, AudioNrecord, itable);
317 		au_check_ports(sc, &sc->sc_outports, &mi, oclass,
318 			       AudioNoutput, AudioNmaster, otable);
319 		if (mi.mixer_class == oclass &&
320 		    strcmp(mi.label.name, AudioNmonitor))
321 			sc->sc_monitor_port = mi.index;
322 	}
323 	DPRINTF(("audio_attach: inputs ports=0x%x, output ports=0x%x\n",
324 		 sc->sc_inports.allports, sc->sc_outports.allports));
325 }
326 
327 int
328 audioactivate(self, act)
329         struct device *self;
330         enum devact act;
331 {
332         struct audio_softc *sc = (struct audio_softc *)self;
333 
334         switch (act) {
335         case DVACT_ACTIVATE:
336                 return (EOPNOTSUPP);
337                 break;
338 
339         case DVACT_DEACTIVATE:
340                 sc->sc_dying = 1;
341                 break;
342         }
343         return (0);
344 }
345 
346 int
347 audiodetach(self, flags)
348         struct device *self;
349         int flags;
350 {
351         struct audio_softc *sc = (struct audio_softc *)self;
352         int maj, mn;
353         int s;
354 
355         DPRINTF(("audio_detach: sc=%p flags=%d\n", sc, flags));
356 
357         sc->sc_dying = 1;
358 
359         wakeup(&sc->sc_wchan);
360         wakeup(&sc->sc_rchan);
361         s = splaudio();
362         if (--sc->sc_refcnt >= 0) {
363                 if (tsleep(&sc->sc_refcnt, PZERO, "auddet", hz * 120))
364                         printf("audiodetach: %s didn't detach\n",
365                                sc->dev.dv_xname);
366         }
367         splx(s);
368 
369         /* free resources */
370         audio_free_ring(sc, &sc->sc_pr);
371         audio_free_ring(sc, &sc->sc_rr);
372 
373         /* locate the major number */
374         for (maj = 0; maj < nchrdev; maj++)
375                 if (cdevsw[maj].d_open == audioopen)
376                         break;
377 
378         /* Nuke the vnodes for any open instances (calls close). */
379         mn = self->dv_unit;
380         vdevgone(maj, mn | SOUND_DEVICE,    mn | SOUND_DEVICE, VCHR);
381         vdevgone(maj, mn | AUDIO_DEVICE,    mn | AUDIO_DEVICE, VCHR);
382         vdevgone(maj, mn | AUDIOCTL_DEVICE, mn | AUDIOCTL_DEVICE, VCHR);
383         vdevgone(maj, mn | MIXER_DEVICE,    mn | MIXER_DEVICE, VCHR);
384 
385         return (0);
386 }
387 
388 int
389 au_portof(sc, name)
390 	struct	audio_softc *sc;
391 	char	*name;
392 {
393 	mixer_devinfo_t mi;
394 
395 	for(mi.index = 0;
396 	    sc->hw_if->query_devinfo(sc->hw_hdl, &mi) == 0;
397 	    mi.index++)
398 		if (strcmp(mi.label.name, name) == 0)
399 			return mi.index;
400 	return -1;
401 }
402 
403 void
404 au_check_ports(sc, ports, mi, cls, name, mname, tbl)
405 	struct	audio_softc *sc;
406 	struct	au_mixer_ports *ports;
407 	mixer_devinfo_t *mi;
408 	int	cls;
409 	char	*name;
410 	char	*mname;
411 	struct	portname *tbl;
412 {
413 	int i, j;
414 
415 	if (mi->mixer_class != cls)
416 		return;
417 	if (strcmp(mi->label.name, mname) == 0) {
418 		ports->master = mi->index;
419 		return;
420 	}
421 	if (strcmp(mi->label.name, name) != 0)
422 		return;
423 	if (mi->type == AUDIO_MIXER_ENUM) {
424 	    ports->index = mi->index;
425 	    for(i = 0; tbl[i].name; i++) {
426 		for(j = 0; j < mi->un.e.num_mem; j++) {
427 		    if (strcmp(mi->un.e.member[j].label.name,
428 			       tbl[i].name) == 0) {
429 			ports->aumask[ports->nports] = tbl[i].mask;
430 			ports->misel [ports->nports] = mi->un.e.member[j].ord;
431 			ports->miport[ports->nports++] =
432 				au_portof(sc, mi->un.e.member[j].label.name);
433 			ports->allports |= tbl[i].mask;
434 		    }
435 		}
436 	    }
437 	    ports->isenum = 1;
438 	} else if (mi->type == AUDIO_MIXER_SET) {
439 	    ports->index = mi->index;
440 	    for(i = 0; tbl[i].name; i++) {
441 		for(j = 0; j < mi->un.s.num_mem; j++) {
442 		    if (strcmp(mi->un.s.member[j].label.name,
443 			       tbl[i].name) == 0) {
444 			ports->aumask[ports->nports] = tbl[i].mask;
445 			ports->misel [ports->nports] = mi->un.s.member[j].mask;
446 			ports->miport[ports->nports++] =
447 				au_portof(sc, mi->un.s.member[j].label.name);
448 			ports->allports |= tbl[i].mask;
449 		    }
450 		}
451 	    }
452 	}
453 }
454 
455 /*
456  * Called from hardware driver.  This is where the MI audio driver gets
457  * probed/attached to the hardware driver.
458  */
459 struct device *
460 audio_attach_mi(ahwp, hdlp, dev)
461 	struct audio_hw_if *ahwp;
462 	void *hdlp;
463 	struct device *dev;
464 {
465 	struct audio_attach_args arg;
466 
467 #ifdef DIAGNOSTIC
468 	if (ahwp == NULL) {
469 	        printf ("audio_attach_mi: NULL\n");
470 		return 0;
471 	}
472 #endif
473 
474 	arg.type = AUDIODEV_TYPE_AUDIO;
475 	arg.hwif = ahwp;
476 	arg.hdl = hdlp;
477 	return config_found(dev, &arg, audioprint);
478 }
479 
480 #if NAUDIO > 0
481 int
482 audioprint(aux, pnp)
483 	void *aux;
484 	const char *pnp;
485 {
486 	struct audio_attach_args *arg = aux;
487 	const char *type;
488 
489 	if (pnp != NULL) {
490 		switch (arg->type) {
491 		case AUDIODEV_TYPE_AUDIO:
492 			type = "audio";
493 			break;
494 		case AUDIODEV_TYPE_OPL:
495 			type = "opl";
496 			break;
497 		case AUDIODEV_TYPE_MPU:
498 			type = "mpu";
499 			break;
500 		default:
501 			panic("audioprint: unknown type %d", arg->type);
502 		}
503 		printf("%s at %s", type, pnp);
504 	}
505 	return (UNCONF);
506 }
507 
508 #endif /* NAUDIO > 0 */
509 
510 #ifdef AUDIO_DEBUG
511 void	audio_printsc __P((struct audio_softc *));
512 void	audio_print_params __P((char *, struct audio_params *));
513 
514 void
515 audio_printsc(sc)
516 	struct audio_softc *sc;
517 {
518 	printf("hwhandle %p hw_if %p ", sc->hw_hdl, sc->hw_if);
519 	printf("open 0x%x mode 0x%x\n", sc->sc_open, sc->sc_mode);
520 	printf("rchan 0x%x wchan 0x%x ", sc->sc_rchan, sc->sc_wchan);
521 	printf("rring used 0x%x pring used=%d\n", sc->sc_rr.used, sc->sc_pr.used);
522 	printf("rbus 0x%x pbus 0x%x ", sc->sc_rbus, sc->sc_pbus);
523 	printf("blksize %d", sc->sc_pr.blksize);
524 	printf("hiwat %d lowat %d\n", sc->sc_pr.usedhigh, sc->sc_pr.usedlow);
525 }
526 
527 void
528 audio_print_params(s, p)
529 	char *s;
530 	struct audio_params *p;
531 {
532 	printf("audio: %s sr=%ld, enc=%d, chan=%d, prec=%d\n", s,
533 	       p->sample_rate, p->encoding, p->channels, p->precision);
534 }
535 #endif
536 
537 int
538 audio_alloc_ring(sc, r, direction, bufsize)
539 	struct audio_softc *sc;
540 	struct audio_ringbuffer *r;
541 	int direction;
542 	int bufsize;
543 {
544 	struct audio_hw_if *hw = sc->hw_if;
545 	void *hdl = sc->hw_hdl;
546 	/*
547 	 * Alloc DMA play and record buffers
548 	 */
549 	if (bufsize < AUMINBUF)
550 		bufsize = AUMINBUF;
551 	ROUNDSIZE(bufsize);
552 	if (hw->round_buffersize)
553 		bufsize = hw->round_buffersize(hdl, direction, bufsize);
554 	else if (hw->round_buffersize_old)
555 		bufsize = hw->round_buffersize_old(hdl, bufsize);
556 	r->bufsize = bufsize;
557 	if (hw->allocm)
558 		r->start = hw->allocm(hdl, direction, r->bufsize, M_DEVBUF,
559 		    M_WAITOK);
560 	else if (hw->allocm_old)
561 		r->start = hw->allocm_old(hdl, r->bufsize, M_DEVBUF, M_WAITOK);
562 	else
563 		r->start = malloc(bufsize, M_DEVBUF, M_WAITOK);
564 	if (r->start == 0)
565 		return ENOMEM;
566 	return 0;
567 }
568 
569 void
570 audio_free_ring(sc, r)
571 	struct audio_softc *sc;
572 	struct audio_ringbuffer *r;
573 {
574 	if (sc->hw_if->freem) {
575 		sc->hw_if->freem(sc->hw_hdl, r->start, M_DEVBUF);
576 	} else {
577 		free(r->start, M_DEVBUF);
578 	}
579 }
580 
581 int
582 audioopen(dev, flags, ifmt, p)
583 	dev_t dev;
584 	int flags, ifmt;
585 	struct proc *p;
586 {
587 	int unit = AUDIOUNIT(dev);
588 	struct audio_softc *sc;
589 	int error;
590 
591         if (unit >= audio_cd.cd_ndevs ||
592 	    (sc = audio_cd.cd_devs[unit]) == NULL)
593 		return ENXIO;
594 
595 	if (sc->sc_dying)
596 	        return (EIO);
597 
598 	if (!sc->hw_if)
599 		return (ENXIO);
600 
601 	sc->sc_refcnt ++;
602 	switch (AUDIODEV(dev)) {
603 	case SOUND_DEVICE:
604 	case AUDIO_DEVICE:
605 	case AUDIOCTL_DEVICE:
606 		error = audio_open(dev, sc, flags, ifmt, p);
607 		break;
608 	case MIXER_DEVICE:
609 	        error = mixer_open(dev, sc, flags, ifmt, p);
610 		break;
611 	default:
612 		error = ENXIO;
613 		break;
614 	}
615 
616 	if (--sc->sc_refcnt < 0)
617 	        wakeup(&sc->sc_refcnt);
618 
619 	return (error);
620 }
621 
622 int
623 audioclose(dev, flags, ifmt, p)
624 	dev_t dev;
625 	int flags, ifmt;
626 	struct proc *p;
627 {
628 
629 	switch (AUDIODEV(dev)) {
630 	case SOUND_DEVICE:
631 	case AUDIO_DEVICE:
632 		return (audio_close(dev, flags, ifmt, p));
633 	case MIXER_DEVICE:
634 		return (mixer_close(dev, flags, ifmt, p));
635 	case AUDIOCTL_DEVICE:
636 		return 0;
637 	default:
638 		return (ENXIO);
639 	}
640 }
641 
642 int
643 audioread(dev, uio, ioflag)
644 	dev_t dev;
645 	struct uio *uio;
646 	int ioflag;
647 {
648 	int unit = AUDIOUNIT(dev);
649 	struct audio_softc *sc;
650 	int error;
651 
652         if (unit >= audio_cd.cd_ndevs ||
653             (sc = audio_cd.cd_devs[unit]) == NULL)
654                 return ENXIO;
655 
656         if (sc->sc_dying)
657                 return (EIO);
658 
659 	sc->sc_refcnt ++;
660 	switch (AUDIODEV(dev)) {
661 	case SOUND_DEVICE:
662 	case AUDIO_DEVICE:
663 		error = audio_read(dev, uio, ioflag);
664 		break;
665 	case AUDIOCTL_DEVICE:
666 	case MIXER_DEVICE:
667 		error = ENODEV;
668 		break;
669 	default:
670 		error = ENXIO;
671 		break;
672 	}
673 
674 	if (--sc->sc_refcnt < 0)
675 	        wakeup(&sc->sc_refcnt);
676 	return (error);
677 }
678 
679 int
680 audiowrite(dev, uio, ioflag)
681 	dev_t dev;
682 	struct uio *uio;
683 	int ioflag;
684 {
685 	int unit = AUDIOUNIT(dev);
686 	struct audio_softc *sc;
687 	int error;
688 
689 	if (unit >= audio_cd.cd_ndevs ||
690             (sc = audio_cd.cd_devs[unit]) == NULL)
691 		return ENXIO;
692 
693         if (sc->sc_dying)
694 	  	return (EIO);
695 
696 	sc->sc_refcnt ++;
697 	switch (AUDIODEV(dev)) {
698 	case SOUND_DEVICE:
699 	case AUDIO_DEVICE:
700 	  	error = audio_write(dev, uio, ioflag);
701 		break;
702 	case AUDIOCTL_DEVICE:
703 	case MIXER_DEVICE:
704 		error = ENODEV;
705 		break;
706 	default:
707 		error = ENXIO;
708 		break;
709 	}
710 
711 	if (--sc->sc_refcnt < 0)
712 	        wakeup(&sc->sc_refcnt);
713 	return (error);
714 }
715 
716 int
717 audioioctl(dev, cmd, addr, flag, p)
718 	dev_t dev;
719 	u_long cmd;
720 	caddr_t addr;
721 	int flag;
722 	struct proc *p;
723 {
724 	int unit = AUDIOUNIT(dev);
725 	struct audio_softc *sc;
726 	int error;
727 
728         if (unit >= audio_cd.cd_ndevs ||
729             (sc = audio_cd.cd_devs[unit]) == NULL)
730                 return ENXIO;
731 
732         if (sc->sc_dying)
733                 return (EIO);
734 
735 	sc->sc_refcnt ++;
736 	switch (AUDIODEV(dev)) {
737 	case SOUND_DEVICE:
738 	case AUDIO_DEVICE:
739 	case AUDIOCTL_DEVICE:
740 		error = audio_ioctl(dev, cmd, addr, flag, p);
741 		break;
742 	case MIXER_DEVICE:
743 		error = mixer_ioctl(dev, cmd, addr, flag, p);
744 		break;
745 	default:
746 		error = ENXIO;
747 		break;
748 	}
749 
750 	if (--sc->sc_refcnt < 0)
751 	        wakeup(&sc->sc_refcnt);
752 	return (error);
753 }
754 
755 int
756 audioselect(dev, events, p)
757 	dev_t dev;
758 	int events;
759 	struct proc *p;
760 {
761         int unit = AUDIOUNIT(dev);
762         struct audio_softc *sc;
763 	int error;
764 
765         if (unit >= audio_cd.cd_ndevs ||
766             (sc = audio_cd.cd_devs[unit]) == NULL)
767                 return ENXIO;
768 
769         if (sc->sc_dying)
770                 return (EIO);
771 
772 	sc->sc_refcnt ++;
773 	switch (AUDIODEV(dev)) {
774 	case SOUND_DEVICE:
775 	case AUDIO_DEVICE:
776 		error = audio_select(dev, events, p);
777 		break;
778 	case AUDIOCTL_DEVICE:
779 	case MIXER_DEVICE:
780 		error = 0;
781 		break;
782 	default:
783 		error = 0;
784 		break;
785 	}
786 
787 	if (--sc->sc_refcnt < 0)
788 	        wakeup(&sc->sc_refcnt);
789 	return (error);
790 }
791 
792 int
793 audiommap(dev, off, prot)
794 	dev_t dev;
795 	int off, prot;
796 {
797         int unit = AUDIOUNIT(dev);
798         struct audio_softc *sc;
799 	int error;
800 
801         if (unit >= audio_cd.cd_ndevs ||
802             (sc = audio_cd.cd_devs[unit]) == NULL)
803                 return (-1);
804 
805         if (sc->sc_dying)
806                 return (-1);
807 
808 	sc->sc_refcnt ++;
809 	switch (AUDIODEV(dev)) {
810 	case SOUND_DEVICE:
811 	case AUDIO_DEVICE:
812 		error = audio_mmap(dev, off, prot);
813 		break;
814 	case AUDIOCTL_DEVICE:
815 	case MIXER_DEVICE:
816 		error = -1;
817 		break;
818 	default:
819 		error = -1;
820 		break;
821 	}
822 
823 	if (--sc->sc_refcnt < 0)
824 	        wakeup(&sc->sc_refcnt);
825 	return (error);
826 }
827 
828 /*
829  * Audio driver
830  */
831 void
832 audio_init_ringbuffer(rp)
833 	struct audio_ringbuffer *rp;
834 {
835 	int nblks;
836 	int blksize = rp->blksize;
837 
838 	if (blksize < AUMINBLK)
839 		blksize = AUMINBLK;
840 	nblks = rp->bufsize / blksize;
841 	if (nblks < AUMINNOBLK) {
842 		nblks = AUMINNOBLK;
843 		blksize = rp->bufsize / nblks;
844 		ROUNDSIZE(blksize);
845 	}
846 	DPRINTF(("audio_init_ringbuffer: blksize=%d\n", blksize));
847 	rp->blksize = blksize;
848 	rp->maxblks = nblks;
849 	rp->used = 0;
850 	rp->end = rp->start + nblks * blksize;
851 	rp->inp = rp->outp = rp->start;
852 	rp->stamp = 0;
853 	rp->drops = 0;
854 	rp->pause = 0;
855 	rp->copying = 0;
856 	rp->needfill = 0;
857 	rp->mmapped = 0;
858 }
859 
860 int
861 audio_initbufs(sc)
862 	struct audio_softc *sc;
863 {
864 	struct audio_hw_if *hw = sc->hw_if;
865 	int error;
866 
867 	DPRINTF(("audio_initbufs: mode=0x%x\n", sc->sc_mode));
868 	audio_init_ringbuffer(&sc->sc_rr);
869 	if (hw->init_input && (sc->sc_mode & AUMODE_RECORD)) {
870 		error = hw->init_input(sc->hw_hdl, sc->sc_rr.start,
871 				       sc->sc_rr.end - sc->sc_rr.start);
872 		if (error)
873 			return error;
874 	}
875 
876 	audio_init_ringbuffer(&sc->sc_pr);
877 	sc->sc_sil_count = 0;
878 	if (hw->init_output && (sc->sc_mode & AUMODE_PLAY)) {
879 		error = hw->init_output(sc->hw_hdl, sc->sc_pr.start,
880 					sc->sc_pr.end - sc->sc_pr.start);
881 		if (error)
882 			return error;
883 	}
884 
885 #ifdef AUDIO_INTR_TIME
886 #define double u_long
887 	sc->sc_pnintr = 0;
888 	sc->sc_pblktime = (u_long)(
889 	    (double)sc->sc_pr.blksize * 100000 /
890 	    (double)(sc->sc_pparams.precision / NBBY *
891                      sc->sc_pparams.channels *
892 		     sc->sc_pparams.sample_rate)) * 10;
893 	DPRINTF(("audio: play blktime = %lu for %d\n",
894 		 sc->sc_pblktime, sc->sc_pr.blksize));
895 	sc->sc_rnintr = 0;
896 	sc->sc_rblktime = (u_long)(
897 	    (double)sc->sc_rr.blksize * 100000 /
898 	    (double)(sc->sc_rparams.precision / NBBY *
899                      sc->sc_rparams.channels *
900 		     sc->sc_rparams.sample_rate)) * 10;
901 	DPRINTF(("audio: record blktime = %lu for %d\n",
902 		 sc->sc_rblktime, sc->sc_rr.blksize));
903 #undef double
904 #endif
905 
906 	return 0;
907 }
908 
909 void
910 audio_calcwater(sc)
911 	struct audio_softc *sc;
912 {
913 	sc->sc_pr.usedhigh = sc->sc_pr.end - sc->sc_pr.start;
914 	sc->sc_pr.usedlow = sc->sc_pr.usedhigh * 3 / 4;	/* set lowater at 75% */
915 	if (sc->sc_pr.usedlow == sc->sc_pr.usedhigh)
916 		sc->sc_pr.usedlow -= sc->sc_pr.blksize;
917 	sc->sc_rr.usedhigh = sc->sc_pr.end - sc->sc_pr.start - sc->sc_pr.blksize;
918 	sc->sc_rr.usedlow = 0;
919 }
920 
921 static __inline int
922 audio_sleep_timo(chan, label, timo)
923 	int *chan;
924 	char *label;
925 	int timo;
926 {
927 	int st;
928 
929 	if (!label)
930 		label = "audio";
931 
932         DPRINTFN(3, ("audio_sleep_timo: chan=%p, label=%s, timo=%d\n",
933                     chan, label, timo));
934 	*chan = 1;
935 	st = tsleep(chan, PWAIT | PCATCH, label, timo);
936 	*chan = 0;
937 #ifdef AUDIO_DEBUG
938 	if (st != 0)
939 	    printf("audio_sleep: woke up st=%d\n", st);
940 #endif
941 	return (st);
942 }
943 
944 static __inline int
945 audio_sleep(chan, label)
946 	int *chan;
947 	char *label;
948 {
949 	return audio_sleep_timo(chan, label, 0);
950 }
951 
952 /* call at splaudio() */
953 static __inline void
954 audio_wakeup(chan)
955 	int *chan;
956 {
957 	DPRINTFN(3, ("audio_wakeup: chan=%p, *chan=%d\n", chan, *chan));
958 	if (*chan) {
959 		wakeup(chan);
960 		*chan = 0;
961 	}
962 }
963 
964 int
965 audio_open(dev, sc, flags, ifmt, p)
966 	dev_t dev;
967 	struct audio_softc *sc;
968 	int flags, ifmt;
969 	struct proc *p;
970 {
971 	int error;
972 	int mode;
973 	struct audio_info ai;
974 
975 	DPRINTF(("audio_open: dev=0x%x flags=0x%x sc=%p hdl=%p\n", dev, flags, sc, sc->hw_hdl));
976 
977 	if (ISDEVAUDIOCTL(dev))
978 		return 0;
979 
980 	if ((sc->sc_open & (AUOPEN_READ|AUOPEN_WRITE)) != 0)
981 		return (EBUSY);
982 
983 	error = sc->hw_if->open(sc->hw_hdl, flags);
984 	if (error)
985 		return (error);
986 
987 	sc->sc_async_audio = 0;
988 	sc->sc_rchan = 0;
989 	sc->sc_wchan = 0;
990 	sc->sc_blkset = 0; /* Block sizes not set yet */
991 	sc->sc_sil_count = 0;
992 	sc->sc_rbus = 0;
993 	sc->sc_pbus = 0;
994 	sc->sc_eof = 0;
995 	sc->sc_playdrop = 0;
996 
997 	sc->sc_full_duplex = 0;
998 /* doesn't always work right on SB.
999 		(flags & (FWRITE|FREAD)) == (FWRITE|FREAD) &&
1000 		(sc->hw_if->get_props(sc->hw_hdl) & AUDIO_PROP_FULLDUPLEX);
1001 */
1002 
1003 	mode = 0;
1004 	if (flags & FREAD) {
1005 		sc->sc_open |= AUOPEN_READ;
1006 		mode |= AUMODE_RECORD;
1007 	}
1008 	if (flags & FWRITE) {
1009 		sc->sc_open |= AUOPEN_WRITE;
1010 		mode |= AUMODE_PLAY | AUMODE_PLAY_ALL;
1011 	}
1012 
1013 	/*
1014 	 * Multiplex device: /dev/audio (MU-Law) and /dev/sound (linear)
1015 	 * The /dev/audio is always (re)set to 8-bit MU-Law mono
1016 	 * For the other devices, you get what they were last set to.
1017 	 */
1018 	if (ISDEVAUDIO(dev)) {
1019 		/* /dev/audio */
1020 		sc->sc_rparams = audio_default;
1021 		sc->sc_pparams = audio_default;
1022 	}
1023 #ifdef DIAGNOSTIC
1024 	/*
1025 	 * Sample rate and precision are supposed to be set to proper
1026 	 * default values by the hardware driver, so that it may give
1027 	 * us these values.
1028 	 */
1029 	if (sc->sc_rparams.precision == 0 || sc->sc_pparams.precision == 0) {
1030 		printf("audio_open: 0 precision\n");
1031 		return EINVAL;
1032 	}
1033 #endif
1034 
1035 	AUDIO_INITINFO(&ai);
1036 	ai.record.sample_rate = sc->sc_rparams.sample_rate;
1037 	ai.record.encoding    = sc->sc_rparams.encoding;
1038 	ai.record.channels    = sc->sc_rparams.channels;
1039 	ai.record.precision   = sc->sc_rparams.precision;
1040 	ai.play.sample_rate   = sc->sc_pparams.sample_rate;
1041 	ai.play.encoding      = sc->sc_pparams.encoding;
1042 	ai.play.channels      = sc->sc_pparams.channels;
1043 	ai.play.precision     = sc->sc_pparams.precision;
1044 	ai.mode		      = mode;
1045 	sc->sc_pr.blksize = sc->sc_rr.blksize = 0; /* force recalculation */
1046 	error = audiosetinfo(sc, &ai);
1047 	if (error)
1048 		goto bad;
1049 
1050 	DPRINTF(("audio_open: done sc_mode = 0x%x\n", sc->sc_mode));
1051 
1052 	return 0;
1053 
1054 bad:
1055 	sc->hw_if->close(sc->hw_hdl);
1056 	sc->sc_open = 0;
1057 	sc->sc_mode = 0;
1058 	sc->sc_full_duplex = 0;
1059 	return error;
1060 }
1061 
1062 /*
1063  * Must be called from task context.
1064  */
1065 void
1066 audio_init_record(sc)
1067 	struct audio_softc *sc;
1068 {
1069 	int s = splaudio();
1070 
1071 	if (sc->hw_if->speaker_ctl &&
1072 	    (!sc->sc_full_duplex || (sc->sc_mode & AUMODE_PLAY) == 0))
1073 		sc->hw_if->speaker_ctl(sc->hw_hdl, SPKR_OFF);
1074 	splx(s);
1075 }
1076 
1077 /*
1078  * Must be called from task context.
1079  */
1080 void
1081 audio_init_play(sc)
1082 	struct audio_softc *sc;
1083 {
1084 	int s = splaudio();
1085 
1086 	sc->sc_wstamp = sc->sc_pr.stamp;
1087 	if (sc->hw_if->speaker_ctl)
1088 		sc->hw_if->speaker_ctl(sc->hw_hdl, SPKR_ON);
1089 	splx(s);
1090 }
1091 
1092 int
1093 audio_drain(sc)
1094 	struct audio_softc *sc;
1095 {
1096 	int error, drops;
1097 	struct audio_ringbuffer *cb = &sc->sc_pr;
1098 	int s;
1099 
1100         DPRINTF(("audio_drain: enter busy=%d used=%d\n",
1101                  sc->sc_pbus, sc->sc_pr.used));
1102 	if (sc->sc_pr.mmapped || sc->sc_pr.used <= 0)
1103 		return 0;
1104 	if (!sc->sc_pbus) {
1105 		/* We've never started playing, probably because the
1106 		 * block was too short.  Pad it and start now.
1107 		 */
1108 		int cc;
1109 		u_char *inp = cb->inp;
1110 
1111 		cc = cb->blksize - (inp - cb->start) % cb->blksize;
1112 		audio_fill_silence(&sc->sc_pparams, inp, cc);
1113 		inp += cc;
1114 		if (inp >= cb->end)
1115 			inp = cb->start;
1116 		s = splaudio();
1117 		cb->used += cc;
1118 		cb->inp = inp;
1119 		error = audiostartp(sc);
1120 		splx(s);
1121 		if (error)
1122 			return error;
1123 	}
1124 	/*
1125 	 * Play until a silence block has been played, then we
1126 	 * know all has been drained.
1127 	 * XXX This should be done some other way to avoid
1128 	 * playing silence.
1129 	 */
1130 #ifdef DIAGNOSTIC
1131 	if (cb->copying) {
1132 		printf("audio_drain: copying in progress!?!\n");
1133 		cb->copying = 0;
1134 	}
1135 #endif
1136 	drops = cb->drops;
1137 	error = 0;
1138 	s = splaudio();
1139 	while (cb->drops == drops && !error) {
1140 		DPRINTF(("audio_drain: used=%d, drops=%ld\n", sc->sc_pr.used, cb->drops));
1141 		/*
1142 		 * When the process is exiting, it ignores all signals and
1143 		 * we can't interrupt this sleep, so we set a timeout just in case.
1144 		 */
1145 		error = audio_sleep_timo(&sc->sc_wchan, "aud_dr", 30*hz);
1146 		if (sc->sc_dying)
1147 		        error = EIO;
1148 	}
1149 	splx(s);
1150 	return error;
1151 }
1152 
1153 /*
1154  * Close an audio chip.
1155  */
1156 /* ARGSUSED */
1157 int
1158 audio_close(dev, flags, ifmt, p)
1159 	dev_t dev;
1160 	int flags, ifmt;
1161 	struct proc *p;
1162 {
1163 	int unit = AUDIOUNIT(dev);
1164 	struct audio_softc *sc = audio_cd.cd_devs[unit];
1165 	struct audio_hw_if *hw = sc->hw_if;
1166 	int s;
1167 
1168 	DPRINTF(("audio_close: unit=%d flags=0x%x\n", unit, flags));
1169 
1170 	s = splaudio();
1171         /* Stop recording. */
1172 	if ((flags & FREAD) && sc->sc_rbus) {
1173 		/*
1174 		 * XXX Some drivers (e.g. SB) use the same routine
1175 		 * to halt input and output so don't halt input if
1176 		 * in full duplex mode.  These drivers should be fixed.
1177 		 */
1178 		if (!sc->sc_full_duplex || sc->hw_if->halt_input != sc->hw_if->halt_output)
1179 			sc->hw_if->halt_input(sc->hw_hdl);
1180 		sc->sc_rbus = 0;
1181 	}
1182 	/*
1183 	 * Block until output drains, but allow ^C interrupt.
1184 	 */
1185 	sc->sc_pr.usedlow = sc->sc_pr.blksize;	/* avoid excessive wakeups */
1186 	/*
1187 	 * If there is pending output, let it drain (unless
1188 	 * the output is paused).
1189 	 */
1190 	if ((flags & FWRITE) && sc->sc_pbus) {
1191 		if (!sc->sc_pr.pause && !audio_drain(sc) && hw->drain)
1192 			(void)hw->drain(sc->hw_hdl);
1193 		sc->hw_if->halt_output(sc->hw_hdl);
1194 		sc->sc_pbus = 0;
1195 	}
1196 
1197 	hw->close(sc->hw_hdl);
1198 
1199 	/*
1200 	 * If flags has neither read nor write then reset both
1201 	 * directions. Encountered when someone runs revoke(2).
1202 	 */
1203 
1204 	if ((flags & FREAD) || ((flags & (FREAD|FWRITE)) == 0)) {
1205 		sc->sc_open &= ~AUOPEN_READ;
1206 		sc->sc_mode &= ~AUMODE_RECORD;
1207 	}
1208 	if ((flags & FWRITE) || ((flags & (FREAD|FWRITE)) == 0)) {
1209 		sc->sc_open &= ~AUOPEN_WRITE;
1210 		sc->sc_mode &= ~(AUMODE_PLAY|AUMODE_PLAY_ALL);
1211 	}
1212 
1213 	sc->sc_async_audio = 0;
1214 	sc->sc_full_duplex = 0;
1215 	splx(s);
1216 	DPRINTF(("audio_close: done\n"));
1217 
1218 	return (0);
1219 }
1220 
1221 int
1222 audio_read(dev, uio, ioflag)
1223 	dev_t dev;
1224 	struct uio *uio;
1225 	int ioflag;
1226 {
1227 	int unit = AUDIOUNIT(dev);
1228 	struct audio_softc *sc = audio_cd.cd_devs[unit];
1229 	struct audio_ringbuffer *cb = &sc->sc_rr;
1230 	u_char *outp;
1231 	int error, s, used, cc, n;
1232 
1233 	if (cb->mmapped)
1234 		return EINVAL;
1235 
1236 	DPRINTFN(1,("audio_read: cc=%d mode=%d\n",
1237                     uio->uio_resid, sc->sc_mode));
1238 
1239 	error = 0;
1240 	/*
1241 	 * If hardware is half-duplex and currently playing, return
1242 	 * silence blocks based on the number of blocks we have output.
1243 	 */
1244 	if (!sc->sc_full_duplex &&
1245 	    (sc->sc_mode & AUMODE_PLAY)) {
1246 		while (uio->uio_resid > 0 && !error) {
1247 			s = splaudio();
1248 			for(;;) {
1249 				cc = sc->sc_pr.stamp - sc->sc_wstamp;
1250 				if (cc > 0)
1251 					break;
1252 				DPRINTF(("audio_read: stamp=%lu, wstamp=%lu\n",
1253 					 sc->sc_pr.stamp, sc->sc_wstamp));
1254 				if (ioflag & IO_NDELAY) {
1255 					splx(s);
1256 					return EWOULDBLOCK;
1257 				}
1258 				error = audio_sleep(&sc->sc_rchan, "aud_hr");
1259 				if (sc->sc_dying)
1260 				        error = EIO;
1261 				if (error) {
1262 					splx(s);
1263 					return error;
1264 				}
1265 			}
1266 			splx(s);
1267 
1268 			if (uio->uio_resid < cc)
1269 				cc = uio->uio_resid;
1270 			DPRINTFN(1, ("audio_read: reading in write mode, cc=%d\n", cc));
1271 			error = audio_silence_copyout(sc, cc, uio);
1272 			sc->sc_wstamp += cc;
1273 		}
1274 		return (error);
1275 	}
1276 	while (uio->uio_resid > 0 && !error) {
1277 		s = splaudio();
1278 		while (cb->used <= 0) {
1279 			if (ioflag & IO_NDELAY) {
1280 				splx(s);
1281 				return EWOULDBLOCK;
1282 			}
1283 			if (!sc->sc_rbus) {
1284 				error = audiostartr(sc);
1285 				if (error) {
1286 					splx(s);
1287 					return error;
1288 				}
1289 			}
1290 			DPRINTFN(2, ("audio_read: sleep used=%d\n", cb->used));
1291 			error = audio_sleep(&sc->sc_rchan, "aud_rd");
1292 			if (sc->sc_dying)
1293 			        error = EIO;
1294 			if (error) {
1295 				splx(s);
1296 				return error;
1297 			}
1298 		}
1299 		used = cb->used;
1300 		outp = cb->outp;
1301 		cb->copying = 1;
1302 		splx(s);
1303 		cc = used - cb->usedlow; /* maximum to read */
1304 		n = cb->end - outp;
1305 		if (n < cc)
1306 			cc = n;	/* don't read beyond end of buffer */
1307 
1308 		if (uio->uio_resid < cc)
1309 			cc = uio->uio_resid; /* and no more than we want */
1310 
1311 		if (sc->sc_rparams.sw_code)
1312 			sc->sc_rparams.sw_code(sc->hw_hdl, outp, cc);
1313 		DPRINTFN(1,("audio_read: outp=%p, cc=%d\n", outp, cc));
1314 		error = uiomove(outp, cc, uio);
1315 		used -= cc;
1316 		outp += cc;
1317 		if (outp >= cb->end)
1318 			outp = cb->start;
1319 		s = splaudio();
1320 		cb->outp = outp;
1321 		cb->used = used;
1322 		cb->copying = 0;
1323 		splx(s);
1324 	}
1325 	return (error);
1326 }
1327 
1328 void
1329 audio_clear(sc)
1330 	struct audio_softc *sc;
1331 {
1332 	int s = splaudio();
1333 
1334 	if (sc->sc_rbus) {
1335 		audio_wakeup(&sc->sc_rchan);
1336 		sc->hw_if->halt_input(sc->hw_hdl);
1337 		sc->sc_rbus = 0;
1338 	}
1339 	if (sc->sc_pbus) {
1340 		audio_wakeup(&sc->sc_wchan);
1341 		sc->hw_if->halt_output(sc->hw_hdl);
1342 		sc->sc_pbus = 0;
1343 	}
1344 	splx(s);
1345 }
1346 
1347 void
1348 audio_calc_blksize(sc, mode)
1349 	struct audio_softc *sc;
1350 	int mode;
1351 {
1352 	struct audio_hw_if *hw = sc->hw_if;
1353 	struct audio_params *parm;
1354 	struct audio_ringbuffer *rb;
1355     	int bs;
1356 
1357 	if (sc->sc_blkset)
1358 		return;
1359 
1360 	if (mode == AUMODE_PLAY) {
1361 		parm = &sc->sc_pparams;
1362 		rb = &sc->sc_pr;
1363 	} else {
1364 		parm = &sc->sc_rparams;
1365 		rb = &sc->sc_rr;
1366 	}
1367 
1368 	bs = parm->sample_rate * audio_blk_ms / 1000 *
1369 	     parm->channels * parm->precision / NBBY *
1370 	     parm->factor;
1371 	ROUNDSIZE(bs);
1372 	if (hw->round_blocksize)
1373 		bs = hw->round_blocksize(sc->hw_hdl, bs);
1374 	rb->blksize = bs;
1375 
1376 	DPRINTF(("audio_calc_blksize: %s blksize=%d\n",
1377 		 mode == AUMODE_PLAY ? "play" : "record", bs));
1378 }
1379 
1380 void
1381 audio_fill_silence(params, p, n)
1382 	struct audio_params *params;
1383         u_char *p;
1384         int n;
1385 {
1386 	u_char auzero0, auzero1 = 0; /* initialize to please gcc */
1387 	int nfill = 1;
1388 
1389 	switch (params->encoding) {
1390 	case AUDIO_ENCODING_ULAW:
1391 	    	auzero0 = 0x7f;
1392 		break;
1393 	case AUDIO_ENCODING_ALAW:
1394 		auzero0 = 0x55;
1395 		break;
1396 	case AUDIO_ENCODING_MPEG_L1_STREAM:
1397 	case AUDIO_ENCODING_MPEG_L1_PACKETS:
1398 	case AUDIO_ENCODING_MPEG_L1_SYSTEM:
1399 	case AUDIO_ENCODING_MPEG_L2_STREAM:
1400 	case AUDIO_ENCODING_MPEG_L2_PACKETS:
1401 	case AUDIO_ENCODING_MPEG_L2_SYSTEM:
1402 	case AUDIO_ENCODING_ADPCM: /* is this right XXX */
1403 	case AUDIO_ENCODING_SLINEAR_LE:
1404 	case AUDIO_ENCODING_SLINEAR_BE:
1405 		auzero0 = 0;	/* fortunately this works for both 8 and 16 bits */
1406 		break;
1407 	case AUDIO_ENCODING_ULINEAR_LE:
1408 	case AUDIO_ENCODING_ULINEAR_BE:
1409 		if (params->precision == 16) {
1410 			nfill = 2;
1411 			if (params->encoding == AUDIO_ENCODING_ULINEAR_LE) {
1412 				auzero0 = 0;
1413 				auzero1 = 0x80;
1414 			} else {
1415 				auzero0 = 0x80;
1416 				auzero1 = 0;
1417 			}
1418 		} else
1419 			auzero0 = 0x80;
1420 		break;
1421 	default:
1422 		DPRINTF(("audio: bad encoding %d\n", params->encoding));
1423 		auzero0 = 0;
1424 		break;
1425 	}
1426 	if (nfill == 1) {
1427 		while (--n >= 0)
1428 			*p++ = auzero0; /* XXX memset */
1429 	} else /* nfill must be 2 */ {
1430 		while (n > 1) {
1431 			*p++ = auzero0;
1432 			*p++ = auzero1;
1433 			n -= 2;
1434 		}
1435 	}
1436 }
1437 
1438 int
1439 audio_silence_copyout(sc, n, uio)
1440 	struct audio_softc *sc;
1441 	int n;
1442 	struct uio *uio;
1443 {
1444 	int error;
1445 	int k;
1446 	u_char zerobuf[128];
1447 
1448 	audio_fill_silence(&sc->sc_rparams, zerobuf, sizeof zerobuf);
1449 
1450 	error = 0;
1451         while (n > 0 && uio->uio_resid > 0 && !error) {
1452 		k = min(n, min(uio->uio_resid, sizeof zerobuf));
1453 		error = uiomove(zerobuf, k, uio);
1454 		n -= k;
1455 	}
1456         return (error);
1457 }
1458 
1459 int
1460 audio_write(dev, uio, ioflag)
1461 	dev_t dev;
1462 	struct uio *uio;
1463 	int ioflag;
1464 {
1465 	int unit = AUDIOUNIT(dev);
1466 	struct audio_softc *sc = audio_cd.cd_devs[unit];
1467 	struct audio_ringbuffer *cb = &sc->sc_pr;
1468 	u_char *inp, *einp;
1469 	int saveerror, error, s, n, cc, used;
1470 
1471 	DPRINTFN(2, ("audio_write: sc=%p(unit=%d) count=%d used=%d(hi=%d)\n", sc, unit,
1472 		 uio->uio_resid, sc->sc_pr.used, sc->sc_pr.usedhigh));
1473 
1474 	if (cb->mmapped)
1475 		return EINVAL;
1476 
1477 	if (uio->uio_resid == 0) {
1478 		sc->sc_eof++;
1479 		return 0;
1480 	}
1481 
1482 	/*
1483 	 * If half-duplex and currently recording, throw away data.
1484 	 */
1485 	if (!sc->sc_full_duplex &&
1486 	    (sc->sc_mode & AUMODE_RECORD)) {
1487 		uio->uio_offset += uio->uio_resid;
1488 		uio->uio_resid = 0;
1489 		DPRINTF(("audio_write: half-dpx read busy\n"));
1490 		return (0);
1491 	}
1492 
1493 	if (!(sc->sc_mode & AUMODE_PLAY_ALL) && sc->sc_playdrop > 0) {
1494 		n = min(sc->sc_playdrop, uio->uio_resid);
1495 		DPRINTF(("audio_write: playdrop %d\n", n));
1496 		uio->uio_offset += n;
1497 		uio->uio_resid -= n;
1498 		sc->sc_playdrop -= n;
1499 		if (uio->uio_resid == 0)
1500 			return 0;
1501 	}
1502 
1503 	DPRINTFN(1, ("audio_write: sr=%ld, enc=%d, prec=%d, chan=%d, sw=%p, fact=%d\n",
1504                      sc->sc_pparams.sample_rate, sc->sc_pparams.encoding,
1505                      sc->sc_pparams.precision, sc->sc_pparams.channels,
1506                      sc->sc_pparams.sw_code, sc->sc_pparams.factor));
1507 
1508 	error = 0;
1509 	while (uio->uio_resid > 0 && !error) {
1510 		s = splaudio();
1511 		while (cb->used >= cb->usedhigh) {
1512 			DPRINTFN(2, ("audio_write: sleep used=%d lowat=%d hiwat=%d\n",
1513 				 cb->used, cb->usedlow, cb->usedhigh));
1514 			if (ioflag & IO_NDELAY) {
1515 				splx(s);
1516 				return (EWOULDBLOCK);
1517 			}
1518 			error = audio_sleep(&sc->sc_wchan, "aud_wr");
1519 			if (sc->sc_dying)
1520 			        error = EIO;
1521 			if (error) {
1522 				splx(s);
1523 				return error;
1524 			}
1525 		}
1526 		used = cb->used;
1527 		inp = cb->inp;
1528 		cb->copying = 1;
1529 		splx(s);
1530 		cc = cb->usedhigh - used; 	/* maximum to write */
1531 		n = cb->end - inp;
1532 		if (sc->sc_pparams.factor != 1) {
1533 			/* Compensate for software coding expansion factor. */
1534 			n /= sc->sc_pparams.factor;
1535 			cc /= sc->sc_pparams.factor;
1536 		}
1537 		if (n < cc)
1538 			cc = n;			/* don't write beyond end of buffer */
1539 		if (uio->uio_resid < cc)
1540 			cc = uio->uio_resid; 	/* and no more than we have */
1541 
1542 #ifdef DIAGNOSTIC
1543 		/*
1544 		 * This should never happen since the block size and and
1545 		 * block pointers are always nicely aligned.
1546 		 */
1547 		if (cc == 0) {
1548 			printf("audio_write: cc == 0, swcode=%p, factor=%d\n",
1549 			       sc->sc_pparams.sw_code, sc->sc_pparams.factor);
1550 			cb->copying = 0;
1551 			return EINVAL;
1552 		}
1553 #endif
1554 		DPRINTFN(1, ("audio_write: uiomove cc=%d inp=%p, left=%d\n",
1555                              cc, inp, uio->uio_resid));
1556 		n = uio->uio_resid;
1557 		error = uiomove(inp, cc, uio);
1558 		cc = n - uio->uio_resid; /* number of bytes actually moved */
1559 #ifdef AUDIO_DEBUG
1560 		if (error)
1561 		        printf("audio_write:(1) uiomove failed %d; cc=%d inp=%p\n",
1562 			       error, cc, inp);
1563 #endif
1564 		/*
1565 		 * Continue even if uiomove() failed because we may have
1566 		 * gotten a partial block.
1567 		 */
1568 
1569 		if (sc->sc_pparams.sw_code) {
1570 			sc->sc_pparams.sw_code(sc->hw_hdl, inp, cc);
1571 			/* Adjust count after the expansion. */
1572 			cc *= sc->sc_pparams.factor;
1573 			DPRINTFN(1, ("audio_write: expanded cc=%d\n", cc));
1574 		}
1575 
1576 		einp = cb->inp + cc;
1577 		if (einp >= cb->end)
1578 			einp = cb->start;
1579 
1580 		s = splaudio();
1581 		/*
1582 		 * This is a very suboptimal way of keeping track of
1583 		 * silence in the buffer, but it is simple.
1584 		 */
1585 		sc->sc_sil_count = 0;
1586 
1587 		cb->inp = einp;
1588 		cb->used += cc;
1589 		/* If the interrupt routine wants the last block filled AND
1590 		 * the copy did not fill the last block completely it needs to
1591 		 * be padded.
1592 		 */
1593 		if (cb->needfill &&
1594 		    (inp  - cb->start) / cb->blksize ==
1595 		    (einp - cb->start) / cb->blksize) {
1596 			/* Figure out how many bytes there is to a block boundary. */
1597 			cc = cb->blksize - (einp - cb->start) % cb->blksize;
1598 			DPRINTF(("audio_write: partial fill %d\n", cc));
1599 		} else
1600 			cc = 0;
1601 		cb->needfill = 0;
1602 		cb->copying = 0;
1603 		if (!sc->sc_pbus && !cb->pause) {
1604 			saveerror = error;
1605 			error = audiostartp(sc);
1606 			if (saveerror != 0) {
1607 				/* Report the first error that occured. */
1608 				error = saveerror;
1609 			}
1610 		}
1611 		splx(s);
1612 		if (cc) {
1613 			DPRINTFN(1, ("audio_write: fill %d\n", cc));
1614 			audio_fill_silence(&sc->sc_pparams, einp, cc);
1615 		}
1616 	}
1617 	return (error);
1618 }
1619 
1620 int
1621 audio_ioctl(dev, cmd, addr, flag, p)
1622 	dev_t dev;
1623 	u_long cmd;
1624 	caddr_t addr;
1625 	int flag;
1626 	struct proc *p;
1627 {
1628 	int unit = AUDIOUNIT(dev);
1629 	struct audio_softc *sc = audio_cd.cd_devs[unit];
1630 	struct audio_hw_if *hw = sc->hw_if;
1631 	struct audio_offset *ao;
1632 	int error = 0, s, offs, fd;
1633         int rbus, pbus;
1634 
1635 	DPRINTF(("audio_ioctl(%d,'%c',%d)\n",
1636 	          IOCPARM_LEN(cmd), IOCGROUP(cmd), cmd&0xff));
1637 	switch (cmd) {
1638 	case FIONBIO:
1639 		/* All handled in the upper FS layer. */
1640 		break;
1641 
1642 	case FIOASYNC:
1643 		if (*(int *)addr) {
1644 			if (sc->sc_async_audio)
1645 				return (EBUSY);
1646 			sc->sc_async_audio = p;
1647 			DPRINTF(("audio_ioctl: FIOASYNC %p\n", p));
1648 		} else
1649 			sc->sc_async_audio = 0;
1650 		break;
1651 
1652 	case AUDIO_FLUSH:
1653 		DPRINTF(("AUDIO_FLUSH\n"));
1654                 rbus = sc->sc_rbus;
1655                 pbus = sc->sc_pbus;
1656 		audio_clear(sc);
1657 		s = splaudio();
1658 		error = audio_initbufs(sc);
1659 		if (error) {
1660 			splx(s);
1661 			return error;
1662 		}
1663 		if ((sc->sc_mode & AUMODE_PLAY) && !sc->sc_pbus && pbus)
1664 			error = audiostartp(sc);
1665 		if (!error &&
1666 		    (sc->sc_mode & AUMODE_RECORD) && !sc->sc_rbus && rbus)
1667 			error = audiostartr(sc);
1668 		splx(s);
1669 		break;
1670 
1671 	/*
1672 	 * Number of read (write) samples dropped.  We don't know where or
1673 	 * when they were dropped.
1674 	 */
1675 	case AUDIO_RERROR:
1676 		*(int *)addr = sc->sc_rr.drops;
1677 		break;
1678 
1679 	case AUDIO_PERROR:
1680 		*(int *)addr = sc->sc_pr.drops;
1681 		break;
1682 
1683 	/*
1684 	 * Offsets into buffer.
1685 	 */
1686 	case AUDIO_GETIOFFS:
1687 		s = splaudio();
1688 		/* figure out where next DMA will start */
1689 		ao = (struct audio_offset *)addr;
1690 		ao->samples = sc->sc_rr.stamp;
1691 		ao->deltablks = (sc->sc_rr.stamp - sc->sc_rr.stamp_last) / sc->sc_rr.blksize;
1692 		sc->sc_rr.stamp_last = sc->sc_rr.stamp;
1693 		ao->offset = sc->sc_rr.inp - sc->sc_rr.start;
1694 		splx(s);
1695 		break;
1696 
1697 	case AUDIO_GETOOFFS:
1698 		s = splaudio();
1699 		/* figure out where next DMA will start */
1700 		ao = (struct audio_offset *)addr;
1701 		offs = sc->sc_pr.outp - sc->sc_pr.start + sc->sc_pr.blksize;
1702 		if (sc->sc_pr.start + offs >= sc->sc_pr.end)
1703 			offs = 0;
1704 		ao->samples = sc->sc_pr.stamp;
1705 		ao->deltablks = (sc->sc_pr.stamp - sc->sc_pr.stamp_last) / sc->sc_pr.blksize;
1706 		sc->sc_pr.stamp_last = sc->sc_pr.stamp;
1707 		ao->offset = offs;
1708 		splx(s);
1709 		break;
1710 
1711 	/*
1712 	 * How many bytes will elapse until mike hears the first
1713 	 * sample of what we write next?
1714 	 */
1715 	case AUDIO_WSEEK:
1716 		*(u_long *)addr = sc->sc_rr.used;
1717 		break;
1718 
1719 	case AUDIO_SETINFO:
1720 		DPRINTF(("AUDIO_SETINFO mode=0x%x\n", sc->sc_mode));
1721 		error = audiosetinfo(sc, (struct audio_info *)addr);
1722 		break;
1723 
1724 	case AUDIO_GETINFO:
1725 		DPRINTF(("AUDIO_GETINFO\n"));
1726 		error = audiogetinfo(sc, (struct audio_info *)addr);
1727 		break;
1728 
1729 	case AUDIO_DRAIN:
1730 		DPRINTF(("AUDIO_DRAIN\n"));
1731 		error = audio_drain(sc);
1732 		if (!error && hw->drain)
1733 		    error = hw->drain(sc->hw_hdl);
1734 		break;
1735 
1736 	case AUDIO_GETDEV:
1737 		DPRINTF(("AUDIO_GETDEV\n"));
1738 		error = hw->getdev(sc->hw_hdl, (audio_device_t *)addr);
1739 		break;
1740 
1741 	case AUDIO_GETENC:
1742 		DPRINTF(("AUDIO_GETENC\n"));
1743 		/* Pass read/write info down to query_encoding */
1744 		((struct audio_encoding *)addr)->flags = sc->sc_open;
1745 		error = hw->query_encoding(sc->hw_hdl, (struct audio_encoding *)addr);
1746 		break;
1747 
1748 	case AUDIO_GETFD:
1749 		DPRINTF(("AUDIO_GETFD\n"));
1750 		*(int *)addr = sc->sc_full_duplex;
1751 		break;
1752 
1753 	case AUDIO_SETFD:
1754 		DPRINTF(("AUDIO_SETFD\n"));
1755 		fd = *(int *)addr;
1756 		if (hw->get_props(sc->hw_hdl) & AUDIO_PROP_FULLDUPLEX) {
1757 			if (hw->setfd)
1758 				error = hw->setfd(sc->hw_hdl, fd);
1759 			else
1760 				error = 0;
1761 			if (!error)
1762 				sc->sc_full_duplex = fd;
1763 		} else {
1764 			if (fd)
1765 				error = ENOTTY;
1766 			else
1767 				error = 0;
1768 		}
1769 		break;
1770 
1771 	case AUDIO_GETPROPS:
1772 		DPRINTF(("AUDIO_GETPROPS\n"));
1773 		*(int *)addr = hw->get_props(sc->hw_hdl);
1774 		break;
1775 
1776 	default:
1777 		DPRINTF(("audio_ioctl: unknown ioctl\n"));
1778 		error = EINVAL;
1779 		break;
1780 	}
1781 	DPRINTF(("audio_ioctl(%d,'%c',%d) result %d\n",
1782 	          IOCPARM_LEN(cmd), IOCGROUP(cmd), cmd&0xff, error));
1783 	return (error);
1784 }
1785 
1786 int
1787 audio_select(dev, rw, p)
1788 	dev_t dev;
1789 	int rw;
1790 	struct proc *p;
1791 {
1792 	int unit = AUDIOUNIT(dev);
1793 	struct audio_softc *sc = audio_cd.cd_devs[unit];
1794 	int s = splaudio();
1795 
1796 	DPRINTF(("audio_select: rw=0x%x mode=%d\n", rw, sc->sc_mode));
1797 
1798 	switch (rw) {
1799 
1800 	case FREAD:
1801 		if ((sc->sc_mode & AUMODE_PLAY) ?
1802 		    sc->sc_pr.stamp > sc->sc_wstamp :
1803 		    sc->sc_rr.used > sc->sc_rr.usedlow) {
1804 			splx(s);
1805 			return (1);
1806 		}
1807 		selrecord(p, &sc->sc_rsel);
1808 		break;
1809 
1810 	case FWRITE:
1811 		if (sc->sc_mode & AUMODE_RECORD ||
1812 		    sc->sc_pr.used <= sc->sc_pr.usedlow) {
1813 			splx(s);
1814 			return (1);
1815 		}
1816 		selrecord(p, &sc->sc_wsel);
1817 		break;
1818 	}
1819 	splx(s);
1820 	return (0);
1821 }
1822 
1823 int
1824 audio_mmap(dev, off, prot)
1825 	dev_t dev;
1826 	int off, prot;
1827 {
1828 	int s;
1829 	int unit = AUDIOUNIT(dev);
1830 	struct audio_softc *sc = audio_cd.cd_devs[unit];
1831 	struct audio_hw_if *hw = sc->hw_if;
1832 	struct audio_ringbuffer *cb;
1833 
1834 	DPRINTF(("audio_mmap: off=%d, prot=%d\n", off, prot));
1835 
1836 	if (!(hw->get_props(sc->hw_hdl) & AUDIO_PROP_MMAP) || !hw->mappage)
1837 		return -1;
1838 #if 0
1839 /* XXX
1840  * The idea here was to use the protection to determine if
1841  * we are mapping the read or write buffer, but it fails.
1842  * The VM system is broken in (at least) two ways.
1843  * 1) If you map memory VM_PROT_WRITE you SIGSEGV
1844  *    when writing to it, so VM_PROT_READ|VM_PROT_WRITE
1845  *    has to be used for mmapping the play buffer.
1846  * 2) Even if calling mmap() with VM_PROT_READ|VM_PROT_WRITE
1847  *    audio_mmap will get called at some point with VM_PROT_READ
1848  *    only.
1849  * So, alas, we always map the play buffer for now.
1850  */
1851 	if (prot == (VM_PROT_READ|VM_PROT_WRITE) ||
1852 	    prot == VM_PROT_WRITE)
1853 		cb = &sc->sc_pr;
1854 	else if (prot == VM_PROT_READ)
1855 		cb = &sc->sc_rr;
1856 	else
1857 		return -1;
1858 #else
1859 	cb = &sc->sc_pr;
1860 #endif
1861 
1862 	if ((u_int)off >= cb->bufsize)
1863 		return -1;
1864 	if (!cb->mmapped) {
1865 		cb->mmapped = 1;
1866 		if (cb == &sc->sc_pr) {
1867 			audio_fill_silence(&sc->sc_pparams, cb->start, cb->bufsize);
1868 			s = splaudio();
1869 			if (!sc->sc_pbus)
1870 				(void)audiostartp(sc);
1871 			splx(s);
1872 		} else {
1873 			s = splaudio();
1874 			if (!sc->sc_rbus)
1875 				(void)audiostartr(sc);
1876 			splx(s);
1877 		}
1878 	}
1879 
1880 	return hw->mappage(sc->hw_hdl, cb->start, off, prot);
1881 }
1882 
1883 int
1884 audiostartr(sc)
1885 	struct audio_softc *sc;
1886 {
1887 	int error;
1888 
1889     	DPRINTF(("audiostartr: start=%p used=%d(hi=%d) mmapped=%d\n",
1890 		 sc->sc_rr.start, sc->sc_rr.used, sc->sc_rr.usedhigh,
1891 		 sc->sc_rr.mmapped));
1892 
1893 	if (sc->hw_if->trigger_input)
1894 		error = sc->hw_if->trigger_input(sc->hw_hdl, sc->sc_rr.start,
1895 		    sc->sc_rr.end, sc->sc_rr.blksize,
1896 		    audio_rint, (void *)sc, &sc->sc_rparams);
1897 	else
1898 		error = sc->hw_if->start_input(sc->hw_hdl, sc->sc_rr.start,
1899 		    sc->sc_rr.blksize, audio_rint, (void *)sc);
1900 	if (error) {
1901 		DPRINTF(("audiostartr failed: %d\n", error));
1902 		return error;
1903 	}
1904 	sc->sc_rbus = 1;
1905 	return 0;
1906 }
1907 
1908 int
1909 audiostartp(sc)
1910 	struct audio_softc *sc;
1911 {
1912 	int error;
1913 
1914     	DPRINTF(("audiostartp: start=%p used=%d(hi=%d) mmapped=%d\n",
1915 		 sc->sc_pr.start, sc->sc_pr.used, sc->sc_pr.usedhigh,
1916 		 sc->sc_pr.mmapped));
1917 
1918 	if (!sc->sc_pr.mmapped && sc->sc_pr.used < sc->sc_pr.blksize)
1919 		return 0;
1920 
1921 	if (sc->hw_if->trigger_output)
1922 		error = sc->hw_if->trigger_output(sc->hw_hdl, sc->sc_pr.start,
1923 		    sc->sc_pr.end, sc->sc_pr.blksize,
1924 		    audio_pint, (void *)sc, &sc->sc_pparams);
1925 	else
1926 		error = sc->hw_if->start_output(sc->hw_hdl, sc->sc_pr.outp,
1927 		    sc->sc_pr.blksize, audio_pint, (void *)sc);
1928 	if (error) {
1929 		DPRINTF(("audiostartp failed: %d\n", error));
1930 	    	return error;
1931 	}
1932 	sc->sc_pbus = 1;
1933 	return 0;
1934 }
1935 
1936 /*
1937  * When the play interrupt routine finds that the write isn't keeping
1938  * the buffer filled it will insert silence in the buffer to make up
1939  * for this.  The part of the buffer that is filled with silence
1940  * is kept track of in a very approximate way: it starts at sc_sil_start
1941  * and extends sc_sil_count bytes.  If there is already silence in
1942  * the requested area nothing is done; so when the whole buffer is
1943  * silent nothing happens.  When the writer starts again sc_sil_count
1944  * is set to 0.
1945  */
1946 /* XXX
1947  * Putting silence into the output buffer should not really be done
1948  * at splaudio, but there is no softaudio level to do it at yet.
1949  */
1950 static __inline void
1951 audio_pint_silence(sc, cb, inp, cc)
1952 	struct audio_softc *sc;
1953 	struct audio_ringbuffer *cb;
1954 	u_char *inp;
1955 	int cc;
1956 {
1957 	u_char *s, *e, *p, *q;
1958 
1959 	if (sc->sc_sil_count > 0) {
1960 		s = sc->sc_sil_start; /* start of silence */
1961 		e = s + sc->sc_sil_count; /* end of silence, may be beyond end */
1962 		p = inp;	/* adjusted pointer to area to fill */
1963 		if (p < s)
1964 			p += cb->end - cb->start;
1965 		q = p+cc;
1966 		/* Check if there is already silence. */
1967 		if (!(s <= p && p <  e &&
1968 		      s <= q && q <= e)) {
1969 			if (s <= p)
1970 				sc->sc_sil_count = max(sc->sc_sil_count, q-s);
1971 			DPRINTFN(5, ("audio_pint_silence: fill cc=%d inp=%p, count=%d size=%d\n",
1972                                     cc, inp, sc->sc_sil_count, (int)(cb->end - cb->start)));
1973 			audio_fill_silence(&sc->sc_pparams, inp, cc);
1974 		} else {
1975 			DPRINTFN(5, ("audio_pint_silence: already silent cc=%d inp=%p\n", cc, inp));
1976 
1977 		}
1978 	} else {
1979 		sc->sc_sil_start = inp;
1980 		sc->sc_sil_count = cc;
1981 		DPRINTFN(5, ("audio_pint_silence: start fill %p %d\n",
1982                              inp, cc));
1983 		audio_fill_silence(&sc->sc_pparams, inp, cc);
1984 	}
1985 }
1986 
1987 /*
1988  * Called from HW driver module on completion of dma output.
1989  * Start output of new block, wrap in ring buffer if needed.
1990  * If no more buffers to play, output zero instead.
1991  * Do a wakeup if necessary.
1992  */
1993 void
1994 audio_pint(v)
1995 	void *v;
1996 {
1997 	struct audio_softc *sc = v;
1998 	struct audio_hw_if *hw = sc->hw_if;
1999 	struct audio_ringbuffer *cb = &sc->sc_pr;
2000 	u_char *inp;
2001 	int cc, ccr;
2002 	int blksize;
2003 	int error;
2004 
2005         if (!sc->sc_open)
2006         	return;         /* ignore interrupt if not open */
2007 
2008 	blksize = cb->blksize;
2009 
2010 	add_audio_randomness((long)cb);
2011 
2012 	cb->outp += blksize;
2013 	if (cb->outp >= cb->end)
2014 		cb->outp = cb->start;
2015 	cb->stamp += blksize / sc->sc_pparams.factor;
2016 	if (cb->mmapped) {
2017 		DPRINTFN(5, ("audio_pint: mmapped outp=%p cc=%d inp=%p\n",
2018                              cb->outp, blksize, cb->inp));
2019 		if (!hw->trigger_output)
2020 			(void)hw->start_output(sc->hw_hdl, cb->outp,
2021 			    blksize, audio_pint, (void *)sc);
2022 		return;
2023 	}
2024 
2025 #ifdef AUDIO_INTR_TIME
2026 	{
2027 		struct timeval tv;
2028 		u_long t;
2029 		microtime(&tv);
2030 		t = tv.tv_usec + 1000000 * tv.tv_sec;
2031 		if (sc->sc_pnintr) {
2032 			long lastdelta, totdelta;
2033 			lastdelta = t - sc->sc_plastintr - sc->sc_pblktime;
2034 			if (lastdelta > sc->sc_pblktime / 3) {
2035 				printf("audio: play interrupt(%d) off relative by %ld us (%lu)\n",
2036 				       sc->sc_pnintr, lastdelta, sc->sc_pblktime);
2037 			}
2038 			totdelta = t - sc->sc_pfirstintr - sc->sc_pblktime * sc->sc_pnintr;
2039 			if (totdelta > sc->sc_pblktime) {
2040 				printf("audio: play interrupt(%d) off absolute by %ld us (%lu) (LOST)\n",
2041 				       sc->sc_pnintr, totdelta, sc->sc_pblktime);
2042 				sc->sc_pnintr++; /* avoid repeated messages */
2043 			}
2044 		} else
2045 			sc->sc_pfirstintr = t;
2046 		sc->sc_plastintr = t;
2047 		sc->sc_pnintr++;
2048 	}
2049 #endif
2050 
2051 	cb->used -= blksize;
2052 	if (cb->used < blksize) {
2053 		/* we don't have a full block to use */
2054 		if (cb->copying) {
2055 			/* writer is in progress, don't disturb */
2056 			cb->needfill = 1;
2057 			DPRINTFN(1, ("audio_pint: copying in progress\n"));
2058 		} else {
2059 			inp = cb->inp;
2060 			cc = blksize - (inp - cb->start) % blksize;
2061 			ccr = cc / sc->sc_pparams.factor;
2062 			if (cb->pause)
2063 				cb->pdrops += ccr;
2064 			else {
2065 				cb->drops += ccr;
2066 				sc->sc_playdrop += ccr;
2067 			}
2068 			audio_pint_silence(sc, cb, inp, cc);
2069 			inp += cc;
2070 			if (inp >= cb->end)
2071 				inp = cb->start;
2072 			cb->inp = inp;
2073 			cb->used += cc;
2074 
2075 			/* Clear next block so we keep ahead of the DMA. */
2076 			if (cb->used + cc < cb->usedhigh)
2077 				audio_pint_silence(sc, cb, inp, blksize);
2078 		}
2079 	}
2080 
2081 	DPRINTFN(5, ("audio_pint: outp=%p cc=%d\n", cb->outp, blksize));
2082 	if (!hw->trigger_output) {
2083 		error = hw->start_output(sc->hw_hdl, cb->outp, blksize,
2084 		    audio_pint, (void *)sc);
2085 		if (error) {
2086 			/* XXX does this really help? */
2087 			DPRINTF(("audio_pint restart failed: %d\n", error));
2088 			audio_clear(sc);
2089 		}
2090 	}
2091 
2092 	DPRINTFN(2, ("audio_pint: mode=%d pause=%d used=%d lowat=%d\n",
2093                      sc->sc_mode, cb->pause, cb->used, cb->usedlow));
2094 	if ((sc->sc_mode & AUMODE_PLAY) && !cb->pause) {
2095 		if (cb->used <= cb->usedlow) {
2096 			audio_wakeup(&sc->sc_wchan);
2097 			selwakeup(&sc->sc_wsel);
2098 			if (sc->sc_async_audio) {
2099 				DPRINTFN(3, ("audio_pint: sending SIGIO %p\n",
2100                                              sc->sc_async_audio));
2101 				psignal(sc->sc_async_audio, SIGIO);
2102 			}
2103 		}
2104 	}
2105 
2106 	/* Possible to return one or more "phantom blocks" now. */
2107 	if (!sc->sc_full_duplex && sc->sc_rchan) {
2108 		audio_wakeup(&sc->sc_rchan);
2109 		selwakeup(&sc->sc_rsel);
2110 		if (sc->sc_async_audio)
2111 			psignal(sc->sc_async_audio, SIGIO);
2112 	}
2113 }
2114 
2115 /*
2116  * Called from HW driver module on completion of dma input.
2117  * Mark it as input in the ring buffer (fiddle pointers).
2118  * Do a wakeup if necessary.
2119  */
2120 void
2121 audio_rint(v)
2122 	void *v;
2123 {
2124 	struct audio_softc *sc = v;
2125 	struct audio_hw_if *hw = sc->hw_if;
2126 	struct audio_ringbuffer *cb = &sc->sc_rr;
2127 	int blksize;
2128 	int error;
2129 
2130         if (!sc->sc_open)
2131         	return;         /* ignore interrupt if not open */
2132 
2133 	add_audio_randomness((long)cb);
2134 
2135 	blksize = cb->blksize;
2136 
2137 	cb->inp += blksize;
2138 	if (cb->inp >= cb->end)
2139 		cb->inp = cb->start;
2140 	cb->stamp += blksize;
2141 	if (cb->mmapped) {
2142 		DPRINTFN(2, ("audio_rint: mmapped inp=%p cc=%d\n",
2143                              cb->inp, blksize));
2144 		if (!hw->trigger_input)
2145 			(void)hw->start_input(sc->hw_hdl, cb->inp, blksize,
2146 			    audio_rint, (void *)sc);
2147 		return;
2148 	}
2149 
2150 #ifdef AUDIO_INTR_TIME
2151 	{
2152 		struct timeval tv;
2153 		u_long t;
2154 		microtime(&tv);
2155 		t = tv.tv_usec + 1000000 * tv.tv_sec;
2156 		if (sc->sc_rnintr) {
2157 			long lastdelta, totdelta;
2158 			lastdelta = t - sc->sc_rlastintr - sc->sc_rblktime;
2159 			if (lastdelta > sc->sc_rblktime / 5) {
2160 				printf("audio: record interrupt(%d) off relative by %ld us (%lu)\n",
2161 				       sc->sc_rnintr, lastdelta, sc->sc_rblktime);
2162 			}
2163 			totdelta = t - sc->sc_rfirstintr - sc->sc_rblktime * sc->sc_rnintr;
2164 			if (totdelta > sc->sc_rblktime / 2) {
2165 				sc->sc_rnintr++;
2166 				printf("audio: record interrupt(%d) off absolute by %ld us (%lu)\n",
2167 				       sc->sc_rnintr, totdelta, sc->sc_rblktime);
2168 				sc->sc_rnintr++; /* avoid repeated messages */
2169 			}
2170 		} else
2171 			sc->sc_rfirstintr = t;
2172 		sc->sc_rlastintr = t;
2173 		sc->sc_rnintr++;
2174 	}
2175 #endif
2176 
2177 	cb->used += blksize;
2178 	if (cb->pause) {
2179 		DPRINTFN(1, ("audio_rint: pdrops %lu\n", cb->pdrops));
2180 		cb->pdrops += blksize;
2181 		cb->outp += blksize;
2182 		cb->used -= blksize;
2183 	} else if (cb->used + blksize >= cb->usedhigh && !cb->copying) {
2184 		DPRINTFN(1, ("audio_rint: drops %lu\n", cb->drops));
2185 		cb->drops += blksize;
2186 		cb->outp += blksize;
2187 		cb->used -= blksize;
2188 	}
2189 
2190 	DPRINTFN(2, ("audio_rint: inp=%p cc=%d used=%d\n",
2191                      cb->inp, blksize, cb->used));
2192 	if (!hw->trigger_input) {
2193 		error = hw->start_input(sc->hw_hdl, cb->inp, blksize,
2194 		    audio_rint, (void *)sc);
2195 		if (error) {
2196 			/* XXX does this really help? */
2197 			DPRINTF(("audio_rint: restart failed: %d\n", error));
2198 			audio_clear(sc);
2199 		}
2200 	}
2201 
2202 	audio_wakeup(&sc->sc_rchan);
2203 	selwakeup(&sc->sc_rsel);
2204 	if (sc->sc_async_audio)
2205 		psignal(sc->sc_async_audio, SIGIO);
2206 }
2207 
2208 int
2209 audio_check_params(p)
2210 	struct audio_params *p;
2211 {
2212 	if (p->encoding == AUDIO_ENCODING_PCM16) {
2213 		if (p->precision == 8)
2214 			p->encoding = AUDIO_ENCODING_ULINEAR;
2215 		else
2216 			p->encoding = AUDIO_ENCODING_SLINEAR;
2217 	} else if (p->encoding == AUDIO_ENCODING_PCM8) {
2218 		if (p->precision == 8)
2219 			p->encoding = AUDIO_ENCODING_ULINEAR;
2220 		else
2221 			return EINVAL;
2222 	}
2223 
2224 	if (p->encoding == AUDIO_ENCODING_SLINEAR)
2225 #if BYTE_ORDER == LITTLE_ENDIAN
2226 		p->encoding = AUDIO_ENCODING_SLINEAR_LE;
2227 #else
2228 		p->encoding = AUDIO_ENCODING_SLINEAR_BE;
2229 #endif
2230 	if (p->encoding == AUDIO_ENCODING_ULINEAR)
2231 #if BYTE_ORDER == LITTLE_ENDIAN
2232 		p->encoding = AUDIO_ENCODING_ULINEAR_LE;
2233 #else
2234 		p->encoding = AUDIO_ENCODING_ULINEAR_BE;
2235 #endif
2236 
2237 	switch (p->encoding) {
2238 	case AUDIO_ENCODING_ULAW:
2239 	case AUDIO_ENCODING_ALAW:
2240 	case AUDIO_ENCODING_ADPCM:
2241 		if (p->precision != 8)
2242 			return (EINVAL);
2243 		break;
2244 	case AUDIO_ENCODING_SLINEAR_LE:
2245 	case AUDIO_ENCODING_SLINEAR_BE:
2246 	case AUDIO_ENCODING_ULINEAR_LE:
2247 	case AUDIO_ENCODING_ULINEAR_BE:
2248 		if (p->precision != 8 && p->precision != 16)
2249 			return (EINVAL);
2250 		break;
2251 	case AUDIO_ENCODING_MPEG_L1_STREAM:
2252 	case AUDIO_ENCODING_MPEG_L1_PACKETS:
2253 	case AUDIO_ENCODING_MPEG_L1_SYSTEM:
2254 	case AUDIO_ENCODING_MPEG_L2_STREAM:
2255 	case AUDIO_ENCODING_MPEG_L2_PACKETS:
2256 	case AUDIO_ENCODING_MPEG_L2_SYSTEM:
2257 		break;
2258 	default:
2259 		return (EINVAL);
2260 	}
2261 
2262 	if (p->channels < 1 || p->channels > 8)	/* sanity check # of channels */
2263 		return (EINVAL);
2264 
2265 	return (0);
2266 }
2267 
2268 int
2269 au_set_lr_value(sc, ct, l, r)
2270 	struct	audio_softc *sc;
2271 	mixer_ctrl_t *ct;
2272 	int l, r;
2273 {
2274 	ct->type = AUDIO_MIXER_VALUE;
2275 	ct->un.value.num_channels = 2;
2276 	ct->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = l;
2277 	ct->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = r;
2278 	if (sc->hw_if->set_port(sc->hw_hdl, ct) == 0)
2279 		return 0;
2280 	ct->un.value.num_channels = 1;
2281 	ct->un.value.level[AUDIO_MIXER_LEVEL_MONO] = (l+r)/2;
2282 	return sc->hw_if->set_port(sc->hw_hdl, ct);
2283 }
2284 
2285 int
2286 au_set_gain(sc, ports, gain, balance)
2287 	struct	audio_softc *sc;
2288 	struct	au_mixer_ports *ports;
2289 	int	gain;
2290 	int	balance;
2291 {
2292 	mixer_ctrl_t ct;
2293 	int i, error;
2294 	int l, r;
2295 	u_int mask;
2296 	int nset;
2297 
2298 	if (balance == AUDIO_MID_BALANCE) {
2299 		l = r = gain;
2300 	} else if (balance < AUDIO_MID_BALANCE) {
2301 		r = gain;
2302 		l = (balance * gain) / AUDIO_MID_BALANCE;
2303 	} else {
2304 		l = gain;
2305 		r = ((AUDIO_RIGHT_BALANCE - balance) * gain)
2306 		    / AUDIO_MID_BALANCE;
2307 	}
2308 	DPRINTF(("au_set_gain: gain=%d balance=%d, l=%d r=%d\n",
2309 		 gain, balance, l, r));
2310 
2311 	if (ports->index == -1) {
2312 	usemaster:
2313 		if (ports->master == -1)
2314 			return 0; /* just ignore it silently */
2315 		ct.dev = ports->master;
2316 		error = au_set_lr_value(sc, &ct, l, r);
2317 	} else {
2318 		ct.dev = ports->index;
2319 		if (ports->isenum) {
2320 			ct.type = AUDIO_MIXER_ENUM;
2321 			error = sc->hw_if->get_port(sc->hw_hdl, &ct);
2322 			if (error)
2323 				return error;
2324 			for(i = 0; i < ports->nports; i++) {
2325 				if (ports->misel[i] == ct.un.ord) {
2326 					ct.dev = ports->miport[i];
2327 					if (ct.dev == -1 ||
2328 					    au_set_lr_value(sc, &ct, l, r))
2329 						goto usemaster;
2330 					else
2331 						break;
2332 				}
2333 			}
2334 		} else {
2335 			ct.type = AUDIO_MIXER_SET;
2336 			error = sc->hw_if->get_port(sc->hw_hdl, &ct);
2337 			if (error)
2338 				return error;
2339 			mask = ct.un.mask;
2340 			nset = 0;
2341 			for(i = 0; i < ports->nports; i++) {
2342 				if (ports->misel[i] & mask) {
2343 				    ct.dev = ports->miport[i];
2344 				    if (ct.dev != -1 &&
2345 					au_set_lr_value(sc, &ct, l, r) == 0)
2346 					    nset++;
2347 				}
2348 			}
2349 			if (nset == 0)
2350 				goto usemaster;
2351 		}
2352 	}
2353 	if (!error)
2354 		mixer_signal(sc);
2355 	return error;
2356 }
2357 
2358 int
2359 au_get_lr_value(sc, ct, l, r)
2360 	struct	audio_softc *sc;
2361 	mixer_ctrl_t *ct;
2362 	int *l, *r;
2363 {
2364 	int error;
2365 
2366 	ct->un.value.num_channels = 2;
2367 	if (sc->hw_if->get_port(sc->hw_hdl, ct) == 0) {
2368 		*l = ct->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
2369 		*r = ct->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
2370 	} else {
2371 		ct->un.value.num_channels = 1;
2372 		error = sc->hw_if->get_port(sc->hw_hdl, ct);
2373 		if (error)
2374 			return error;
2375 		*r = *l = ct->un.value.level[AUDIO_MIXER_LEVEL_MONO];
2376 	}
2377 	return 0;
2378 }
2379 
2380 void
2381 au_get_gain(sc, ports, pgain, pbalance)
2382 	struct	audio_softc *sc;
2383 	struct	au_mixer_ports *ports;
2384 	u_int	*pgain;
2385 	u_char	*pbalance;
2386 {
2387 	mixer_ctrl_t ct;
2388 	int i, l, r, n;
2389 	int lgain = AUDIO_MAX_GAIN/2, rgain = AUDIO_MAX_GAIN/2;
2390 
2391 	if (ports->index == -1) {
2392 	usemaster:
2393 		if (ports->master == -1)
2394 			goto bad;
2395 		ct.dev = ports->master;
2396 		ct.type = AUDIO_MIXER_VALUE;
2397 		if (au_get_lr_value(sc, &ct, &lgain, &rgain))
2398 			goto bad;
2399 	} else {
2400 		ct.dev = ports->index;
2401 		if (ports->isenum) {
2402 			ct.type = AUDIO_MIXER_ENUM;
2403 			if (sc->hw_if->get_port(sc->hw_hdl, &ct))
2404 				goto bad;
2405 			ct.type = AUDIO_MIXER_VALUE;
2406 			for(i = 0; i < ports->nports; i++) {
2407 				if (ports->misel[i] == ct.un.ord) {
2408 					ct.dev = ports->miport[i];
2409 					if (ct.dev == -1 ||
2410 					    au_get_lr_value(sc, &ct,
2411 							    &lgain, &rgain))
2412 						goto usemaster;
2413 					else
2414 						break;
2415 				}
2416 			}
2417 		} else {
2418 			ct.type = AUDIO_MIXER_SET;
2419 			if (sc->hw_if->get_port(sc->hw_hdl, &ct))
2420 				goto bad;
2421 			ct.type = AUDIO_MIXER_VALUE;
2422 			lgain = rgain = n = 0;
2423 			for(i = 0; i < ports->nports; i++) {
2424 				if (ports->misel[i] & ct.un.mask) {
2425 					ct.dev = ports->miport[i];
2426 					if (ct.dev == -1 ||
2427 					    au_get_lr_value(sc, &ct, &l, &r))
2428 						goto usemaster;
2429 					else {
2430 						lgain += l;
2431 						rgain += r;
2432 						n++;
2433 					}
2434 				}
2435 			}
2436 			if (n != 0) {
2437 				lgain /= n;
2438 				rgain /= n;
2439 			}
2440 		}
2441 	}
2442 bad:
2443 	if (lgain == rgain) {	/* handles lgain==rgain==0 */
2444 		*pgain = lgain;
2445 		*pbalance = AUDIO_MID_BALANCE;
2446 	} else if (lgain < rgain) {
2447 		*pgain = rgain;
2448 		*pbalance = (AUDIO_MID_BALANCE * lgain) / rgain;
2449 	} else /* lgain > rgain */ {
2450 		*pgain = lgain;
2451 		*pbalance = AUDIO_RIGHT_BALANCE -
2452 			    (AUDIO_MID_BALANCE * rgain) / lgain;
2453 	}
2454 }
2455 
2456 int
2457 au_set_port(sc, ports, port)
2458 	struct	audio_softc *sc;
2459 	struct	au_mixer_ports *ports;
2460 	u_int	port;
2461 {
2462 	mixer_ctrl_t ct;
2463 	int i, error;
2464 
2465 	if (port == 0 && ports->allports == 0)
2466 		return 0;	/* allow this special case */
2467 
2468 	if (ports->index == -1)
2469 		return EINVAL;
2470 	ct.dev = ports->index;
2471 	if (ports->isenum) {
2472 		if (port & (port-1))
2473 			return EINVAL; /* Only one port allowed */
2474 		ct.type = AUDIO_MIXER_ENUM;
2475 		error = EINVAL;
2476 		for(i = 0; i < ports->nports; i++)
2477 			if (ports->aumask[i] == port) {
2478 				ct.un.ord = ports->misel[i];
2479 				error = sc->hw_if->set_port(sc->hw_hdl, &ct);
2480 				break;
2481 			}
2482 	} else {
2483 		ct.type = AUDIO_MIXER_SET;
2484 		ct.un.mask = 0;
2485 		for(i = 0; i < ports->nports; i++)
2486 			if (ports->aumask[i] & port)
2487 				ct.un.mask |= ports->misel[i];
2488 		if (port != 0 && ct.un.mask == 0)
2489 			error = EINVAL;
2490 		else
2491 			error = sc->hw_if->set_port(sc->hw_hdl, &ct);
2492 	}
2493 	if (!error)
2494 		mixer_signal(sc);
2495 	return error;
2496 }
2497 
2498 int
2499 au_get_port(sc, ports)
2500 	struct	audio_softc *sc;
2501 	struct	au_mixer_ports *ports;
2502 {
2503 	mixer_ctrl_t ct;
2504 	int i, aumask;
2505 
2506 	if (ports->index == -1)
2507 		return 0;
2508 	ct.dev = ports->index;
2509 	ct.type = ports->isenum ? AUDIO_MIXER_ENUM : AUDIO_MIXER_SET;
2510 	if (sc->hw_if->get_port(sc->hw_hdl, &ct))
2511 		return 0;
2512 	aumask = 0;
2513 	if (ports->isenum) {
2514 		for(i = 0; i < ports->nports; i++)
2515 			if (ct.un.ord == ports->misel[i])
2516 				aumask = ports->aumask[i];
2517 	} else {
2518 		for(i = 0; i < ports->nports; i++)
2519 			if (ct.un.mask & ports->misel[i])
2520 				aumask |= ports->aumask[i];
2521 	}
2522 	return aumask;
2523 }
2524 
2525 int
2526 audiosetinfo(sc, ai)
2527 	struct audio_softc *sc;
2528 	struct audio_info *ai;
2529 {
2530 	struct audio_prinfo *r = &ai->record, *p = &ai->play;
2531 	int cleared;
2532 	int s, setmode, modechange = 0;
2533 	int error;
2534 	struct audio_hw_if *hw = sc->hw_if;
2535 	struct audio_params pp, rp;
2536 	int np, nr;
2537 	unsigned int blks;
2538 	int oldpblksize, oldrblksize;
2539 	int rbus, pbus;
2540 	u_int gain;
2541 	u_char balance;
2542 
2543 	if (hw == 0)		/* HW has not attached */
2544 		return(ENXIO);
2545 
2546 	rbus = sc->sc_rbus;
2547 	pbus = sc->sc_pbus;
2548 	error = 0;
2549 	cleared = 0;
2550 
2551 	pp = sc->sc_pparams;	/* Temporary encoding storage in */
2552 	rp = sc->sc_rparams;	/* case setting the modes fails. */
2553 	nr = np = 0;
2554 
2555 	if (p->sample_rate != ~0) {
2556 		pp.sample_rate = p->sample_rate;
2557 		np++;
2558 	}
2559 	if (r->sample_rate != ~0) {
2560 		rp.sample_rate = r->sample_rate;
2561 		nr++;
2562 	}
2563 	if (p->encoding != ~0) {
2564 		pp.encoding = p->encoding;
2565 		np++;
2566 	}
2567 	if (r->encoding != ~0) {
2568 		rp.encoding = r->encoding;
2569 		nr++;
2570 	}
2571 	if (p->precision != ~0) {
2572 		pp.precision = p->precision;
2573 		np++;
2574 	}
2575 	if (r->precision != ~0) {
2576 		rp.precision = r->precision;
2577 		nr++;
2578 	}
2579 	if (p->channels != ~0) {
2580 		pp.channels = p->channels;
2581 		np++;
2582 	}
2583 	if (r->channels != ~0) {
2584 		rp.channels = r->channels;
2585 		nr++;
2586 	}
2587 #ifdef AUDIO_DEBUG
2588 	if (audiodebug && nr)
2589 	    audio_print_params("Setting record params", &rp);
2590 	if (audiodebug && np)
2591 	    audio_print_params("Setting play params", &pp);
2592 #endif
2593 	if (nr && (error = audio_check_params(&rp)))
2594 		return error;
2595 	if (np && (error = audio_check_params(&pp)))
2596 		return error;
2597 	setmode = 0;
2598 	if (nr) {
2599 		if (!cleared)
2600 			audio_clear(sc);
2601 		modechange = cleared = 1;
2602 		rp.sw_code = 0;
2603 		rp.factor = 1;
2604 		setmode |= AUMODE_RECORD;
2605 	}
2606 	if (np) {
2607 		if (!cleared)
2608 			audio_clear(sc);
2609 		modechange = cleared = 1;
2610 		pp.sw_code = 0;
2611 		pp.factor = 1;
2612 		setmode |= AUMODE_PLAY;
2613 	}
2614 
2615 	if (ai->mode != ~0) {
2616 		if (!cleared)
2617 			audio_clear(sc);
2618 		modechange = cleared = 1;
2619 		sc->sc_mode = ai->mode;
2620 		if (sc->sc_mode & AUMODE_PLAY_ALL)
2621 			sc->sc_mode |= AUMODE_PLAY;
2622 		if ((sc->sc_mode & AUMODE_PLAY) && !sc->sc_full_duplex)
2623 			/* Play takes precedence */
2624 			sc->sc_mode &= ~AUMODE_RECORD;
2625 	}
2626 
2627 	if (modechange) {
2628 		int indep = hw->get_props(sc->hw_hdl) & AUDIO_PROP_INDEPENDENT;
2629 		if (!indep) {
2630 			if (setmode == AUMODE_RECORD)
2631 				pp = rp;
2632 			else if (setmode == AUMODE_PLAY)
2633 				rp = pp;
2634 		}
2635 		error = hw->set_params(sc->hw_hdl, setmode,
2636 		    sc->sc_mode & (AUMODE_PLAY | AUMODE_RECORD), &pp, &rp);
2637 		if (error)
2638 			return (error);
2639 		if (!indep) {
2640 			if (setmode == AUMODE_RECORD) {
2641 				pp.sample_rate = rp.sample_rate;
2642 				pp.encoding    = rp.encoding;
2643 				pp.channels    = rp.channels;
2644 				pp.precision   = rp.precision;
2645 			} else if (setmode == AUMODE_PLAY) {
2646 				rp.sample_rate = pp.sample_rate;
2647 				rp.encoding    = pp.encoding;
2648 				rp.channels    = pp.channels;
2649 				rp.precision   = pp.precision;
2650 			}
2651 		}
2652 		sc->sc_rparams = rp;
2653 		sc->sc_pparams = pp;
2654 	}
2655 
2656 	oldpblksize = sc->sc_pr.blksize;
2657 	oldrblksize = sc->sc_rr.blksize;
2658 	/* Play params can affect the record params, so recalculate blksize. */
2659 	if (nr || np) {
2660 		audio_calc_blksize(sc, AUMODE_RECORD);
2661 		audio_calc_blksize(sc, AUMODE_PLAY);
2662 	}
2663 #ifdef AUDIO_DEBUG
2664 	if (audiodebug > 1 && nr)
2665 	    audio_print_params("After setting record params", &sc->sc_rparams);
2666 	if (audiodebug > 1 && np)
2667 	    audio_print_params("After setting play params", &sc->sc_pparams);
2668 #endif
2669 
2670 	if (p->port != ~0) {
2671 		if (!cleared)
2672 			audio_clear(sc);
2673 		cleared = 1;
2674 
2675 		error = au_set_port(sc, &sc->sc_outports, p->port);
2676 		if (error)
2677 			return(error);
2678 	}
2679 	if (r->port != ~0) {
2680 		if (!cleared)
2681 			audio_clear(sc);
2682 		cleared = 1;
2683 
2684 		error = au_set_port(sc, &sc->sc_inports, r->port);
2685 		if (error)
2686 			return(error);
2687 	}
2688 	if (p->gain != ~0) {
2689 		au_get_gain(sc, &sc->sc_outports, &gain, &balance);
2690 		error = au_set_gain(sc, &sc->sc_outports, p->gain, balance);
2691 		if (error)
2692 			return(error);
2693 	}
2694 	if (r->gain != ~0) {
2695 		au_get_gain(sc, &sc->sc_inports, &gain, &balance);
2696 		error = au_set_gain(sc, &sc->sc_inports, r->gain, balance);
2697 		if (error)
2698 			return(error);
2699 	}
2700 
2701 	if (p->balance != (u_char)~0) {
2702 		au_get_gain(sc, &sc->sc_outports, &gain, &balance);
2703 		error = au_set_gain(sc, &sc->sc_outports, gain, p->balance);
2704 		if (error)
2705 			return(error);
2706 	}
2707 	if (r->balance != (u_char)~0) {
2708 		au_get_gain(sc, &sc->sc_inports, &gain, &balance);
2709 		error = au_set_gain(sc, &sc->sc_inports, gain, r->balance);
2710 		if (error)
2711 			return(error);
2712 	}
2713 
2714 	if (ai->monitor_gain != ~0 &&
2715 	    sc->sc_monitor_port != -1) {
2716 		mixer_ctrl_t ct;
2717 
2718 		ct.dev = sc->sc_monitor_port;
2719 		ct.type = AUDIO_MIXER_VALUE;
2720 		ct.un.value.num_channels = 1;
2721 		ct.un.value.level[AUDIO_MIXER_LEVEL_MONO] = ai->monitor_gain;
2722 		error = sc->hw_if->get_port(sc->hw_hdl, &ct);
2723 		if (error)
2724 			return(error);
2725 	}
2726 
2727 	if (p->pause != (u_char)~0) {
2728 		sc->sc_pr.pause = p->pause;
2729 		if (!p->pause && !sc->sc_pbus && (sc->sc_mode & AUMODE_PLAY)) {
2730 			s = splaudio();
2731 			error = audiostartp(sc);
2732 			splx(s);
2733 			if (error)
2734 				return error;
2735 		}
2736 	}
2737 	if (r->pause != (u_char)~0) {
2738 		sc->sc_rr.pause = r->pause;
2739 		if (!r->pause && !sc->sc_rbus && (sc->sc_mode & AUMODE_RECORD)) {
2740 			s = splaudio();
2741 			error = audiostartr(sc);
2742 			splx(s);
2743 			if (error)
2744 				return error;
2745 		}
2746 	}
2747 
2748 	if (ai->blocksize != ~0) {
2749 		/* Block size specified explicitly. */
2750 		if (!cleared)
2751 			audio_clear(sc);
2752 		cleared = 1;
2753 
2754 		if (ai->blocksize == 0) {
2755 			audio_calc_blksize(sc, AUMODE_RECORD);
2756 			audio_calc_blksize(sc, AUMODE_PLAY);
2757 			sc->sc_blkset = 0;
2758 		} else {
2759 			int bs = ai->blocksize;
2760 			if (hw->round_blocksize)
2761 				bs = hw->round_blocksize(sc->hw_hdl, bs);
2762 			sc->sc_pr.blksize = sc->sc_rr.blksize = bs;
2763 			sc->sc_blkset = 1;
2764 		}
2765 	}
2766 
2767 	if (ai->mode != ~0) {
2768 		if (sc->sc_mode & AUMODE_PLAY)
2769 			audio_init_play(sc);
2770 		if (sc->sc_mode & AUMODE_RECORD)
2771 			audio_init_record(sc);
2772 	}
2773 
2774 	if (hw->commit_settings) {
2775 		error = hw->commit_settings(sc->hw_hdl);
2776 		if (error)
2777 			return (error);
2778 	}
2779 
2780 	if (cleared) {
2781 		s = splaudio();
2782 		error = audio_initbufs(sc);
2783 		if (error) goto err;
2784 		if (sc->sc_pr.blksize != oldpblksize ||
2785 		    sc->sc_rr.blksize != oldrblksize)
2786 			audio_calcwater(sc);
2787 		if ((sc->sc_mode & AUMODE_PLAY) &&
2788 		    pbus && !sc->sc_pbus)
2789 			error = audiostartp(sc);
2790 		if (!error &&
2791 		    (sc->sc_mode & AUMODE_RECORD) &&
2792 		    rbus && !sc->sc_rbus)
2793 			error = audiostartr(sc);
2794 	err:
2795 		splx(s);
2796 		if (error)
2797 			return error;
2798 	}
2799 
2800 	/* Change water marks after initializing the buffers. */
2801 	if (ai->hiwat != ~0) {
2802 		blks = ai->hiwat;
2803 		if (blks > sc->sc_pr.maxblks)
2804 			blks = sc->sc_pr.maxblks;
2805 		if (blks < 2)
2806 			blks = 2;
2807 		sc->sc_pr.usedhigh = blks * sc->sc_pr.blksize;
2808 	}
2809 	if (ai->lowat != ~0) {
2810 		blks = ai->lowat;
2811 		if (blks > sc->sc_pr.maxblks - 1)
2812 			blks = sc->sc_pr.maxblks - 1;
2813 		sc->sc_pr.usedlow = blks * sc->sc_pr.blksize;
2814 	}
2815 	if (ai->hiwat != ~0 || ai->lowat != ~0) {
2816 		if (sc->sc_pr.usedlow > sc->sc_pr.usedhigh - sc->sc_pr.blksize)
2817 			sc->sc_pr.usedlow = sc->sc_pr.usedhigh - sc->sc_pr.blksize;
2818 	}
2819 
2820 	return (0);
2821 }
2822 
2823 int
2824 audiogetinfo(sc, ai)
2825 	struct audio_softc *sc;
2826 	struct audio_info *ai;
2827 {
2828 	struct audio_prinfo *r = &ai->record, *p = &ai->play;
2829 	struct audio_hw_if *hw = sc->hw_if;
2830 
2831 	if (hw == 0)		/* HW has not attached */
2832 		return(ENXIO);
2833 
2834 	p->sample_rate = sc->sc_pparams.sample_rate;
2835 	r->sample_rate = sc->sc_rparams.sample_rate;
2836 	p->channels = sc->sc_pparams.channels;
2837 	r->channels = sc->sc_rparams.channels;
2838 	p->precision = sc->sc_pparams.precision;
2839 	r->precision = sc->sc_rparams.precision;
2840 	p->encoding = sc->sc_pparams.encoding;
2841 	r->encoding = sc->sc_rparams.encoding;
2842 
2843 	r->port = au_get_port(sc, &sc->sc_inports);
2844 	p->port = au_get_port(sc, &sc->sc_outports);
2845 
2846 	r->avail_ports = sc->sc_inports.allports;
2847 	p->avail_ports = sc->sc_outports.allports;
2848 
2849 	au_get_gain(sc, &sc->sc_inports,  &r->gain, &r->balance);
2850 	au_get_gain(sc, &sc->sc_outports, &p->gain, &p->balance);
2851 
2852 	if (sc->sc_monitor_port != -1) {
2853 		mixer_ctrl_t ct;
2854 
2855 		ct.dev = sc->sc_monitor_port;
2856 		ct.type = AUDIO_MIXER_VALUE;
2857 		ct.un.value.num_channels = 1;
2858 		if (sc->hw_if->get_port(sc->hw_hdl, &ct))
2859 			ai->monitor_gain = 0;
2860 		else
2861 			ai->monitor_gain =
2862 				ct.un.value.level[AUDIO_MIXER_LEVEL_MONO];
2863 	} else
2864 		ai->monitor_gain = 0;
2865 
2866 	p->seek = sc->sc_pr.used;
2867 	r->seek = sc->sc_rr.used;
2868 
2869 	p->samples = sc->sc_pr.stamp - sc->sc_pr.drops;
2870 	r->samples = sc->sc_rr.stamp - sc->sc_rr.drops;
2871 
2872 	p->eof = sc->sc_eof;
2873 	r->eof = 0;
2874 
2875 	p->pause = sc->sc_pr.pause;
2876 	r->pause = sc->sc_rr.pause;
2877 
2878 	p->error = sc->sc_pr.drops != 0;
2879 	r->error = sc->sc_rr.drops != 0;
2880 
2881 	p->waiting = r->waiting = 0;		/* open never hangs */
2882 
2883 	p->open = (sc->sc_open & AUOPEN_WRITE) != 0;
2884 	r->open = (sc->sc_open & AUOPEN_READ) != 0;
2885 
2886 	p->active = sc->sc_pbus;
2887 	r->active = sc->sc_rbus;
2888 
2889 	p->buffer_size = sc->sc_pr.bufsize;
2890 	r->buffer_size = sc->sc_rr.bufsize;
2891 
2892 	ai->blocksize = sc->sc_pr.blksize;
2893 	ai->hiwat = sc->sc_pr.usedhigh / sc->sc_pr.blksize;
2894 	ai->lowat = sc->sc_pr.usedlow / sc->sc_pr.blksize;
2895 	ai->mode = sc->sc_mode;
2896 
2897 	return (0);
2898 }
2899 
2900 /*
2901  * Mixer driver
2902  */
2903 int
2904 mixer_open(dev, sc, flags, ifmt, p)
2905 	dev_t dev;
2906 	struct audio_softc *sc;
2907 	int flags, ifmt;
2908 	struct proc *p;
2909 {
2910 	DPRINTF(("mixer_open: dev=0x%x flags=0x%x sc=%p\n", dev, flags, sc));
2911 
2912 	return (0);
2913 }
2914 
2915 /*
2916  * Remove a process from those to be signalled on mixer activity.
2917  */
2918 static void
2919 mixer_remove(sc, p)
2920 	struct audio_softc *sc;
2921 	struct proc *p;
2922 {
2923 	struct mixer_asyncs **pm, *m;
2924 
2925 	for(pm = &sc->sc_async_mixer; *pm; pm = &(*pm)->next) {
2926 		if ((*pm)->proc == p) {
2927 			m = *pm;
2928 			*pm = m->next;
2929 			free(m, M_DEVBUF);
2930 			return;
2931 		}
2932 	}
2933 }
2934 
2935 /*
2936  * Signal all processes waitinf for the mixer.
2937  */
2938 static void
2939 mixer_signal(sc)
2940 	struct audio_softc *sc;
2941 {
2942 	struct mixer_asyncs *m;
2943 
2944 	for(m = sc->sc_async_mixer; m; m = m->next)
2945 		psignal(m->proc, SIGIO);
2946 }
2947 
2948 /*
2949  * Close a mixer device
2950  */
2951 /* ARGSUSED */
2952 int
2953 mixer_close(dev, flags, ifmt, p)
2954 	dev_t dev;
2955 	int flags, ifmt;
2956 	struct proc *p;
2957 {
2958 	int unit = AUDIOUNIT(dev);
2959 	struct audio_softc *sc = audio_cd.cd_devs[unit];
2960 
2961 	DPRINTF(("mixer_close: unit %d\n", AUDIOUNIT(dev)));
2962 
2963 	mixer_remove(sc, p);
2964 
2965 	return (0);
2966 }
2967 
2968 int
2969 mixer_ioctl(dev, cmd, addr, flag, p)
2970 	dev_t dev;
2971 	u_long cmd;
2972 	caddr_t addr;
2973 	int flag;
2974 	struct proc *p;
2975 {
2976 	int unit = AUDIOUNIT(dev);
2977 	struct audio_softc *sc = audio_cd.cd_devs[unit];
2978 	struct audio_hw_if *hw = sc->hw_if;
2979 	int error = EINVAL;
2980 
2981 	DPRINTF(("mixer_ioctl(%d,'%c',%d)\n",
2982 		 IOCPARM_LEN(cmd), IOCGROUP(cmd), cmd&0xff));
2983 
2984 	switch (cmd) {
2985 	case FIOASYNC:
2986 		mixer_remove(sc, p); /* remove old entry */
2987 		if (*(int *)addr) {
2988 			struct mixer_asyncs *ma;
2989 			ma = malloc(sizeof (struct mixer_asyncs),
2990                                     M_DEVBUF, M_WAITOK);
2991 			ma->next = sc->sc_async_mixer;
2992 			ma->proc = p;
2993 			sc->sc_async_mixer = ma;
2994 		}
2995 		error = 0;
2996 		break;
2997 
2998 	case AUDIO_GETDEV:
2999 		DPRINTF(("AUDIO_GETDEV\n"));
3000 		error = hw->getdev(sc->hw_hdl, (audio_device_t *)addr);
3001 		break;
3002 
3003 	case AUDIO_MIXER_DEVINFO:
3004 		DPRINTF(("AUDIO_MIXER_DEVINFO\n"));
3005 		((mixer_devinfo_t *)addr)->un.v.delta = 0; /* default */
3006 		error = hw->query_devinfo(sc->hw_hdl, (mixer_devinfo_t *)addr);
3007 		break;
3008 
3009 	case AUDIO_MIXER_READ:
3010 		DPRINTF(("AUDIO_MIXER_READ\n"));
3011 		error = hw->get_port(sc->hw_hdl, (mixer_ctrl_t *)addr);
3012 		break;
3013 
3014 	case AUDIO_MIXER_WRITE:
3015 		DPRINTF(("AUDIO_MIXER_WRITE\n"));
3016 		error = hw->set_port(sc->hw_hdl, (mixer_ctrl_t *)addr);
3017 		if (!error && hw->commit_settings)
3018 			error = hw->commit_settings(sc->hw_hdl);
3019 		if (!error)
3020 			mixer_signal(sc);
3021 		break;
3022 
3023 	default:
3024 		error = EINVAL;
3025 		break;
3026 	}
3027 	DPRINTF(("mixer_ioctl(%d,'%c',%d) result %d\n",
3028 		 IOCPARM_LEN(cmd), IOCGROUP(cmd), cmd&0xff, error));
3029 	return (error);
3030 }
3031 #endif
3032