1 /* $NetBSD: cs4231_sbus.c,v 1.35 2007/10/19 12:01:10 ad 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.35 2007/10/19 12:01:10 ad 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 <sys/bus.h> 52 #include <sys/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 const audio_params_t *); 98 static int cs4231_sbus_trigger_input(void *, void *, void *, int, 99 void (*)(void *), void *, 100 const audio_params_t *); 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 NULL, /* powerstate */ 133 }; 134 135 136 #ifdef AUDIO_DEBUG 137 static void cs4231_sbus_regdump(char *, struct cs4231_sbus_softc *); 138 #endif 139 140 static int cs4231_sbus_intr(void *); 141 142 143 144 static int 145 cs4231_sbus_match(struct device *parent, struct cfdata *cf, void *aux) 146 { 147 struct sbus_attach_args *sa; 148 149 sa = aux; 150 return strcmp(sa->sa_name, AUDIOCS_PROM_NAME) == 0; 151 } 152 153 154 static void 155 cs4231_sbus_attach(struct device *parent, struct device *self, void *aux) 156 { 157 struct cs4231_sbus_softc *sbsc; 158 struct cs4231_softc *sc; 159 struct sbus_attach_args *sa; 160 bus_space_handle_t bh; 161 162 sbsc = (struct cs4231_sbus_softc *)self; 163 sc = &sbsc->sc_cs4231; 164 sa = aux; 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(char *label, struct cs4231_sbus_softc *sc) 205 { 206 char bits[128]; 207 208 printf("cs4231regdump(%s): regs:", label); 209 printf("dmapva: 0x%x; ", 210 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_PVA)); 211 printf("dmapc: 0x%x; ", 212 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_PC)); 213 printf("dmapnva: 0x%x; ", 214 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_PNVA)); 215 printf("dmapnc: 0x%x\n", 216 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_PNC)); 217 printf("dmacva: 0x%x; ", 218 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_CVA)); 219 printf("dmacc: 0x%x; ", 220 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_CC)); 221 printf("dmacnva: 0x%x; ", 222 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_CNVA)); 223 printf("dmacnc: 0x%x\n", 224 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_CNC)); 225 226 printf("apc_dmacsr=%s\n", 227 bitmask_snprintf( 228 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_CSR), 229 APC_BITS, bits, sizeof(bits))); 230 231 ad1848_dump_regs(&sc->sc_cs4231.sc_ad1848); 232 } 233 #endif /* AUDIO_DEBUG */ 234 235 236 static int 237 cs4231_sbus_trigger_output(void *addr, void *start, void *end, int blksize, 238 void (*intr)(void *), void *arg, 239 const audio_params_t *param) 240 { 241 struct cs4231_sbus_softc *sbsc; 242 struct cs4231_softc *sc; 243 struct cs_transfer *t; 244 uint32_t csr; 245 bus_addr_t dmaaddr; 246 bus_size_t dmasize; 247 int ret; 248 #ifdef AUDIO_DEBUG 249 char bits[128]; 250 #endif 251 252 sbsc = addr; 253 sc = &sbsc->sc_cs4231; 254 t = &sc->sc_playback; 255 ret = cs4231_transfer_init(sc, t, &dmaaddr, &dmasize, 256 start, end, blksize, intr, arg); 257 if (ret != 0) 258 return ret; 259 260 DPRINTF(("trigger_output: was: %x %d, %x %d\n", 261 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PVA), 262 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PC), 263 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA), 264 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC))); 265 266 /* load first block */ 267 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA, dmaaddr); 268 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC, dmasize); 269 270 DPRINTF(("trigger_output: 1st: %x %d, %x %d\n", 271 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PVA), 272 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PC), 273 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA), 274 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC))); 275 276 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 277 DPRINTF(("trigger_output: csr=%s\n", 278 bitmask_snprintf(csr, APC_BITS, bits, sizeof(bits)))); 279 if ((csr & PDMA_GO) == 0 || (csr & APC_PPAUSE) != 0) { 280 int cfg; 281 282 csr &= ~(APC_PPAUSE | APC_PMIE | APC_INTR_MASK); 283 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 284 285 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 286 csr &= ~APC_INTR_MASK; 287 csr |= APC_ENABLE | APC_PIE | APC_PMIE | PDMA_GO; 288 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 289 290 ad_write(&sc->sc_ad1848, SP_LOWER_BASE_COUNT, 0xff); 291 ad_write(&sc->sc_ad1848, SP_UPPER_BASE_COUNT, 0xff); 292 293 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 294 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG, 295 (cfg | PLAYBACK_ENABLE)); 296 } else { 297 DPRINTF(("trigger_output: already: csr=%s\n", 298 bitmask_snprintf(csr, APC_BITS, bits, sizeof(bits)))); 299 } 300 301 /* load next block if we can */ 302 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 303 if (csr & APC_PD) { 304 cs4231_transfer_advance(t, &dmaaddr, &dmasize); 305 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA, dmaaddr); 306 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC, dmasize); 307 308 DPRINTF(("trigger_output: 2nd: %x %d, %x %d\n", 309 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PVA), 310 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PC), 311 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA), 312 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC))); 313 } 314 315 return 0; 316 } 317 318 319 static int 320 cs4231_sbus_halt_output(void *addr) 321 { 322 struct cs4231_sbus_softc *sbsc; 323 struct cs4231_softc *sc; 324 uint32_t csr; 325 int cfg; 326 #ifdef AUDIO_DEBUG 327 char bits[128]; 328 #endif 329 330 sbsc = addr; 331 sc = &sbsc->sc_cs4231; 332 sc->sc_playback.t_active = 0; 333 334 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 335 DPRINTF(("halt_output: csr=%s\n", 336 bitmask_snprintf(csr, APC_BITS, bits, sizeof(bits)))); 337 338 csr &= ~APC_INTR_MASK; /* do not clear interrupts accidentally */ 339 csr |= APC_PPAUSE; /* pause playback (let current complete) */ 340 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 341 342 /* let the curernt transfer complete */ 343 if (csr & PDMA_GO) 344 do { 345 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, 346 APC_DMA_CSR); 347 DPRINTF(("halt_output: csr=%s\n", 348 bitmask_snprintf(csr, APC_BITS, 349 bits, sizeof(bits)))); 350 } while ((csr & APC_PM) == 0); 351 352 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 353 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG,(cfg & ~PLAYBACK_ENABLE)); 354 355 return 0; 356 } 357 358 359 /* NB: we don't enable APC_CMIE and won't use APC_CM */ 360 static int 361 cs4231_sbus_trigger_input(void *addr, void *start, void *end, int blksize, 362 void (*intr)(void *), void *arg, 363 const audio_params_t *param) 364 { 365 struct cs4231_sbus_softc *sbsc; 366 struct cs4231_softc *sc; 367 struct cs_transfer *t; 368 uint32_t csr; 369 bus_addr_t dmaaddr; 370 bus_size_t dmasize; 371 int ret; 372 #ifdef AUDIO_DEBUG 373 char bits[128]; 374 #endif 375 376 sbsc = addr; 377 sc = &sbsc->sc_cs4231; 378 t = &sc->sc_capture; 379 ret = cs4231_transfer_init(sc, t, &dmaaddr, &dmasize, 380 start, end, blksize, intr, arg); 381 if (ret != 0) 382 return ret; 383 384 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 385 DPRINTF(("trigger_input: csr=%s\n", 386 bitmask_snprintf(csr, APC_BITS, bits, sizeof(bits)))); 387 DPRINTF(("trigger_input: was: %x %d, %x %d\n", 388 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CVA), 389 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CC), 390 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA), 391 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC))); 392 393 /* supply first block */ 394 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA, dmaaddr); 395 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC, dmasize); 396 397 DPRINTF(("trigger_input: 1st: %x %d, %x %d\n", 398 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CVA), 399 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CC), 400 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA), 401 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC))); 402 403 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 404 if ((csr & CDMA_GO) == 0 || (csr & APC_CPAUSE) != 0) { 405 int cfg; 406 407 csr &= ~(APC_CPAUSE | APC_CMIE | APC_INTR_MASK); 408 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 409 410 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 411 csr &= ~APC_INTR_MASK; 412 csr |= APC_ENABLE | APC_CIE | CDMA_GO; 413 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 414 415 ad_write(&sc->sc_ad1848, CS_LOWER_REC_CNT, 0xff); 416 ad_write(&sc->sc_ad1848, CS_UPPER_REC_CNT, 0xff); 417 418 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 419 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG, 420 (cfg | CAPTURE_ENABLE)); 421 } else { 422 DPRINTF(("trigger_input: already: csr=%s\n", 423 bitmask_snprintf(csr, APC_BITS, bits, sizeof(bits)))); 424 } 425 426 /* supply next block if we can */ 427 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 428 if (csr & APC_CD) { 429 cs4231_transfer_advance(t, &dmaaddr, &dmasize); 430 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA, dmaaddr); 431 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC, dmasize); 432 DPRINTF(("trigger_input: 2nd: %x %d, %x %d\n", 433 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CVA), 434 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CC), 435 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA), 436 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC))); 437 } 438 439 return 0; 440 } 441 442 443 static int 444 cs4231_sbus_halt_input(void *addr) 445 { 446 struct cs4231_sbus_softc *sbsc; 447 struct cs4231_softc *sc; 448 uint32_t csr; 449 int cfg; 450 #ifdef AUDIO_DEBUG 451 char bits[128]; 452 #endif 453 454 sbsc = addr; 455 sc = &sbsc->sc_cs4231; 456 sc->sc_capture.t_active = 0; 457 458 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 459 DPRINTF(("halt_input: csr=%s\n", 460 bitmask_snprintf(csr, APC_BITS, bits, sizeof(bits)))); 461 462 csr &= ~APC_INTR_MASK; /* do not clear interrupts accidentally */ 463 csr |= APC_CPAUSE; 464 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 465 466 /* let the curernt transfer complete */ 467 if (csr & CDMA_GO) 468 do { 469 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, 470 APC_DMA_CSR); 471 DPRINTF(("halt_input: csr=%s\n", 472 bitmask_snprintf(csr, APC_BITS, 473 bits, sizeof(bits)))); 474 } while ((csr & APC_CM) == 0); 475 476 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 477 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG, (cfg & ~CAPTURE_ENABLE)); 478 479 return 0; 480 } 481 482 483 static int 484 cs4231_sbus_intr(void *arg) 485 { 486 struct cs4231_sbus_softc *sbsc; 487 struct cs4231_softc *sc; 488 uint32_t csr; 489 int status; 490 bus_addr_t dmaaddr; 491 bus_size_t dmasize; 492 int served; 493 #if defined(AUDIO_DEBUG) || defined(DIAGNOSTIC) 494 char bits[128]; 495 #endif 496 497 sbsc = arg; 498 sc = &sbsc->sc_cs4231; 499 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 500 if ((csr & APC_INTR_MASK) == 0) /* any interrupt pedning? */ 501 return 0; 502 503 /* write back DMA status to clear interrupt */ 504 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 505 ++sc->sc_intrcnt.ev_count; 506 served = 0; 507 508 #ifdef AUDIO_DEBUG 509 if (cs4231_sbus_debug > 1) 510 cs4231_sbus_regdump("audiointr", sbsc); 511 #endif 512 513 status = ADREAD(&sc->sc_ad1848, AD1848_STATUS); 514 DPRINTF(("%s: status: %s\n", sc->sc_ad1848.sc_dev.dv_xname, 515 bitmask_snprintf(status, AD_R2_BITS, bits, sizeof(bits)))); 516 if (status & INTERRUPT_STATUS) { 517 #ifdef AUDIO_DEBUG 518 int reason; 519 520 reason = ad_read(&sc->sc_ad1848, CS_IRQ_STATUS); 521 DPRINTF(("%s: i24: %s\n", sc->sc_ad1848.sc_dev.dv_xname, 522 bitmask_snprintf(reason, CS_I24_BITS, bits, sizeof(bits)))); 523 #endif 524 /* clear ad1848 interrupt */ 525 ADWRITE(&sc->sc_ad1848, AD1848_STATUS, 0); 526 } 527 528 if (csr & APC_CI) { 529 if (csr & APC_CD) { /* can supply new block */ 530 struct cs_transfer *t = &sc->sc_capture; 531 532 cs4231_transfer_advance(t, &dmaaddr, &dmasize); 533 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, 534 APC_DMA_CNVA, dmaaddr); 535 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, 536 APC_DMA_CNC, dmasize); 537 538 if (t->t_intr != NULL) 539 (*t->t_intr)(t->t_arg); 540 ++t->t_intrcnt.ev_count; 541 served = 1; 542 } 543 } 544 545 if (csr & APC_PMI) { 546 if (!sc->sc_playback.t_active) 547 served = 1; /* draining in halt_output() */ 548 } 549 550 if (csr & APC_PI) { 551 if (csr & APC_PD) { /* can load new block */ 552 struct cs_transfer *t = &sc->sc_playback; 553 554 if (t->t_active) { 555 cs4231_transfer_advance(t, &dmaaddr, &dmasize); 556 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, 557 APC_DMA_PNVA, dmaaddr); 558 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, 559 APC_DMA_PNC, dmasize); 560 } 561 562 if (t->t_intr != NULL) 563 (*t->t_intr)(t->t_arg); 564 ++t->t_intrcnt.ev_count; 565 served = 1; 566 } 567 } 568 569 /* got an interrupt we don't know how to handle */ 570 if (!served) { 571 #ifdef DIAGNOSTIC 572 printf("%s: unhandled csr=%s\n", sc->sc_ad1848.sc_dev.dv_xname, 573 bitmask_snprintf(csr, APC_BITS, bits, sizeof(bits))); 574 #endif 575 /* evcnt? */ 576 } 577 578 return 1; 579 } 580 581 #endif /* NAUDIO > 0 */ 582