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