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