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