xref: /netbsd-src/sys/dev/isa/aria.c (revision d710132b4b8ce7f7cccaaf660cb16aa16b4077a0)
1 /*	$NetBSD: aria.c,v 1.18 2003/05/03 18:11:26 wiz Exp $	*/
2 
3 /*-
4  * Copyright (c) 1995, 1996, 1998 Roland C. Dowdeswell.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. All advertising materials mentioning features or use of this software
15  *    must display the following acknowledgement:
16  *      This product includes software developed by Roland C. Dowdeswell.
17  * 4. The name of the authors may not be used to endorse or promote products
18  *      derived from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*-
33  * TODO:
34  *  o   Test the driver on cards other than a single
35  *      Prometheus Aria 16.
36  *  o   Look into where aria_prometheus_kludge() belongs.
37  *  o   Add some DMA code.  It accomplishes its goal by
38  *      direct IO at the moment.
39  *  o   Different programs should be able to open the device
40  *      with O_RDONLY and O_WRONLY at the same time.  But I
41  *      do not see support for this in /sys/dev/audio.c, so
42  *	I cannot effectively code it.
43  *  o   We should nicely deal with the cards that can do mu-law
44  *      and A-law output.
45  *  o   Rework the mixer interface.
46  *       o   Deal with the lvls better.  We need to do better mapping
47  *           between logarithmic scales and the one byte that
48  *           we are passed.
49  *       o   Deal better with cards that have no mixer.
50  */
51 
52 #include <sys/cdefs.h>
53 __KERNEL_RCSID(0, "$NetBSD: aria.c,v 1.18 2003/05/03 18:11:26 wiz Exp $");
54 
55 #include <sys/param.h>
56 #include <sys/systm.h>
57 #include <sys/errno.h>
58 #include <sys/ioctl.h>
59 #include <sys/syslog.h>
60 #include <sys/device.h>
61 #include <sys/proc.h>
62 #include <sys/buf.h>
63 
64 #include <machine/cpu.h>
65 #include <machine/bus.h>
66 
67 #include <sys/audioio.h>
68 #include <dev/audio_if.h>
69 #include <dev/auconv.h>
70 
71 #include <dev/mulaw.h>
72 #include <dev/isa/isavar.h>
73 
74 #include <dev/isa/ariareg.h>
75 
76 #define FREAD 1
77 #define FWRITE 2
78 
79 #ifdef AUDIO_DEBUG
80 #define DPRINTF(x)	printf x
81 int	ariadebug = 0;
82 #else
83 #define DPRINTF(x)
84 #endif
85 
86 struct aria_mixdev_info {
87 	u_char	num_channels;
88 	u_char	level[2];
89 	u_char	mute;
90 };
91 
92 struct aria_mixmaster {
93 	u_char num_channels;
94 	u_char level[2];
95 	u_char treble[2];
96 	u_char bass[2];
97 };
98 
99 struct aria_softc {
100 	struct	device sc_dev;		/* base device */
101 	void	*sc_ih;			/* interrupt vectoring */
102 	bus_space_tag_t sc_iot;		/* Tag on 'da bus. */
103 	bus_space_handle_t sc_ioh;	/* Handle of iospace */
104 	isa_chipset_tag_t sc_ic;	/* ISA chipset info */
105 
106 	u_short	sc_open;		/* reference count of open calls */
107 	u_short sc_play;		/* non-paused play chans 2**chan */
108 	u_short sc_record;		/* non-paused record chans 2**chan */
109 /* XXX -- keep this? */
110 	u_short sc_gain[2];		/* left/right gain (play) */
111 
112 	u_long	sc_rate;		/* Sample rate for input and output */
113 	u_int	sc_encoding;		/* audio encoding -- mu-law/linear */
114 	int	sc_chans;		/* # of channels */
115 	int	sc_precision;		/* # bits per sample */
116 
117 	u_long	sc_interrupts;		/* number of interrupts taken */
118 	void	(*sc_rintr)(void*);	/* record transfer completion intr handler */
119 	void	(*sc_pintr)(void*);	/* play transfer completion intr handler */
120 	void	*sc_rarg;		/* arg for sc_rintr() */
121 	void	*sc_parg;		/* arg for sc_pintr() */
122 
123 	int	sc_blocksize;		/* literal dio block size */
124 	void	*sc_rdiobuffer;		/* record: where the next samples should be */
125 	void	*sc_pdiobuffer;		/* play:   where the next samples are */
126 
127 	u_short sc_hardware;		/* bit field of hardware present */
128 #define ARIA_TELEPHONE	0x0001		/* has telephone input */
129 #define ARIA_MIXER	0x0002		/* has SC18075 digital mixer */
130 #define ARIA_MODEL	0x0004		/* is SC18025 (=0) or SC18026 (=1) */
131 
132 	struct aria_mixdev_info aria_mix[6];
133 	struct aria_mixmaster ariamix_master;
134 	u_char	aria_mix_source;
135 
136 	int	sc_sendcmd_err;
137 };
138 
139 int	ariaprobe __P((struct device *, struct cfdata *, void *));
140 void	ariaattach __P((struct device *, struct device *, void *));
141 void	ariaclose __P((void *));
142 int	ariaopen __P((void *, int));
143 int	ariareset __P((bus_space_tag_t, bus_space_handle_t));
144 int	aria_reset __P((struct aria_softc *));
145 int	aria_getdev __P((void *, struct audio_device *));
146 
147 void	aria_do_kludge __P((bus_space_tag_t, bus_space_handle_t,
148 			    bus_space_handle_t,
149 			    u_short, u_short, u_short, u_short));
150 void	aria_prometheus_kludge __P((struct isa_attach_args *,
151 				    bus_space_handle_t));
152 
153 int	aria_query_encoding __P((void *, struct audio_encoding *));
154 int	aria_round_blocksize __P((void *, int));
155 int	aria_speaker_ctl __P((void *, int));
156 int	aria_commit_settings __P((void *));
157 int	aria_set_params __P((void *, int, int,
158 			     struct audio_params *, struct audio_params *));
159 int	aria_get_props __P((void *));
160 
161 int	aria_start_output __P((void *, void *, int,
162 			       void (*) __P((void *)), void*));
163 int	aria_start_input __P((void *, void *, int,
164 			      void (*) __P((void *)), void*));
165 
166 int	aria_halt_input __P((void *));
167 int	aria_halt_output __P((void *));
168 
169 int	aria_sendcmd __P((struct aria_softc *, u_short, int, int, int));
170 
171 u_short	aria_getdspmem __P((struct aria_softc *, u_short));
172 void	aria_putdspmem __P((struct aria_softc *, u_short, u_short));
173 
174 int	aria_intr __P((void *));
175 short	ariaversion __P((struct aria_softc *));
176 
177 void	aria_set_mixer __P((struct aria_softc *, int));
178 
179 void	aria_mix_write __P((struct aria_softc *, int, int));
180 int	aria_mix_read __P((struct aria_softc *, int));
181 
182 int	aria_mixer_set_port __P((void *, mixer_ctrl_t *));
183 int	aria_mixer_get_port __P((void *, mixer_ctrl_t *));
184 int	aria_mixer_query_devinfo __P((void *, mixer_devinfo_t *));
185 
186 CFATTACH_DECL(aria, sizeof(struct aria_softc),
187     ariaprobe, ariaattach, NULL, NULL);
188 
189 /* XXX temporary test for 1.3 */
190 #ifndef AudioNaux
191 /* 1.3 */
192 struct cfdriver aria_cd = {
193 	NULL, "aria", DV_DULL
194 };
195 #endif
196 
197 struct audio_device aria_device = {
198 	"Aria 16(se)",
199 	"x",
200 	"aria"
201 };
202 
203 /*
204  * Define our interface to the higher level audio driver.
205  */
206 
207 struct audio_hw_if aria_hw_if = {
208 	ariaopen,
209 	ariaclose,
210 	NULL,
211 	aria_query_encoding,
212 	aria_set_params,
213 	aria_round_blocksize,
214 	aria_commit_settings,
215 	NULL,
216 	NULL,
217 	aria_start_output,
218 	aria_start_input,
219 	aria_halt_input,
220 	aria_halt_output,
221 	NULL,
222 	aria_getdev,
223 	NULL,
224 	aria_mixer_set_port,
225 	aria_mixer_get_port,
226 	aria_mixer_query_devinfo,
227 	NULL,
228 	NULL,
229 	NULL,
230 	NULL,
231 	aria_get_props,
232 	NULL,
233 	NULL,
234 	NULL,
235 };
236 
237 /*
238  * Probe / attach routines.
239  */
240 
241 /*
242  * Probe for the aria hardware.
243  */
244 int
245 ariaprobe(parent, cf, aux)
246 	struct device *parent;
247 	struct cfdata *cf;
248 	void *aux;
249 {
250 	bus_space_handle_t ioh;
251 	struct isa_attach_args *ia = aux;
252 
253 	if (ia->ia_nio < 1)
254 		return (0);
255 	if (ia->ia_nirq < 1)
256 		return (0);
257 
258 	if (ISA_DIRECT_CONFIG(ia))
259 		return (0);
260 
261 	if (!ARIA_BASE_VALID(ia->ia_io[0].ir_addr)) {
262 		printf("aria: configured iobase %d invalid\n",
263 		    ia->ia_io[0].ir_addr);
264 		return 0;
265 	}
266 
267 	if (!ARIA_IRQ_VALID(ia->ia_irq[0].ir_irq)) {
268 		printf("aria: configured irq %d invalid\n",
269 		    ia->ia_irq[0].ir_irq);
270 		return 0;
271 	}
272 
273 	if (bus_space_map(ia->ia_iot, ia->ia_io[0].ir_addr, ARIADSP_NPORT,
274 	    0, &ioh)) {
275 		DPRINTF(("aria: aria probe failed\n"));
276 		return 0;
277 	}
278 
279 	if (cf->cf_flags & 1)
280 		aria_prometheus_kludge(ia, ioh);
281 
282 	if (ariareset(ia->ia_iot, ioh) != 0) {
283 		DPRINTF(("aria: aria probe failed\n"));
284 		bus_space_unmap(ia->ia_iot, ioh,  ARIADSP_NPORT);
285 		return 0;
286 	}
287 
288 	bus_space_unmap(ia->ia_iot, ioh, ARIADSP_NPORT);
289 
290 	ia->ia_nio = 1;
291 	ia->ia_io[0].ir_size = ARIADSP_NPORT;
292 
293 	ia->ia_nirq = 1;
294 
295 	ia->ia_niomem = 0;
296 	ia->ia_ndrq = 0;
297 
298 	DPRINTF(("aria: aria probe succeeded\n"));
299 	return 1;
300 }
301 
302 /*
303  * I didn't call this a kludge for
304  * nothing.  This is cribbed from
305  * ariainit, the author of that
306  * disassembled some code to discover
307  * how to set up the initial values of
308  * the card.  Without this, the card
309  * is dead. (It will not respond to _any_
310  * input at all.)
311  *
312  * ariainit can be found (ftp) at:
313  * ftp://ftp.wi.leidenuniv.nl/pub/audio/aria/programming/contrib/ariainit.zip
314  * currently.
315  */
316 
317 void
318 aria_prometheus_kludge(ia, ioh1)
319 	struct isa_attach_args *ia;
320 	bus_space_handle_t ioh1;
321 {
322 	bus_space_tag_t iot;
323 	bus_space_handle_t ioh;
324 	u_short	end;
325 
326 	DPRINTF(("aria: begin aria_prometheus_kludge\n"));
327 
328 /* Begin Config Sequence */
329 
330 	iot = ia->ia_iot;
331 	bus_space_map(iot, 0x200, 8, 0, &ioh);
332 
333         bus_space_write_1(iot, ioh, 4, 0x4c);
334         bus_space_write_1(iot, ioh, 5, 0x42);
335         bus_space_write_1(iot, ioh, 6, 0x00);
336         bus_space_write_2(iot, ioh, 0, 0x0f);
337         bus_space_write_1(iot, ioh, 1, 0x00);
338         bus_space_write_2(iot, ioh, 0, 0x02);
339         bus_space_write_1(iot, ioh, 1, ia->ia_io[0].ir_addr>>2);
340 
341 /*
342  * These next three lines set up the iobase
343  * and the irq; and disable the drq.
344  */
345 
346 	aria_do_kludge(iot, ioh, ioh1, 0x111,
347 	    ((ia->ia_io[0].ir_addr-0x280)>>2)+0xA0, 0xbf, 0xa0);
348 	aria_do_kludge(iot, ioh, ioh1, 0x011,
349 	    ia->ia_irq[0].ir_irq-6, 0xf8, 0x00);
350 	aria_do_kludge(iot, ioh, ioh1, 0x011, 0x00, 0xef, 0x00);
351 
352 /* The rest of these lines just disable everything else */
353 
354 	aria_do_kludge(iot, ioh, ioh1, 0x113, 0x00, 0x88, 0x00);
355 	aria_do_kludge(iot, ioh, ioh1, 0x013, 0x00, 0xf8, 0x00);
356 	aria_do_kludge(iot, ioh, ioh1, 0x013, 0x00, 0xef, 0x00);
357 	aria_do_kludge(iot, ioh, ioh1, 0x117, 0x00, 0x88, 0x00);
358 	aria_do_kludge(iot, ioh, ioh1, 0x017, 0x00, 0xff, 0x00);
359 
360 /* End Sequence */
361 
362 	bus_space_write_1(iot, ioh, 0, 0x0f);
363 	end = bus_space_read_1(iot, ioh1, 0);
364 	bus_space_write_2(iot, ioh, 0, 0x0f);
365 	bus_space_write_1(iot, ioh, 1, end|0x80);
366 	bus_space_read_1(iot, ioh, 0);
367 
368 	bus_space_unmap(iot, ioh, 8);
369 /*
370  * This delay is necessary for some reason,
371  * at least it would crash, and sometimes not
372  * probe properly if it did not exist.
373  */
374 	delay(1000000);
375 }
376 
377 void
378 aria_do_kludge(iot, ioh, ioh1, func, bits, and, or)
379 	bus_space_tag_t iot;
380 	bus_space_handle_t ioh;
381 	bus_space_handle_t ioh1;
382 	u_short func;
383 	u_short bits;
384 	u_short and;
385 	u_short or;
386 {
387 	u_int i;
388 	if (func & 0x100) {
389 		func &= ~0x100;
390 		if (bits) {
391 			bus_space_write_2(iot, ioh, 0, func-1);
392 			bus_space_write_1(iot, ioh, 1, bits);
393 		}
394 	} else
395 		or |= bits;
396 
397 	bus_space_write_1(iot, ioh, 0, func);
398 	i = bus_space_read_1(iot, ioh1, 0);
399 	bus_space_write_2(iot, ioh, 0, func);
400 	bus_space_write_1(iot, ioh, 1, (i&and) | or);
401 }
402 
403 /*
404  * Attach hardware to driver, attach hardware driver to audio
405  * pseudo-device driver.
406  */
407 void
408 ariaattach(parent, self, aux)
409 	struct device *parent, *self;
410 	void *aux;
411 {
412 	bus_space_handle_t ioh;
413 	struct aria_softc *sc = (void *)self;
414 	struct isa_attach_args *ia = aux;
415 	u_short i;
416 
417 	if (bus_space_map(ia->ia_iot, ia->ia_io[0].ir_addr, ARIADSP_NPORT,
418 	    0, &ioh))
419 		panic("%s: can map io port range", self->dv_xname);
420 
421 	sc->sc_iot = ia->ia_iot;
422 	sc->sc_ioh = ioh;
423 	sc->sc_ic = ia->ia_ic;
424 
425 	sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq,
426 	    IST_EDGE, IPL_AUDIO, aria_intr, sc);
427 
428 	DPRINTF(("isa_intr_establish() returns (%x)\n", (unsigned) sc->sc_ih));
429 
430 	i = aria_getdspmem(sc, ARIAA_HARDWARE_A);
431 
432 	sc->sc_hardware  = 0;
433 	sc->sc_hardware |= ((i>>13)&0x01)==1 ? ARIA_TELEPHONE:0;
434 	sc->sc_hardware |= (((i>>5)&0x07))==0x04 ? ARIA_MIXER:0;
435 	sc->sc_hardware |= (aria_getdspmem(sc, ARIAA_MODEL_A)>=1)?ARIA_MODEL:0;
436 
437 	sc->sc_open       = 0;
438 	sc->sc_play       = 0;
439 	sc->sc_record     = 0;
440 	sc->sc_rate       = 7875;
441 	sc->sc_chans      = 1;
442 	sc->sc_blocksize  = 1024;
443 	sc->sc_precision  = 8;
444         sc->sc_rintr      = 0;
445         sc->sc_rarg       = 0;
446         sc->sc_pintr      = 0;
447         sc->sc_parg       = 0;
448 	sc->sc_gain[0]       = 127;
449 	sc->sc_gain[1]       = 127;
450 
451 	for (i=0; i<6; i++) {
452 		if (i == ARIAMIX_TEL_LVL)
453 			sc->aria_mix[i].num_channels = 1;
454 		else
455 			sc->aria_mix[i].num_channels = 2;
456 		sc->aria_mix[i].level[0] = 127;
457 		sc->aria_mix[i].level[1] = 127;
458 	}
459 
460 	sc->ariamix_master.num_channels = 2;
461 	sc->ariamix_master.level[0] = 222;
462 	sc->ariamix_master.level[1] = 222;
463 	sc->ariamix_master.bass[0] = 127;
464 	sc->ariamix_master.bass[1] = 127;
465 	sc->ariamix_master.treble[0] = 127;
466 	sc->ariamix_master.treble[1] = 127;
467 	sc->aria_mix_source = 0;
468 
469 	aria_commit_settings(sc);
470 
471 	printf(": dsp %s", (ARIA_MODEL&sc->sc_hardware)?"SC18026":"SC18025");
472 	if (ARIA_TELEPHONE&sc->sc_hardware)
473 		printf(", tel");
474 	if (ARIA_MIXER&sc->sc_hardware)
475 		printf(", SC18075 mixer");
476 	printf("\n");
477 
478 	sprintf(aria_device.version, "%s",
479 		ARIA_MODEL & sc->sc_hardware ? "SC18026" : "SC18025");
480 
481 	audio_attach_mi(&aria_hw_if, (void *)sc, &sc->sc_dev);
482 }
483 
484 /*
485  * Various routines to interface to higher level audio driver
486  */
487 
488 int
489 ariaopen(addr, flags)
490 	void *addr;
491 	int flags;
492 {
493 	struct aria_softc *sc = addr;
494 
495 	DPRINTF(("ariaopen() called\n"));
496 
497 	if (!sc)
498 		return ENXIO;
499 	if ((flags&FREAD) && (sc->sc_open & ARIAR_OPEN_RECORD))
500 		return ENXIO;
501 	if ((flags&FWRITE) && (sc->sc_open & ARIAR_OPEN_PLAY))
502 		return ENXIO;
503 
504 	if (flags&FREAD)
505 		sc->sc_open |= ARIAR_OPEN_RECORD;
506 	if (flags&FWRITE)
507 		sc->sc_open |= ARIAR_OPEN_PLAY;
508 	sc->sc_play  = 0;
509 	sc->sc_record= 0;
510 	sc->sc_rintr = 0;
511 	sc->sc_rarg  = 0;
512 	sc->sc_pintr = 0;
513 	sc->sc_parg  = 0;
514 
515 	return 0;
516 }
517 
518 int
519 aria_getdev(addr, retp)
520 	void *addr;
521 	struct audio_device *retp;
522 {
523 	*retp = aria_device;
524 	return 0;
525 }
526 
527 /*
528  * Various routines to interface to higher level audio driver
529  */
530 
531 int
532 aria_query_encoding(addr, fp)
533     void *addr;
534     struct audio_encoding *fp;
535 {
536 	struct aria_softc *sc = addr;
537 
538 	switch (fp->index) {
539 		case 0:
540 			strcpy(fp->name, AudioEmulaw);
541 			fp->encoding = AUDIO_ENCODING_ULAW;
542 			fp->precision = 8;
543 			if ((ARIA_MODEL&sc->sc_hardware) == 0)
544 				fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
545 			break;
546 		case 1:
547 			strcpy(fp->name, AudioEalaw);
548 			fp->encoding = AUDIO_ENCODING_ALAW;
549 			fp->precision = 8;
550 			if ((ARIA_MODEL&sc->sc_hardware) == 0)
551 				fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
552 			break;
553 		case 2:
554 			strcpy(fp->name, AudioEslinear);
555 			fp->encoding = AUDIO_ENCODING_SLINEAR;
556 			fp->precision = 8;
557 			fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
558 			break;
559 		case 3:
560 			strcpy(fp->name, AudioEslinear_le);
561 			fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
562 			fp->precision = 16;
563 			fp->flags = 0;
564 			break;
565 		case 4:
566 			strcpy(fp->name, AudioEslinear_be);
567 			fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
568 			fp->precision = 16;
569 			fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
570 			break;
571 		case 5:
572 			strcpy(fp->name, AudioEulinear);
573 			fp->encoding = AUDIO_ENCODING_ULINEAR;
574 			fp->precision = 8;
575 			fp->flags = 0;
576 			break;
577 		case 6:
578 			strcpy(fp->name, AudioEulinear_le);
579 			fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
580 			fp->precision = 16;
581 			fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
582 			break;
583 		case 7:
584 			strcpy(fp->name, AudioEulinear_be);
585 			fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
586 			fp->precision = 16;
587 			fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
588 			break;
589 		default:
590 			return(EINVAL);
591 		/*NOTREACHED*/
592 	}
593 
594 	return (0);
595 }
596 
597 /*
598  * Store blocksize in bytes.
599  */
600 
601 int
602 aria_round_blocksize(addr, blk)
603 	void *addr;
604 	int blk;
605 {
606 	int i;
607 #if 0 /* XXX -- this is being a tad bit of a problem... */
608 	for (i=64; i<1024; i*=2)
609 		if (blk <= i)
610 			break;
611 #else
612 	i = 1024;
613 #endif
614 	return(i);
615 }
616 
617 int
618 aria_get_props(addr)
619 	void *addr;
620 {
621 	return AUDIO_PROP_FULLDUPLEX;
622 }
623 
624 int
625 aria_set_params(addr, setmode, usemode, p, r)
626 	void *addr;
627 	int setmode, usemode;
628 	struct audio_params *p, *r;
629 {
630 	struct aria_softc *sc = addr;
631 
632 	switch(p->encoding) {
633 	case AUDIO_ENCODING_ULAW:
634 	case AUDIO_ENCODING_ALAW:
635 	case AUDIO_ENCODING_SLINEAR:
636 	case AUDIO_ENCODING_SLINEAR_LE:
637 	case AUDIO_ENCODING_SLINEAR_BE:
638 	case AUDIO_ENCODING_ULINEAR:
639 	case AUDIO_ENCODING_ULINEAR_LE:
640 	case AUDIO_ENCODING_ULINEAR_BE:
641 		break;
642 	default:
643 		return (EINVAL);
644 	}
645 
646 	if (p->sample_rate <= 9450)
647 		p->sample_rate = 7875;
648 	else if (p->sample_rate <= 13387)
649 		p->sample_rate = 11025;
650 	else if (p->sample_rate <= 18900)
651 		p->sample_rate = 15750;
652 	else if (p->sample_rate <= 26775)
653 		p->sample_rate = 22050;
654 	else if (p->sample_rate <= 37800)
655 		p->sample_rate = 31500;
656 	else
657 		p->sample_rate = 44100;
658 
659 	sc->sc_encoding = p->encoding;
660 	sc->sc_precision = p->precision;
661 	sc->sc_chans = p->channels;
662 	sc->sc_rate = p->sample_rate;
663 
664 	switch(p->encoding) {
665 	case AUDIO_ENCODING_ULAW:
666 		if ((ARIA_MODEL&sc->sc_hardware) == 0) {
667 			p->sw_code = mulaw_to_ulinear8;
668 			r->sw_code = ulinear8_to_mulaw;
669 		}
670 		break;
671 	case AUDIO_ENCODING_ALAW:
672 		if ((ARIA_MODEL&sc->sc_hardware) == 0) {
673 			p->sw_code = alaw_to_ulinear8;
674 			r->sw_code = ulinear8_to_alaw;
675 		}
676 		break;
677 	case AUDIO_ENCODING_SLINEAR:
678 		p->sw_code = r->sw_code = change_sign8;
679 		break;
680 	case AUDIO_ENCODING_ULINEAR_LE:
681 		p->sw_code = r->sw_code = change_sign16_le;
682 		break;
683 	case AUDIO_ENCODING_SLINEAR_BE:
684 		p->sw_code = r->sw_code = swap_bytes;
685 		break;
686 	case AUDIO_ENCODING_ULINEAR_BE:
687 		p->sw_code = r->sw_code = swap_bytes_change_sign16_le;
688 		break;
689 	}
690 
691 	return 0;
692 }
693 
694 /*
695  * This is where all of the twiddling goes on.
696  */
697 
698 int
699 aria_commit_settings(addr)
700 	void *addr;
701 {
702         struct aria_softc *sc = addr;
703 	bus_space_tag_t iot = sc->sc_iot;
704 	bus_space_handle_t ioh = sc->sc_ioh;
705 	static u_char tones[16] =
706 	    { 7, 6, 5, 4, 3, 2, 1, 0, 8, 9, 10, 11, 12, 13, 14, 15 };
707 	u_short format;
708 	u_short left, right;
709 	u_short samp;
710 	u_char i;
711 
712 	DPRINTF(("aria_commit_settings\n"));
713 
714 	switch (sc->sc_rate) {
715 	case  7875: format = 0x00; samp = 0x60; break;
716 	case 11025: format = 0x00; samp = 0x40; break;
717 	case 15750: format = 0x10; samp = 0x60; break;
718 	case 22050: format = 0x10; samp = 0x40; break;
719 	case 31500: format = 0x10; samp = 0x20; break;
720 	case 44100: format = 0x20; samp = 0x00; break;
721 	default:    format = 0x00; samp = 0x40; break;/* XXX can we get here? */
722 	}
723 
724 	if ((ARIA_MODEL&sc->sc_hardware) != 0) {
725 		format |= (sc->sc_encoding==AUDIO_ENCODING_ULAW)?0x06:0x00;
726 		format |= (sc->sc_encoding==AUDIO_ENCODING_ALAW)?0x08:0x00;
727 	}
728 
729 	format |= (sc->sc_precision==16)?0x02:0x00;
730 	format |= (sc->sc_chans==2)?1:0;
731 	samp |= bus_space_read_2(iot, ioh, ARIADSP_STATUS) & ~0x60;
732 
733 	aria_sendcmd(sc, ARIADSPC_FORMAT, format, -1, -1);
734 	bus_space_write_2(iot, ioh, ARIADSP_CONTROL, samp);
735 
736 	if (sc->sc_hardware&ARIA_MIXER) {
737 		for (i = 0; i < 6; i++)
738 			aria_set_mixer(sc, i);
739 
740 		if (sc->sc_chans==2) {
741 			aria_sendcmd(sc, ARIADSPC_CHAN_VOL, ARIAR_PLAY_CHAN,
742 				     ((sc->sc_gain[0]+sc->sc_gain[1])/2)<<7,
743 				     -1);
744 			aria_sendcmd(sc, ARIADSPC_CHAN_PAN, ARIAR_PLAY_CHAN,
745 				     (sc->sc_gain[0]-sc->sc_gain[1])/4+0x40,
746 				     -1);
747 		} else {
748 			aria_sendcmd(sc, ARIADSPC_CHAN_VOL, ARIAR_PLAY_CHAN,
749 				     sc->sc_gain[0]<<7, -1);
750 			aria_sendcmd(sc, ARIADSPC_CHAN_PAN, ARIAR_PLAY_CHAN,
751 				     0x40, -1);
752 		}
753 
754 		aria_sendcmd(sc, ARIADSPC_MASMONMODE,
755 			     sc->ariamix_master.num_channels != 2, -1, -1);
756 
757 		aria_sendcmd(sc, ARIADSPC_MIXERVOL, 0x0004,
758 			     sc->ariamix_master.level[0] << 7,
759 			     sc->ariamix_master.level[1] << 7);
760 
761 		/* Convert treble/bass from byte to soundcard style */
762 
763 		left  = (tones[(sc->ariamix_master.treble[0]>>4)&0x0f]<<8) |
764 			 tones[(sc->ariamix_master.bass[0]>>4)&0x0f];
765 		right = (tones[(sc->ariamix_master.treble[1]>>4)&0x0f]<<8) |
766 			 tones[(sc->ariamix_master.bass[1]>>4)&0x0f];
767 
768 		aria_sendcmd(sc, ARIADSPC_TONE, left, right, -1);
769 	}
770 
771 	aria_sendcmd(sc, ARIADSPC_BLOCKSIZE, sc->sc_blocksize/2, -1, -1);
772 
773 /*
774  * If we think that the card is recording or playing, start it up again here.
775  * Some of the previous commands turn the channels off.
776  */
777 
778 	if (sc->sc_record&(1<<ARIAR_RECORD_CHAN))
779 		aria_sendcmd(sc, ARIADSPC_START_REC, ARIAR_RECORD_CHAN, -1,-1);
780 
781 	if (sc->sc_play&(1<<ARIAR_PLAY_CHAN))
782 		aria_sendcmd(sc, ARIADSPC_START_PLAY, ARIAR_PLAY_CHAN, -1, -1);
783 
784 	return(0);
785 }
786 
787 void
788 aria_set_mixer(sc, i)
789         struct aria_softc *sc;
790 	int i;
791 {
792 	u_char source;
793 	switch(i) {
794 	case ARIAMIX_MIC_LVL:     source = 0x0001; break;
795 	case ARIAMIX_CD_LVL:      source = 0x0002; break;
796 	case ARIAMIX_LINE_IN_LVL: source = 0x0008; break;
797 	case ARIAMIX_TEL_LVL:     source = 0x0020; break;
798 	case ARIAMIX_AUX_LVL:     source = 0x0010; break;
799 	case ARIAMIX_DAC_LVL:     source = 0x0004; break;
800 	default:                  source = 0x0000; break;
801 	}
802 
803 	if (source != 0x0000 && source != 0x0004) {
804 		if (sc->aria_mix[i].mute == 1)
805 			aria_sendcmd(sc, ARIADSPC_INPMONMODE, source, 3, -1);
806 		else
807 			aria_sendcmd(sc, ARIADSPC_INPMONMODE, source,
808 				     sc->aria_mix[i].num_channels != 2, -1);
809 
810 		aria_sendcmd(sc, ARIADSPC_INPMONMODE, 0x8000|source,
811 			     sc->aria_mix[i].num_channels != 2, -1);
812 		aria_sendcmd(sc, ARIADSPC_MIXERVOL, source,
813 			     sc->aria_mix[i].level[0] << 7,
814 			     sc->aria_mix[i].level[1] << 7);
815 	}
816 
817 	if (sc->aria_mix_source == i) {
818 		aria_sendcmd(sc, ARIADSPC_ADCSOURCE, source, -1, -1);
819 
820 		if (sc->sc_open & ARIAR_OPEN_RECORD)
821 			aria_sendcmd(sc, ARIADSPC_ADCCONTROL, 1, -1, -1);
822 		else
823 			aria_sendcmd(sc, ARIADSPC_ADCCONTROL, 0, -1, -1);
824 	}
825 }
826 
827 void
828 ariaclose(addr)
829 	void *addr;
830 {
831         struct aria_softc *sc = addr;
832 
833 	DPRINTF(("aria_close sc=0x%x\n", (unsigned) sc));
834 
835         sc->sc_rintr = 0;
836         sc->sc_pintr = 0;
837 	sc->sc_rdiobuffer = 0;
838 	sc->sc_pdiobuffer = 0;
839 
840 	if (sc->sc_play&(1<<ARIAR_PLAY_CHAN) &&
841 	    sc->sc_open & ARIAR_OPEN_PLAY) {
842 		aria_sendcmd(sc, ARIADSPC_STOP_PLAY, ARIAR_PLAY_CHAN, -1, -1);
843 		sc->sc_play &= ~(1<<ARIAR_PLAY_CHAN);
844 	}
845 
846 	if (sc->sc_record&(1<<ARIAR_RECORD_CHAN) &&
847 	    sc->sc_open & ARIAR_OPEN_RECORD) {
848 		aria_sendcmd(sc, ARIADSPC_STOP_REC, ARIAR_RECORD_CHAN, -1, -1);
849 		sc->sc_record &= ~(1<<ARIAR_RECORD_CHAN);
850 	}
851 
852 	sc->sc_open = 0;
853 
854 	if (aria_reset(sc) != 0) {
855 		delay(500);
856 		aria_reset(sc);
857 	}
858 }
859 
860 /*
861  * Reset the hardware.
862  */
863 
864 int ariareset(iot, ioh)
865 	bus_space_tag_t iot;
866 	bus_space_handle_t ioh;
867 {
868 	struct aria_softc tmp, *sc = &tmp;
869 
870 	sc->sc_iot = iot;
871 	sc->sc_ioh = ioh;
872 	return aria_reset(sc);
873 }
874 
875 int
876 aria_reset(sc)
877 	struct aria_softc *sc;
878 {
879 	bus_space_tag_t iot = sc->sc_iot;
880 	bus_space_handle_t ioh = sc->sc_ioh;
881 	int fail=0;
882 	int i;
883 
884 	bus_space_write_2(iot, ioh, ARIADSP_CONTROL,
885 			  ARIAR_ARIA_SYNTH | ARIAR_SR22K|ARIAR_DSPINTWR);
886 	aria_putdspmem(sc, 0x6102, 0);
887 
888 	fail |= aria_sendcmd(sc, ARIADSPC_SYSINIT, 0x0000, 0x0000, 0x0000);
889 
890 	for (i=0; i < ARIAR_NPOLL; i++)
891 		if (aria_getdspmem(sc, ARIAA_TASK_A) == 1)
892 			break;
893 
894 	bus_space_write_2(iot, ioh, ARIADSP_CONTROL,
895 			  ARIAR_ARIA_SYNTH|ARIAR_SR22K | ARIAR_DSPINTWR |
896 			  ARIAR_PCINTWR);
897 	fail |= aria_sendcmd(sc, ARIADSPC_MODE, ARIAV_MODE_NO_SYNTH,-1,-1);
898 
899 	return (fail);
900 }
901 
902 /*
903  * Lower-level routines
904  */
905 
906 void
907 aria_putdspmem(sc, loc, val)
908 	struct aria_softc *sc;
909 	u_short loc;
910 	u_short val;
911 {
912 	bus_space_tag_t iot = sc->sc_iot;
913 	bus_space_handle_t ioh = sc->sc_ioh;
914 	bus_space_write_2(iot, ioh, ARIADSP_DMAADDRESS, loc);
915 	bus_space_write_2(iot, ioh, ARIADSP_DMADATA, val);
916 }
917 
918 u_short
919 aria_getdspmem(sc, loc)
920 	struct aria_softc *sc;
921 	u_short loc;
922 {
923 	bus_space_tag_t iot = sc->sc_iot;
924 	bus_space_handle_t ioh = sc->sc_ioh;
925 	bus_space_write_2(iot, ioh, ARIADSP_DMAADDRESS, loc);
926 	return bus_space_read_2(iot, ioh, ARIADSP_DMADATA);
927 }
928 
929 /*
930  * aria_sendcmd()
931  *  each full DSP command is unified into this
932  *  function.
933  */
934 
935 #define ARIASEND(data, flag) \
936 	for (i = ARIAR_NPOLL; \
937 	     (bus_space_read_2(iot, ioh, ARIADSP_STATUS) & ARIAR_BUSY) && i>0; \
938 	     i--) \
939 		; \
940 	if (bus_space_read_2(iot, ioh, ARIADSP_STATUS) & ARIAR_BUSY) \
941 		fail |= flag; \
942 	bus_space_write_2(iot, ioh, ARIADSP_WRITE, (u_short)data)
943 
944 int
945 aria_sendcmd(sc, command, arg1, arg2, arg3)
946 	struct aria_softc *sc;
947 	u_short command;
948 	int arg1;
949 	int arg2;
950 	int arg3;
951 {
952 	bus_space_tag_t iot = sc->sc_iot;
953 	bus_space_handle_t ioh = sc->sc_ioh;
954 	int i, fail = 0;
955 
956 	ARIASEND(command, 1);
957 	if (arg1 != -1) {
958 		ARIASEND(arg1, 2);
959 	}
960 	if (arg2 != -1) {
961 		ARIASEND(arg2, 4);
962 	}
963 	if (arg3 != -1) {
964 		ARIASEND(arg3, 8);
965 	}
966 	ARIASEND(ARIADSPC_TERM, 16);
967 
968 	if (fail) {
969 		sc->sc_sendcmd_err++;
970 #ifdef AUDIO_DEBUG
971 		DPRINTF(("aria_sendcmd: failure=(%d) cmd=(0x%x) fail=(0x%x)\n",
972 			 sc->sc_sendcmd_err, command, fail));
973 #endif
974 		return -1;
975 	}
976 
977 	return 0;
978 }
979 #undef ARIASEND
980 
981 int
982 aria_halt_input(addr)
983 	void *addr;
984 {
985 	struct aria_softc *sc = addr;
986 
987 	DPRINTF(("aria_halt_input\n"));
988 
989 	if (sc->sc_record & (1<<0)) {
990 		aria_sendcmd(sc, ARIADSPC_STOP_REC, 0, -1, -1);
991 		sc->sc_record &= ~(1<<0);
992 	}
993 
994 	return(0);
995 }
996 
997 int
998 aria_halt_output(addr)
999 	void *addr;
1000 {
1001 	struct aria_softc *sc = addr;
1002 
1003 	DPRINTF(("aria_halt_output\n"));
1004 
1005 	if (sc->sc_play & (1<<1)) {
1006 		aria_sendcmd(sc, ARIADSPC_STOP_PLAY, 1, -1, -1);
1007 		sc->sc_play &= ~(1<<1);
1008 	}
1009 
1010 	return(0);
1011 }
1012 
1013 /*
1014  * Here we just set up the buffers.  If we receive
1015  * an interrupt without these set, it is ignored.
1016  */
1017 
1018 int
1019 aria_start_input(addr, p, cc, intr, arg)
1020 	void *addr;
1021 	void *p;
1022 	int cc;
1023 	void (*intr) __P((void *));
1024 	void *arg;
1025 {
1026 	struct aria_softc *sc = addr;
1027 
1028 	DPRINTF(("aria_start_input %d @ %x\n", cc, (unsigned) p));
1029 
1030 	if (cc != sc->sc_blocksize) {
1031 		DPRINTF(("aria_start_input reqsize %d not sc_blocksize %d\n",
1032 			cc, sc->sc_blocksize));
1033 		return EINVAL;
1034 	}
1035 
1036 	sc->sc_rarg = arg;
1037 	sc->sc_rintr = intr;
1038 	sc->sc_rdiobuffer = p;
1039 
1040 	if (!(sc->sc_record&(1<<ARIAR_RECORD_CHAN))) {
1041 		aria_sendcmd(sc, ARIADSPC_START_REC, ARIAR_RECORD_CHAN, -1,-1);
1042 		sc->sc_record |= (1<<ARIAR_RECORD_CHAN);
1043 	}
1044 
1045 	return 0;
1046 }
1047 
1048 int
1049 aria_start_output(addr, p, cc, intr, arg)
1050 	void *addr;
1051 	void *p;
1052 	int cc;
1053 	void (*intr) __P((void *));
1054 	void *arg;
1055 {
1056 	struct aria_softc *sc = addr;
1057 
1058 	DPRINTF(("aria_start_output %d @ %x\n", cc, (unsigned) p));
1059 
1060 	if (cc != sc->sc_blocksize) {
1061 		DPRINTF(("aria_start_output reqsize %d not sc_blocksize %d\n",
1062 			cc, sc->sc_blocksize));
1063 		return EINVAL;
1064 	}
1065 
1066 	sc->sc_parg = arg;
1067 	sc->sc_pintr = intr;
1068 	sc->sc_pdiobuffer = p;
1069 
1070 	if (!(sc->sc_play&(1<<ARIAR_PLAY_CHAN))) {
1071 		aria_sendcmd(sc, ARIADSPC_START_PLAY, ARIAR_PLAY_CHAN, -1, -1);
1072 		sc->sc_play |= (1<<ARIAR_PLAY_CHAN);
1073 	}
1074 
1075 	return 0;
1076 }
1077 
1078 /*
1079  * Process an interrupt.  This should be a
1080  * request (from the card) to write or read
1081  * samples.
1082  */
1083 int
1084 aria_intr(arg)
1085 	void *arg;
1086 {
1087 	struct  aria_softc *sc = arg;
1088 	bus_space_tag_t iot = sc->sc_iot;
1089 	bus_space_handle_t ioh = sc->sc_ioh;
1090 	u_short *pdata = sc->sc_pdiobuffer;
1091 	u_short *rdata = sc->sc_rdiobuffer;
1092 	u_short address;
1093 
1094 #if 0 /*  XXX --  BAD BAD BAD (That this is #define'd out */
1095 	DPRINTF(("Checking to see if this is our intr\n"));
1096 
1097 	if ((inw(iobase) & 1) != 0x1)
1098 		return 0;  /* not for us */
1099 #endif
1100 
1101 	sc->sc_interrupts++;
1102 
1103 	DPRINTF(("aria_intr\n"));
1104 
1105 	if ((sc->sc_open & ARIAR_OPEN_PLAY) && (pdata!=NULL)) {
1106 		DPRINTF(("aria_intr play=(%x)\n", (unsigned) pdata));
1107 		address = 0x8000 - 2*(sc->sc_blocksize);
1108 		address+= aria_getdspmem(sc, ARIAA_PLAY_FIFO_A);
1109 		bus_space_write_2(iot, ioh, ARIADSP_DMAADDRESS, address);
1110 		bus_space_write_multi_2(iot, ioh, ARIADSP_DMADATA, pdata,
1111 					sc->sc_blocksize / 2);
1112 		if (sc->sc_pintr != NULL)
1113 			(*sc->sc_pintr)(sc->sc_parg);
1114 	}
1115 
1116 	if ((sc->sc_open & ARIAR_OPEN_RECORD) && (rdata!=NULL)) {
1117 		DPRINTF(("aria_intr record=(%x)\n", (unsigned) rdata));
1118 		address = 0x8000 - (sc->sc_blocksize);
1119 		address+= aria_getdspmem(sc, ARIAA_REC_FIFO_A);
1120 		bus_space_write_2(iot, ioh, ARIADSP_DMAADDRESS, address);
1121 		bus_space_read_multi_2(iot, ioh, ARIADSP_DMADATA, rdata,
1122 				       sc->sc_blocksize / 2);
1123 		if (sc->sc_rintr != NULL)
1124 			(*sc->sc_rintr)(sc->sc_rarg);
1125 	}
1126 
1127 	aria_sendcmd(sc, ARIADSPC_TRANSCOMPLETE, -1, -1, -1);
1128 
1129 	return 1;
1130 }
1131 
1132 int
1133 aria_mixer_set_port(addr, cp)
1134 	void *addr;
1135 	mixer_ctrl_t *cp;
1136 {
1137 	struct aria_softc *sc = addr;
1138 	int error = EINVAL;
1139 
1140 	DPRINTF(("aria_mixer_set_port\n"));
1141 
1142 	/* This could be done better, no mixer still has some controls. */
1143 	if (!(ARIA_MIXER & sc->sc_hardware))
1144 		return ENXIO;
1145 
1146 	if (cp->type == AUDIO_MIXER_VALUE) {
1147 		mixer_level_t *mv = &cp->un.value;
1148 		switch (cp->dev) {
1149 		case ARIAMIX_MIC_LVL:
1150 			if (mv->num_channels == 1 || mv->num_channels == 2) {
1151 				sc->aria_mix[ARIAMIX_MIC_LVL].num_channels =
1152 					mv->num_channels;
1153 				sc->aria_mix[ARIAMIX_MIC_LVL].level[0] =
1154 					mv->level[0];
1155 				sc->aria_mix[ARIAMIX_MIC_LVL].level[1] =
1156 					mv->level[1];
1157 				error = 0;
1158 			}
1159 			break;
1160 
1161 		case ARIAMIX_LINE_IN_LVL:
1162 			if (mv->num_channels == 1 || mv->num_channels == 2) {
1163 				sc->aria_mix[ARIAMIX_LINE_IN_LVL].num_channels=
1164 					mv->num_channels;
1165 				sc->aria_mix[ARIAMIX_LINE_IN_LVL].level[0] =
1166 					mv->level[0];
1167 				sc->aria_mix[ARIAMIX_LINE_IN_LVL].level[1] =
1168 					mv->level[1];
1169 				error = 0;
1170 			}
1171 			break;
1172 
1173 		case ARIAMIX_CD_LVL:
1174 			if (mv->num_channels == 1 || mv->num_channels == 2) {
1175 				sc->aria_mix[ARIAMIX_CD_LVL].num_channels =
1176 					mv->num_channels;
1177 				sc->aria_mix[ARIAMIX_CD_LVL].level[0] =
1178 					mv->level[0];
1179 				sc->aria_mix[ARIAMIX_CD_LVL].level[1] =
1180 					mv->level[1];
1181 				error = 0;
1182 			}
1183 			break;
1184 
1185 		case ARIAMIX_TEL_LVL:
1186 			if (mv->num_channels == 1) {
1187 				sc->aria_mix[ARIAMIX_TEL_LVL].num_channels =
1188 					mv->num_channels;
1189 				sc->aria_mix[ARIAMIX_TEL_LVL].level[0] =
1190 					mv->level[0];
1191 				error = 0;
1192 			}
1193 			break;
1194 
1195 		case ARIAMIX_DAC_LVL:
1196 			if (mv->num_channels == 1 || mv->num_channels == 2) {
1197 				sc->aria_mix[ARIAMIX_DAC_LVL].num_channels =
1198 					mv->num_channels;
1199 				sc->aria_mix[ARIAMIX_DAC_LVL].level[0] =
1200 					mv->level[0];
1201 				sc->aria_mix[ARIAMIX_DAC_LVL].level[1] =
1202 					mv->level[1];
1203 				error = 0;
1204 			}
1205 			break;
1206 
1207 		case ARIAMIX_AUX_LVL:
1208 			if (mv->num_channels == 1 || mv->num_channels == 2) {
1209 				sc->aria_mix[ARIAMIX_AUX_LVL].num_channels =
1210 					mv->num_channels;
1211 				sc->aria_mix[ARIAMIX_AUX_LVL].level[0] =
1212 					mv->level[0];
1213 				sc->aria_mix[ARIAMIX_AUX_LVL].level[1] =
1214 					mv->level[1];
1215 				error = 0;
1216 			}
1217 			break;
1218 
1219 		case ARIAMIX_MASTER_LVL:
1220 			if (mv->num_channels == 1 || mv->num_channels == 2) {
1221 				sc->ariamix_master.num_channels =
1222 					mv->num_channels;
1223 				sc->ariamix_master.level[0] = mv->level[0];
1224 				sc->ariamix_master.level[1] = mv->level[1];
1225 				error = 0;
1226 			}
1227 			break;
1228 
1229 		case ARIAMIX_MASTER_TREBLE:
1230 			if (mv->num_channels == 2) {
1231 				sc->ariamix_master.treble[0] =
1232 					mv->level[0] == 0 ? 1 : mv->level[0];
1233 				sc->ariamix_master.treble[1] =
1234 					mv->level[1] == 0 ? 1 : mv->level[1];
1235 				error = 0;
1236 			}
1237 			break;
1238 		case ARIAMIX_MASTER_BASS:
1239 			if (mv->num_channels == 2) {
1240 				sc->ariamix_master.bass[0] =
1241 					mv->level[0] == 0 ? 1 : mv->level[0];
1242 				sc->ariamix_master.bass[1] =
1243 					mv->level[1] == 0 ? 1 : mv->level[1];
1244 				error = 0;
1245 			}
1246 			break;
1247 		case ARIAMIX_OUT_LVL:
1248 			if (mv->num_channels == 1 || mv->num_channels == 2) {
1249 				sc->sc_gain[0] = mv->level[0];
1250 				sc->sc_gain[1] = mv->level[1];
1251 				error = 0;
1252 			}
1253 			break;
1254 		default:
1255 		}
1256 	}
1257 
1258 	if (cp->type == AUDIO_MIXER_ENUM)
1259 		switch(cp->dev) {
1260 		case ARIAMIX_RECORD_SOURCE:
1261 			if (cp->un.ord>=0 && cp->un.ord<=6) {
1262 				sc->aria_mix_source = cp->un.ord;
1263 				error = 0;
1264 			}
1265 			break;
1266 
1267 		case ARIAMIX_MIC_MUTE:
1268 			if (cp->un.ord == 0 || cp->un.ord == 1) {
1269 				sc->aria_mix[ARIAMIX_MIC_LVL].mute =cp->un.ord;
1270 				error = 0;
1271 			}
1272 			break;
1273 
1274 		case ARIAMIX_LINE_IN_MUTE:
1275 			if (cp->un.ord == 0 || cp->un.ord == 1) {
1276 				sc->aria_mix[ARIAMIX_LINE_IN_LVL].mute =
1277 					cp->un.ord;
1278 				error = 0;
1279 			}
1280 			break;
1281 
1282 		case ARIAMIX_CD_MUTE:
1283 			if (cp->un.ord == 0 || cp->un.ord == 1) {
1284 				sc->aria_mix[ARIAMIX_CD_LVL].mute = cp->un.ord;
1285 				error = 0;
1286 			}
1287 			break;
1288 
1289 		case ARIAMIX_DAC_MUTE:
1290 			if (cp->un.ord == 0 || cp->un.ord == 1) {
1291 				sc->aria_mix[ARIAMIX_DAC_LVL].mute =cp->un.ord;
1292 				error = 0;
1293 			}
1294 			break;
1295 
1296 		case ARIAMIX_AUX_MUTE:
1297 			if (cp->un.ord == 0 || cp->un.ord == 1) {
1298 				sc->aria_mix[ARIAMIX_AUX_LVL].mute =cp->un.ord;
1299 				error = 0;
1300 			}
1301 			break;
1302 
1303 		case ARIAMIX_TEL_MUTE:
1304 			if (cp->un.ord == 0 || cp->un.ord == 1) {
1305 				sc->aria_mix[ARIAMIX_TEL_LVL].mute =cp->un.ord;
1306 				error = 0;
1307 			}
1308 			break;
1309 
1310 		default:
1311 			/* NOTREACHED */
1312 			return ENXIO;
1313 		}
1314 
1315 	return(error);
1316 }
1317 
1318 int
1319 aria_mixer_get_port(addr, cp)
1320     void *addr;
1321     mixer_ctrl_t *cp;
1322 {
1323 	struct aria_softc *sc = addr;
1324 	int error = EINVAL;
1325 
1326 	DPRINTF(("aria_mixer_get_port\n"));
1327 
1328 	/* This could be done better, no mixer still has some controls. */
1329 	if (!(ARIA_MIXER&sc->sc_hardware))
1330 		return ENXIO;
1331 
1332 	switch (cp->dev) {
1333 	case ARIAMIX_MIC_LVL:
1334 		if (cp->type == AUDIO_MIXER_VALUE) {
1335 			cp->un.value.num_channels =
1336 				sc->aria_mix[ARIAMIX_MIC_LVL].num_channels;
1337 			cp->un.value.level[0] =
1338 				sc->aria_mix[ARIAMIX_MIC_LVL].level[0];
1339 			cp->un.value.level[1] =
1340 				sc->aria_mix[ARIAMIX_MIC_LVL].level[1];
1341 			error = 0;
1342 		}
1343 		break;
1344 
1345 	case ARIAMIX_LINE_IN_LVL:
1346 		if (cp->type == AUDIO_MIXER_VALUE) {
1347 			cp->un.value.num_channels =
1348 				sc->aria_mix[ARIAMIX_LINE_IN_LVL].num_channels;
1349 			cp->un.value.level[0] =
1350 				sc->aria_mix[ARIAMIX_LINE_IN_LVL].level[0];
1351 			cp->un.value.level[1] =
1352 				sc->aria_mix[ARIAMIX_LINE_IN_LVL].level[1];
1353 			error = 0;
1354 		}
1355 		break;
1356 
1357 	case ARIAMIX_CD_LVL:
1358 		if (cp->type == AUDIO_MIXER_VALUE) {
1359 			cp->un.value.num_channels =
1360 				sc->aria_mix[ARIAMIX_CD_LVL].num_channels;
1361 			cp->un.value.level[0] =
1362 				sc->aria_mix[ARIAMIX_CD_LVL].level[0];
1363 			cp->un.value.level[1] =
1364 				sc->aria_mix[ARIAMIX_CD_LVL].level[1];
1365 			error = 0;
1366 		}
1367 		break;
1368 
1369 	case ARIAMIX_TEL_LVL:
1370 		if (cp->type == AUDIO_MIXER_VALUE) {
1371 			cp->un.value.num_channels =
1372 				sc->aria_mix[ARIAMIX_TEL_LVL].num_channels;
1373 			cp->un.value.level[0] =
1374 				sc->aria_mix[ARIAMIX_TEL_LVL].level[0];
1375 			error = 0;
1376 		}
1377 		break;
1378 	case ARIAMIX_DAC_LVL:
1379 		if (cp->type == AUDIO_MIXER_VALUE) {
1380 			cp->un.value.num_channels =
1381 				sc->aria_mix[ARIAMIX_DAC_LVL].num_channels;
1382 			cp->un.value.level[0] =
1383 				sc->aria_mix[ARIAMIX_DAC_LVL].level[0];
1384 			cp->un.value.level[1] =
1385 				sc->aria_mix[ARIAMIX_DAC_LVL].level[1];
1386 			error = 0;
1387 		}
1388 		break;
1389 
1390 	case ARIAMIX_AUX_LVL:
1391 		if (cp->type == AUDIO_MIXER_VALUE) {
1392 			cp->un.value.num_channels =
1393 				sc->aria_mix[ARIAMIX_AUX_LVL].num_channels;
1394 			cp->un.value.level[0] =
1395 				sc->aria_mix[ARIAMIX_AUX_LVL].level[0];
1396 			cp->un.value.level[1] =
1397 				sc->aria_mix[ARIAMIX_AUX_LVL].level[1];
1398 			error = 0;
1399 		}
1400 		break;
1401 
1402 	case ARIAMIX_MIC_MUTE:
1403 		if (cp->type == AUDIO_MIXER_ENUM) {
1404 			cp->un.ord = sc->aria_mix[ARIAMIX_MIC_LVL].mute;
1405 			error = 0;
1406 		}
1407 		break;
1408 
1409 	case ARIAMIX_LINE_IN_MUTE:
1410 		if (cp->type == AUDIO_MIXER_ENUM) {
1411 			cp->un.ord = sc->aria_mix[ARIAMIX_LINE_IN_LVL].mute;
1412 			error = 0;
1413 		}
1414 		break;
1415 
1416 	case ARIAMIX_CD_MUTE:
1417 		if (cp->type == AUDIO_MIXER_ENUM) {
1418 			cp->un.ord = sc->aria_mix[ARIAMIX_CD_LVL].mute;
1419 			error = 0;
1420 		}
1421 		break;
1422 
1423 	case ARIAMIX_DAC_MUTE:
1424 		if (cp->type == AUDIO_MIXER_ENUM) {
1425 			cp->un.ord = sc->aria_mix[ARIAMIX_DAC_LVL].mute;
1426 			error = 0;
1427 		}
1428 		break;
1429 
1430 	case ARIAMIX_AUX_MUTE:
1431 		if (cp->type == AUDIO_MIXER_ENUM) {
1432 			cp->un.ord = sc->aria_mix[ARIAMIX_AUX_LVL].mute;
1433 			error = 0;
1434 		}
1435 		break;
1436 
1437 	case ARIAMIX_TEL_MUTE:
1438 		if (cp->type == AUDIO_MIXER_ENUM) {
1439 			cp->un.ord = sc->aria_mix[ARIAMIX_TEL_LVL].mute;
1440 			error = 0;
1441 		}
1442 		break;
1443 
1444 	case ARIAMIX_MASTER_LVL:
1445 		if (cp->type == AUDIO_MIXER_VALUE) {
1446 			cp->un.value.num_channels =
1447 				sc->ariamix_master.num_channels;
1448 			cp->un.value.level[0] = sc->ariamix_master.level[0];
1449 			cp->un.value.level[1] = sc->ariamix_master.level[1];
1450 			error = 0;
1451 		}
1452 		break;
1453 
1454 	case ARIAMIX_MASTER_TREBLE:
1455 		if (cp->type == AUDIO_MIXER_VALUE) {
1456 			cp->un.value.num_channels = 2;
1457 			cp->un.value.level[0] = sc->ariamix_master.treble[0];
1458 			cp->un.value.level[1] = sc->ariamix_master.treble[1];
1459 			error = 0;
1460 		}
1461 		break;
1462 
1463 	case ARIAMIX_MASTER_BASS:
1464 		if (cp->type == AUDIO_MIXER_VALUE) {
1465 			cp->un.value.num_channels = 2;
1466 			cp->un.value.level[0] = sc->ariamix_master.bass[0];
1467 			cp->un.value.level[1] = sc->ariamix_master.bass[1];
1468 			error = 0;
1469 		}
1470 		break;
1471 
1472 	case ARIAMIX_OUT_LVL:
1473 		if (cp->type == AUDIO_MIXER_VALUE) {
1474 			cp->un.value.num_channels = sc->sc_chans;
1475 			cp->un.value.level[0] = sc->sc_gain[0];
1476 			cp->un.value.level[1] = sc->sc_gain[1];
1477 			error = 0;
1478 		}
1479 		break;
1480 	case ARIAMIX_RECORD_SOURCE:
1481 		if (cp->type == AUDIO_MIXER_ENUM) {
1482 			cp->un.ord = sc->aria_mix_source;
1483 			error = 0;
1484 		}
1485 		break;
1486 
1487 	default:
1488 		return ENXIO;
1489 		/* NOT REACHED */
1490 	}
1491 
1492 	return(error);
1493 }
1494 
1495 int
1496 aria_mixer_query_devinfo(addr, dip)
1497 	   void *addr;
1498 	   mixer_devinfo_t *dip;
1499 {
1500 
1501 	struct aria_softc *sc = addr;
1502 
1503 	DPRINTF(("aria_mixer_query_devinfo\n"));
1504 
1505 	/* This could be done better, no mixer still has some controls. */
1506 	if (!(ARIA_MIXER & sc->sc_hardware))
1507 		return ENXIO;
1508 
1509 	dip->prev = dip->next = AUDIO_MIXER_LAST;
1510 
1511 	switch(dip->index) {
1512 	case ARIAMIX_MIC_LVL:
1513 		dip->type = AUDIO_MIXER_VALUE;
1514 		dip->mixer_class = ARIAMIX_INPUT_CLASS;
1515 		dip->next = ARIAMIX_MIC_MUTE;
1516 		strcpy(dip->label.name, AudioNmicrophone);
1517 		dip->un.v.num_channels = 2;
1518 		strcpy(dip->un.v.units.name, AudioNvolume);
1519 		break;
1520 
1521 	case ARIAMIX_LINE_IN_LVL:
1522 		dip->type = AUDIO_MIXER_VALUE;
1523 		dip->mixer_class = ARIAMIX_INPUT_CLASS;
1524 		dip->next = ARIAMIX_LINE_IN_MUTE;
1525 		strcpy(dip->label.name, AudioNline);
1526 		dip->un.v.num_channels = 2;
1527 		strcpy(dip->un.v.units.name, AudioNvolume);
1528 		break;
1529 
1530 	case ARIAMIX_CD_LVL:
1531 		dip->type = AUDIO_MIXER_VALUE;
1532 		dip->mixer_class = ARIAMIX_INPUT_CLASS;
1533 		dip->next = ARIAMIX_CD_MUTE;
1534 		strcpy(dip->label.name, AudioNcd);
1535 		dip->un.v.num_channels = 2;
1536 		strcpy(dip->un.v.units.name, AudioNvolume);
1537 		break;
1538 
1539 	case ARIAMIX_TEL_LVL:
1540 		dip->type = AUDIO_MIXER_VALUE;
1541 		dip->mixer_class = ARIAMIX_INPUT_CLASS;
1542 		dip->next = ARIAMIX_TEL_MUTE;
1543 		strcpy(dip->label.name, "telephone");
1544 		dip->un.v.num_channels = 1;
1545 		strcpy(dip->un.v.units.name, AudioNvolume);
1546 		break;
1547 
1548 	case ARIAMIX_DAC_LVL:
1549 		dip->type = AUDIO_MIXER_VALUE;
1550 		dip->mixer_class = ARIAMIX_INPUT_CLASS;
1551 		dip->next = ARIAMIX_DAC_MUTE;
1552 		strcpy(dip->label.name, AudioNdac);
1553 		dip->un.v.num_channels = 1;
1554 		strcpy(dip->un.v.units.name, AudioNvolume);
1555 		break;
1556 
1557 	case ARIAMIX_AUX_LVL:
1558 		dip->type = AUDIO_MIXER_VALUE;
1559 		dip->mixer_class = ARIAMIX_INPUT_CLASS;
1560 		dip->next = ARIAMIX_AUX_MUTE;
1561 		strcpy(dip->label.name, AudioNoutput);
1562 		dip->un.v.num_channels = 1;
1563 		strcpy(dip->un.v.units.name, AudioNvolume);
1564 		break;
1565 
1566 	case ARIAMIX_MIC_MUTE:
1567 		dip->prev = ARIAMIX_MIC_LVL;
1568 		goto mute;
1569 
1570 	case ARIAMIX_LINE_IN_MUTE:
1571 		dip->prev = ARIAMIX_LINE_IN_LVL;
1572 		goto mute;
1573 
1574 	case ARIAMIX_CD_MUTE:
1575 		dip->prev = ARIAMIX_CD_LVL;
1576 		goto mute;
1577 
1578 	case ARIAMIX_DAC_MUTE:
1579 		dip->prev = ARIAMIX_DAC_LVL;
1580 		goto mute;
1581 
1582 	case ARIAMIX_AUX_MUTE:
1583 		dip->prev = ARIAMIX_AUX_LVL;
1584 		goto mute;
1585 
1586 	case ARIAMIX_TEL_MUTE:
1587 		dip->prev = ARIAMIX_TEL_LVL;
1588 		goto mute;
1589 
1590 mute:
1591 		dip->mixer_class = ARIAMIX_INPUT_CLASS;
1592 		dip->type = AUDIO_MIXER_ENUM;
1593 		strcpy(dip->label.name, AudioNmute);
1594 		dip->un.e.num_mem = 2;
1595 		strcpy(dip->un.e.member[0].label.name, AudioNoff);
1596 		dip->un.e.member[0].ord = 0;
1597 		strcpy(dip->un.e.member[1].label.name, AudioNon);
1598 		dip->un.e.member[1].ord = 1;
1599 		break;
1600 
1601 	case ARIAMIX_MASTER_LVL:
1602 		dip->type = AUDIO_MIXER_VALUE;
1603 		dip->mixer_class = ARIAMIX_OUTPUT_CLASS;
1604 		dip->next = AUDIO_MIXER_LAST;
1605 		strcpy(dip->label.name, AudioNvolume);
1606 		dip->un.v.num_channels = 2;
1607 		strcpy(dip->un.v.units.name, AudioNvolume);
1608 		break;
1609 
1610 	case ARIAMIX_MASTER_TREBLE:
1611 		dip->type = AUDIO_MIXER_VALUE;
1612 		dip->mixer_class = ARIAMIX_EQ_CLASS;
1613 		strcpy(dip->label.name, AudioNtreble);
1614 		dip->un.v.num_channels = 2;
1615 		strcpy(dip->un.v.units.name, AudioNtreble);
1616 		break;
1617 
1618 	case ARIAMIX_MASTER_BASS:
1619 		dip->type = AUDIO_MIXER_VALUE;
1620 		dip->mixer_class = ARIAMIX_EQ_CLASS;
1621 		strcpy(dip->label.name, AudioNbass);
1622 		dip->un.v.num_channels = 2;
1623 		strcpy(dip->un.v.units.name, AudioNbass);
1624 		break;
1625 
1626 	case ARIAMIX_OUT_LVL:
1627 		dip->type = AUDIO_MIXER_VALUE;
1628 		dip->mixer_class = ARIAMIX_OUTPUT_CLASS;
1629 		strcpy(dip->label.name, AudioNoutput);
1630 		dip->un.v.num_channels = 2;
1631 		strcpy(dip->un.v.units.name, AudioNvolume);
1632 		break;
1633 
1634 	case ARIAMIX_RECORD_SOURCE:
1635 		dip->mixer_class = ARIAMIX_RECORD_CLASS;
1636 		dip->type = AUDIO_MIXER_ENUM;
1637 		strcpy(dip->label.name, AudioNsource);
1638 		dip->un.e.num_mem = 6;
1639 		strcpy(dip->un.e.member[0].label.name, AudioNoutput);
1640 		dip->un.e.member[0].ord = ARIAMIX_AUX_LVL;
1641 		strcpy(dip->un.e.member[1].label.name, AudioNmicrophone);
1642 		dip->un.e.member[1].ord = ARIAMIX_MIC_LVL;
1643 		strcpy(dip->un.e.member[2].label.name, AudioNdac);
1644 		dip->un.e.member[2].ord = ARIAMIX_DAC_LVL;
1645 		strcpy(dip->un.e.member[3].label.name, AudioNline);
1646 		dip->un.e.member[3].ord = ARIAMIX_LINE_IN_LVL;
1647 		strcpy(dip->un.e.member[4].label.name, AudioNcd);
1648 		dip->un.e.member[4].ord = ARIAMIX_CD_LVL;
1649 		strcpy(dip->un.e.member[5].label.name, "telephone");
1650 		dip->un.e.member[5].ord = ARIAMIX_TEL_LVL;
1651 		break;
1652 
1653 	case ARIAMIX_INPUT_CLASS:
1654 		dip->type = AUDIO_MIXER_CLASS;
1655 		dip->mixer_class = ARIAMIX_INPUT_CLASS;
1656 		strcpy(dip->label.name, AudioCinputs);
1657 		break;
1658 
1659 	case ARIAMIX_OUTPUT_CLASS:
1660 		dip->type = AUDIO_MIXER_CLASS;
1661 		dip->mixer_class = ARIAMIX_OUTPUT_CLASS;
1662 		strcpy(dip->label.name, AudioCoutputs);
1663 		break;
1664 
1665 	case ARIAMIX_RECORD_CLASS:
1666 		dip->type = AUDIO_MIXER_CLASS;
1667 		dip->mixer_class = ARIAMIX_RECORD_CLASS;
1668 		strcpy(dip->label.name, AudioCrecord);
1669 		break;
1670 
1671 	case ARIAMIX_EQ_CLASS:
1672 		dip->type = AUDIO_MIXER_CLASS;
1673 		dip->mixer_class = ARIAMIX_EQ_CLASS;
1674 		strcpy(dip->label.name, AudioCequalization);
1675 		break;
1676 
1677 	default:
1678 		return ENXIO;
1679 		/*NOTREACHED*/
1680 	}
1681 	return 0;
1682 }
1683