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