1 /* $NetBSD: cs4231_sbus.c,v 1.20 2002/03/27 16:03:52 pk Exp $ */ 2 3 /*- 4 * Copyright (c) 1998, 1999, 2002 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Paul Kranenburg. 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 the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 #include <sys/cdefs.h> 40 __KERNEL_RCSID(0, "$NetBSD: cs4231_sbus.c,v 1.20 2002/03/27 16:03:52 pk Exp $"); 41 42 #include "audio.h" 43 #if NAUDIO > 0 44 45 #include <sys/param.h> 46 #include <sys/systm.h> 47 #include <sys/errno.h> 48 #include <sys/device.h> 49 #include <sys/malloc.h> 50 51 #include <machine/bus.h> 52 #include <machine/intr.h> 53 54 #include <dev/sbus/sbusvar.h> 55 56 #include <sys/audioio.h> 57 #include <dev/audio_if.h> 58 59 #include <dev/ic/ad1848reg.h> 60 #include <dev/ic/cs4231reg.h> 61 #include <dev/ic/ad1848var.h> 62 #include <dev/ic/cs4231var.h> 63 64 #include <dev/ic/apcdmareg.h> 65 66 #ifdef AUDIO_DEBUG 67 int cs4231_sbus_debug = 0; 68 #define DPRINTF(x) if (cs4231_sbus_debug) printf x 69 #else 70 #define DPRINTF(x) 71 #endif 72 73 /* where APC DMA registers are located */ 74 #define CS4231_APCDMA_OFFSET 16 75 76 /* interrupt enable bits except those specific for playback/capture */ 77 #define APC_ENABLE (APC_EI | APC_IE | APC_EIE) 78 79 struct cs4231_sbus_softc { 80 struct cs4231_softc sc_cs4231; 81 82 struct sbusdev sc_sd; /* sbus device */ 83 bus_space_tag_t sc_bt; /* DMA controller tag */ 84 bus_space_handle_t sc_bh; /* DMA controller registers */ 85 }; 86 87 88 static int cs4231_sbus_match(struct device *, struct cfdata *, void *); 89 static void cs4231_sbus_attach(struct device *, struct device *, void *); 90 91 struct cfattach audiocs_sbus_ca = { 92 sizeof(struct cs4231_sbus_softc), cs4231_sbus_match, cs4231_sbus_attach 93 }; 94 95 96 97 /* audio_hw_if methods specific to apc dma */ 98 static int cs4231_sbus_trigger_output(void *, void *, void *, int, 99 void (*)(void *), void *, 100 struct audio_params *); 101 static int cs4231_sbus_trigger_input(void *, void *, void *, int, 102 void (*)(void *), void *, 103 struct audio_params *); 104 static int cs4231_sbus_halt_output(void *); 105 static int cs4231_sbus_halt_input(void *); 106 107 struct audio_hw_if audiocs_sbus_hw_if = { 108 cs4231_open, 109 cs4231_close, 110 NULL, /* drain */ 111 ad1848_query_encoding, 112 ad1848_set_params, 113 cs4231_round_blocksize, 114 ad1848_commit_settings, 115 NULL, /* init_output */ 116 NULL, /* init_input */ 117 NULL, /* start_output */ 118 NULL, /* start_input */ 119 cs4231_sbus_halt_output, 120 cs4231_sbus_halt_input, 121 NULL, /* speaker_ctl */ 122 cs4231_getdev, 123 NULL, /* setfd */ 124 cs4231_set_port, 125 cs4231_get_port, 126 cs4231_query_devinfo, 127 cs4231_malloc, 128 cs4231_free, 129 cs4231_round_buffersize, 130 NULL, /* mappage */ 131 cs4231_get_props, 132 cs4231_sbus_trigger_output, 133 cs4231_sbus_trigger_input, 134 NULL, /* dev_ioctl */ 135 }; 136 137 138 #ifdef AUDIO_DEBUG 139 static void cs4231_sbus_regdump(char *, struct cs4231_sbus_softc *); 140 #endif 141 142 static int cs4231_sbus_intr(void *); 143 144 145 146 static int 147 cs4231_sbus_match(parent, cf, aux) 148 struct device *parent; 149 struct cfdata *cf; 150 void *aux; 151 { 152 struct sbus_attach_args *sa = aux; 153 154 return (strcmp(sa->sa_name, AUDIOCS_PROM_NAME) == 0); 155 } 156 157 158 static void 159 cs4231_sbus_attach(parent, self, aux) 160 struct device *parent, *self; 161 void *aux; 162 { 163 struct cs4231_sbus_softc *sbsc = (struct cs4231_sbus_softc *)self; 164 struct cs4231_softc *sc = &sbsc->sc_cs4231; 165 struct sbus_attach_args *sa = aux; 166 bus_space_handle_t bh; 167 168 sbsc->sc_bt = sc->sc_bustag = sa->sa_bustag; 169 sc->sc_dmatag = sa->sa_dmatag; 170 171 /* 172 * Map my registers in, if they aren't already in virtual 173 * address space. 174 */ 175 if (sa->sa_npromvaddrs) { 176 sbus_promaddr_to_handle(sa->sa_bustag, 177 sa->sa_promvaddrs[0], &bh); 178 } else { 179 if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, 180 sa->sa_offset, sa->sa_size, 0, &bh) != 0) { 181 printf("%s @ sbus: cannot map registers\n", 182 self->dv_xname); 183 return; 184 } 185 } 186 187 bus_space_subregion(sa->sa_bustag, bh, CS4231_APCDMA_OFFSET, 188 sizeof(struct apc_dma), &sbsc->sc_bh); 189 190 cs4231_common_attach(sc, bh); 191 printf("\n"); 192 193 sbus_establish(&sbsc->sc_sd, &sc->sc_ad1848.sc_dev); 194 195 /* Establish interrupt channel */ 196 if (sa->sa_nintr) 197 bus_intr_establish(sa->sa_bustag, 198 sa->sa_pri, IPL_AUDIO, 0, 199 cs4231_sbus_intr, sbsc); 200 201 audio_attach_mi(&audiocs_sbus_hw_if, sbsc, &sc->sc_ad1848.sc_dev); 202 } 203 204 205 #ifdef AUDIO_DEBUG 206 static void 207 cs4231_sbus_regdump(label, sc) 208 char *label; 209 struct cs4231_sbus_softc *sc; 210 { 211 char bits[128]; 212 volatile struct apc_dma *dma = NULL; 213 214 printf("cs4231regdump(%s): regs:", label); 215 printf("dmapva: 0x%x; ", 216 bus_space_read_4(sc->sc_bh, sc->sc_bh, &dma->dmapva)); 217 printf("dmapc: 0x%x; ", 218 bus_space_read_4(sc->sc_bh, sc->sc_bh, &dma->dmapc)); 219 printf("dmapnva: 0x%x; ", 220 bus_space_read_4(sc->sc_bh, sc->sc_bh, &dma->dmapnva)); 221 printf("dmapnc: 0x%x\n", 222 bus_space_read_4(sc->sc_bh, sc->sc_bh, &dma->dmapnc)); 223 printf("dmacva: 0x%x; ", 224 bus_space_read_4(sc->sc_bh, sc->sc_bh, &dma->dmacva)); 225 printf("dmacc: 0x%x; ", 226 bus_space_read_4(sc->sc_bh, sc->sc_bh, &dma->dmacc)); 227 printf("dmacnva: 0x%x; ", 228 bus_space_read_4(sc->sc_bh, sc->sc_bh, &dma->dmacnva)); 229 printf("dmacnc: 0x%x\n", 230 bus_space_read_4(sc->sc_bh, sc->sc_bh, &dma->dmacnc)); 231 232 printf("apc_dmacsr=%s\n", 233 bitmask_snprintf( 234 bus_space_read_4(sc->sc_bh, sc->sc_bh, &dma->dmacsr), 235 APC_BITS, bits, sizeof(bits))); 236 237 ad1848_dump_regs(&sc->sc_cs4231.sc_ad1848); 238 } 239 #endif /* AUDIO_DEBUG */ 240 241 242 static int 243 cs4231_sbus_trigger_output(addr, start, end, blksize, intr, arg, param) 244 void *addr; 245 void *start, *end; 246 int blksize; 247 void (*intr)(void *); 248 void *arg; 249 struct audio_params *param; 250 { 251 struct cs4231_sbus_softc *sbsc = addr; 252 struct cs4231_softc *sc = &sbsc->sc_cs4231; 253 struct cs_transfer *t = &sc->sc_playback; 254 volatile struct apc_dma *dma = NULL; 255 u_int32_t csr; 256 bus_addr_t dmaaddr; 257 bus_size_t dmasize; 258 int ret; 259 #ifdef AUDIO_DEBUG 260 char bits[128]; 261 #endif 262 263 ret = cs4231_transfer_init(sc, t, &dmaaddr, &dmasize, 264 start, end, blksize, intr, arg); 265 if (ret != 0) 266 return (ret); 267 268 DPRINTF(("trigger_output: was: %x %d, %x %d\n", 269 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmapva), 270 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmapc), 271 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmapnva), 272 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmapnc))); 273 274 /* load first block */ 275 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmapnva, dmaaddr); 276 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmapnc, dmasize); 277 278 DPRINTF(("trigger_output: 1st: %x %d, %x %d\n", 279 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmapva), 280 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmapc), 281 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmapnva), 282 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmapnc))); 283 284 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacsr); 285 DPRINTF(("trigger_output: csr=%s\n", 286 bitmask_snprintf(csr, APC_BITS, bits, sizeof(bits)))); 287 if ((csr & PDMA_GO) == 0 || (csr & APC_PPAUSE) != 0) { 288 int cfg; 289 290 csr &= ~(APC_PPAUSE | APC_PMIE | APC_INTR_MASK); 291 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacsr, csr); 292 293 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacsr); 294 csr &= ~APC_INTR_MASK; 295 csr |= APC_ENABLE | APC_PIE | APC_PMIE | PDMA_GO; 296 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacsr, csr); 297 298 ad_write(&sc->sc_ad1848, SP_LOWER_BASE_COUNT, 0xff); 299 ad_write(&sc->sc_ad1848, SP_UPPER_BASE_COUNT, 0xff); 300 301 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 302 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG, 303 (cfg | PLAYBACK_ENABLE)); 304 } else { 305 DPRINTF(("trigger_output: already: csr=%s\n", 306 bitmask_snprintf(csr, APC_BITS, bits, sizeof(bits)))); 307 } 308 309 /* load next block if we can */ 310 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacsr); 311 if (csr & APC_PD) { 312 cs4231_transfer_advance(t, &dmaaddr, &dmasize); 313 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmapnva, dmaaddr); 314 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmapnc, dmasize); 315 316 DPRINTF(("trigger_output: 2nd: %x %d, %x %d\n", 317 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmapva), 318 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmapc), 319 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmapnva), 320 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmapnc))); 321 } 322 323 return (0); 324 } 325 326 327 static int 328 cs4231_sbus_halt_output(addr) 329 void *addr; 330 { 331 struct cs4231_sbus_softc *sbsc = addr; 332 struct cs4231_softc *sc = &sbsc->sc_cs4231; 333 volatile struct apc_dma *dma = NULL; 334 u_int32_t csr; 335 int cfg; 336 #ifdef AUDIO_DEBUG 337 char bits[128]; 338 #endif 339 340 sc->sc_playback.t_active = 0; 341 342 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacsr); 343 DPRINTF(("halt_output: csr=%s\n", 344 bitmask_snprintf(csr, APC_BITS, bits, sizeof(bits)))); 345 346 csr &= ~APC_INTR_MASK; /* do not clear interrupts accidentally */ 347 csr |= APC_PPAUSE; /* pause playback (let current complete) */ 348 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacsr, csr); 349 350 /* let the curernt transfer complete */ 351 if (csr & PDMA_GO) 352 do { 353 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, 354 (vaddr_t)&dma->dmacsr); 355 DPRINTF(("halt_output: csr=%s\n", 356 bitmask_snprintf(csr, APC_BITS, 357 bits, sizeof(bits)))); 358 } while ((csr & APC_PM) == 0); 359 360 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 361 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG,(cfg & ~PLAYBACK_ENABLE)); 362 363 return (0); 364 } 365 366 367 /* NB: we don't enable APC_CMIE and won't use APC_CM */ 368 static int 369 cs4231_sbus_trigger_input(addr, start, end, blksize, intr, arg, param) 370 void *addr; 371 void *start, *end; 372 int blksize; 373 void (*intr)(void *); 374 void *arg; 375 struct audio_params *param; 376 { 377 struct cs4231_sbus_softc *sbsc = addr; 378 struct cs4231_softc *sc = &sbsc->sc_cs4231; 379 struct cs_transfer *t = &sc->sc_capture; 380 volatile struct apc_dma *dma = NULL; 381 u_int32_t csr; 382 bus_addr_t dmaaddr; 383 bus_size_t dmasize; 384 int ret; 385 #ifdef AUDIO_DEBUG 386 char bits[128]; 387 #endif 388 389 ret = cs4231_transfer_init(sc, t, &dmaaddr, &dmasize, 390 start, end, blksize, intr, arg); 391 if (ret != 0) 392 return (ret); 393 394 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacsr); 395 DPRINTF(("trigger_input: csr=%s\n", 396 bitmask_snprintf(csr, APC_BITS, bits, sizeof(bits)))); 397 DPRINTF(("trigger_input: was: %x %d, %x %d\n", 398 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacva), 399 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacc), 400 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacnva), 401 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacnc))); 402 403 /* supply first block */ 404 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacnva, dmaaddr); 405 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacnc, dmasize); 406 407 DPRINTF(("trigger_input: 1st: %x %d, %x %d\n", 408 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacva), 409 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacc), 410 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacnva), 411 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacnc))); 412 413 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacsr); 414 if ((csr & CDMA_GO) == 0 || (csr & APC_CPAUSE) != 0) { 415 int cfg; 416 417 csr &= ~(APC_CPAUSE | APC_CMIE | APC_INTR_MASK); 418 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacsr, csr); 419 420 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacsr); 421 csr &= ~APC_INTR_MASK; 422 csr |= APC_ENABLE | APC_CIE | CDMA_GO; 423 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacsr, csr); 424 425 ad_write(&sc->sc_ad1848, CS_LOWER_REC_CNT, 0xff); 426 ad_write(&sc->sc_ad1848, CS_UPPER_REC_CNT, 0xff); 427 428 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 429 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG, 430 (cfg | CAPTURE_ENABLE)); 431 } else { 432 DPRINTF(("trigger_input: already: csr=%s\n", 433 bitmask_snprintf(csr, APC_BITS, bits, sizeof(bits)))); 434 } 435 436 /* supply next block if we can */ 437 if (dma->dmacsr & APC_CD) { 438 cs4231_transfer_advance(t, &dmaaddr, &dmasize); 439 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacnva, dmaaddr); 440 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacnc, dmasize); 441 DPRINTF(("trigger_input: 2nd: %x %d, %x %d\n", 442 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacva), 443 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacc), 444 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacnva), 445 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacnc))); 446 } 447 448 return (0); 449 } 450 451 452 static int 453 cs4231_sbus_halt_input(addr) 454 void *addr; 455 { 456 struct cs4231_sbus_softc *sbsc = addr; 457 struct cs4231_softc *sc = &sbsc->sc_cs4231; 458 volatile struct apc_dma *dma = NULL; 459 u_int32_t csr; 460 int cfg; 461 #ifdef AUDIO_DEBUG 462 char bits[128]; 463 #endif 464 465 sc->sc_capture.t_active = 0; 466 467 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacsr); 468 DPRINTF(("halt_input: csr=%s\n", 469 bitmask_snprintf(csr, APC_BITS, bits, sizeof(bits)))); 470 471 csr &= ~APC_INTR_MASK; /* do not clear interrupts accidentally */ 472 csr |= APC_CPAUSE; 473 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacsr, csr); 474 475 /* let the curernt transfer complete */ 476 if (csr & CDMA_GO) 477 do { 478 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, 479 (vaddr_t)&dma->dmacsr); 480 DPRINTF(("halt_input: csr=%s\n", 481 bitmask_snprintf(csr, APC_BITS, 482 bits, sizeof(bits)))); 483 } while ((csr & APC_CM) == 0); 484 485 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 486 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG, (cfg & ~CAPTURE_ENABLE)); 487 488 return (0); 489 } 490 491 492 static int 493 cs4231_sbus_intr(arg) 494 void *arg; 495 { 496 struct cs4231_sbus_softc *sbsc = arg; 497 struct cs4231_softc *sc = &sbsc->sc_cs4231; 498 volatile struct apc_dma *dma = NULL; 499 u_int32_t csr; 500 int status; 501 bus_addr_t dmaaddr; 502 bus_size_t dmasize; 503 int served; 504 #if defined(AUDIO_DEBUG) || defined(DIAGNOSTIC) 505 char bits[128]; 506 #endif 507 508 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacsr); 509 if ((csr & APC_INTR_MASK) == 0) /* any interrupt pedning? */ 510 return (0); 511 512 /* write back DMA status to clear interrupt */ 513 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, (vaddr_t)&dma->dmacsr, csr); 514 ++sc->sc_intrcnt.ev_count; 515 served = 0; 516 517 #ifdef AUDIO_DEBUG 518 if (cs4231_sbus_debug > 1) 519 cs4231_sbus_regdump("audiointr", sbsc); 520 #endif 521 522 status = ADREAD(&sc->sc_ad1848, AD1848_STATUS); 523 DPRINTF(("%s: status: %s\n", sc->sc_ad1848.sc_dev.dv_xname, 524 bitmask_snprintf(status, AD_R2_BITS, bits, sizeof(bits)))); 525 if (status & INTERRUPT_STATUS) { 526 #ifdef AUDIO_DEBUG 527 int reason; 528 529 reason = ad_read(&sc->sc_ad1848, CS_IRQ_STATUS); 530 DPRINTF(("%s: i24: %s\n", sc->sc_ad1848.sc_dev.dv_xname, 531 bitmask_snprintf(reason, CS_I24_BITS, bits, sizeof(bits)))); 532 #endif 533 /* clear ad1848 interrupt */ 534 ADWRITE(&sc->sc_ad1848, AD1848_STATUS, 0); 535 } 536 537 if (csr & APC_CI) { 538 if (csr & APC_CD) { /* can supply new block */ 539 struct cs_transfer *t = &sc->sc_capture; 540 541 cs4231_transfer_advance(t, &dmaaddr, &dmasize); 542 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, 543 (vaddr_t)&dma->dmacnva, dmaaddr); 544 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, 545 (vaddr_t)&dma->dmacnc, dmasize); 546 547 if (t->t_intr != NULL) 548 (*t->t_intr)(t->t_arg); 549 ++t->t_intrcnt.ev_count; 550 served = 1; 551 } 552 } 553 554 if (csr & APC_PMI) { 555 if (!sc->sc_playback.t_active) 556 served = 1; /* draining in halt_output() */ 557 } 558 559 if (csr & APC_PI) { 560 if (csr & APC_PD) { /* can load new block */ 561 struct cs_transfer *t = &sc->sc_playback; 562 563 if (t->t_active) { 564 cs4231_transfer_advance(t, &dmaaddr, &dmasize); 565 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, 566 (vaddr_t)&dma->dmapnva, dmaaddr); 567 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, 568 (vaddr_t)&dma->dmapnc, dmasize); 569 } 570 571 if (t->t_intr != NULL) 572 (*t->t_intr)(t->t_arg); 573 ++t->t_intrcnt.ev_count; 574 served = 1; 575 } 576 } 577 578 /* got an interrupt we don't know how to handle */ 579 if (!served) { 580 #ifdef DIAGNOSTIC 581 printf("%s: unhandled csr=%s\n", sc->sc_ad1848.sc_dev.dv_xname, 582 bitmask_snprintf(csr, APC_BITS, bits, sizeof(bits))); 583 #endif 584 /* evcnt? */ 585 } 586 587 return (1); 588 } 589 590 #endif /* NAUDIO > 0 */ 591