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