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