1 /* $NetBSD: ad1848_isa.c,v 1.35 2008/04/28 18:49:27 garbled Exp $ */
4 * Copyright (c) 1999 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Ken Hornstein and John Kohl.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 * Copyright (c) 1994 John Brezak
33 * Copyright (c) 1991-1993 Regents of the University of California.
34 * All rights reserved.
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. All advertising materials mentioning features or use of this software
45 * must display the following acknowledgement:
46 * This product includes software developed by the Computer Systems
47 * Engineering Group at Lawrence Berkeley Laboratory.
48 * 4. Neither the name of the University nor of the Laboratory may be used
49 * to endorse or promote products derived from this software without
50 * specific prior written permission.
52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
67 * Copyright by Hannu Savolainen 1994
69 * Redistribution and use in source and binary forms, with or without
70 * modification, are permitted provided that the following conditions are
71 * met: 1. Redistributions of source code must retain the above copyright
72 * notice, this list of conditions and the following disclaimer. 2.
73 * Redistributions in binary form must reproduce the above copyright notice,
74 * this list of conditions and the following disclaimer in the documentation
75 * and/or other materials provided with the distribution.
77 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
78 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
79 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
80 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
81 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
82 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
83 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
84 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
85 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
86 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
91 * Portions of this code are from the VOXware support for the ad1848
92 * by Hannu Savolainen <hannu@voxware.pp.fi>
94 * Portions also supplied from the SoundBlaster driver for NetBSD.
97 #include <sys/cdefs.h>
98 __KERNEL_RCSID(0, "$NetBSD: ad1848_isa.c,v 1.35 2008/04/28 18:49:27 garbled Exp $");
100 #include <sys/param.h>
101 #include <sys/systm.h>
102 #include <sys/errno.h>
103 #include <sys/ioctl.h>
104 #include <sys/syslog.h>
105 #include <sys/device.h>
106 #include <sys/proc.h>
112 #include <sys/audioio.h>
114 #include <dev/audio_if.h>
115 #include <dev/auconv.h>
117 #include <dev/isa/isavar.h>
118 #include <dev/isa/isadmavar.h>
120 #include <dev/ic/ad1848reg.h>
121 #include <dev/ic/cs4231reg.h>
122 #include <dev/ic/cs4237reg.h>
123 #include <dev/isa/ad1848var.h>
124 #include <dev/isa/cs4231var.h>
127 #define DPRINTF(x) if (ad1848debug) printf x
128 extern int ad1848debug
;
133 static int ad1848_isa_read( struct ad1848_softc
*, int);
134 static void ad1848_isa_write( struct ad1848_softc
*, int, int);
137 ad1848_isa_read(struct ad1848_softc
*sc
, int index
)
140 return bus_space_read_1(sc
->sc_iot
, sc
->sc_ioh
, index
);
144 ad1848_isa_write(struct ad1848_softc
*sc
, int index
, int value
)
147 bus_space_write_1(sc
->sc_iot
, sc
->sc_ioh
, index
, value
);
151 * Map and probe for the ad1848 chip
154 ad1848_isa_mapprobe(struct ad1848_isa_softc
*isc
, int iobase
)
156 struct ad1848_softc
*sc
;
158 sc
= &isc
->sc_ad1848
;
159 if (!AD1848_BASE_VALID(iobase
)) {
161 printf("ad1848: configured iobase %04x invalid\n", iobase
);
166 /* Map the AD1848 ports */
167 if (bus_space_map(sc
->sc_iot
, iobase
, AD1848_NPORT
, 0, &sc
->sc_ioh
))
170 if (!ad1848_isa_probe(isc
)) {
171 bus_space_unmap(sc
->sc_iot
, sc
->sc_ioh
, AD1848_NPORT
);
178 * Probe for the ad1848 chip
181 ad1848_isa_probe(struct ad1848_isa_softc
*isc
)
183 struct ad1848_softc
*sc
;
184 u_char tmp
, tmp1
= 0xff, tmp2
= 0xff;
187 sc
= &isc
->sc_ad1848
;
188 sc
->sc_readreg
= ad1848_isa_read
;
189 sc
->sc_writereg
= ad1848_isa_write
;
191 /* Is there an ad1848 chip ? */
192 sc
->MCE_bit
= MODE_CHANGE_ENABLE
;
193 sc
->mode
= 1; /* MODE 1 = original ad1848/ad1846/cs4248 */
196 * Check that the I/O address is in use.
198 * The SP_IN_INIT bit of the base I/O port is known to be 0 after the
199 * chip has performed its power-on initialization. Just assume
200 * this has happened before the OS is starting.
202 * If the I/O address is unused, inb() typically returns 0xff.
204 tmp
= ADREAD(sc
, AD1848_IADDR
);
205 if (tmp
& SP_IN_INIT
) { /* Not a AD1848 */
206 DPRINTF(("ad_detect_A %x\n", tmp
));
211 * Test if it's possible to change contents of the indirect registers.
212 * Registers 0 and 1 are ADC volume registers. The bit 0x10 is read
213 * only so try to avoid using it. The bit 0x20 is the mic preamp
214 * enable; on some chips it is always the same in both registers, so
215 * we avoid tests where they are different.
217 ad_write(sc
, 0, 0x8a);
218 ad_write(sc
, 1, 0x45); /* 0x55 with bit 0x10 clear */
219 tmp1
= ad_read(sc
, 0);
220 tmp2
= ad_read(sc
, 1);
222 if (tmp1
!= 0x8a || tmp2
!= 0x45) {
223 DPRINTF(("ad_detect_B (%x/%x)\n", tmp1
, tmp2
));
227 ad_write(sc
, 0, 0x65);
228 ad_write(sc
, 1, 0xaa);
229 tmp1
= ad_read(sc
, 0);
230 tmp2
= ad_read(sc
, 1);
232 if (tmp1
!= 0x65 || tmp2
!= 0xaa) {
233 DPRINTF(("ad_detect_C (%x/%x)\n", tmp1
, tmp2
));
238 * The indirect register I12 has some read only bits. Lets
239 * try to change them.
241 tmp
= ad_read(sc
, SP_MISC_INFO
);
242 ad_write(sc
, SP_MISC_INFO
, (~tmp
) & 0x0f);
244 /* Here, AD1845 may sometimes be busy. Wait til it becomes ready. */
245 for (t
= 0; t
< 100000 && ADREAD(sc
, AD1848_IADDR
) & SP_IN_INIT
; t
++)
249 DPRINTF(("ad1848_isa_probe: t %d\n", t
));
252 if ((tmp
& 0x0f) != ((tmp1
= ad_read(sc
, SP_MISC_INFO
)) & 0x0f)) {
253 DPRINTF(("ad_detect_D (%x)\n", tmp1
));
258 * MSB and 4 LSBs of the reg I12 tell the chip revision.
260 * A preliminary version of the AD1846 data sheet stated that it
261 * used an ID field of 0x0B. The current version, however,
262 * states that the AD1846 uses ID 0x0A, just like the AD1848K.
264 * this switch statement will need updating as newer clones arrive....
266 switch (tmp1
& 0x8f) {
268 sc
->chip_name
= "AD1848J";
271 sc
->chip_name
= "AD1848K";
273 #if 0 /* See above */
275 sc
->chip_name
= "AD1846";
279 sc
->chip_name
= "CS4248revB"; /* or CS4231 rev B; see below */
282 sc
->chip_name
= "CS4248";
285 sc
->chip_name
= "broken"; /* CS4231/AD1845; see below */
288 sc
->chip_name
= "unknown";
289 DPRINTF(("ad1848: unknown codec version 0x%02x\n",
295 * The original AD1848/CS4248 has just 16 indirect registers. This
296 * means that I0 and I16 should return the same value (etc.).
297 * Ensure that the Mode2 enable bit of I12 is 0. Otherwise this test
298 * fails with CS4231, AD1845, etc.
300 ad_write(sc
, SP_MISC_INFO
, 0); /* Mode2 = disabled */
302 for (i
= 0; i
< 16; i
++)
303 if ((tmp1
= ad_read(sc
, i
)) != (tmp2
= ad_read(sc
, i
+ 16))) {
304 if (i
!= SP_TEST_AND_INIT
) {
305 DPRINTF(("ad_detect_F(%d/%x/%x)\n", i
, tmp1
, tmp2
));
311 * Try to switch the chip to mode2 (CS4231) by setting the MODE2 bit
312 * The bit 0x80 is always 1 in CS4248, CS4231, and AD1845.
314 ad_write(sc
, SP_MISC_INFO
, MODE2
); /* Set mode2, clear 0x80 */
316 tmp1
= ad_read(sc
, SP_MISC_INFO
);
317 if ((tmp1
& 0xc0) == (0x80 | MODE2
)) {
319 * CS4231 or AD1845 detected - is it?
321 * Verify that setting I2 doesn't change I18.
323 ad_write(sc
, 18, 0x88); /* Set I18 to known value */
325 ad_write(sc
, 2, 0x45);
326 if ((tmp2
= ad_read(sc
, 18)) != 0x45) { /* No change -> CS4231? */
327 ad_write(sc
, 2, 0xaa);
328 if ((tmp2
= ad_read(sc
, 18)) == 0xaa) { /* Rotten bits? */
329 DPRINTF(("ad_detect_H(%x)\n", tmp2
));
336 * It's a CS4231, or another clone with 32 registers.
337 * Let's find out which by checking I25.
339 if ((tmp1
& 0x8f) == 0x8a) {
340 tmp1
= ad_read(sc
, CS_VERSION_ID
);
341 switch (tmp1
& 0xe7) {
343 sc
->chip_name
= "CS4231A";
346 /* XXX I25 no good, AD1845 same as CS4231 */
349 * This test is correct only after reset
351 if (ad_read(sc
, 17) & 0xf0) {
352 sc
->chip_name
= "AD1845";
355 sc
->chip_name
= "CS4231";
358 sc
->chip_name
= "CS4232";
361 sc
->chip_name
= "CS4232C";
365 sc
->chip_name
= "CS4236";
368 * Try to switch to mode3 (CS4236B or
369 * CS4237B) by setting CMS to 3. A
370 * plain CS4236 will not react to
373 ad_write(sc
, SP_MISC_INFO
, MODE3
);
375 tmp1
= ad_read(sc
, CS_LEFT_LINE_CONTROL
);
376 ad_write(sc
, CS_LEFT_LINE_CONTROL
, 0xe0);
377 tmp2
= ad_read(sc
, CS_LEFT_LINE_CONTROL
);
380 * it's a CS4237B or another
381 * clone supporting mode 3.
382 * Let's determine which by
383 * enabling extended registers
386 tmp2
= ad_xread(sc
, CS_X_CHIP_VERSION
);
387 switch (tmp2
& X_CHIP_VERSIONF_CID
) {
388 case X_CHIP_CID_CS4236BB
:
389 sc
->chip_name
= "CS4236BrevB";
391 case X_CHIP_CID_CS4236B
:
392 sc
->chip_name
= "CS4236B";
394 case X_CHIP_CID_CS4237B
:
395 sc
->chip_name
= "CS4237B";
398 sc
->chip_name
= "CS4236B compatible";
399 DPRINTF(("cs4236: unknown mode 3 compatible codec, version 0x%02x\n", tmp2
));
405 /* restore volume control information */
406 ad_write(sc
, CS_LEFT_LINE_CONTROL
, tmp1
);
413 /* Wait for 1848 to init */
414 while (ADREAD(sc
, AD1848_IADDR
) & SP_IN_INIT
)
417 /* Wait for 1848 to autocal */
418 ADWRITE(sc
, AD1848_IADDR
, SP_TEST_AND_INIT
);
419 while (ADREAD(sc
, AD1848_IDATA
) & AUTO_CAL_IN_PROG
)
427 /* Unmap the I/O ports */
429 ad1848_isa_unmap(struct ad1848_isa_softc
*isc
)
431 struct ad1848_softc
*sc
;
433 sc
= &isc
->sc_ad1848
;
434 bus_space_unmap(sc
->sc_iot
, sc
->sc_ioh
, AD1848_NPORT
);
438 * Attach hardware to driver, attach hardware driver to audio
439 * pseudo-device driver .
442 ad1848_isa_attach(struct ad1848_isa_softc
*isc
)
444 struct ad1848_softc
*sc
;
447 sc
= &isc
->sc_ad1848
;
448 sc
->sc_readreg
= ad1848_isa_read
;
449 sc
->sc_writereg
= ad1848_isa_write
;
451 if (isc
->sc_playdrq
!= -1) {
452 isc
->sc_play_maxsize
= isa_dmamaxsize(isc
->sc_ic
,
454 error
= isa_dmamap_create(isc
->sc_ic
, isc
->sc_playdrq
,
455 isc
->sc_play_maxsize
, BUS_DMA_NOWAIT
|BUS_DMA_ALLOCNOW
);
457 aprint_error_dev(&sc
->sc_dev
, "can't create map for drq %d\n",
462 if (isc
->sc_recdrq
!= -1 && isc
->sc_recdrq
!= isc
->sc_playdrq
) {
463 isc
->sc_rec_maxsize
= isa_dmamaxsize(isc
->sc_ic
,
465 error
= isa_dmamap_create(isc
->sc_ic
, isc
->sc_recdrq
,
466 isc
->sc_rec_maxsize
, BUS_DMA_NOWAIT
|BUS_DMA_ALLOCNOW
);
468 aprint_error_dev(&sc
->sc_dev
, "can't create map for drq %d\n",
470 isa_dmamap_destroy(isc
->sc_ic
, isc
->sc_playdrq
);
479 ad1848_isa_open(void *addr
, int flags
)
481 struct ad1848_isa_softc
*isc
;
482 struct ad1848_softc
*sc
;
486 sc
= &isc
->sc_ad1848
;
487 DPRINTF(("ad1848_isa_open: sc=%p\n", isc
));
490 if (isc
->sc_playdrq
!= -1) {
491 error
= isa_drq_alloc(isc
->sc_ic
, isc
->sc_playdrq
);
496 if (isc
->sc_recdrq
!= -1 && isc
->sc_recdrq
!= isc
->sc_playdrq
) {
497 error
= isa_drq_alloc(isc
->sc_ic
, isc
->sc_recdrq
);
503 #ifndef AUDIO_NO_POWER_CTL
506 isc
->powerctl(isc
->powerarg
, flags
);
509 /* Init and mute wave output */
510 ad1848_mute_wave_output(sc
, WAVE_MUTE2_INIT
, 1);
512 error
= ad1848_open(sc
, flags
);
514 #ifndef AUDIO_NO_POWER_CTL
516 isc
->powerctl(isc
->powerarg
, 0);
521 DPRINTF(("ad1848_isa_open: opened\n"));
526 isa_drq_free(isc
->sc_ic
, isc
->sc_playdrq
);
528 isa_drq_free(isc
->sc_ic
, isc
->sc_recdrq
);
534 * Close function is called at splaudio().
537 ad1848_isa_close(void *addr
)
539 struct ad1848_isa_softc
*isc
;
540 struct ad1848_softc
*sc
;
542 DPRINTF(("ad1848_isa_close: stop DMA\n"));
544 sc
= &isc
->sc_ad1848
;
547 #ifndef AUDIO_NO_POWER_CTL
548 /* Power-down chip */
550 isc
->powerctl(isc
->powerarg
, 0);
553 if (isc
->sc_playdrq
!= -1)
554 isa_drq_free(isc
->sc_ic
, isc
->sc_playdrq
);
555 if (isc
->sc_recdrq
!= -1 && isc
->sc_recdrq
!= isc
->sc_playdrq
)
556 isa_drq_free(isc
->sc_ic
, isc
->sc_recdrq
);
560 ad1848_isa_trigger_input(
562 void *start
, void *end
,
564 void (*intr
)(void *),
566 const audio_params_t
*param
)
568 struct ad1848_isa_softc
*isc
;
569 struct ad1848_softc
*sc
;
573 sc
= &isc
->sc_ad1848
;
574 isa_dmastart(isc
->sc_ic
, isc
->sc_recdrq
, start
,
575 (char *)end
- (char *)start
, NULL
,
576 DMAMODE_READ
| DMAMODE_LOOPDEMAND
, BUS_DMA_NOWAIT
);
579 if (sc
->mode
== 2 && isc
->sc_playdrq
!= isc
->sc_recdrq
) {
580 isc
->sc_rintr
= intr
;
583 isc
->sc_pintr
= intr
;
588 * Calculate number of transfers.
589 * Note that ADPCM is always transferred 4 bytes at at a time.
591 blksize
= (param
->encoding
== AUDIO_ENCODING_ADPCM
) ? blksize
/ 4 - 1 :
592 (blksize
* 8) / (param
->precision
* param
->channels
) - 1;
595 ad_write(sc
, CS_LOWER_REC_CNT
, blksize
& 0xff);
596 ad_write(sc
, CS_UPPER_REC_CNT
, blksize
>> 8);
598 ad_write(sc
, SP_LOWER_BASE_COUNT
, blksize
& 0xff);
599 ad_write(sc
, SP_UPPER_BASE_COUNT
, blksize
>> 8);
602 reg
= ad_read(sc
, SP_INTERFACE_CONFIG
);
603 ad_write(sc
, SP_INTERFACE_CONFIG
, CAPTURE_ENABLE
|reg
);
609 ad1848_isa_trigger_output(
611 void *start
, void *end
,
613 void (*intr
)(void *),
615 const audio_params_t
*param
)
617 struct ad1848_isa_softc
*isc
;
618 struct ad1848_softc
*sc
;
622 sc
= &isc
->sc_ad1848
;
623 isa_dmastart(isc
->sc_ic
, isc
->sc_playdrq
, start
,
624 (char *)end
- (char *)start
, NULL
,
625 DMAMODE_WRITE
| DMAMODE_LOOPDEMAND
, BUS_DMA_NOWAIT
);
628 isc
->sc_pintr
= intr
;
632 * Calculate number of transfers.
633 * Note that ADPCM is always transferred 4 bytes at at a time.
635 blksize
= (param
->encoding
== AUDIO_ENCODING_ADPCM
) ? blksize
/ 4 - 1 :
636 (blksize
* 8) / (param
->precision
* param
->channels
) - 1;
638 ad_write(sc
, SP_LOWER_BASE_COUNT
, blksize
& 0xff);
639 ad_write(sc
, SP_UPPER_BASE_COUNT
, blksize
>> 8);
641 /* Unmute wave output */
642 ad1848_mute_wave_output(sc
, WAVE_MUTE2
, 0);
644 reg
= ad_read(sc
, SP_INTERFACE_CONFIG
);
645 ad_write(sc
, SP_INTERFACE_CONFIG
, PLAYBACK_ENABLE
|reg
);
651 ad1848_isa_halt_input(void *addr
)
653 struct ad1848_isa_softc
*isc
;
654 struct ad1848_softc
*sc
;
657 sc
= &isc
->sc_ad1848
;
658 if (isc
->sc_recrun
) {
659 ad1848_halt_input(sc
);
660 isa_dmaabort(isc
->sc_ic
, isc
->sc_recdrq
);
668 ad1848_isa_halt_output(void *addr
)
670 struct ad1848_isa_softc
*isc
;
671 struct ad1848_softc
*sc
;
674 sc
= &isc
->sc_ad1848
;
675 if (isc
->sc_playrun
) {
676 /* Mute wave output */
677 ad1848_mute_wave_output(sc
, WAVE_MUTE2
, 1);
679 ad1848_halt_output(sc
);
680 isa_dmaabort(isc
->sc_ic
, isc
->sc_playdrq
);
688 ad1848_isa_intr(void *arg
)
690 struct ad1848_isa_softc
*isc
;
691 struct ad1848_softc
*sc
;
696 sc
= &isc
->sc_ad1848
;
698 /* Get intr status */
699 status
= ADREAD(sc
, AD1848_STATUS
);
703 printf("ad1848_isa_intr: pintr=%p rintr=%p status=%x\n",
704 isc
->sc_pintr
, isc
->sc_rintr
, status
);
706 isc
->sc_interrupts
++;
708 /* Handle interrupt */
709 if ((status
& INTERRUPT_STATUS
) != 0) {
710 if (sc
->mode
== 2 && isc
->sc_playdrq
!= isc
->sc_recdrq
) {
711 status
= ad_read(sc
, CS_IRQ_STATUS
);
712 if ((status
& CS_IRQ_PI
) && isc
->sc_playrun
) {
713 (*isc
->sc_pintr
)(isc
->sc_parg
);
716 if ((status
& CS_IRQ_CI
) && isc
->sc_recrun
) {
717 (*isc
->sc_rintr
)(isc
->sc_rarg
);
721 if (isc
->sc_playrun
) {
722 (*isc
->sc_pintr
)(isc
->sc_parg
);
727 /* Clear interrupt */
728 ADWRITE(sc
, AD1848_STATUS
, 0);
738 struct malloc_type
*pool
,
741 struct ad1848_isa_softc
*isc
;
745 if (direction
== AUMODE_PLAY
)
746 drq
= isc
->sc_playdrq
;
748 drq
= isc
->sc_recdrq
;
749 return isa_malloc(isc
->sc_ic
, drq
, size
, pool
, flags
);
753 ad1848_isa_free(void *addr
, void *ptr
, struct malloc_type
*pool
)
760 ad1848_isa_round_buffersize(void *addr
, int direction
, size_t size
)
762 struct ad1848_isa_softc
*isc
;
766 if (direction
== AUMODE_PLAY
)
767 maxsize
= isc
->sc_play_maxsize
;
768 else if (isc
->sc_recdrq
== isc
->sc_playdrq
)
769 maxsize
= isc
->sc_play_maxsize
;
771 maxsize
= isc
->sc_rec_maxsize
;
779 ad1848_isa_mappage(void *addr
, void *mem
, off_t off
, int prot
)
781 return isa_mappage(mem
, off
, prot
);
785 ad1848_isa_get_props(void *addr
)
787 struct ad1848_isa_softc
*isc
;
790 return AUDIO_PROP_MMAP
|
791 (isc
->sc_playdrq
!= isc
->sc_recdrq
? AUDIO_PROP_FULLDUPLEX
: 0);