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