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