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