1 /* $NetBSD: cs4231_sbus.c,v 1.42 2008/04/29 18:07:11 ad Exp $ */ 2 3 /*- 4 * Copyright (c) 1998, 1999, 2002, 2007 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 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 __KERNEL_RCSID(0, "$NetBSD: cs4231_sbus.c,v 1.42 2008/04/29 18:07:11 ad Exp $"); 34 35 #include "audio.h" 36 #if NAUDIO > 0 37 38 #include <sys/param.h> 39 #include <sys/systm.h> 40 #include <sys/errno.h> 41 #include <sys/device.h> 42 #include <sys/malloc.h> 43 #include <sys/bus.h> 44 #include <sys/intr.h> 45 46 #include <dev/sbus/sbusvar.h> 47 48 #include <sys/audioio.h> 49 #include <dev/audio_if.h> 50 51 #include <dev/ic/ad1848reg.h> 52 #include <dev/ic/cs4231reg.h> 53 #include <dev/ic/ad1848var.h> 54 #include <dev/ic/cs4231var.h> 55 56 #include <dev/ic/apcdmareg.h> 57 58 #ifdef AUDIO_DEBUG 59 int cs4231_sbus_debug = 0; 60 #define DPRINTF(x) if (cs4231_sbus_debug) printf x 61 #else 62 #define DPRINTF(x) 63 #endif 64 65 /* where APC DMA registers are located */ 66 #define CS4231_APCDMA_OFFSET 16 67 68 /* interrupt enable bits except those specific for playback/capture */ 69 #define APC_ENABLE (APC_EI | APC_IE | APC_EIE) 70 71 struct cs4231_sbus_softc { 72 struct cs4231_softc sc_cs4231; 73 74 void *sc_pint; 75 void *sc_rint; 76 struct sbusdev sc_sd; /* sbus device */ 77 bus_space_tag_t sc_bt; /* DMA controller tag */ 78 bus_space_handle_t sc_bh; /* DMA controller registers */ 79 }; 80 81 82 static int cs4231_sbus_match(struct device *, struct cfdata *, void *); 83 static void cs4231_sbus_attach(struct device *, struct device *, void *); 84 static int cs4231_sbus_pint(void *); 85 static int cs4231_sbus_rint(void *); 86 87 CFATTACH_DECL(audiocs_sbus, sizeof(struct cs4231_sbus_softc), 88 cs4231_sbus_match, cs4231_sbus_attach, NULL, NULL); 89 90 /* audio_hw_if methods specific to apc DMA */ 91 static int cs4231_sbus_trigger_output(void *, void *, void *, int, 92 void (*)(void *), void *, 93 const audio_params_t *); 94 static int cs4231_sbus_trigger_input(void *, void *, void *, int, 95 void (*)(void *), void *, 96 const audio_params_t *); 97 static int cs4231_sbus_halt_output(void *); 98 static int cs4231_sbus_halt_input(void *); 99 100 const struct audio_hw_if audiocs_sbus_hw_if = { 101 cs4231_open, 102 cs4231_close, 103 NULL, /* drain */ 104 ad1848_query_encoding, 105 ad1848_set_params, 106 NULL, /* round_blocksize */ 107 ad1848_commit_settings, 108 NULL, /* init_output */ 109 NULL, /* init_input */ 110 NULL, /* start_output */ 111 NULL, /* start_input */ 112 cs4231_sbus_halt_output, 113 cs4231_sbus_halt_input, 114 NULL, /* speaker_ctl */ 115 cs4231_getdev, 116 NULL, /* setfd */ 117 cs4231_set_port, 118 cs4231_get_port, 119 cs4231_query_devinfo, 120 cs4231_malloc, 121 cs4231_free, 122 NULL, /* round_buffersize */ 123 NULL, /* mappage */ 124 cs4231_get_props, 125 cs4231_sbus_trigger_output, 126 cs4231_sbus_trigger_input, 127 NULL, /* dev_ioctl */ 128 NULL, /* powerstate */ 129 }; 130 131 132 #ifdef AUDIO_DEBUG 133 static void cs4231_sbus_regdump(char *, struct cs4231_sbus_softc *); 134 #endif 135 136 static int cs4231_sbus_intr(void *); 137 138 139 140 static int 141 cs4231_sbus_match(struct device *parent, struct cfdata *cf, void *aux) 142 { 143 struct sbus_attach_args *sa; 144 145 sa = aux; 146 return strcmp(sa->sa_name, AUDIOCS_PROM_NAME) == 0; 147 } 148 149 150 static void 151 cs4231_sbus_attach(struct device *parent, struct device *self, void *aux) 152 { 153 struct cs4231_sbus_softc *sbsc; 154 struct cs4231_softc *sc; 155 struct sbus_attach_args *sa; 156 bus_space_handle_t bh; 157 158 sbsc = (struct cs4231_sbus_softc *)self; 159 sc = &sbsc->sc_cs4231; 160 sa = aux; 161 sbsc->sc_bt = sc->sc_bustag = sa->sa_bustag; 162 sc->sc_dmatag = sa->sa_dmatag; 163 164 sbsc->sc_pint = sparc_softintr_establish(IPL_VM, 165 (void *)cs4231_sbus_pint, sc); 166 sbsc->sc_rint = sparc_softintr_establish(IPL_VM, 167 (void *)cs4231_sbus_rint, sc); 168 169 /* 170 * Map my registers in, if they aren't already in virtual 171 * address space. 172 */ 173 if (sa->sa_npromvaddrs) { 174 sbus_promaddr_to_handle(sa->sa_bustag, 175 sa->sa_promvaddrs[0], &bh); 176 } else { 177 if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, 178 sa->sa_offset, sa->sa_size, 0, &bh) != 0) { 179 aprint_error("%s @ sbus: cannot map registers\n", 180 device_xname(self)); 181 return; 182 } 183 } 184 185 bus_space_subregion(sa->sa_bustag, bh, CS4231_APCDMA_OFFSET, 186 APC_DMA_SIZE, &sbsc->sc_bh); 187 188 cs4231_common_attach(sc, bh); 189 printf("\n"); 190 191 sbus_establish(&sbsc->sc_sd, &sc->sc_ad1848.sc_dev); 192 193 /* Establish interrupt channel */ 194 if (sa->sa_nintr) 195 bus_intr_establish(sa->sa_bustag, 196 sa->sa_pri, IPL_SCHED, 197 cs4231_sbus_intr, sbsc); 198 199 audio_attach_mi(&audiocs_sbus_hw_if, sbsc, &sc->sc_ad1848.sc_dev); 200 } 201 202 203 #ifdef AUDIO_DEBUG 204 static void 205 cs4231_sbus_regdump(char *label, struct cs4231_sbus_softc *sc) 206 { 207 char bits[128]; 208 209 printf("cs4231regdump(%s): regs:", label); 210 printf("dmapva: 0x%x; ", 211 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_PVA)); 212 printf("dmapc: 0x%x; ", 213 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_PC)); 214 printf("dmapnva: 0x%x; ", 215 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_PNVA)); 216 printf("dmapnc: 0x%x\n", 217 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_PNC)); 218 printf("dmacva: 0x%x; ", 219 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_CVA)); 220 printf("dmacc: 0x%x; ", 221 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_CC)); 222 printf("dmacnva: 0x%x; ", 223 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_CNVA)); 224 printf("dmacnc: 0x%x\n", 225 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_CNC)); 226 227 printf("apc_dmacsr=%s\n", 228 bitmask_snprintf( 229 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_CSR), 230 APC_BITS, bits, sizeof(bits))); 231 232 ad1848_dump_regs(&sc->sc_cs4231.sc_ad1848); 233 } 234 #endif /* AUDIO_DEBUG */ 235 236 237 static int 238 cs4231_sbus_trigger_output(void *addr, void *start, void *end, int blksize, 239 void (*intr)(void *), void *arg, 240 const audio_params_t *param) 241 { 242 struct cs4231_sbus_softc *sbsc; 243 struct cs4231_softc *sc; 244 struct cs_transfer *t; 245 uint32_t csr; 246 bus_addr_t dmaaddr; 247 bus_size_t dmasize; 248 int ret; 249 #ifdef AUDIO_DEBUG 250 char bits[128]; 251 #endif 252 253 sbsc = addr; 254 sc = &sbsc->sc_cs4231; 255 t = &sc->sc_playback; 256 ret = cs4231_transfer_init(sc, t, &dmaaddr, &dmasize, 257 start, end, blksize, intr, arg); 258 if (ret != 0) 259 return ret; 260 261 DPRINTF(("trigger_output: was: %x %d, %x %d\n", 262 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PVA), 263 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PC), 264 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA), 265 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC))); 266 267 /* load first block */ 268 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA, dmaaddr); 269 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC, dmasize); 270 271 DPRINTF(("trigger_output: 1st: %x %d, %x %d\n", 272 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PVA), 273 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PC), 274 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA), 275 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC))); 276 277 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 278 DPRINTF(("trigger_output: csr=%s\n", 279 bitmask_snprintf(csr, APC_BITS, bits, sizeof(bits)))); 280 if ((csr & PDMA_GO) == 0 || (csr & APC_PPAUSE) != 0) { 281 int cfg; 282 283 csr &= ~(APC_PPAUSE | APC_PMIE | APC_INTR_MASK); 284 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 285 286 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 287 csr &= ~APC_INTR_MASK; 288 csr |= APC_ENABLE | APC_PIE | APC_PMIE | PDMA_GO; 289 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 290 291 ad_write(&sc->sc_ad1848, SP_LOWER_BASE_COUNT, 0xff); 292 ad_write(&sc->sc_ad1848, SP_UPPER_BASE_COUNT, 0xff); 293 294 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 295 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG, 296 (cfg | PLAYBACK_ENABLE)); 297 } else { 298 DPRINTF(("trigger_output: already: csr=%s\n", 299 bitmask_snprintf(csr, APC_BITS, bits, sizeof(bits)))); 300 } 301 302 /* load next block if we can */ 303 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 304 if (csr & APC_PD) { 305 cs4231_transfer_advance(t, &dmaaddr, &dmasize); 306 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA, dmaaddr); 307 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC, dmasize); 308 309 DPRINTF(("trigger_output: 2nd: %x %d, %x %d\n", 310 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PVA), 311 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PC), 312 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA), 313 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC))); 314 } 315 316 return 0; 317 } 318 319 320 static int 321 cs4231_sbus_halt_output(void *addr) 322 { 323 struct cs4231_sbus_softc *sbsc; 324 struct cs4231_softc *sc; 325 uint32_t csr; 326 int cfg; 327 #ifdef AUDIO_DEBUG 328 char bits[128]; 329 #endif 330 331 sbsc = addr; 332 sc = &sbsc->sc_cs4231; 333 sc->sc_playback.t_active = 0; 334 335 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 336 DPRINTF(("halt_output: csr=%s\n", 337 bitmask_snprintf(csr, APC_BITS, bits, sizeof(bits)))); 338 339 csr &= ~APC_INTR_MASK; /* do not clear interrupts accidentally */ 340 csr |= APC_PPAUSE; /* pause playback (let current complete) */ 341 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 342 343 /* let the curernt transfer complete */ 344 if (csr & PDMA_GO) 345 do { 346 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, 347 APC_DMA_CSR); 348 DPRINTF(("halt_output: csr=%s\n", 349 bitmask_snprintf(csr, APC_BITS, 350 bits, sizeof(bits)))); 351 } while ((csr & APC_PM) == 0); 352 353 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 354 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG,(cfg & ~PLAYBACK_ENABLE)); 355 356 return 0; 357 } 358 359 360 /* NB: we don't enable APC_CMIE and won't use APC_CM */ 361 static int 362 cs4231_sbus_trigger_input(void *addr, void *start, void *end, int blksize, 363 void (*intr)(void *), void *arg, 364 const audio_params_t *param) 365 { 366 struct cs4231_sbus_softc *sbsc; 367 struct cs4231_softc *sc; 368 struct cs_transfer *t; 369 uint32_t csr; 370 bus_addr_t dmaaddr; 371 bus_size_t dmasize; 372 int ret; 373 #ifdef AUDIO_DEBUG 374 char bits[128]; 375 #endif 376 377 sbsc = addr; 378 sc = &sbsc->sc_cs4231; 379 t = &sc->sc_capture; 380 ret = cs4231_transfer_init(sc, t, &dmaaddr, &dmasize, 381 start, end, blksize, intr, arg); 382 if (ret != 0) 383 return ret; 384 385 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 386 DPRINTF(("trigger_input: csr=%s\n", 387 bitmask_snprintf(csr, APC_BITS, bits, sizeof(bits)))); 388 DPRINTF(("trigger_input: was: %x %d, %x %d\n", 389 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CVA), 390 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CC), 391 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA), 392 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC))); 393 394 /* supply first block */ 395 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA, dmaaddr); 396 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC, dmasize); 397 398 DPRINTF(("trigger_input: 1st: %x %d, %x %d\n", 399 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CVA), 400 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CC), 401 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA), 402 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC))); 403 404 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 405 if ((csr & CDMA_GO) == 0 || (csr & APC_CPAUSE) != 0) { 406 int cfg; 407 408 csr &= ~(APC_CPAUSE | APC_CMIE | APC_INTR_MASK); 409 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 410 411 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 412 csr &= ~APC_INTR_MASK; 413 csr |= APC_ENABLE | APC_CIE | CDMA_GO; 414 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 415 416 ad_write(&sc->sc_ad1848, CS_LOWER_REC_CNT, 0xff); 417 ad_write(&sc->sc_ad1848, CS_UPPER_REC_CNT, 0xff); 418 419 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 420 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG, 421 (cfg | CAPTURE_ENABLE)); 422 } else { 423 DPRINTF(("trigger_input: already: csr=%s\n", 424 bitmask_snprintf(csr, APC_BITS, bits, sizeof(bits)))); 425 } 426 427 /* supply next block if we can */ 428 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 429 if (csr & APC_CD) { 430 cs4231_transfer_advance(t, &dmaaddr, &dmasize); 431 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA, dmaaddr); 432 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC, dmasize); 433 DPRINTF(("trigger_input: 2nd: %x %d, %x %d\n", 434 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CVA), 435 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CC), 436 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA), 437 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC))); 438 } 439 440 return 0; 441 } 442 443 444 static int 445 cs4231_sbus_halt_input(void *addr) 446 { 447 struct cs4231_sbus_softc *sbsc; 448 struct cs4231_softc *sc; 449 uint32_t csr; 450 int cfg; 451 #ifdef AUDIO_DEBUG 452 char bits[128]; 453 #endif 454 455 sbsc = addr; 456 sc = &sbsc->sc_cs4231; 457 sc->sc_capture.t_active = 0; 458 459 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 460 DPRINTF(("halt_input: csr=%s\n", 461 bitmask_snprintf(csr, APC_BITS, bits, sizeof(bits)))); 462 463 csr &= ~APC_INTR_MASK; /* do not clear interrupts accidentally */ 464 csr |= APC_CPAUSE; 465 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 466 467 /* let the curernt transfer complete */ 468 if (csr & CDMA_GO) 469 do { 470 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, 471 APC_DMA_CSR); 472 DPRINTF(("halt_input: csr=%s\n", 473 bitmask_snprintf(csr, APC_BITS, 474 bits, sizeof(bits)))); 475 } while ((csr & APC_CM) == 0); 476 477 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 478 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG, (cfg & ~CAPTURE_ENABLE)); 479 480 return 0; 481 } 482 483 484 static int 485 cs4231_sbus_intr(void *arg) 486 { 487 struct cs4231_sbus_softc *sbsc; 488 struct cs4231_softc *sc; 489 uint32_t csr; 490 int status; 491 bus_addr_t dmaaddr; 492 bus_size_t dmasize; 493 int served; 494 #if defined(AUDIO_DEBUG) || defined(DIAGNOSTIC) 495 char bits[128]; 496 #endif 497 498 sbsc = arg; 499 sc = &sbsc->sc_cs4231; 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", device_xname(&sc->sc_ad1848.sc_dev), 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", device_xname(&sc->sc_ad1848.sc_dev), 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 sparc_softintr_schedule(sbsc->sc_rint); 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 sparc_softintr_schedule(sbsc->sc_pint); 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", device_xname(&sc->sc_ad1848.sc_dev), 574 bitmask_snprintf(csr, APC_BITS, bits, sizeof(bits))); 575 #endif 576 /* evcnt? */ 577 } 578 579 return 1; 580 } 581 582 static int 583 cs4231_sbus_pint(void *cookie) 584 { 585 struct cs4231_softc *sc = cookie; 586 struct cs_transfer *t; 587 588 KERNEL_LOCK(1, NULL); 589 t = &sc->sc_playback; 590 if (t->t_intr != NULL) 591 (*t->t_intr)(t->t_arg); 592 KERNEL_UNLOCK_ONE(NULL); 593 return 0; 594 } 595 596 static int 597 cs4231_sbus_rint(void *cookie) 598 { 599 struct cs4231_softc *sc = cookie; 600 struct cs_transfer *t; 601 602 KERNEL_LOCK(1, NULL); 603 t = &sc->sc_capture; 604 if (t->t_intr != NULL) 605 (*t->t_intr)(t->t_arg); 606 KERNEL_UNLOCK_ONE(NULL); 607 return 0; 608 } 609 610 #endif /* NAUDIO > 0 */ 611