Annotation of sys/dev/isa/ad1848.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: ad1848.c,v 1.32 2005/05/22 19:40:51 art Exp $ */
2: /* $NetBSD: ad1848.c,v 1.45 1998/01/30 02:02:38 augustss Exp $ */
3:
4: /*
5: * Copyright (c) 1994 John Brezak
6: * Copyright (c) 1991-1993 Regents of the University of California.
7: * All rights reserved.
8: *
9: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: * 1. Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
14: * 2. Redistributions in binary form must reproduce the above copyright
15: * notice, this list of conditions and the following disclaimer in the
16: * documentation and/or other materials provided with the distribution.
17: * 3. All advertising materials mentioning features or use of this software
18: * must display the following acknowledgement:
19: * This product includes software developed by the Computer Systems
20: * Engineering Group at Lawrence Berkeley Laboratory.
21: * 4. Neither the name of the University nor of the Laboratory may be used
22: * to endorse or promote products derived from this software without
23: * specific prior written permission.
24: *
25: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35: * SUCH DAMAGE.
36: *
37: */
38:
39: /*
40: * Copyright by Hannu Savolainen 1994
41: *
42: * Redistribution and use in source and binary forms, with or without
43: * modification, are permitted provided that the following conditions are
44: * met: 1. Redistributions of source code must retain the above copyright
45: * notice, this list of conditions and the following disclaimer. 2.
46: * Redistributions in binary form must reproduce the above copyright notice,
47: * this list of conditions and the following disclaimer in the documentation
48: * and/or other materials provided with the distribution.
49: *
50: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
51: * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
52: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
53: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
54: * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
56: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
57: * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
58: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
59: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
60: * SUCH DAMAGE.
61: *
62: */
63: /*
64: * Portions of this code are from the VOXware support for the ad1848
65: * by Hannu Savolainen <hannu@voxware.pp.fi>
66: *
67: * Portions also supplied from the SoundBlaster driver for NetBSD.
68: */
69:
70: #include <sys/param.h>
71: #include <sys/systm.h>
72: #include <sys/errno.h>
73: #include <sys/ioctl.h>
74: #include <sys/syslog.h>
75: #include <sys/device.h>
76: #include <sys/proc.h>
77: #include <sys/buf.h>
78:
79: #include <machine/cpu.h>
80: #include <machine/bus.h>
81:
82: #include <sys/audioio.h>
83:
84: #include <dev/audio_if.h>
85: #include <dev/auconv.h>
86:
87: #include <dev/isa/isavar.h>
88: #include <dev/isa/isadmavar.h>
89:
90: #include <dev/ic/ad1848reg.h>
91: #include <dev/ic/cs4231reg.h>
92: #include <dev/isa/ad1848var.h>
93: #include <dev/isa/cs4231var.h>
94:
95: #ifdef AUDIO_DEBUG
96: #define DPRINTF(x) if (ad1848debug) printf x
97: int ad1848debug = 0;
98: #else
99: #define DPRINTF(x)
100: #endif
101:
102: /*
103: * Initial values for the indirect registers of CS4248/AD1848.
104: */
105: static int ad1848_init_values[] = {
106: /* Left Input Control */
107: GAIN_12|INPUT_MIC_GAIN_ENABLE,
108: /* Right Input Control */
109: GAIN_12|INPUT_MIC_GAIN_ENABLE,
110: ATTEN_12, /* Left Aux #1 Input Control */
111: ATTEN_12, /* Right Aux #1 Input Control */
112: ATTEN_12, /* Left Aux #2 Input Control */
113: ATTEN_12, /* Right Aux #2 Input Control */
114: /* bits 5-0 are attenuation select */
115: ATTEN_12, /* Left DAC output Control */
116: ATTEN_12, /* Right DAC output Control */
117: /* Clock and Data Format */
118: CLOCK_XTAL1|FMT_PCM8,
119: /* Interface Config */
120: SINGLE_DMA|AUTO_CAL_ENABLE,
121: INTERRUPT_ENABLE, /* Pin control */
122: 0x00, /* Test and Init */
123: MODE2, /* Misc control */
124: ATTEN_0<<2, /* Digital Mix Control */
125: 0, /* Upper base Count */
126: 0, /* Lower base Count */
127:
128: /* These are for CS4231 &c. only (additional registers): */
129: 0, /* Alt feature 1 */
130: 0, /* Alt feature 2 */
131: ATTEN_12, /* Left line in */
132: ATTEN_12, /* Right line in */
133: 0, /* Timer low */
134: 0, /* Timer high */
135: 0, /* unused */
136: 0, /* unused */
137: 0, /* IRQ status */
138: 0, /* unused */
139: /* Mono input (a.k.a speaker) (mic) Control */
140: MONO_INPUT_MUTE|ATTEN_6, /* mute speaker by default */
141: 0, /* unused */
142: 0, /* record format */
143: 0, /* Crystal Clock Select */
144: 0, /* upper record count */
145: 0 /* lower record count */
146: };
147:
148: void ad1848_reset(struct ad1848_softc *);
149: int ad1848_set_speed(struct ad1848_softc *, u_long *);
150: void ad1848_mute_monitor(void *, int);
151:
152: static int ad_read(struct ad1848_softc *, int);
153: static void ad_write(struct ad1848_softc *, int, int);
154: static void ad_set_MCE(struct ad1848_softc *, int);
155: static void wait_for_calibration(struct ad1848_softc *);
156:
157: #define ADREAD(sc, addr) bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, (sc)->sc_iooffs+(addr))
158: #define ADWRITE(sc, addr, data) bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, (sc)->sc_iooffs+(addr), (data))
159:
160: static int
161: ad_read(sc, reg)
162: struct ad1848_softc *sc;
163: int reg;
164: {
165: int x, s;
166:
167: s = splaudio();
168: ADWRITE(sc, AD1848_IADDR, (reg & 0xff) | sc->MCE_bit);
169: x = ADREAD(sc, AD1848_IDATA);
170: splx(s);
171: /* printf("(%02x<-%02x) ", reg|sc->MCE_bit, x); */
172:
173: return x;
174: }
175:
176: static void
177: ad_write(sc, reg, data)
178: struct ad1848_softc *sc;
179: int reg;
180: int data;
181: {
182: int s = splaudio();
183: ADWRITE(sc, AD1848_IADDR, (reg & 0xff) | sc->MCE_bit);
184: ADWRITE(sc, AD1848_IDATA, data & 0xff);
185: splx(s);
186: /* printf("(%02x->%02x) ", reg|sc->MCE_bit, data); */
187: }
188:
189: static void
190: ad_set_MCE(sc, state)
191: struct ad1848_softc *sc;
192: int state;
193: {
194: if (state)
195: sc->MCE_bit = MODE_CHANGE_ENABLE;
196: else
197: sc->MCE_bit = 0;
198:
199: ADWRITE(sc, AD1848_IADDR, sc->MCE_bit);
200: }
201:
202: static void
203: wait_for_calibration(sc)
204: struct ad1848_softc *sc;
205: {
206: int timeout;
207:
208: DPRINTF(("ad1848: Auto calibration started.\n"));
209: /*
210: * Wait until the auto calibration process has finished.
211: *
212: * 1) Wait until the chip becomes ready (reads don't return 0x80).
213: * 2) Wait until the ACI bit of I11 gets on and then off.
214: */
215: timeout = 100000;
216: while (timeout > 0 && ADREAD(sc, AD1848_IADDR) == SP_IN_INIT)
217: timeout--;
218:
219: if (ADREAD(sc, AD1848_IADDR) == SP_IN_INIT)
220: DPRINTF(("ad1848: Auto calibration timed out(1).\n"));
221:
222: ADWRITE(sc, AD1848_IADDR, SP_TEST_AND_INIT);
223: timeout = 100000;
224: while (timeout > 0 && ADREAD(sc, AD1848_IADDR) != SP_TEST_AND_INIT)
225: timeout--;
226:
227: if (ADREAD(sc, AD1848_IADDR) == SP_TEST_AND_INIT)
228: DPRINTF(("ad1848: Auto calibration timed out(1.5).\n"));
229:
230: if (!(ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG)) {
231: timeout = 100000;
232: while (timeout > 0 && !(ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG))
233: timeout--;
234:
235: if (!(ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG))
236: DPRINTF(("ad1848: Auto calibration timed out(2).\n"));
237: }
238:
239: timeout = 100000;
240: while (timeout > 0 && ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG)
241: timeout--;
242: if (ad_read(sc, SP_TEST_AND_INIT) & AUTO_CAL_IN_PROG)
243: DPRINTF(("ad1848: Auto calibration timed out(3).\n"));
244: }
245:
246: #ifdef AUDIO_DEBUG
247: void ad1848_dump_regs(struct ad1848_softc *);
248:
249: void
250: ad1848_dump_regs(sc)
251: struct ad1848_softc *sc;
252: {
253: int i;
254: u_char r;
255:
256: printf("ad1848 status=%02x", ADREAD(sc, AD1848_STATUS));
257: printf(" regs: ");
258: for (i = 0; i < 16; i++) {
259: r = ad_read(sc, i);
260: printf("%02x ", r);
261: }
262: if (sc->mode == 2) {
263: for (i = 16; i < 32; i++) {
264: r = ad_read(sc, i);
265: printf("%02x ", r);
266: }
267: }
268: printf("\n");
269: }
270: #endif
271:
272: /*
273: * Map and probe for the ad1848 chip
274: */
275: int
276: ad1848_mapprobe(sc, iobase)
277: struct ad1848_softc *sc;
278: int iobase;
279: {
280: if (!AD1848_BASE_VALID(iobase)) {
281: #ifdef AUDIO_DEBUG
282: printf("ad1848: configured iobase %04x invalid\n", iobase);
283: #endif
284: return 0;
285: }
286:
287: sc->sc_iooffs = 0;
288: /* Map the AD1848 ports */
289: if (bus_space_map(sc->sc_iot, iobase, AD1848_NPORT, 0, &sc->sc_ioh))
290: return 0;
291:
292: if (!ad1848_probe(sc)) {
293: bus_space_unmap(sc->sc_iot, sc->sc_ioh, AD1848_NPORT);
294: return 0;
295: } else
296: return 1;
297: }
298:
299: /*
300: * Probe for the ad1848 chip
301: */
302: int
303: ad1848_probe(sc)
304: struct ad1848_softc *sc;
305: {
306: u_char tmp, tmp1 = 0xff, tmp2 = 0xff;
307: #if 0
308: int i;
309: #endif
310:
311: /* Is there an ad1848 chip ? */
312: sc->MCE_bit = MODE_CHANGE_ENABLE;
313: sc->mode = 1; /* MODE 1 = original ad1848/ad1846/cs4248 */
314:
315: /*
316: * Check that the I/O address is in use.
317: *
318: * The SP_IN_INIT bit of the base I/O port is known to be 0 after the
319: * chip has performed its power-on initialization. Just assume
320: * this has happened before the OS is starting.
321: *
322: * If the I/O address is unused, inb() typically returns 0xff.
323: */
324: tmp = ADREAD(sc, AD1848_IADDR);
325: if (tmp & SP_IN_INIT) { /* Not a AD1848 */
326: #if 0
327: DPRINTF(("ad_detect_A %x\n", tmp));
328: #endif
329: goto bad;
330: }
331:
332: /*
333: * Test if it's possible to change contents of the indirect registers.
334: * Registers 0 and 1 are ADC volume registers. The bit 0x10 is read only
335: * so try to avoid using it.
336: */
337: ad_write(sc, 0, 0xaa);
338: ad_write(sc, 1, 0x45); /* 0x55 with bit 0x10 clear */
339:
340: if ((tmp1 = ad_read(sc, 0)) != 0xaa ||
341: (tmp2 = ad_read(sc, 1)) != 0x45) {
342: DPRINTF(("ad_detect_B (%x/%x)\n", tmp1, tmp2));
343: goto bad;
344: }
345:
346: ad_write(sc, 0, 0x45);
347: ad_write(sc, 1, 0xaa);
348:
349: if ((tmp1 = ad_read(sc, 0)) != 0x45 ||
350: (tmp2 = ad_read(sc, 1)) != 0xaa) {
351: DPRINTF(("ad_detect_C (%x/%x)\n", tmp1, tmp2));
352: goto bad;
353: }
354:
355: /*
356: * The indirect register I12 has some read only bits. Lets
357: * try to change them.
358: */
359: tmp = ad_read(sc, SP_MISC_INFO);
360: ad_write(sc, SP_MISC_INFO, (~tmp) & 0x0f);
361:
362: if ((tmp & 0x0f) != ((tmp1 = ad_read(sc, SP_MISC_INFO)) & 0x0f)) {
363: DPRINTF(("ad_detect_D (%x)\n", tmp1));
364: goto bad;
365: }
366:
367: /*
368: * MSB and 4 LSBs of the reg I12 tell the chip revision.
369: *
370: * A preliminary version of the AD1846 data sheet stated that it
371: * used an ID field of 0x0B. The current version, however,
372: * states that the AD1846 uses ID 0x0A, just like the AD1848K.
373: *
374: * this switch statement will need updating as newer clones arrive....
375: */
376: switch (tmp1 & 0x8f) {
377: case 0x09:
378: sc->chip_name = "AD1848J";
379: break;
380: case 0x0A:
381: sc->chip_name = "AD1848K";
382: break;
383: #if 0 /* See above */
384: case 0x0B:
385: sc->chip_name = "AD1846";
386: break;
387: #endif
388: case 0x81:
389: sc->chip_name = "CS4248revB"; /* or CS4231 rev B; see below */
390: break;
391: case 0x89:
392: sc->chip_name = "CS4248";
393: break;
394: case 0x8A:
395: sc->chip_name = "broken"; /* CS4231/AD1845; see below */
396: break;
397: default:
398: sc->chip_name = "unknown";
399: DPRINTF(("ad1848: unknown codec version %#02X\n", (tmp1 & 0x8f)));
400: }
401:
402: #if 0
403: /*
404: * XXX I don't know why, but this probe fails on an otherwise well-working
405: * AW35/pro card, so I'll just take it out for now. [niklas@openbsd.org]
406: */
407:
408: /*
409: * The original AD1848/CS4248 has just 16 indirect registers. This means
410: * that I0 and I16 should return the same value (etc.).
411: * Ensure that the Mode2 enable bit of I12 is 0. Otherwise this test fails
412: * with CS4231, AD1845, etc.
413: */
414: ad_write(sc, SP_MISC_INFO, 0); /* Mode2 = disabled */
415:
416: for (i = 0; i < 16; i++)
417: if ((tmp1 = ad_read(sc, i)) != (tmp2 = ad_read(sc, i + 16))) {
418: if (i != SP_TEST_AND_INIT) {
419: DPRINTF(("ad_detect_F(%d/%x/%x)\n", i, tmp1, tmp2));
420: goto bad;
421: }
422: }
423: #endif
424:
425: /*
426: * Try to switch the chip to mode2 (CS4231) by setting the MODE2 bit
427: * The bit 0x80 is always 1 in CS4248, CS4231, and AD1845.
428: */
429: ad_write(sc, SP_MISC_INFO, MODE2); /* Set mode2, clear 0x80 */
430:
431: tmp1 = ad_read(sc, SP_MISC_INFO);
432: if ((tmp1 & 0xc0) == (0x80 | MODE2)) {
433: /*
434: * CS4231 or AD1845 detected - is it?
435: *
436: * Verify that setting I2 doesn't change I18.
437: */
438: ad_write(sc, 18, 0x88); /* Set I18 to known value */
439:
440: ad_write(sc, 2, 0x45);
441: if ((tmp2 = ad_read(sc, 18)) != 0x45) { /* No change -> CS4231? */
442: ad_write(sc, 2, 0xaa);
443: if ((tmp2 = ad_read(sc, 18)) == 0xaa) { /* Rotten bits? */
444: DPRINTF(("ad_detect_H(%x)\n", tmp2));
445: goto bad;
446: }
447:
448: /*
449: * It's a CS4231, or another clone with 32 registers.
450: * Let's find out which by checking I25.
451: */
452: if ((tmp1 & 0x8f) == 0x8a) {
453: tmp1 = ad_read(sc, CS_VERSION_ID);
454: switch (tmp1 & 0xe7) {
455: case 0xA0:
456: sc->chip_name = "CS4231A";
457: break;
458: case 0x80:
459: /* XXX I25 no good, AD1845 same as CS4231 */
460: sc->chip_name = "CS4231 or AD1845";
461: break;
462: case 0x82:
463: case 0xa2:
464: sc->chip_name = "CS4232";
465: break;
466: case 0x03:
467: sc->chip_name = "CS4236/CS4236B";
468: break;
469: }
470: }
471: sc->mode = 2;
472: }
473: }
474:
475: /* Wait for 1848 to init */
476: while(ADREAD(sc, AD1848_IADDR) & SP_IN_INIT)
477: ;
478:
479: /* Wait for 1848 to autocal */
480: ADWRITE(sc, AD1848_IADDR, SP_TEST_AND_INIT);
481: while(ADREAD(sc, AD1848_IDATA) & AUTO_CAL_IN_PROG)
482: ;
483:
484: return 1;
485: bad:
486: return 0;
487: }
488:
489: /* Unmap the I/O ports */
490: void
491: ad1848_unmap(sc)
492: struct ad1848_softc *sc;
493: {
494: bus_space_unmap(sc->sc_iot, sc->sc_ioh, AD1848_NPORT);
495: }
496:
497: /*
498: * Attach hardware to driver, attach hardware driver to audio
499: * pseudo-device driver .
500: */
501: void
502: ad1848_attach(sc)
503: struct ad1848_softc *sc;
504: {
505: int i;
506: struct ad1848_volume vol_mid = {220, 220};
507: struct ad1848_volume vol_0 = {0, 0};
508: struct audio_params pparams, rparams;
509: int timeout;
510:
511: sc->sc_locked = 0;
512: sc->sc_playrun = NOTRUNNING;
513: sc->sc_recrun = NOTRUNNING;
514:
515: if (sc->sc_drq != -1) {
516: if (isa_dmamap_create(sc->sc_isa, sc->sc_drq, MAX_ISADMA,
517: BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
518: printf("ad1848_attach: can't create map for drq %d\n",
519: sc->sc_drq);
520: return;
521: }
522: }
523: if (sc->sc_recdrq != -1 && sc->sc_recdrq != sc->sc_drq) {
524: if (isa_dmamap_create(sc->sc_isa, sc->sc_recdrq, MAX_ISADMA,
525: BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
526: printf("ad1848_attach: can't creape map for drq %d\n",
527: sc->sc_recdrq);
528: return;
529: }
530: }
531:
532: /* Initialize the ad1848... */
533: for (i = 0; i < 0x10; i++) {
534: ad_write(sc, i, ad1848_init_values[i]);
535: timeout = 100000;
536: while (timeout > 0 && ad_read(sc, AD1848_IADDR) & SP_IN_INIT)
537: timeout--;
538: }
539: /* ...and additional CS4231 stuff too */
540: if (sc->mode == 2) {
541: ad_write(sc, SP_INTERFACE_CONFIG, 0); /* disable SINGLE_DMA */
542: for (i = 0x10; i < 0x20; i++)
543: if (ad1848_init_values[i] != 0) {
544: ad_write(sc, i, ad1848_init_values[i]);
545: timeout = 100000;
546: while (timeout > 0 &&
547: ad_read(sc, AD1848_IADDR) & SP_IN_INIT)
548: timeout--;
549: }
550: }
551: ad1848_reset(sc);
552:
553: pparams = audio_default;
554: rparams = audio_default;
555: (void) ad1848_set_params(sc, AUMODE_RECORD|AUMODE_PLAY, 0, &pparams, &rparams);
556:
557: /* Set default gains */
558: (void) ad1848_set_rec_gain(sc, &vol_mid);
559: (void) ad1848_set_channel_gain(sc, AD1848_DAC_CHANNEL, &vol_mid);
560: (void) ad1848_set_channel_gain(sc, AD1848_MONITOR_CHANNEL, &vol_0);
561: (void) ad1848_set_channel_gain(sc, AD1848_AUX1_CHANNEL, &vol_mid); /* CD volume */
562: if (sc->mode == 2) {
563: (void) ad1848_set_channel_gain(sc, AD1848_AUX2_CHANNEL, &vol_mid); /* CD volume */
564: (void) ad1848_set_channel_gain(sc, AD1848_LINE_CHANNEL, &vol_mid);
565: (void) ad1848_set_channel_gain(sc, AD1848_MONO_CHANNEL, &vol_0);
566: sc->mute[AD1848_MONO_CHANNEL] = MUTE_ALL;
567: } else
568: (void) ad1848_set_channel_gain(sc, AD1848_AUX2_CHANNEL, &vol_0);
569:
570: /* Set default port */
571: (void) ad1848_set_rec_port(sc, MIC_IN_PORT);
572:
573: if (sc->chip_name)
574: printf(": %s", sc->chip_name);
575: #undef WAITREADY
576: }
577:
578: /*
579: * Various routines to interface to higher level audio driver
580: */
581: struct ad1848_mixerinfo {
582: int left_reg;
583: int right_reg;
584: int atten_bits;
585: int atten_mask;
586: } mixer_channel_info[] =
587: { { SP_LEFT_AUX2_CONTROL, SP_RIGHT_AUX2_CONTROL, AUX_INPUT_ATTEN_BITS,
588: AUX_INPUT_ATTEN_MASK },
589: { SP_LEFT_AUX1_CONTROL, SP_RIGHT_AUX1_CONTROL, AUX_INPUT_ATTEN_BITS,
590: AUX_INPUT_ATTEN_MASK },
591: { SP_LEFT_OUTPUT_CONTROL, SP_RIGHT_OUTPUT_CONTROL,
592: OUTPUT_ATTEN_BITS, OUTPUT_ATTEN_MASK },
593: { CS_LEFT_LINE_CONTROL, CS_RIGHT_LINE_CONTROL, LINE_INPUT_ATTEN_BITS,
594: LINE_INPUT_ATTEN_MASK },
595: { CS_MONO_IO_CONTROL, 0, MONO_INPUT_ATTEN_BITS, MONO_INPUT_ATTEN_MASK },
596: { SP_DIGITAL_MIX, 0, OUTPUT_ATTEN_BITS, MIX_ATTEN_MASK }
597: };
598:
599: /*
600: * This function doesn't set the mute flags but does use them.
601: * The mute flags reflect the mutes that have been applied by the user.
602: * However, the driver occasionally wants to mute devices (e.g. when chaing
603: * sampling rate). These operations should not affect the mute flags.
604: */
605:
606: void
607: ad1848_mute_channel(sc, device, mute)
608: struct ad1848_softc *sc;
609: int device;
610: int mute;
611: {
612: u_char reg;
613:
614: reg = ad_read(sc, mixer_channel_info[device].left_reg);
615:
616: if (mute & MUTE_LEFT) {
617: if (device == AD1848_MONITOR_CHANNEL)
618: ad_write(sc, mixer_channel_info[device].left_reg, reg & 0xFE);
619: else
620: ad_write(sc, mixer_channel_info[device].left_reg, reg | 0x80);
621: } else if (!(sc->mute[device] & MUTE_LEFT)) {
622: if (device == AD1848_MONITOR_CHANNEL)
623: ad_write(sc, mixer_channel_info[device].left_reg, reg | 0x01);
624: else
625: ad_write(sc, mixer_channel_info[device].left_reg, reg & ~0x80);
626: }
627:
628: if (!mixer_channel_info[device].right_reg) {
629: return;
630: }
631:
632: reg = ad_read(sc, mixer_channel_info[device].right_reg);
633:
634: if (mute & MUTE_RIGHT)
635: ad_write(sc, mixer_channel_info[device].right_reg, reg | 0x80);
636: else if (!(sc->mute[device] & MUTE_RIGHT)) {
637: ad_write(sc, mixer_channel_info[device].right_reg, reg & ~0x80);
638: }
639: }
640:
641:
642: int
643: ad1848_set_channel_gain(sc, device, gp)
644: struct ad1848_softc *sc;
645: int device;
646: struct ad1848_volume *gp;
647: {
648: struct ad1848_mixerinfo *info = &mixer_channel_info[device];
649: u_char reg;
650: u_int atten;
651:
652: sc->gains[device] = *gp;
653:
654: atten = ((AUDIO_MAX_GAIN - gp->left) * info->atten_bits)/AUDIO_MAX_GAIN;
655:
656: reg = ad_read(sc, info->left_reg) & (info->atten_mask);
657: if (device == AD1848_MONITOR_CHANNEL)
658: reg |= ((atten & info->atten_bits) << 2);
659: else
660: reg |= ((atten & info->atten_bits));
661:
662: ad_write(sc, info->left_reg, reg);
663:
664: if (!info->right_reg)
665: return (0);
666:
667: atten = ((AUDIO_MAX_GAIN - gp->right) * info->atten_bits)/AUDIO_MAX_GAIN;
668: reg = ad_read(sc, info->right_reg);
669: reg &= (info->atten_mask);
670: ad_write(sc, info->right_reg, (atten& info->atten_bits)|reg);
671:
672: return(0);
673: }
674:
675:
676: int
677: ad1848_get_device_gain(sc, device, gp)
678: struct ad1848_softc *sc;
679: int device;
680: struct ad1848_volume *gp;
681: {
682: *gp = sc->gains[device];
683: return(0);
684: }
685:
686: int
687: ad1848_get_rec_gain(sc, gp)
688: struct ad1848_softc *sc;
689: struct ad1848_volume *gp;
690: {
691: *gp = sc->rec_gain;
692: return(0);
693: }
694:
695: int
696: ad1848_set_rec_gain(sc, gp)
697: struct ad1848_softc *sc;
698: struct ad1848_volume *gp;
699: {
700: u_char reg, gain;
701:
702: DPRINTF(("ad1848_set_rec_gain: %d:%d\n", gp->left, gp->right));
703:
704: sc->rec_gain = *gp;
705:
706: gain = (gp->left * GAIN_22_5)/AUDIO_MAX_GAIN;
707: reg = ad_read(sc, SP_LEFT_INPUT_CONTROL);
708: reg &= INPUT_GAIN_MASK;
709: ad_write(sc, SP_LEFT_INPUT_CONTROL, (gain&0x0f)|reg);
710:
711: gain = (gp->right * GAIN_22_5)/AUDIO_MAX_GAIN;
712: reg = ad_read(sc, SP_RIGHT_INPUT_CONTROL);
713: reg &= INPUT_GAIN_MASK;
714: ad_write(sc, SP_RIGHT_INPUT_CONTROL, (gain&0x0f)|reg);
715:
716: return(0);
717: }
718:
719:
720: void
721: ad1848_mute_monitor(addr, mute)
722: void *addr;
723: int mute;
724: {
725: struct ad1848_softc *sc = addr;
726:
727: DPRINTF(("ad1848_mute_monitor: %smuting\n", mute ? "" : "un"));
728: if (sc->mode == 2) {
729: ad1848_mute_channel(sc, AD1848_DAC_CHANNEL, mute ? MUTE_ALL : 0);
730: ad1848_mute_channel(sc, AD1848_MONO_CHANNEL, mute ? MUTE_MONO : 0);
731: ad1848_mute_channel(sc, AD1848_LINE_CHANNEL, mute ? MUTE_ALL : 0);
732: }
733:
734: ad1848_mute_channel(sc, AD1848_AUX2_CHANNEL, mute ? MUTE_ALL : 0);
735: ad1848_mute_channel(sc, AD1848_AUX1_CHANNEL, mute ? MUTE_ALL : 0);
736: }
737:
738: int
739: ad1848_set_mic_gain(sc, gp)
740: struct ad1848_softc *sc;
741: struct ad1848_volume *gp;
742: {
743: u_char reg;
744:
745: DPRINTF(("cs4231_set_mic_gain: %d\n", gp->left));
746:
747: if (gp->left > AUDIO_MAX_GAIN/2) {
748: sc->mic_gain_on = 1;
749: reg = ad_read(sc, SP_LEFT_INPUT_CONTROL);
750: ad_write(sc, SP_LEFT_INPUT_CONTROL, reg | INPUT_MIC_GAIN_ENABLE);
751: } else {
752: sc->mic_gain_on = 0;
753: reg = ad_read(sc, SP_LEFT_INPUT_CONTROL);
754: ad_write(sc, SP_LEFT_INPUT_CONTROL, reg & ~INPUT_MIC_GAIN_ENABLE);
755: }
756:
757: return(0);
758: }
759:
760: int
761: ad1848_get_mic_gain(sc, gp)
762: struct ad1848_softc *sc;
763: struct ad1848_volume *gp;
764: {
765: if (sc->mic_gain_on)
766: gp->left = gp->right = AUDIO_MAX_GAIN;
767: else
768: gp->left = gp->right = AUDIO_MIN_GAIN;
769: return(0);
770: }
771:
772:
773: static ad1848_devmap_t *ad1848_mixer_find_dev(ad1848_devmap_t *, int, mixer_ctrl_t *);
774:
775: static ad1848_devmap_t *
776: ad1848_mixer_find_dev(map, cnt, cp)
777: ad1848_devmap_t *map;
778: int cnt;
779: mixer_ctrl_t *cp;
780:
781: {
782: int idx;
783:
784: for (idx = 0; idx < cnt; idx++) {
785: if (map[idx].id == cp->dev) {
786: return (&map[idx]);
787: }
788: }
789: return (NULL);
790: }
791:
792: int
793: ad1848_mixer_get_port(ac, map, cnt, cp)
794: struct ad1848_softc *ac;
795: struct ad1848_devmap *map;
796: int cnt;
797: mixer_ctrl_t *cp;
798: {
799: ad1848_devmap_t *entry;
800: struct ad1848_volume vol;
801: int error = EINVAL;
802: int dev;
803:
804: if (!(entry = ad1848_mixer_find_dev(map, cnt, cp)))
805: return (ENXIO);
806:
807: dev = entry->dev;
808:
809: switch (entry->kind) {
810: case AD1848_KIND_LVL:
811: if (cp->type != AUDIO_MIXER_VALUE)
812: break;
813:
814: if (dev < AD1848_AUX2_CHANNEL ||
815: dev > AD1848_MONITOR_CHANNEL)
816: break;
817:
818: if (cp->un.value.num_channels != 1 &&
819: mixer_channel_info[dev].right_reg == 0)
820: break;
821:
822: error = ad1848_get_device_gain(ac, dev, &vol);
823: if (!error)
824: ad1848_from_vol(cp, &vol);
825:
826: break;
827:
828: case AD1848_KIND_MUTE:
829: if (cp->type != AUDIO_MIXER_ENUM) break;
830:
831: cp->un.ord = ac->mute[dev] ? 1 : 0;
832: error = 0;
833: break;
834:
835: case AD1848_KIND_RECORDGAIN:
836: if (cp->type != AUDIO_MIXER_VALUE) break;
837:
838: error = ad1848_get_rec_gain(ac, &vol);
839: if (!error)
840: ad1848_from_vol(cp, &vol);
841:
842: break;
843:
844: case AD1848_KIND_MICGAIN:
845: if (cp->type != AUDIO_MIXER_VALUE) break;
846:
847: error = ad1848_get_mic_gain(ac, &vol);
848: if (!error)
849: ad1848_from_vol(cp, &vol);
850:
851: break;
852:
853: case AD1848_KIND_RECORDSOURCE:
854: if (cp->type != AUDIO_MIXER_ENUM) break;
855: cp->un.ord = ad1848_get_rec_port(ac);
856: error = 0;
857: break;
858: default:
859: printf ("Invalid kind\n");
860: break;
861: }
862:
863: return (error);
864: }
865:
866: int
867: ad1848_mixer_set_port(ac, map, cnt, cp)
868: struct ad1848_softc *ac;
869: struct ad1848_devmap *map;
870: int cnt;
871: mixer_ctrl_t *cp;
872: {
873: ad1848_devmap_t *entry;
874: struct ad1848_volume vol;
875: int error = EINVAL;
876: int dev;
877:
878: if (!(entry = ad1848_mixer_find_dev(map, cnt, cp)))
879: return (ENXIO);
880:
881: dev = entry->dev;
882:
883: switch (entry->kind) {
884: case AD1848_KIND_LVL:
885: if (cp->type != AUDIO_MIXER_VALUE)
886: break;
887:
888: if (dev < AD1848_AUX2_CHANNEL ||
889: dev > AD1848_MONITOR_CHANNEL)
890: break;
891:
892: if (cp->un.value.num_channels != 1 &&
893: mixer_channel_info[dev].right_reg == 0)
894: break;
895:
896: ad1848_to_vol(cp, &vol);
897: error = ad1848_set_channel_gain(ac, dev, &vol);
898: break;
899:
900: case AD1848_KIND_MUTE:
901: if (cp->type != AUDIO_MIXER_ENUM) break;
902:
903: ac->mute[dev] = (cp->un.ord ? MUTE_ALL : 0);
904: ad1848_mute_channel(ac, dev, ac->mute[dev]);
905: error = 0;
906: break;
907:
908: case AD1848_KIND_RECORDGAIN:
909: if (cp->type != AUDIO_MIXER_VALUE) break;
910:
911: ad1848_to_vol(cp, &vol);
912: error = ad1848_set_rec_gain(ac, &vol);
913: break;
914:
915: case AD1848_KIND_MICGAIN:
916: if (cp->type != AUDIO_MIXER_VALUE) break;
917:
918: ad1848_to_vol(cp, &vol);
919: error = ad1848_set_mic_gain(ac, &vol);
920: break;
921:
922: case AD1848_KIND_RECORDSOURCE:
923: if (cp->type != AUDIO_MIXER_ENUM) break;
924:
925: error = ad1848_set_rec_port(ac, cp->un.ord);
926: break;
927: default:
928: printf ("Invalid kind\n");
929: break;
930: }
931:
932: return (error);
933: }
934:
935:
936: int
937: ad1848_query_encoding(addr, fp)
938: void *addr;
939: struct audio_encoding *fp;
940: {
941: struct ad1848_softc *sc = addr;
942:
943: switch (fp->index) {
944: case 0:
945: strlcpy(fp->name, AudioEmulaw, sizeof fp->name);
946: fp->encoding = AUDIO_ENCODING_ULAW;
947: fp->precision = 8;
948: fp->flags = 0;
949: break;
950: case 1:
951: strlcpy(fp->name, AudioEalaw, sizeof fp->name);
952: fp->encoding = AUDIO_ENCODING_ALAW;
953: fp->precision = 8;
954: fp->flags = 0;
955: break;
956: case 2:
957: strlcpy(fp->name, AudioEslinear_le, sizeof fp->name);
958: fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
959: fp->precision = 16;
960: fp->flags = 0;
961: break;
962: case 3:
963: strlcpy(fp->name, AudioEulinear, sizeof fp->name);
964: fp->encoding = AUDIO_ENCODING_ULINEAR;
965: fp->precision = 8;
966: fp->flags = 0;
967: break;
968:
969: case 4: /* only on CS4231 */
970: strlcpy(fp->name, AudioEslinear_be, sizeof fp->name);
971: fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
972: fp->precision = 16;
973: fp->flags = sc->mode == 1 ? AUDIO_ENCODINGFLAG_EMULATED : 0;
974: break;
975:
976: /* emulate some modes */
977: case 5:
978: strlcpy(fp->name, AudioEslinear, sizeof fp->name);
979: fp->encoding = AUDIO_ENCODING_SLINEAR;
980: fp->precision = 8;
981: fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
982: break;
983: case 6:
984: strlcpy(fp->name, AudioEulinear_le, sizeof fp->name);
985: fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
986: fp->precision = 16;
987: fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
988: break;
989: case 7:
990: strlcpy(fp->name, AudioEulinear_be, sizeof fp->name);
991: fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
992: fp->precision = 16;
993: fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
994: break;
995:
996: case 8: /* only on CS4231 */
997: if (sc->mode == 1)
998: return EINVAL;
999: strlcpy(fp->name, AudioEadpcm, sizeof fp->name);
1000: fp->encoding = AUDIO_ENCODING_ADPCM;
1001: fp->precision = 8;
1002: fp->flags = 0;
1003: break;
1004: default:
1005: return EINVAL;
1006: /*NOTREACHED*/
1007: }
1008: return (0);
1009: }
1010:
1011: int
1012: ad1848_set_params(addr, setmode, usemode, p, r)
1013: void *addr;
1014: int setmode, usemode;
1015: struct audio_params *p, *r;
1016: {
1017: struct ad1848_softc *sc = addr;
1018: int error, bits, enc;
1019: void (*pswcode)(void *, u_char *buf, int cnt);
1020: void (*rswcode)(void *, u_char *buf, int cnt);
1021:
1022: DPRINTF(("ad1848_set_params: %d %d %d %ld\n",
1023: p->encoding, p->precision, p->channels, p->sample_rate));
1024:
1025: enc = p->encoding;
1026: pswcode = rswcode = 0;
1027: switch (enc) {
1028: case AUDIO_ENCODING_SLINEAR_LE:
1029: if (p->precision == 8) {
1030: enc = AUDIO_ENCODING_ULINEAR_LE;
1031: pswcode = rswcode = change_sign8;
1032: }
1033: break;
1034: case AUDIO_ENCODING_SLINEAR_BE:
1035: if (p->precision == 16 && sc->mode == 1) {
1036: enc = AUDIO_ENCODING_SLINEAR_LE;
1037: pswcode = rswcode = swap_bytes;
1038: }
1039: break;
1040: case AUDIO_ENCODING_ULINEAR_LE:
1041: if (p->precision == 16) {
1042: enc = AUDIO_ENCODING_SLINEAR_LE;
1043: pswcode = rswcode = change_sign16;
1044: }
1045: break;
1046: case AUDIO_ENCODING_ULINEAR_BE:
1047: if (p->precision == 16) {
1048: enc = AUDIO_ENCODING_SLINEAR_LE;
1049: pswcode = swap_bytes_change_sign16;
1050: rswcode = change_sign16_swap_bytes;
1051: }
1052: break;
1053: }
1054: switch (enc) {
1055: case AUDIO_ENCODING_ULAW:
1056: bits = FMT_ULAW >> 5;
1057: break;
1058: case AUDIO_ENCODING_ALAW:
1059: bits = FMT_ALAW >> 5;
1060: break;
1061: case AUDIO_ENCODING_ADPCM:
1062: bits = FMT_ADPCM >> 5;
1063: break;
1064: case AUDIO_ENCODING_SLINEAR_LE:
1065: if (p->precision == 16)
1066: bits = FMT_TWOS_COMP >> 5;
1067: else
1068: return EINVAL;
1069: break;
1070: case AUDIO_ENCODING_SLINEAR_BE:
1071: if (p->precision == 16)
1072: bits = FMT_TWOS_COMP_BE >> 5;
1073: else
1074: return EINVAL;
1075: break;
1076: case AUDIO_ENCODING_ULINEAR_LE:
1077: if (p->precision == 8)
1078: bits = FMT_PCM8 >> 5;
1079: else
1080: return EINVAL;
1081: break;
1082: default:
1083: return EINVAL;
1084: }
1085:
1086: if (p->channels < 1 || p->channels > 2)
1087: return EINVAL;
1088:
1089: error = ad1848_set_speed(sc, &p->sample_rate);
1090: if (error)
1091: return error;
1092:
1093: p->sw_code = pswcode;
1094: r->sw_code = rswcode;
1095:
1096: sc->format_bits = bits;
1097: sc->channels = p->channels;
1098: sc->precision = p->precision;
1099: sc->need_commit = 1;
1100:
1101: DPRINTF(("ad1848_set_params succeeded, bits=%x\n", bits));
1102: return (0);
1103: }
1104:
1105: int
1106: ad1848_set_rec_port(sc, port)
1107: struct ad1848_softc *sc;
1108: int port;
1109: {
1110: u_char inp, reg;
1111:
1112: DPRINTF(("ad1848_set_rec_port: 0x%x\n", port));
1113:
1114: if (port == MIC_IN_PORT) {
1115: inp = MIC_INPUT;
1116: }
1117: else if (port == LINE_IN_PORT) {
1118: inp = LINE_INPUT;
1119: }
1120: else if (port == DAC_IN_PORT) {
1121: inp = MIXED_DAC_INPUT;
1122: }
1123: else if (sc->mode == 2 && port == AUX1_IN_PORT) {
1124: inp = AUX_INPUT;
1125: }
1126: else
1127: return(EINVAL);
1128:
1129: reg = ad_read(sc, SP_LEFT_INPUT_CONTROL);
1130: reg &= INPUT_SOURCE_MASK;
1131: ad_write(sc, SP_LEFT_INPUT_CONTROL, (inp|reg));
1132:
1133: reg = ad_read(sc, SP_RIGHT_INPUT_CONTROL);
1134: reg &= INPUT_SOURCE_MASK;
1135: ad_write(sc, SP_RIGHT_INPUT_CONTROL, (inp|reg));
1136:
1137: sc->rec_port = port;
1138:
1139: return(0);
1140: }
1141:
1142: int
1143: ad1848_get_rec_port(sc)
1144: struct ad1848_softc *sc;
1145: {
1146: return(sc->rec_port);
1147: }
1148:
1149: int
1150: ad1848_round_blocksize(addr, blk)
1151: void *addr;
1152: int blk;
1153: {
1154: struct ad1848_softc *sc = addr;
1155:
1156: sc->sc_lastcc = -1;
1157:
1158: /* Round to a multiple of the biggest sample size. */
1159: blk = (blk + 3) & -4;
1160:
1161: return (blk);
1162: }
1163:
1164: int
1165: ad1848_open(addr, flags)
1166: void *addr;
1167: int flags;
1168: {
1169: struct ad1848_softc *sc = addr;
1170:
1171: DPRINTF(("ad1848_open: sc=%p\n", sc));
1172:
1173: sc->sc_intr = 0;
1174: sc->sc_lastcc = -1;
1175: sc->sc_locked = 0;
1176:
1177: /* Enable interrupts */
1178: DPRINTF(("ad1848_open: enable intrs\n"));
1179: ad_write(sc, SP_PIN_CONTROL, INTERRUPT_ENABLE|ad_read(sc, SP_PIN_CONTROL));
1180:
1181: #ifdef AUDIO_DEBUG
1182: if (ad1848debug)
1183: ad1848_dump_regs(sc);
1184: #endif
1185:
1186: return 0;
1187: }
1188:
1189: /*
1190: * Close function is called at splaudio().
1191: */
1192: void
1193: ad1848_close(addr)
1194: void *addr;
1195: {
1196: struct ad1848_softc *sc = addr;
1197: u_char r;
1198:
1199: sc->sc_intr = 0;
1200:
1201: DPRINTF(("ad1848_close: stop DMA\n"));
1202: if (sc->sc_playrun != NOTRUNNING) {
1203: isa_dmaabort(sc->sc_isa, sc->sc_drq);
1204: sc->sc_playrun = NOTRUNNING;
1205: }
1206: if (sc->sc_recrun != NOTRUNNING) {
1207: isa_dmaabort(sc->sc_isa, sc->sc_recdrq);
1208: sc->sc_recrun = NOTRUNNING;
1209: }
1210: ad_write(sc, SP_LOWER_BASE_COUNT, (u_char)0);
1211: ad_write(sc, SP_UPPER_BASE_COUNT, (u_char)0);
1212:
1213: /* Disable interrupts */
1214: DPRINTF(("ad1848_close: disable intrs\n"));
1215: ad_write(sc, SP_PIN_CONTROL,
1216: ad_read(sc, SP_PIN_CONTROL) & ~INTERRUPT_ENABLE);
1217:
1218: DPRINTF(("ad1848_close: disable capture and playback\n"));
1219: r = ad_read(sc, SP_INTERFACE_CONFIG);
1220: r &= ~(CAPTURE_ENABLE|PLAYBACK_ENABLE);
1221: ad_write(sc, SP_INTERFACE_CONFIG, r);
1222:
1223: #ifdef AUDIO_DEBUG
1224: if (ad1848debug)
1225: ad1848_dump_regs(sc);
1226: #endif
1227: }
1228:
1229: /*
1230: * Lower-level routines
1231: */
1232: int
1233: ad1848_commit_settings(addr)
1234: void *addr;
1235: {
1236: struct ad1848_softc *sc = addr;
1237: int timeout;
1238: u_char fs;
1239: int s;
1240:
1241: if (!sc->need_commit)
1242: return 0;
1243:
1244: s = splaudio();
1245:
1246: ad1848_mute_monitor(sc, 1);
1247:
1248: ad_set_MCE(sc, 1); /* Enables changes to the format select reg */
1249:
1250: fs = sc->speed_bits | (sc->format_bits << 5);
1251:
1252: if (sc->channels == 2)
1253: fs |= FMT_STEREO;
1254:
1255: ad_write(sc, SP_CLOCK_DATA_FORMAT, fs);
1256:
1257: /*
1258: * If mode == 2 (CS4231), set I28 also. It's the capture format register.
1259: */
1260: if (sc->mode == 2) {
1261: /* Gravis Ultrasound MAX SDK sources says something about errata
1262: * sheets, with the implication that these inb()s are necessary.
1263: */
1264: (void)ADREAD(sc, AD1848_IDATA);
1265: (void)ADREAD(sc, AD1848_IDATA);
1266: /*
1267: * Write to I8 starts resynchronization. Wait until it completes.
1268: */
1269: timeout = 100000;
1270: while (timeout > 0 && ADREAD(sc, AD1848_IADDR) == SP_IN_INIT)
1271: timeout--;
1272:
1273: ad_write(sc, CS_REC_FORMAT, fs);
1274: /* Gravis Ultrasound MAX SDK sources says something about errata
1275: * sheets, with the implication that these inb()s are necessary.
1276: */
1277: (void)ADREAD(sc, AD1848_IDATA);
1278: (void)ADREAD(sc, AD1848_IDATA);
1279: /* Now wait for resync for capture side of the house */
1280: }
1281: /*
1282: * Write to I8 starts resynchronization. Wait until it completes.
1283: */
1284: timeout = 100000;
1285: while (timeout > 0 && ADREAD(sc, AD1848_IADDR) == SP_IN_INIT)
1286: timeout--;
1287:
1288: if (ADREAD(sc, AD1848_IADDR) == SP_IN_INIT)
1289: printf("ad1848_commit: Auto calibration timed out\n");
1290:
1291: /*
1292: * Starts the calibration process and
1293: * enters playback mode after it.
1294: */
1295: ad_set_MCE(sc, 0);
1296: wait_for_calibration(sc);
1297:
1298: ad1848_mute_monitor(sc, 0);
1299:
1300: sc->sc_lastcc = -1;
1301:
1302: splx(s);
1303:
1304: sc->need_commit = 0;
1305: return 0;
1306: }
1307:
1308: void
1309: ad1848_reset(sc)
1310: struct ad1848_softc *sc;
1311: {
1312: u_char r;
1313:
1314: DPRINTF(("ad1848_reset\n"));
1315:
1316: /* Clear the PEN and CEN bits */
1317: r = ad_read(sc, SP_INTERFACE_CONFIG);
1318: r &= ~(CAPTURE_ENABLE|PLAYBACK_ENABLE);
1319: ad_write(sc, SP_INTERFACE_CONFIG, r);
1320:
1321: if (sc->mode == 2) {
1322: ADWRITE(sc, AD1848_IADDR, CS_IRQ_STATUS);
1323: ADWRITE(sc, AD1848_IDATA, 0);
1324: }
1325: /* Clear interrupt status */
1326: ADWRITE(sc, AD1848_STATUS, 0);
1327: #ifdef AUDIO_DEBUG
1328: if (ad1848debug)
1329: ad1848_dump_regs(sc);
1330: #endif
1331: }
1332:
1333: int
1334: ad1848_set_speed(sc, argp)
1335: struct ad1848_softc *sc;
1336: u_long *argp;
1337: {
1338: /*
1339: * The sampling speed is encoded in the least significant nible of I8. The
1340: * LSB selects the clock source (0=24.576 MHz, 1=16.9344 MHz) and other
1341: * three bits select the divisor (indirectly):
1342: *
1343: * The available speeds are in the following table. Keep the speeds in
1344: * the increasing order.
1345: */
1346: typedef struct {
1347: int speed;
1348: u_char bits;
1349: } speed_struct;
1350: u_long arg = *argp;
1351:
1352: static speed_struct speed_table[] = {
1353: {5510, (0 << 1) | 1},
1354: {5510, (0 << 1) | 1},
1355: {6620, (7 << 1) | 1},
1356: {8000, (0 << 1) | 0},
1357: {9600, (7 << 1) | 0},
1358: {11025, (1 << 1) | 1},
1359: {16000, (1 << 1) | 0},
1360: {18900, (2 << 1) | 1},
1361: {22050, (3 << 1) | 1},
1362: {27420, (2 << 1) | 0},
1363: {32000, (3 << 1) | 0},
1364: {33075, (6 << 1) | 1},
1365: {37800, (4 << 1) | 1},
1366: {44100, (5 << 1) | 1},
1367: {48000, (6 << 1) | 0}
1368: };
1369:
1370: int i, n, selected = -1;
1371:
1372: n = sizeof(speed_table) / sizeof(speed_struct);
1373:
1374: if (arg < speed_table[0].speed)
1375: selected = 0;
1376: if (arg > speed_table[n - 1].speed)
1377: selected = n - 1;
1378:
1379: for (i = 1 /*really*/ ; selected == -1 && i < n; i++)
1380: if (speed_table[i].speed == arg)
1381: selected = i;
1382: else if (speed_table[i].speed > arg) {
1383: int diff1, diff2;
1384:
1385: diff1 = arg - speed_table[i - 1].speed;
1386: diff2 = speed_table[i].speed - arg;
1387:
1388: if (diff1 < diff2)
1389: selected = i - 1;
1390: else
1391: selected = i;
1392: }
1393:
1394: if (selected == -1) {
1395: printf("ad1848: Can't find speed???\n");
1396: selected = 3;
1397: }
1398:
1399: sc->speed_bits = speed_table[selected].bits;
1400: sc->need_commit = 1;
1401: *argp = speed_table[selected].speed;
1402:
1403: return (0);
1404: }
1405:
1406: /*
1407: * Halt a DMA in progress.
1408: */
1409: int
1410: ad1848_halt_out_dma(addr)
1411: void *addr;
1412: {
1413: struct ad1848_softc *sc = addr;
1414: u_char reg;
1415:
1416: DPRINTF(("ad1848: ad1848_halt_out_dma\n"));
1417:
1418: reg = ad_read(sc, SP_INTERFACE_CONFIG);
1419: ad_write(sc, SP_INTERFACE_CONFIG, (reg & ~PLAYBACK_ENABLE));
1420: sc->sc_locked = 0;
1421:
1422: return(0);
1423: }
1424:
1425: int
1426: ad1848_halt_in_dma(addr)
1427: void *addr;
1428: {
1429: struct ad1848_softc *sc = addr;
1430: u_char reg;
1431:
1432: DPRINTF(("ad1848: ad1848_halt_in_dma\n"));
1433:
1434: reg = ad_read(sc, SP_INTERFACE_CONFIG);
1435: ad_write(sc, SP_INTERFACE_CONFIG, (reg & ~CAPTURE_ENABLE));
1436: sc->sc_locked = 0;
1437:
1438: return(0);
1439: }
1440:
1441: int
1442: ad1848_dma_init_input(addr, buf, cc)
1443: void *addr;
1444: void *buf;
1445: int cc;
1446: {
1447: struct ad1848_softc *sc = addr;
1448:
1449: sc->sc_recrun = DMARUNNING;
1450: sc->sc_dma_flags = DMAMODE_READ | DMAMODE_LOOP;
1451: sc->sc_dma_bp = buf;
1452: sc->sc_dma_cnt = cc;
1453: isa_dmastart(sc->sc_isa, sc->sc_recdrq, buf, cc, NULL,
1454: sc->sc_dma_flags, BUS_DMA_NOWAIT);
1455: DPRINTF(("ad1848_dma_init_input: %p %d\n", buf, cc));
1456: return 0;
1457: }
1458:
1459: /*
1460: * DMA input/output are called at splaudio().
1461: */
1462: int
1463: ad1848_dma_input(addr, p, cc, intr, arg)
1464: void *addr;
1465: void *p;
1466: int cc;
1467: void (*intr)(void *);
1468: void *arg;
1469: {
1470: struct ad1848_softc *sc = addr;
1471: u_char reg;
1472:
1473: if (sc->sc_locked) {
1474: DPRINTF(("ad1848_dma_input: locked\n"));
1475: return 0;
1476: }
1477:
1478: #ifdef AUDIO_DEBUG
1479: if (ad1848debug > 1)
1480: printf("ad1848_dma_input: cc=%d %p (%p)\n", cc, intr, arg);
1481: #endif
1482: sc->sc_locked = 1;
1483: sc->sc_intr = intr;
1484: sc->sc_arg = arg;
1485:
1486: switch (sc->sc_recrun) {
1487: case NOTRUNNING:
1488: sc->sc_dma_flags = DMAMODE_READ;
1489: sc->sc_dma_bp = p;
1490: sc->sc_dma_cnt = cc;
1491: isa_dmastart(sc->sc_isa, sc->sc_recdrq, p, cc, NULL,
1492: DMAMODE_READ, BUS_DMA_NOWAIT);
1493: goto startpcm;
1494: case DMARUNNING:
1495: sc->sc_recrun = PCMRUNNING;
1496: startpcm:
1497: if (sc->precision == 16)
1498: cc >>= 1;
1499: if (sc->channels == 2)
1500: cc >>= 1;
1501: cc--;
1502:
1503: if (sc->sc_lastcc != cc || sc->sc_mode != AUMODE_RECORD) {
1504: ad_write(sc, SP_LOWER_BASE_COUNT, (u_char)(cc & 0xff));
1505: ad_write(sc, SP_UPPER_BASE_COUNT, (u_char)((cc >> 8) & 0xff));
1506:
1507: if (sc->mode == 2) {
1508: ad_write(sc, CS_LOWER_REC_CNT, (u_char)(cc & 0xff));
1509: ad_write(sc, CS_UPPER_REC_CNT, (u_char)((cc >> 8) & 0xff));
1510: }
1511:
1512: reg = ad_read(sc, SP_INTERFACE_CONFIG);
1513: ad_write(sc, SP_INTERFACE_CONFIG, (CAPTURE_ENABLE|reg));
1514:
1515: sc->sc_lastcc = cc;
1516: sc->sc_mode = AUMODE_RECORD;
1517: #ifdef AUDIO_DEBUG
1518: if (ad1848debug > 1)
1519: printf("ad1848_dma_input: started capture\n");
1520: #endif
1521: }
1522: case PCMRUNNING:
1523: break;
1524: }
1525:
1526: return 0;
1527: }
1528:
1529: int
1530: ad1848_dma_init_output(addr, buf, cc)
1531: void *addr;
1532: void *buf;
1533: int cc;
1534: {
1535: struct ad1848_softc *sc = addr;
1536:
1537: sc->sc_playrun = DMARUNNING;
1538: sc->sc_dma_flags = DMAMODE_WRITE | DMAMODE_LOOP;
1539: sc->sc_dma_bp = buf;
1540: sc->sc_dma_cnt = cc;
1541: isa_dmastart(sc->sc_isa, sc->sc_drq, buf, cc, NULL,
1542: sc->sc_dma_flags, BUS_DMA_NOWAIT);
1543: DPRINTF(("ad1848_dma_init_output: %p %d\n", buf, cc));
1544: return 0;
1545: }
1546:
1547: int
1548: ad1848_dma_output(addr, p, cc, intr, arg)
1549: void *addr;
1550: void *p;
1551: int cc;
1552: void (*intr)(void *);
1553: void *arg;
1554: {
1555: struct ad1848_softc *sc = addr;
1556: u_char reg;
1557:
1558: if (sc->sc_locked) {
1559: DPRINTF(("ad1848_dma_output: locked\n"));
1560: return 0;
1561: }
1562:
1563: #ifdef AUDIO_DEBUG
1564: if (ad1848debug > 0)
1565: printf("ad1848_dma_output: cc=%d at %p %p (%p)\n", cc, p, intr, arg);
1566: #endif
1567: sc->sc_locked = 1;
1568: sc->sc_intr = intr;
1569: sc->sc_arg = arg;
1570:
1571: switch (sc->sc_playrun) {
1572: case NOTRUNNING:
1573: sc->sc_dma_flags = DMAMODE_WRITE;
1574: sc->sc_dma_bp = p;
1575: sc->sc_dma_cnt = cc;
1576: isa_dmastart(sc->sc_isa, sc->sc_drq, p, cc, NULL,
1577: DMAMODE_WRITE, BUS_DMA_NOWAIT);
1578: goto startpcm;
1579: case DMARUNNING:
1580: sc->sc_playrun = PCMRUNNING;
1581: startpcm:
1582: if (sc->precision == 16)
1583: cc >>= 1;
1584: if (sc->channels == 2)
1585: cc >>= 1;
1586: cc--;
1587:
1588: if (sc->sc_lastcc != cc || sc->sc_mode != AUMODE_PLAY) {
1589: ad_write(sc, SP_LOWER_BASE_COUNT, (u_char)(cc & 0xff));
1590: ad_write(sc, SP_UPPER_BASE_COUNT, (u_char)((cc >> 8) & 0xff));
1591:
1592: reg = ad_read(sc, SP_INTERFACE_CONFIG);
1593: ad_write(sc, SP_INTERFACE_CONFIG, (PLAYBACK_ENABLE|reg));
1594:
1595: sc->sc_lastcc = cc;
1596: sc->sc_mode = AUMODE_PLAY;
1597: }
1598: break;
1599: case PCMRUNNING:
1600: break;
1601: }
1602:
1603: return 0;
1604: }
1605:
1606: int
1607: ad1848_intr(arg)
1608: void *arg;
1609: {
1610: struct ad1848_softc *sc = arg;
1611: int retval = 0;
1612: u_char status;
1613:
1614: /* Get intr status */
1615: status = ADREAD(sc, AD1848_STATUS);
1616:
1617: #ifdef AUDIO_DEBUG
1618: if (ad1848debug > 1)
1619: printf("ad1848_intr: intr=%p status=%x\n", sc->sc_intr, status);
1620: #endif
1621: sc->sc_locked = 0;
1622: sc->sc_interrupts++;
1623:
1624: /* Handle interrupt */
1625: if (sc->sc_intr && (status & INTERRUPT_STATUS)) {
1626: /* ACK DMA read because it may be in a bounce buffer */
1627: /* XXX Do write to mask DMA ? */
1628: if ((sc->sc_dma_flags & DMAMODE_READ) && sc->sc_recrun == NOTRUNNING)
1629: isa_dmadone(sc->sc_isa, sc->sc_recdrq);
1630: (*sc->sc_intr)(sc->sc_arg);
1631: retval = 1;
1632: }
1633:
1634: /* clear interrupt */
1635: if (status & INTERRUPT_STATUS)
1636: ADWRITE(sc, AD1848_STATUS, 0);
1637:
1638: return(retval);
1639: }
1640:
1641: void *
1642: ad1848_malloc(addr, direction, size, pool, flags)
1643: void *addr;
1644: int direction;
1645: size_t size;
1646: int pool;
1647: int flags;
1648: {
1649: struct ad1848_softc *sc = addr;
1650: int drq;
1651:
1652: if (sc->sc_mode == AUMODE_RECORD)
1653: drq = sc->sc_recdrq == -1 ? sc->sc_drq : sc->sc_recdrq;
1654: else
1655: drq = sc->sc_drq;
1656:
1657: return isa_malloc(sc->sc_isa, drq, size, pool, flags);
1658: }
1659:
1660: void
1661: ad1848_free(addr, ptr, pool)
1662: void *addr;
1663: void *ptr;
1664: int pool;
1665: {
1666: isa_free(ptr, pool);
1667: }
1668:
1669: size_t
1670: ad1848_round(addr, direction, size)
1671: void *addr;
1672: int direction;
1673: size_t size;
1674: {
1675: if (size > MAX_ISADMA)
1676: size = MAX_ISADMA;
1677: return size;
1678: }
1679:
1680: paddr_t
1681: ad1848_mappage(addr, mem, off, prot)
1682: void *addr;
1683: void *mem;
1684: off_t off;
1685: int prot;
1686: {
1687: return isa_mappage(mem, off, prot);
1688: }
1689:
1690: int
1691: ad1848_get_props(addr)
1692: void *addr;
1693: {
1694: struct ad1848_softc *sc = addr;
1695:
1696: return AUDIO_PROP_MMAP |
1697: (sc->sc_drq != sc->sc_recdrq ? AUDIO_PROP_FULLDUPLEX : 0);
1698: }
CVSweb