aucc.c revision 1.29 1 /* $NetBSD: aucc.c,v 1.29 2002/01/26 13:40:53 aymeric Exp $ */
2
3 /*
4 * Copyright (c) 1999 Bernardo Innocenti
5 * All rights reserved.
6 *
7 * Copyright (c) 1997 Stephan Thesing
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by Stephan Thesing.
21 * 4. The name of the author may not be used to endorse or promote products
22 * derived from this software without specific prior written permission
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36 /* TODO:
37 *
38 * - ulaw -> 14bit conversion
39 * - channel allocation is wrong for 14bit mono
40 * - convert the... err... conversion routines to 68k asm for best performance
41 * XXX: NO. aucc audio is limited by chipmem speed, anyway. You dont
42 * want to make life difficult for amigappc work.
43 * -is
44 *
45 * - rely on auconv.c routines for ulaw/alaw conversions
46 * - perhaps use a calibration table for better 14bit output
47 * - set 31KHz AGA video mode to allow 44.1KHz even if grfcc is missing
48 * in the kernel
49 * - 14bit output requires maximum volume
50 */
51
52 #include "aucc.h"
53 #if NAUCC > 0
54
55 #include <sys/param.h>
56 #include <sys/systm.h>
57 #include <sys/errno.h>
58 #include <sys/ioctl.h>
59 #include <sys/device.h>
60 #include <sys/proc.h>
61 #include <machine/cpu.h>
62
63 #include <sys/audioio.h>
64 #include <dev/audio_if.h>
65 #include <amiga/amiga/cc.h>
66 #include <amiga/amiga/custom.h>
67 #include <amiga/amiga/device.h>
68 #include <amiga/dev/auccvar.h>
69
70 #include "opt_lev6_defer.h"
71
72
73 #ifdef LEV6_DEFER
74 #define AUCC_MAXINT 3
75 #define AUCC_ALLINTF (INTF_AUD0|INTF_AUD1|INTF_AUD2)
76 #else
77 #define AUCC_MAXINT 4
78 #define AUCC_ALLINTF (INTF_AUD0|INTF_AUD1|INTF_AUD2|INTF_AUD3)
79 #endif
80 /* this unconditionally; we may use AUD3 as slave channel with LEV6_DEFER */
81 #define AUCC_ALLDMAF (DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3)
82
83 #ifdef AUDIO_DEBUG
84 /*extern printf(const char *,...);*/
85 int auccdebug = 1;
86 #define DPRINTF(x) if (auccdebug) printf x
87 #else
88 #define DPRINTF(x)
89 #endif
90
91 #ifdef splaudio
92 #undef splaudio
93 #endif
94
95 #define splaudio() spl4();
96
97 /* clock frequency.. */
98 extern int eclockfreq;
99
100
101 /* hw audio ch */
102 extern struct audio_channel channel[4];
103
104
105 /*
106 * Software state.
107 */
108 struct aucc_softc {
109 struct device sc_dev; /* base device */
110
111 int sc_open; /* single use device */
112 aucc_data_t sc_channel[4]; /* per channel freq, ... */
113 u_int sc_encoding; /* encoding AUDIO_ENCODING_.*/
114 int sc_channels; /* # of channels used */
115 int sc_precision; /* 8 or 16 bits */
116 int sc_14bit; /* 14bit output enabled */
117
118 int sc_intrcnt; /* interrupt count */
119 int sc_channelmask; /* which channels are used ? */
120 void (*sc_decodefunc)(u_char **, u_char *, int);
121 /* pointer to format conversion routine */
122 };
123
124 /* interrupt interfaces */
125 void aucc_inthdl(int);
126
127 /* forward declarations */
128 static int init_aucc(struct aucc_softc *);
129 static u_int freqtoper(u_int);
130 static u_int pertofreq(u_int);
131
132 /* autoconfiguration driver */
133 void auccattach(struct device *, struct device *, void *);
134 int auccmatch(struct device *, struct cfdata *, void *);
135
136 struct cfattach aucc_ca = {
137 sizeof(struct aucc_softc),
138 auccmatch,
139 auccattach
140 };
141
142 struct audio_device aucc_device = {
143 "Amiga-audio",
144 "2.0",
145 "aucc"
146 };
147
148
149 struct aucc_softc *aucc=NULL;
150
151
152 unsigned char ulaw_to_lin[] = {
153 0x82, 0x86, 0x8a, 0x8e, 0x92, 0x96, 0x9a, 0x9e,
154 0xa2, 0xa6, 0xaa, 0xae, 0xb2, 0xb6, 0xba, 0xbe,
155 0xc1, 0xc3, 0xc5, 0xc7, 0xc9, 0xcb, 0xcd, 0xcf,
156 0xd1, 0xd3, 0xd5, 0xd7, 0xd9, 0xdb, 0xdd, 0xdf,
157 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8,
158 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0,
159 0xf0, 0xf1, 0xf1, 0xf2, 0xf2, 0xf3, 0xf3, 0xf4,
160 0xf4, 0xf5, 0xf5, 0xf6, 0xf6, 0xf7, 0xf7, 0xf8,
161 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xfa, 0xfa,
162 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc,
163 0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd,
164 0xfd, 0xfd, 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe,
165 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
166 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
167 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
168 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
169 0x7d, 0x79, 0x75, 0x71, 0x6d, 0x69, 0x65, 0x61,
170 0x5d, 0x59, 0x55, 0x51, 0x4d, 0x49, 0x45, 0x41,
171 0x3e, 0x3c, 0x3a, 0x38, 0x36, 0x34, 0x32, 0x30,
172 0x2e, 0x2c, 0x2a, 0x28, 0x26, 0x24, 0x22, 0x20,
173 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17,
174 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f,
175 0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b,
176 0x0b, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x07,
177 0x07, 0x07, 0x06, 0x06, 0x06, 0x06, 0x05, 0x05,
178 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03,
179 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02,
180 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
181 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
183 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
184 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
185 };
186
187 /*
188 * Define our interface to the higher level audio driver.
189 */
190 int aucc_open(void *, int);
191 void aucc_close(void *);
192 int aucc_set_out_sr(void *, u_long);
193 int aucc_query_encoding(void *, struct audio_encoding *);
194 int aucc_round_blocksize(void *, int);
195 int aucc_commit_settings(void *);
196 int aucc_start_output(void *, void *, int, void (*)(void *), void *);
197 int aucc_start_input(void *, void *, int, void (*)(void *), void *);
198 int aucc_halt_output(void *);
199 int aucc_halt_input(void *);
200 int aucc_getdev(void *, struct audio_device *);
201 int aucc_set_port(void *, mixer_ctrl_t *);
202 int aucc_get_port(void *, mixer_ctrl_t *);
203 int aucc_query_devinfo(void *, mixer_devinfo_t *);
204 void aucc_encode(int, int, int, int, u_char *, u_short **);
205 int aucc_set_params(void *, int, int, struct audio_params *,
206 struct audio_params *);
207 int aucc_get_props(void *);
208
209
210 static void aucc_decode_slinear8_1ch(u_char **, u_char *, int);
211 static void aucc_decode_slinear8_2ch(u_char **, u_char *, int);
212 static void aucc_decode_slinear8_3ch(u_char **, u_char *, int);
213 static void aucc_decode_slinear8_4ch(u_char **, u_char *, int);
214
215 static void aucc_decode_ulinear8_1ch(u_char **, u_char *, int);
216 static void aucc_decode_ulinear8_2ch(u_char **, u_char *, int);
217 static void aucc_decode_ulinear8_3ch(u_char **, u_char *, int);
218 static void aucc_decode_ulinear8_4ch(u_char **, u_char *, int);
219
220 static void aucc_decode_ulaw_1ch(u_char **, u_char *, int);
221 static void aucc_decode_ulaw_2ch(u_char **, u_char *, int);
222 static void aucc_decode_ulaw_3ch(u_char **, u_char *, int);
223 static void aucc_decode_ulaw_4ch(u_char **, u_char *, int);
224
225 static void aucc_decode_slinear16_1ch(u_char **, u_char *, int);
226 static void aucc_decode_slinear16_2ch(u_char **, u_char *, int);
227 static void aucc_decode_slinear16_3ch(u_char **, u_char *, int);
228 static void aucc_decode_slinear16_4ch(u_char **, u_char *, int);
229
230 static void aucc_decode_slinear16sw_1ch(u_char **, u_char *, int);
231 static void aucc_decode_slinear16sw_2ch(u_char **, u_char *, int);
232 static void aucc_decode_slinear16sw_3ch(u_char **, u_char *, int);
233 static void aucc_decode_slinear16sw_4ch(u_char **, u_char *, int);
234
235
236
237 struct audio_hw_if sa_hw_if = {
238 aucc_open,
239 aucc_close,
240 NULL,
241 aucc_query_encoding,
242 aucc_set_params,
243 aucc_round_blocksize,
244 aucc_commit_settings,
245 NULL,
246 NULL,
247 aucc_start_output,
248 aucc_start_input,
249 aucc_halt_output,
250 aucc_halt_input,
251 NULL,
252 aucc_getdev,
253 NULL,
254 aucc_set_port,
255 aucc_get_port,
256 aucc_query_devinfo,
257 NULL,
258 NULL,
259 NULL,
260 NULL,
261 aucc_get_props,
262 NULL,
263 NULL,
264 NULL,
265 };
266
267 /* autoconfig routines */
268
269 int
270 auccmatch(struct device *pdp, struct cfdata *cfp, void *aux)
271 {
272 static int aucc_matched = 0;
273
274 if (!matchname((char *)aux, "aucc") ||
275 #ifdef DRACO
276 is_draco() ||
277 #endif
278 aucc_matched)
279 return 0;
280
281 aucc_matched = 1;
282 return 1;
283 }
284
285 /*
286 * Audio chip found.
287 */
288 void
289 auccattach(struct device *parent, struct device *self, void *args)
290 {
291 register struct aucc_softc *sc = (struct aucc_softc *)self;
292 register int i;
293
294 printf("\n");
295
296 if((i=init_aucc(sc))) {
297 printf("audio: no chipmem\n");
298 return;
299 }
300
301 audio_attach_mi(&sa_hw_if, sc, &sc->sc_dev);
302 }
303
304
305 static int
306 init_aucc(struct aucc_softc *sc)
307 {
308 register int i, err=0;
309
310 /* init values per channel */
311 for (i=0;i<4;i++) {
312 sc->sc_channel[i].nd_freq=8000;
313 sc->sc_channel[i].nd_per=freqtoper(8000);
314 sc->sc_channel[i].nd_busy=0;
315 sc->sc_channel[i].nd_dma=alloc_chipmem(AUDIO_BUF_SIZE*2);
316 if (sc->sc_channel[i].nd_dma==NULL)
317 err=1;
318 sc->sc_channel[i].nd_dmalength=0;
319 sc->sc_channel[i].nd_volume=64;
320 sc->sc_channel[i].nd_intr=NULL;
321 sc->sc_channel[i].nd_intrdata=NULL;
322 sc->sc_channel[i].nd_doublebuf=0;
323 DPRINTF(("dma buffer for channel %d is %p\n", i,
324 sc->sc_channel[i].nd_dma));
325 }
326
327 if (err) {
328 for(i=0;i<4;i++)
329 if (sc->sc_channel[i].nd_dma)
330 free_chipmem(sc->sc_channel[i].nd_dma);
331 }
332
333 sc->sc_channels=1;
334 sc->sc_channelmask=0xf;
335 sc->sc_precision=8;
336 sc->sc_14bit = 0;
337 sc->sc_encoding=AUDIO_ENCODING_ULAW;
338 sc->sc_decodefunc = aucc_decode_ulaw_1ch;
339
340 /* clear interrupts and dma: */
341 custom.intena = AUCC_ALLINTF;
342 custom.dmacon = AUCC_ALLDMAF;
343
344 return err;
345 }
346
347 int
348 aucc_open(void *addr, int flags)
349 {
350 struct aucc_softc *sc = addr;
351 int i;
352
353 DPRINTF(("sa_open: unit %p\n",sc));
354
355 if (sc->sc_open)
356 return (EBUSY);
357 sc->sc_open = 1;
358 for (i=0;i<AUCC_MAXINT;i++) {
359 sc->sc_channel[i].nd_intr=NULL;
360 sc->sc_channel[i].nd_intrdata=NULL;
361 }
362 aucc=sc;
363 sc->sc_channelmask=0xf;
364
365 DPRINTF(("saopen: ok -> sc=0x%p\n",sc));
366
367 return (0);
368 }
369
370 void
371 aucc_close(void *addr)
372 {
373 register struct aucc_softc *sc = addr;
374
375 DPRINTF(("sa_close: sc=0x%p\n", sc));
376 /*
377 * halt i/o, clear open flag, and done.
378 */
379 aucc_halt_output(sc);
380 sc->sc_open = 0;
381
382 DPRINTF(("sa_close: closed.\n"));
383 }
384
385 int
386 aucc_set_out_sr(void *addr, u_long sr)
387 {
388 struct aucc_softc *sc=addr;
389 u_long per;
390 register int i;
391
392 per=freqtoper(sr);
393 if (per>0xffff)
394 return EINVAL;
395 sr=pertofreq(per);
396
397 for (i=0;i<4;i++) {
398 sc->sc_channel[i].nd_freq=sr;
399 sc->sc_channel[i].nd_per=per;
400 }
401
402 return(0);
403 }
404
405 int
406 aucc_query_encoding(void *addr, struct audio_encoding *fp)
407 {
408 switch (fp->index) {
409 case 0:
410 strcpy(fp->name, AudioEslinear);
411 fp->encoding = AUDIO_ENCODING_SLINEAR;
412 fp->precision = 8;
413 fp->flags = 0;
414 break;
415 case 1:
416 strcpy(fp->name, AudioEmulaw);
417 fp->encoding = AUDIO_ENCODING_ULAW;
418 fp->precision = 8;
419 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
420 break;
421
422 case 2:
423 strcpy(fp->name, AudioEulinear);
424 fp->encoding = AUDIO_ENCODING_ULINEAR;
425 fp->precision = 8;
426 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
427 break;
428
429 case 3:
430 strcpy(fp->name, AudioEslinear);
431 fp->encoding = AUDIO_ENCODING_SLINEAR;
432 fp->precision = 16;
433 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
434 break;
435
436 case 4:
437 strcpy(fp->name, AudioEslinear_be);
438 fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
439 fp->precision = 16;
440 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
441 break;
442
443 case 5:
444 strcpy(fp->name, AudioEslinear_le);
445 fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
446 fp->precision = 16;
447 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
448 break;
449
450 default:
451 return(EINVAL);
452 /*NOTREACHED*/
453 }
454 return(0);
455 }
456
457 int
458 aucc_set_params(void *addr, int setmode, int usemode, struct audio_params *p,
459 struct audio_params *r)
460 {
461 struct aucc_softc *sc = addr;
462
463 /* if (setmode & AUMODE_RECORD)
464 return 0 ENXIO*/;
465
466 #ifdef AUCCDEBUG
467 printf("aucc_set_params(setmode 0x%x, usemode 0x%x, "
468 "enc %d, bits %d, chn %d, sr %ld)\n", setmode, usemode,
469 p->encoding, p->precision, p->channels, p->sample_rate);
470 #endif
471
472 switch (p->precision) {
473 case 8:
474 switch (p->encoding) {
475 case AUDIO_ENCODING_ULAW:
476 switch (p->channels) {
477 case 1:
478 sc->sc_decodefunc = aucc_decode_ulaw_1ch;
479 break;
480 case 2:
481 sc->sc_decodefunc = aucc_decode_ulaw_2ch;
482 break;
483 case 3:
484 sc->sc_decodefunc = aucc_decode_ulaw_3ch;
485 break;
486 case 4:
487 sc->sc_decodefunc = aucc_decode_ulaw_4ch;
488 break;
489 default:
490 return EINVAL;
491 }
492 break;
493
494 case AUDIO_ENCODING_SLINEAR:
495 case AUDIO_ENCODING_SLINEAR_BE:
496 case AUDIO_ENCODING_SLINEAR_LE:
497 switch (p->channels) {
498 case 1:
499 sc->sc_decodefunc = aucc_decode_slinear8_1ch;
500 break;
501 case 2:
502 sc->sc_decodefunc = aucc_decode_slinear8_2ch;
503 break;
504 case 3:
505 sc->sc_decodefunc = aucc_decode_slinear8_3ch;
506 break;
507 case 4:
508 sc->sc_decodefunc = aucc_decode_slinear8_4ch;
509 break;
510 default:
511 return EINVAL;
512 }
513 break;
514
515 case AUDIO_ENCODING_ULINEAR:
516 case AUDIO_ENCODING_ULINEAR_BE:
517 case AUDIO_ENCODING_ULINEAR_LE:
518 switch (p->channels) {
519 case 1:
520 sc->sc_decodefunc = aucc_decode_ulinear8_1ch;
521 break;
522 case 2:
523 sc->sc_decodefunc = aucc_decode_ulinear8_2ch;
524 break;
525 case 3:
526 sc->sc_decodefunc = aucc_decode_ulinear8_3ch;
527 break;
528 case 4:
529 sc->sc_decodefunc = aucc_decode_ulinear8_4ch;
530 break;
531 default:
532 return EINVAL;
533 }
534 break;
535
536 default:
537 return EINVAL;
538 }
539 break;
540
541 case 16:
542 switch (p->encoding) {
543 #if BYTE_ORDER == BIG_ENDIAN
544 case AUDIO_ENCODING_SLINEAR:
545 #endif
546 case AUDIO_ENCODING_SLINEAR_BE:
547 switch (p->channels) {
548 case 1:
549 sc->sc_decodefunc = aucc_decode_slinear16_1ch;
550 break;
551
552 case 2:
553 sc->sc_decodefunc = aucc_decode_slinear16_2ch;
554 break;
555 case 3:
556 sc->sc_decodefunc = aucc_decode_slinear16_3ch;
557 break;
558 case 4:
559 sc->sc_decodefunc = aucc_decode_slinear16_4ch;
560 break;
561 default:
562 return EINVAL;
563 }
564 break;
565
566 #if BYTE_ORDER == LITTLE_ENDIAN
567 case AUDIO_ENCODING_SLINEAR:
568 #endif
569 case AUDIO_ENCODING_SLINEAR_LE:
570 switch (p->channels) {
571 case 1:
572 sc->sc_decodefunc = aucc_decode_slinear16sw_1ch;
573 break;
574 case 2:
575 sc->sc_decodefunc = aucc_decode_slinear16sw_2ch;
576 break;
577 case 3:
578 sc->sc_decodefunc = aucc_decode_slinear16sw_3ch;
579 break;
580 case 4:
581 sc->sc_decodefunc = aucc_decode_slinear16sw_4ch;
582 break;
583 default:
584 return EINVAL;
585 }
586 break;
587
588 default:
589 return EINVAL;
590 }
591 break;
592
593 default:
594 return EINVAL;
595 }
596
597 sc->sc_encoding = p->encoding;
598 sc->sc_precision = p->precision;
599 sc->sc_14bit = ((p->precision == 16) && (p->channels <= 2));
600 sc->sc_channels = sc->sc_14bit ? (p->channels * 2) : p->channels;
601
602 return aucc_set_out_sr(addr, p->sample_rate);
603 }
604
605 int
606 aucc_round_blocksize(void *addr, int blk)
607 {
608 /* round up to even size */
609 return blk > AUDIO_BUF_SIZE ? AUDIO_BUF_SIZE : blk;
610 }
611
612 int
613 aucc_commit_settings(void *addr)
614 {
615 register struct aucc_softc *sc = addr;
616 register int i;
617
618 DPRINTF(("sa_commit.\n"));
619
620 for (i=0;i<4;i++) {
621 custom.aud[i].vol=sc->sc_channel[i].nd_volume;
622 custom.aud[i].per=sc->sc_channel[i].nd_per;
623 }
624
625 DPRINTF(("commit done\n"));
626
627 return(0);
628 }
629
630 static int masks[4] = {1,3,7,15}; /* masks for n first channels */
631 static int masks2[4] = {1,2,4,8};
632
633 int
634 aucc_start_output(void *addr, void *p, int cc, void (*intr)(void *), void *arg)
635 {
636 struct aucc_softc *sc;
637 int mask;
638 int i, j, k, len;
639 u_char *dmap[4];
640
641
642 sc = addr;
643 mask = sc->sc_channelmask;
644
645 dmap[0] = dmap[1] = dmap[2] = dmap[3] = NULL;
646
647 DPRINTF(("sa_start_output: cc=%d %p (%p)\n", cc, intr, arg));
648
649 if (sc->sc_channels > 1)
650 mask &= masks[sc->sc_channels - 1];
651 /* we use first sc_channels channels */
652 if (mask == 0) /* active and used channels are disjoint */
653 return EINVAL;
654
655 for (i=0;i<4;i++) {
656 /* channels available ? */
657 if ((masks2[i] & mask) && (sc->sc_channel[i].nd_busy))
658 return EBUSY; /* channel is busy */
659 if (channel[i].isaudio == -1)
660 return EBUSY; /* system uses them */
661 }
662
663 /* enable interrupt on 1st channel */
664 for (i = j = 0; i < AUCC_MAXINT; i++) {
665 if (masks2[i] & mask) {
666 DPRINTF(("first channel is %d\n",i));
667 j=i;
668 sc->sc_channel[i].nd_intr=intr;
669 sc->sc_channel[i].nd_intrdata=arg;
670 break;
671 }
672 }
673
674 DPRINTF(("dmap is %p %p %p %p, mask=0x%x\n", dmap[0], dmap[1],
675 dmap[2], dmap[3], mask));
676
677 /* disable ints, dma for channels, until all parameters set */
678 /* XXX dont disable DMA! custom.dmacon=mask;*/
679 custom.intreq = mask << INTB_AUD0;
680 custom.intena = mask << INTB_AUD0;
681
682 /* copy data to dma buffer */
683
684 if (sc->sc_channels == 1) {
685 dmap[0] =
686 dmap[1] =
687 dmap[2] =
688 dmap[3] = (u_char *)sc->sc_channel[j].nd_dma;
689 }
690 else {
691 for (k=0; k<4; k++) {
692 if (masks2[k+j] & mask)
693 dmap[k] = (u_char *)sc->sc_channel[k+j].nd_dma;
694 }
695 }
696
697 sc->sc_channel[j].nd_doublebuf ^= 1;
698 if (sc->sc_channel[j].nd_doublebuf) {
699 dmap[0] += AUDIO_BUF_SIZE;
700 dmap[1] += AUDIO_BUF_SIZE;
701 dmap[2] += AUDIO_BUF_SIZE;
702 dmap[3] += AUDIO_BUF_SIZE;
703 }
704
705 /* compute output length in bytes per channel.
706 * divide by two only for 16bit->8bit conversion.
707 */
708 len = cc / sc->sc_channels;
709 if (!sc->sc_14bit && (sc->sc_precision == 16))
710 len /= 2;
711
712 /* call audio decoding routine */
713 sc->sc_decodefunc (dmap, (u_char *)p, len);
714
715 /* dma buffers: we use same buffer 4 all channels
716 * write dma location and length
717 */
718 for (i = k = 0; i < 4; i++) {
719 if (masks2[i] & mask) {
720 DPRINTF(("turning channel %d on\n",i));
721 /* sc->sc_channel[i].nd_busy=1; */
722 channel[i].isaudio = 1;
723 channel[i].play_count = 1;
724 channel[i].handler = NULL;
725 custom.aud[i].per = sc->sc_channel[i].nd_per;
726 if (sc->sc_14bit && (i > 1))
727 custom.aud[i].vol = 1;
728 else
729 custom.aud[i].vol = sc->sc_channel[i].nd_volume;
730 custom.aud[i].lc = PREP_DMA_MEM(dmap[k++]);
731 custom.aud[i].len = len / 2;
732 sc->sc_channel[i].nd_mask = mask;
733 DPRINTF(("per is %d, vol is %d, len is %d\n",\
734 sc->sc_channel[i].nd_per,
735 sc->sc_channel[i].nd_volume, len));
736 }
737 }
738
739 channel[j].handler=aucc_inthdl;
740
741 /* enable ints */
742 custom.intena = INTF_SETCLR | INTF_INTEN | (masks2[j] << INTB_AUD0);
743
744 DPRINTF(("enabled ints: 0x%x\n", (masks2[j] << INTB_AUD0)));
745
746 /* enable dma */
747 custom.dmacon = DMAF_SETCLR | DMAF_MASTER | mask;
748
749 DPRINTF(("enabled dma, mask=0x%x\n",mask));
750
751 return(0);
752 }
753
754 /* ARGSUSED */
755 int
756 aucc_start_input(void *addr, void *p, int cc, void (*intr)(void *), void *arg)
757 {
758
759 return ENXIO; /* no input */
760 }
761
762 int
763 aucc_halt_output(void *addr)
764 {
765 register struct aucc_softc *sc = addr;
766 register int i;
767
768 /* XXX only halt, if input is also halted ?? */
769 /* stop dma, etc */
770 custom.intena = AUCC_ALLINTF;
771 custom.dmacon = AUCC_ALLDMAF;
772 /* mark every busy unit idle */
773 for (i=0;i<4;i++) {
774 sc->sc_channel[i].nd_busy=sc->sc_channel[i].nd_mask=0;
775 channel[i].isaudio=0;
776 channel[i].play_count=0;
777 }
778
779 return(0);
780 }
781
782 int
783 aucc_halt_input(void *addr)
784 {
785 /* no input */
786
787 return ENXIO;
788 }
789
790 int
791 aucc_getdev(void *addr, struct audio_device *retp)
792 {
793 *retp = aucc_device;
794 return 0;
795 }
796
797 int
798 aucc_set_port(void *addr, mixer_ctrl_t *cp)
799 {
800 register struct aucc_softc *sc = addr;
801 register int i,j;
802
803 DPRINTF(("aucc_set_port: port=%d", cp->dev));
804
805 switch (cp->type) {
806 case AUDIO_MIXER_SET:
807 if (cp->dev!=AUCC_CHANNELS)
808 return EINVAL;
809 i=cp->un.mask;
810 if ((i<1) || (i>15))
811 return EINVAL;
812
813 sc->sc_channelmask=i;
814 break;
815
816 case AUDIO_MIXER_VALUE:
817 i=cp->un.value.num_channels;
818 if ((i<1) || (i>4))
819 return EINVAL;
820
821 #ifdef __XXXwhatsthat
822 if (cp->dev!=AUCC_VOLUME)
823 return EINVAL;
824 #endif
825
826 /* set volume for channel 0..i-1 */
827
828 /* evil workaround for xanim bug, IMO */
829 if ((sc->sc_channels == 1) && (i == 2)) {
830 sc->sc_channel[0].nd_volume =
831 sc->sc_channel[3].nd_volume =
832 cp->un.value.level[0]>>2;
833 sc->sc_channel[1].nd_volume =
834 sc->sc_channel[2].nd_volume =
835 cp->un.value.level[1]>>2;
836 } else if (i>1) {
837 for (j=0;j<i;j++)
838 sc->sc_channel[j].nd_volume =
839 cp->un.value.level[j]>>2;
840 } else if (sc->sc_channels > 1)
841 for (j=0; j<sc->sc_channels; j++)
842 sc->sc_channel[j].nd_volume =
843 cp->un.value.level[0]>>2;
844 else
845 for (j=0; j<4; j++)
846 sc->sc_channel[j].nd_volume =
847 cp->un.value.level[0]>>2;
848 break;
849
850 default:
851 return EINVAL;
852 break;
853 }
854 return 0;
855 }
856
857
858 int
859 aucc_get_port(void *addr, mixer_ctrl_t *cp)
860 {
861 register struct aucc_softc *sc = addr;
862 register int i,j;
863
864 DPRINTF(("aucc_get_port: port=%d", cp->dev));
865
866 switch (cp->type) {
867 case AUDIO_MIXER_SET:
868 if (cp->dev!=AUCC_CHANNELS)
869 return EINVAL;
870 cp->un.mask=sc->sc_channelmask;
871 break;
872
873 case AUDIO_MIXER_VALUE:
874 i = cp->un.value.num_channels;
875 if ((i<1)||(i>4))
876 return EINVAL;
877
878 for (j=0;j<i;j++)
879 cp->un.value.level[j] =
880 (sc->sc_channel[j].nd_volume<<2) +
881 (sc->sc_channel[j].nd_volume>>4);
882 break;
883
884 default:
885 return EINVAL;
886 }
887 return 0;
888 }
889
890
891 int
892 aucc_get_props(void *addr)
893 {
894 return 0;
895 }
896
897 int
898 aucc_query_devinfo(void *addr, register mixer_devinfo_t *dip)
899 {
900 register int i;
901
902 switch(dip->index) {
903 case AUCC_CHANNELS:
904 dip->type = AUDIO_MIXER_SET;
905 dip->mixer_class = AUCC_OUTPUT_CLASS;
906 dip->prev = dip->next = AUDIO_MIXER_LAST;
907 strcpy(dip->label.name, AudioNspeaker);
908 for (i=0;i<16;i++) {
909 sprintf(dip->un.s.member[i].label.name,
910 "channelmask%d", i);
911 dip->un.s.member[i].mask = i;
912 }
913 dip->un.s.num_mem = 16;
914 break;
915
916 case AUCC_VOLUME:
917 dip->type = AUDIO_MIXER_VALUE;
918 dip->mixer_class = AUCC_OUTPUT_CLASS;
919 dip->prev = dip->next = AUDIO_MIXER_LAST;
920 strcpy(dip->label.name, AudioNmaster);
921 dip->un.v.num_channels = 4;
922 strcpy(dip->un.v.units.name, AudioNvolume);
923 break;
924
925 case AUCC_OUTPUT_CLASS:
926 dip->type = AUDIO_MIXER_CLASS;
927 dip->mixer_class = AUCC_OUTPUT_CLASS;
928 dip->next = dip->prev = AUDIO_MIXER_LAST;
929 strcpy(dip->label.name, AudioCoutputs);
930 break;
931
932 default:
933 return ENXIO;
934 }
935
936 DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
937
938 return(0);
939 }
940
941
942 /* audio int handler */
943 void
944 aucc_inthdl(int ch)
945 {
946 register int i;
947 register int mask=aucc->sc_channel[ch].nd_mask;
948
949 /* for all channels in this maskgroup:
950 disable dma, int
951 mark idle */
952 DPRINTF(("inthandler called, channel %d, mask 0x%x\n",ch,mask));
953
954 custom.intreq=mask<<INTB_AUD0; /* clear request */
955 /*
956 * XXX: maybe we can leave ints and/or DMA on,
957 * if another sample has to be played?
958 */
959 custom.intena=mask<<INTB_AUD0;
960 /*
961 * XXX custom.dmacon=mask; NO!!!
962 */
963 for (i=0; i<4; i++) {
964 if (masks2[i]&&mask) {
965 DPRINTF(("marking channel %d idle\n",i));
966 aucc->sc_channel[i].nd_busy=0;
967 aucc->sc_channel[i].nd_mask=0;
968 channel[i].isaudio=channel[i].play_count=0;
969 }
970 }
971
972 /* call handler */
973 if (aucc->sc_channel[ch].nd_intr) {
974 DPRINTF(("calling %p\n",aucc->sc_channel[ch].nd_intr));
975 (*(aucc->sc_channel[ch].nd_intr))
976 (aucc->sc_channel[ch].nd_intrdata);
977 }
978 else
979 DPRINTF(("zero int handler\n"));
980 DPRINTF(("ints done\n"));
981 }
982
983
984
985
986 /* transform frequency to period, adjust bounds */
987 static u_int
988 freqtoper(u_int freq)
989 {
990 u_int per=eclockfreq*5/freq;
991
992 if (per<124)
993 per=124; /* must have at least 124 ticks between samples */
994
995 return per;
996 }
997
998 /* transform period to frequency */
999 static u_int
1000 pertofreq(u_int per)
1001 {
1002 u_int freq=eclockfreq*5/per;
1003
1004 return freq;
1005 }
1006
1007 static void
1008 aucc_decode_slinear8_1ch(u_char **dmap, u_char *p, int i)
1009 {
1010 memcpy (dmap[0], p, i);
1011 }
1012
1013 static void
1014 aucc_decode_slinear8_2ch(u_char **dmap, u_char *p, int i)
1015 {
1016 u_char *ch0 = dmap[0];
1017 u_char *ch1 = dmap[1];
1018
1019 while (i--) {
1020 *ch0++ = *p++;
1021 *ch1++ = *p++;
1022 }
1023 }
1024
1025 static void
1026 aucc_decode_slinear8_3ch(u_char **dmap, u_char *p, int i)
1027 {
1028 u_char *ch0 = dmap[0];
1029 u_char *ch1 = dmap[1];
1030 u_char *ch2 = dmap[2];
1031
1032 while (i--) {
1033 *ch0++ = *p++;
1034 *ch1++ = *p++;
1035 *ch2++ = *p++;
1036 }
1037 }
1038
1039 static void
1040 aucc_decode_slinear8_4ch(u_char **dmap, u_char *p, int i)
1041 {
1042 u_char *ch0 = dmap[0];
1043 u_char *ch1 = dmap[1];
1044 u_char *ch2 = dmap[2];
1045 u_char *ch3 = dmap[3];
1046
1047 while (i--) {
1048 *ch0++ = *p++;
1049 *ch1++ = *p++;
1050 *ch2++ = *p++;
1051 *ch3++ = *p++;
1052 }
1053 }
1054
1055 static void
1056 aucc_decode_ulinear8_1ch(u_char **dmap, u_char *p, int i)
1057 {
1058 u_char *ch0 = dmap[0];
1059
1060 while (i--)
1061 *ch0++ = *p++ - 128;
1062 }
1063
1064 static void
1065 aucc_decode_ulinear8_2ch(u_char **dmap, u_char *p, int i)
1066 {
1067 u_char *ch0 = dmap[0];
1068 u_char *ch1 = dmap[1];
1069
1070 while (i--) {
1071 *ch0++ = *p++ - 128;
1072 *ch1++ = *p++ - 128;
1073 }
1074 }
1075
1076 static void
1077 aucc_decode_ulinear8_3ch(u_char **dmap, u_char *p, int i)
1078 {
1079 u_char *ch0 = dmap[0];
1080 u_char *ch1 = dmap[1];
1081 u_char *ch2 = dmap[2];
1082
1083 while (i--) {
1084 *ch0++ = *p++ - 128;
1085 *ch1++ = *p++ - 128;
1086 *ch2++ = *p++ - 128;
1087 }
1088 }
1089
1090 static void
1091 aucc_decode_ulinear8_4ch(u_char **dmap, u_char *p, int i)
1092 {
1093 u_char *ch0 = dmap[0];
1094 u_char *ch1 = dmap[1];
1095 u_char *ch2 = dmap[2];
1096 u_char *ch3 = dmap[3];
1097
1098 while (i--) {
1099 *ch0++ = *p++ - 128;
1100 *ch1++ = *p++ - 128;
1101 *ch2++ = *p++ - 128;
1102 *ch3++ = *p++ - 128;
1103 }
1104 }
1105
1106
1107 static void
1108 aucc_decode_ulaw_1ch(u_char **dmap, u_char *p, int i)
1109 {
1110 u_char *ch0 = dmap[0];
1111
1112 while (i--)
1113 *ch0++ = ulaw_to_lin[*p++];
1114 }
1115
1116 static void
1117 aucc_decode_ulaw_2ch(u_char **dmap, u_char *p, int i)
1118 {
1119 u_char *ch0 = dmap[0];
1120 u_char *ch1 = dmap[1];
1121
1122 while (i--) {
1123 *ch0++ = ulaw_to_lin[*p++];
1124 *ch1++ = ulaw_to_lin[*p++];
1125 }
1126 }
1127
1128 static void
1129 aucc_decode_ulaw_3ch(u_char **dmap, u_char *p, int i)
1130 {
1131 u_char *ch0 = dmap[0];
1132 u_char *ch1 = dmap[1];
1133 u_char *ch2 = dmap[2];
1134
1135 while (i--) {
1136 *ch0++ = ulaw_to_lin[*p++];
1137 *ch1++ = ulaw_to_lin[*p++];
1138 *ch2++ = ulaw_to_lin[*p++];
1139 }
1140 }
1141
1142 static void
1143 aucc_decode_ulaw_4ch(u_char **dmap, u_char *p, int i)
1144 {
1145 u_char *ch0 = dmap[0];
1146 u_char *ch1 = dmap[1];
1147 u_char *ch2 = dmap[2];
1148 u_char *ch3 = dmap[3];
1149
1150 while (i--) {
1151 *ch0++ = ulaw_to_lin[*p++];
1152 *ch1++ = ulaw_to_lin[*p++];
1153 *ch2++ = ulaw_to_lin[*p++];
1154 *ch3++ = ulaw_to_lin[*p++];
1155 }
1156 }
1157
1158
1159 /* 14bit output */
1160 static void
1161 aucc_decode_slinear16_1ch(u_char **dmap, u_char *p, int i)
1162 {
1163 u_char *ch0 = dmap[0];
1164 u_char *ch3 = dmap[1]; /* XXX should be 3 */
1165
1166 while (i--) {
1167 *ch0++ = *p++;
1168 *ch3++ = *p++ >> 2;
1169 }
1170 }
1171
1172 /* 14bit stereo output */
1173 static void
1174 aucc_decode_slinear16_2ch(u_char **dmap, u_char *p, int i)
1175 {
1176 u_char *ch0 = dmap[0];
1177 u_char *ch1 = dmap[1];
1178 u_char *ch2 = dmap[2];
1179 u_char *ch3 = dmap[3];
1180
1181 while (i--) {
1182 *ch0++ = *p++;
1183 *ch3++ = *p++ >> 2;
1184 *ch1++ = *p++;
1185 *ch2++ = *p++ >> 2;
1186 }
1187 }
1188
1189 static void
1190 aucc_decode_slinear16_3ch(u_char **dmap, u_char *p, int i)
1191 {
1192 u_char *ch0 = dmap[0];
1193 u_char *ch1 = dmap[1];
1194 u_char *ch2 = dmap[2];
1195
1196 while (i--) {
1197 *ch0++ = *p++; p++;
1198 *ch1++ = *p++; p++;
1199 *ch2++ = *p++; p++;
1200 }
1201 }
1202
1203 static void
1204 aucc_decode_slinear16_4ch(u_char **dmap, u_char *p, int i)
1205 {
1206 u_char *ch0 = dmap[0];
1207 u_char *ch1 = dmap[1];
1208 u_char *ch2 = dmap[2];
1209 u_char *ch3 = dmap[3];
1210
1211 while (i--) {
1212 *ch0++ = *p++; p++;
1213 *ch1++ = *p++; p++;
1214 *ch2++ = *p++; p++;
1215 *ch3++ = *p++; p++;
1216 }
1217 }
1218
1219 /* 14bit output, swap bytes */
1220 static void
1221 aucc_decode_slinear16sw_1ch(u_char **dmap, u_char *p, int i)
1222 {
1223 u_char *ch0 = dmap[0];
1224 u_char *ch3 = dmap[1]; /* XXX should be 3 */
1225
1226 while (i--) {
1227 *ch3++ = *p++ >> 2;
1228 *ch0++ = *p++;
1229 }
1230 }
1231
1232 static void
1233 aucc_decode_slinear16sw_2ch(u_char **dmap, u_char *p, int i)
1234 {
1235 u_char *ch0 = dmap[0];
1236 u_char *ch1 = dmap[1];
1237 u_char *ch2 = dmap[2];
1238 u_char *ch3 = dmap[3];
1239
1240 while (i--) {
1241 *ch3++ = *p++ >> 2;
1242 *ch0++ = *p++;
1243 *ch2++ = *p++ >> 2;
1244 *ch1++ = *p++;
1245 }
1246 }
1247
1248 static void
1249 aucc_decode_slinear16sw_3ch(u_char **dmap, u_char *p, int i)
1250 {
1251 u_char *ch0 = dmap[0];
1252 u_char *ch1 = dmap[1];
1253 u_char *ch2 = dmap[2];
1254
1255 while (i--) {
1256 p++; *ch0++ = *p++;
1257 p++; *ch1++ = *p++;
1258 p++; *ch2++ = *p++;
1259 }
1260 }
1261
1262 static void
1263 aucc_decode_slinear16sw_4ch(u_char **dmap, u_char *p, int i)
1264 {
1265 u_char *ch0 = dmap[0];
1266 u_char *ch1 = dmap[1];
1267 u_char *ch2 = dmap[2];
1268 u_char *ch3 = dmap[3];
1269
1270 while (i--) {
1271 p++; *ch0++ = *p++;
1272 p++; *ch1++ = *p++;
1273 p++; *ch2++ = *p++;
1274 p++; *ch3++ = *p++;
1275 }
1276 }
1277
1278
1279 #endif /* NAUCC > 0 */
1280