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