1 /* $NetBSD: cs4231_sbus.c,v 1.30 2004/10/29 12:57:26 yamt 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.30 2004/10/29 12:57:26 yamt 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 CFATTACH_DECL(audiocs_sbus, sizeof(struct cs4231_sbus_softc), 92 cs4231_sbus_match, cs4231_sbus_attach, NULL, NULL); 93 94 /* audio_hw_if methods specific to apc DMA */ 95 static int cs4231_sbus_trigger_output(void *, void *, void *, int, 96 void (*)(void *), void *, 97 struct audio_params *); 98 static int cs4231_sbus_trigger_input(void *, void *, void *, int, 99 void (*)(void *), void *, 100 struct audio_params *); 101 static int cs4231_sbus_halt_output(void *); 102 static int cs4231_sbus_halt_input(void *); 103 104 const struct audio_hw_if audiocs_sbus_hw_if = { 105 cs4231_open, 106 cs4231_close, 107 NULL, /* drain */ 108 ad1848_query_encoding, 109 ad1848_set_params, 110 NULL, /* round_blocksize */ 111 ad1848_commit_settings, 112 NULL, /* init_output */ 113 NULL, /* init_input */ 114 NULL, /* start_output */ 115 NULL, /* start_input */ 116 cs4231_sbus_halt_output, 117 cs4231_sbus_halt_input, 118 NULL, /* speaker_ctl */ 119 cs4231_getdev, 120 NULL, /* setfd */ 121 cs4231_set_port, 122 cs4231_get_port, 123 cs4231_query_devinfo, 124 cs4231_malloc, 125 cs4231_free, 126 NULL, /* round_buffersize */ 127 NULL, /* mappage */ 128 cs4231_get_props, 129 cs4231_sbus_trigger_output, 130 cs4231_sbus_trigger_input, 131 NULL, /* dev_ioctl */ 132 }; 133 134 135 #ifdef AUDIO_DEBUG 136 static void cs4231_sbus_regdump(char *, struct cs4231_sbus_softc *); 137 #endif 138 139 static int cs4231_sbus_intr(void *); 140 141 142 143 static int 144 cs4231_sbus_match(parent, cf, aux) 145 struct device *parent; 146 struct cfdata *cf; 147 void *aux; 148 { 149 struct sbus_attach_args *sa = aux; 150 151 return (strcmp(sa->sa_name, AUDIOCS_PROM_NAME) == 0); 152 } 153 154 155 static void 156 cs4231_sbus_attach(parent, self, aux) 157 struct device *parent, *self; 158 void *aux; 159 { 160 struct cs4231_sbus_softc *sbsc = (struct cs4231_sbus_softc *)self; 161 struct cs4231_softc *sc = &sbsc->sc_cs4231; 162 struct sbus_attach_args *sa = aux; 163 bus_space_handle_t bh; 164 165 sbsc->sc_bt = sc->sc_bustag = sa->sa_bustag; 166 sc->sc_dmatag = sa->sa_dmatag; 167 168 /* 169 * Map my registers in, if they aren't already in virtual 170 * address space. 171 */ 172 if (sa->sa_npromvaddrs) { 173 sbus_promaddr_to_handle(sa->sa_bustag, 174 sa->sa_promvaddrs[0], &bh); 175 } else { 176 if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, 177 sa->sa_offset, sa->sa_size, 0, &bh) != 0) { 178 printf("%s @ sbus: cannot map registers\n", 179 self->dv_xname); 180 return; 181 } 182 } 183 184 bus_space_subregion(sa->sa_bustag, bh, CS4231_APCDMA_OFFSET, 185 APC_DMA_SIZE, &sbsc->sc_bh); 186 187 cs4231_common_attach(sc, bh); 188 printf("\n"); 189 190 sbus_establish(&sbsc->sc_sd, &sc->sc_ad1848.sc_dev); 191 192 /* Establish interrupt channel */ 193 if (sa->sa_nintr) 194 bus_intr_establish(sa->sa_bustag, 195 sa->sa_pri, IPL_AUDIO, 196 cs4231_sbus_intr, sbsc); 197 198 audio_attach_mi(&audiocs_sbus_hw_if, sbsc, &sc->sc_ad1848.sc_dev); 199 } 200 201 202 #ifdef AUDIO_DEBUG 203 static void 204 cs4231_sbus_regdump(label, sc) 205 char *label; 206 struct cs4231_sbus_softc *sc; 207 { 208 char bits[128]; 209 210 printf("cs4231regdump(%s): regs:", label); 211 printf("dmapva: 0x%x; ", 212 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_PVA)); 213 printf("dmapc: 0x%x; ", 214 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_PC)); 215 printf("dmapnva: 0x%x; ", 216 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_PNVA)); 217 printf("dmapnc: 0x%x\n", 218 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_PNC)); 219 printf("dmacva: 0x%x; ", 220 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_CVA)); 221 printf("dmacc: 0x%x; ", 222 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_CC)); 223 printf("dmacnva: 0x%x; ", 224 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_CNVA)); 225 printf("dmacnc: 0x%x\n", 226 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_CNC)); 227 228 printf("apc_dmacsr=%s\n", 229 bitmask_snprintf( 230 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_CSR), 231 APC_BITS, bits, sizeof(bits))); 232 233 ad1848_dump_regs(&sc->sc_cs4231.sc_ad1848); 234 } 235 #endif /* AUDIO_DEBUG */ 236 237 238 static int 239 cs4231_sbus_trigger_output(addr, start, end, blksize, intr, arg, param) 240 void *addr; 241 void *start, *end; 242 int blksize; 243 void (*intr)(void *); 244 void *arg; 245 struct audio_params *param; 246 { 247 struct cs4231_sbus_softc *sbsc = addr; 248 struct cs4231_softc *sc = &sbsc->sc_cs4231; 249 struct cs_transfer *t = &sc->sc_playback; 250 u_int32_t csr; 251 bus_addr_t dmaaddr; 252 bus_size_t dmasize; 253 int ret; 254 #ifdef AUDIO_DEBUG 255 char bits[128]; 256 #endif 257 258 ret = cs4231_transfer_init(sc, t, &dmaaddr, &dmasize, 259 start, end, blksize, intr, arg); 260 if (ret != 0) 261 return (ret); 262 263 DPRINTF(("trigger_output: was: %x %d, %x %d\n", 264 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PVA), 265 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PC), 266 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA), 267 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC))); 268 269 /* load first block */ 270 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA, dmaaddr); 271 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC, dmasize); 272 273 DPRINTF(("trigger_output: 1st: %x %d, %x %d\n", 274 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PVA), 275 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PC), 276 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA), 277 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC))); 278 279 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 280 DPRINTF(("trigger_output: csr=%s\n", 281 bitmask_snprintf(csr, APC_BITS, bits, sizeof(bits)))); 282 if ((csr & PDMA_GO) == 0 || (csr & APC_PPAUSE) != 0) { 283 int cfg; 284 285 csr &= ~(APC_PPAUSE | APC_PMIE | APC_INTR_MASK); 286 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 287 288 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 289 csr &= ~APC_INTR_MASK; 290 csr |= APC_ENABLE | APC_PIE | APC_PMIE | PDMA_GO; 291 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 292 293 ad_write(&sc->sc_ad1848, SP_LOWER_BASE_COUNT, 0xff); 294 ad_write(&sc->sc_ad1848, SP_UPPER_BASE_COUNT, 0xff); 295 296 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 297 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG, 298 (cfg | PLAYBACK_ENABLE)); 299 } else { 300 DPRINTF(("trigger_output: already: csr=%s\n", 301 bitmask_snprintf(csr, APC_BITS, bits, sizeof(bits)))); 302 } 303 304 /* load next block if we can */ 305 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 306 if (csr & APC_PD) { 307 cs4231_transfer_advance(t, &dmaaddr, &dmasize); 308 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA, dmaaddr); 309 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC, dmasize); 310 311 DPRINTF(("trigger_output: 2nd: %x %d, %x %d\n", 312 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PVA), 313 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PC), 314 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA), 315 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC))); 316 } 317 318 return (0); 319 } 320 321 322 static int 323 cs4231_sbus_halt_output(addr) 324 void *addr; 325 { 326 struct cs4231_sbus_softc *sbsc = addr; 327 struct cs4231_softc *sc = &sbsc->sc_cs4231; 328 u_int32_t csr; 329 int cfg; 330 #ifdef AUDIO_DEBUG 331 char bits[128]; 332 #endif 333 334 sc->sc_playback.t_active = 0; 335 336 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 337 DPRINTF(("halt_output: csr=%s\n", 338 bitmask_snprintf(csr, APC_BITS, bits, sizeof(bits)))); 339 340 csr &= ~APC_INTR_MASK; /* do not clear interrupts accidentally */ 341 csr |= APC_PPAUSE; /* pause playback (let current complete) */ 342 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 343 344 /* let the curernt transfer complete */ 345 if (csr & PDMA_GO) 346 do { 347 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, 348 APC_DMA_CSR); 349 DPRINTF(("halt_output: csr=%s\n", 350 bitmask_snprintf(csr, APC_BITS, 351 bits, sizeof(bits)))); 352 } while ((csr & APC_PM) == 0); 353 354 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 355 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG,(cfg & ~PLAYBACK_ENABLE)); 356 357 return (0); 358 } 359 360 361 /* NB: we don't enable APC_CMIE and won't use APC_CM */ 362 static int 363 cs4231_sbus_trigger_input(addr, start, end, blksize, intr, arg, param) 364 void *addr; 365 void *start, *end; 366 int blksize; 367 void (*intr)(void *); 368 void *arg; 369 struct audio_params *param; 370 { 371 struct cs4231_sbus_softc *sbsc = addr; 372 struct cs4231_softc *sc = &sbsc->sc_cs4231; 373 struct cs_transfer *t = &sc->sc_capture; 374 u_int32_t csr; 375 bus_addr_t dmaaddr; 376 bus_size_t dmasize; 377 int ret; 378 #ifdef AUDIO_DEBUG 379 char bits[128]; 380 #endif 381 382 ret = cs4231_transfer_init(sc, t, &dmaaddr, &dmasize, 383 start, end, blksize, intr, arg); 384 if (ret != 0) 385 return (ret); 386 387 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 388 DPRINTF(("trigger_input: csr=%s\n", 389 bitmask_snprintf(csr, APC_BITS, bits, sizeof(bits)))); 390 DPRINTF(("trigger_input: was: %x %d, %x %d\n", 391 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CVA), 392 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CC), 393 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA), 394 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC))); 395 396 /* supply first block */ 397 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA, dmaaddr); 398 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC, dmasize); 399 400 DPRINTF(("trigger_input: 1st: %x %d, %x %d\n", 401 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CVA), 402 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CC), 403 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA), 404 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC))); 405 406 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 407 if ((csr & CDMA_GO) == 0 || (csr & APC_CPAUSE) != 0) { 408 int cfg; 409 410 csr &= ~(APC_CPAUSE | APC_CMIE | APC_INTR_MASK); 411 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 412 413 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 414 csr &= ~APC_INTR_MASK; 415 csr |= APC_ENABLE | APC_CIE | CDMA_GO; 416 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 417 418 ad_write(&sc->sc_ad1848, CS_LOWER_REC_CNT, 0xff); 419 ad_write(&sc->sc_ad1848, CS_UPPER_REC_CNT, 0xff); 420 421 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 422 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG, 423 (cfg | CAPTURE_ENABLE)); 424 } else { 425 DPRINTF(("trigger_input: already: csr=%s\n", 426 bitmask_snprintf(csr, APC_BITS, bits, sizeof(bits)))); 427 } 428 429 /* supply next block if we can */ 430 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 431 if (csr & APC_CD) { 432 cs4231_transfer_advance(t, &dmaaddr, &dmasize); 433 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA, dmaaddr); 434 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC, dmasize); 435 DPRINTF(("trigger_input: 2nd: %x %d, %x %d\n", 436 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CVA), 437 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CC), 438 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA), 439 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC))); 440 } 441 442 return (0); 443 } 444 445 446 static int 447 cs4231_sbus_halt_input(addr) 448 void *addr; 449 { 450 struct cs4231_sbus_softc *sbsc = addr; 451 struct cs4231_softc *sc = &sbsc->sc_cs4231; 452 u_int32_t csr; 453 int cfg; 454 #ifdef AUDIO_DEBUG 455 char bits[128]; 456 #endif 457 458 sc->sc_capture.t_active = 0; 459 460 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 461 DPRINTF(("halt_input: csr=%s\n", 462 bitmask_snprintf(csr, APC_BITS, bits, sizeof(bits)))); 463 464 csr &= ~APC_INTR_MASK; /* do not clear interrupts accidentally */ 465 csr |= APC_CPAUSE; 466 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 467 468 /* let the curernt transfer complete */ 469 if (csr & CDMA_GO) 470 do { 471 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, 472 APC_DMA_CSR); 473 DPRINTF(("halt_input: csr=%s\n", 474 bitmask_snprintf(csr, APC_BITS, 475 bits, sizeof(bits)))); 476 } while ((csr & APC_CM) == 0); 477 478 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 479 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG, (cfg & ~CAPTURE_ENABLE)); 480 481 return (0); 482 } 483 484 485 static int 486 cs4231_sbus_intr(arg) 487 void *arg; 488 { 489 struct cs4231_sbus_softc *sbsc = arg; 490 struct cs4231_softc *sc = &sbsc->sc_cs4231; 491 u_int32_t csr; 492 int status; 493 bus_addr_t dmaaddr; 494 bus_size_t dmasize; 495 int served; 496 #if defined(AUDIO_DEBUG) || defined(DIAGNOSTIC) 497 char bits[128]; 498 #endif 499 500 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 501 if ((csr & APC_INTR_MASK) == 0) /* any interrupt pedning? */ 502 return (0); 503 504 /* write back DMA status to clear interrupt */ 505 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 506 ++sc->sc_intrcnt.ev_count; 507 served = 0; 508 509 #ifdef AUDIO_DEBUG 510 if (cs4231_sbus_debug > 1) 511 cs4231_sbus_regdump("audiointr", sbsc); 512 #endif 513 514 status = ADREAD(&sc->sc_ad1848, AD1848_STATUS); 515 DPRINTF(("%s: status: %s\n", sc->sc_ad1848.sc_dev.dv_xname, 516 bitmask_snprintf(status, AD_R2_BITS, bits, sizeof(bits)))); 517 if (status & INTERRUPT_STATUS) { 518 #ifdef AUDIO_DEBUG 519 int reason; 520 521 reason = ad_read(&sc->sc_ad1848, CS_IRQ_STATUS); 522 DPRINTF(("%s: i24: %s\n", sc->sc_ad1848.sc_dev.dv_xname, 523 bitmask_snprintf(reason, CS_I24_BITS, bits, sizeof(bits)))); 524 #endif 525 /* clear ad1848 interrupt */ 526 ADWRITE(&sc->sc_ad1848, AD1848_STATUS, 0); 527 } 528 529 if (csr & APC_CI) { 530 if (csr & APC_CD) { /* can supply new block */ 531 struct cs_transfer *t = &sc->sc_capture; 532 533 cs4231_transfer_advance(t, &dmaaddr, &dmasize); 534 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, 535 APC_DMA_CNVA, dmaaddr); 536 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, 537 APC_DMA_CNC, dmasize); 538 539 if (t->t_intr != NULL) 540 (*t->t_intr)(t->t_arg); 541 ++t->t_intrcnt.ev_count; 542 served = 1; 543 } 544 } 545 546 if (csr & APC_PMI) { 547 if (!sc->sc_playback.t_active) 548 served = 1; /* draining in halt_output() */ 549 } 550 551 if (csr & APC_PI) { 552 if (csr & APC_PD) { /* can load new block */ 553 struct cs_transfer *t = &sc->sc_playback; 554 555 if (t->t_active) { 556 cs4231_transfer_advance(t, &dmaaddr, &dmasize); 557 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, 558 APC_DMA_PNVA, dmaaddr); 559 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, 560 APC_DMA_PNC, dmasize); 561 } 562 563 if (t->t_intr != NULL) 564 (*t->t_intr)(t->t_arg); 565 ++t->t_intrcnt.ev_count; 566 served = 1; 567 } 568 } 569 570 /* got an interrupt we don't know how to handle */ 571 if (!served) { 572 #ifdef DIAGNOSTIC 573 printf("%s: unhandled csr=%s\n", sc->sc_ad1848.sc_dev.dv_xname, 574 bitmask_snprintf(csr, APC_BITS, bits, sizeof(bits))); 575 #endif 576 /* evcnt? */ 577 } 578 579 return (1); 580 } 581 582 #endif /* NAUDIO > 0 */ 583