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