1 /* $NetBSD: cs4231_sbus.c,v 1.47 2009/09/18 12:23:16 tsutsui 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.47 2009/09/18 12:23:16 tsutsui 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 bus_space_tag_t sc_bt; /* DMA controller tag */ 77 bus_space_handle_t sc_bh; /* DMA controller registers */ 78 }; 79 80 81 static int cs4231_sbus_match(device_t, cfdata_t, void *); 82 static void cs4231_sbus_attach(device_t, device_t, void *); 83 static int cs4231_sbus_pint(void *); 84 static int cs4231_sbus_rint(void *); 85 86 CFATTACH_DECL(audiocs_sbus, sizeof(struct cs4231_sbus_softc), 87 cs4231_sbus_match, cs4231_sbus_attach, NULL, NULL); 88 89 /* audio_hw_if methods specific to apc DMA */ 90 static int cs4231_sbus_trigger_output(void *, void *, void *, int, 91 void (*)(void *), void *, 92 const audio_params_t *); 93 static int cs4231_sbus_trigger_input(void *, void *, void *, int, 94 void (*)(void *), void *, 95 const audio_params_t *); 96 static int cs4231_sbus_halt_output(void *); 97 static int cs4231_sbus_halt_input(void *); 98 99 const struct audio_hw_if audiocs_sbus_hw_if = { 100 cs4231_open, 101 cs4231_close, 102 NULL, /* drain */ 103 ad1848_query_encoding, 104 ad1848_set_params, 105 NULL, /* round_blocksize */ 106 ad1848_commit_settings, 107 NULL, /* init_output */ 108 NULL, /* init_input */ 109 NULL, /* start_output */ 110 NULL, /* start_input */ 111 cs4231_sbus_halt_output, 112 cs4231_sbus_halt_input, 113 NULL, /* speaker_ctl */ 114 cs4231_getdev, 115 NULL, /* setfd */ 116 cs4231_set_port, 117 cs4231_get_port, 118 cs4231_query_devinfo, 119 cs4231_malloc, 120 cs4231_free, 121 NULL, /* round_buffersize */ 122 NULL, /* mappage */ 123 cs4231_get_props, 124 cs4231_sbus_trigger_output, 125 cs4231_sbus_trigger_input, 126 NULL, /* dev_ioctl */ 127 NULL, /* powerstate */ 128 }; 129 130 131 #ifdef AUDIO_DEBUG 132 static void cs4231_sbus_regdump(char *, struct cs4231_sbus_softc *); 133 #endif 134 135 static int cs4231_sbus_intr(void *); 136 137 138 139 static int 140 cs4231_sbus_match(device_t parent, cfdata_t cf, void *aux) 141 { 142 struct sbus_attach_args *sa; 143 144 sa = aux; 145 return strcmp(sa->sa_name, AUDIOCS_PROM_NAME) == 0; 146 } 147 148 149 static void 150 cs4231_sbus_attach(device_t parent, device_t self, void *aux) 151 { 152 struct cs4231_sbus_softc *sbsc; 153 struct cs4231_softc *sc; 154 struct sbus_attach_args *sa; 155 bus_space_handle_t bh; 156 157 sbsc = device_private(self); 158 sc = &sbsc->sc_cs4231; 159 sa = aux; 160 sbsc->sc_bt = sc->sc_bustag = sa->sa_bustag; 161 sc->sc_dmatag = sa->sa_dmatag; 162 163 sbsc->sc_pint = sparc_softintr_establish(IPL_VM, 164 (void *)cs4231_sbus_pint, sc); 165 sbsc->sc_rint = sparc_softintr_establish(IPL_VM, 166 (void *)cs4231_sbus_rint, sc); 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 aprint_error("%s @ sbus: cannot map registers\n", 179 device_xname(self)); 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 /* Establish interrupt channel */ 191 if (sa->sa_nintr) 192 bus_intr_establish(sa->sa_bustag, 193 sa->sa_pri, IPL_SCHED, 194 cs4231_sbus_intr, sbsc); 195 196 audio_attach_mi(&audiocs_sbus_hw_if, sbsc, self); 197 } 198 199 200 #ifdef AUDIO_DEBUG 201 static void 202 cs4231_sbus_regdump(char *label, struct cs4231_sbus_softc *sc) 203 { 204 char bits[128]; 205 206 printf("cs4231regdump(%s): regs:", label); 207 printf("dmapva: 0x%x; ", 208 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_PVA)); 209 printf("dmapc: 0x%x; ", 210 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_PC)); 211 printf("dmapnva: 0x%x; ", 212 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_PNVA)); 213 printf("dmapnc: 0x%x\n", 214 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_PNC)); 215 printf("dmacva: 0x%x; ", 216 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_CVA)); 217 printf("dmacc: 0x%x; ", 218 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_CC)); 219 printf("dmacnva: 0x%x; ", 220 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_CNVA)); 221 printf("dmacnc: 0x%x\n", 222 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_CNC)); 223 224 snprintb(bits, sizeof(bits), APC_BITS, 225 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_CSR)); 226 printf("apc_dmacsr=%s\n", bits); 227 228 ad1848_dump_regs(&sc->sc_cs4231.sc_ad1848); 229 } 230 #endif /* AUDIO_DEBUG */ 231 232 233 static int 234 cs4231_sbus_trigger_output(void *addr, void *start, void *end, int blksize, 235 void (*intr)(void *), void *arg, 236 const audio_params_t *param) 237 { 238 struct cs4231_sbus_softc *sbsc; 239 struct cs4231_softc *sc; 240 struct cs_transfer *t; 241 uint32_t csr; 242 bus_addr_t dmaaddr; 243 bus_size_t dmasize; 244 int ret; 245 #ifdef AUDIO_DEBUG 246 char bits[128]; 247 #endif 248 249 sbsc = addr; 250 sc = &sbsc->sc_cs4231; 251 t = &sc->sc_playback; 252 ret = cs4231_transfer_init(sc, t, &dmaaddr, &dmasize, 253 start, end, blksize, intr, arg); 254 if (ret != 0) 255 return ret; 256 257 DPRINTF(("trigger_output: was: %x %d, %x %d\n", 258 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PVA), 259 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PC), 260 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA), 261 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC))); 262 263 /* load first block */ 264 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA, dmaaddr); 265 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC, dmasize); 266 267 DPRINTF(("trigger_output: 1st: %x %d, %x %d\n", 268 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PVA), 269 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PC), 270 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA), 271 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC))); 272 273 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 274 #ifdef AUDIO_DEBUG 275 snprintb(bits, sizeof(bits), APC_BITS, csr); 276 #endif 277 DPRINTF(("trigger_output: csr=%s\n", 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 #ifdef AUDIO_DEBUG 297 snprintb(bits, sizeof(bits), APC_BITS, csr); 298 #endif 299 DPRINTF(("trigger_output: already: csr=%s\n", bits)); 300 301 } 302 303 /* load next block if we can */ 304 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 305 if (csr & APC_PD) { 306 cs4231_transfer_advance(t, &dmaaddr, &dmasize); 307 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA, dmaaddr); 308 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC, dmasize); 309 310 DPRINTF(("trigger_output: 2nd: %x %d, %x %d\n", 311 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PVA), 312 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PC), 313 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA), 314 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC))); 315 } 316 317 return 0; 318 } 319 320 321 static int 322 cs4231_sbus_halt_output(void *addr) 323 { 324 struct cs4231_sbus_softc *sbsc; 325 struct cs4231_softc *sc; 326 uint32_t csr; 327 int cfg; 328 #ifdef AUDIO_DEBUG 329 char bits[128]; 330 #endif 331 332 sbsc = addr; 333 sc = &sbsc->sc_cs4231; 334 sc->sc_playback.t_active = 0; 335 336 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 337 #ifdef AUDIO_DEBUG 338 snprintb(bits, sizeof(bits), APC_BITS, csr); 339 #endif 340 DPRINTF(("halt_output: csr=%s\n", bits)); 341 342 csr &= ~APC_INTR_MASK; /* do not clear interrupts accidentally */ 343 csr |= APC_PPAUSE; /* pause playback (let current complete) */ 344 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 345 346 /* let the curernt transfer complete */ 347 if (csr & PDMA_GO) 348 do { 349 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, 350 APC_DMA_CSR); 351 #ifdef AUDIO_DEBUG 352 snprintb(bits, sizeof(bits), APC_BITS, csr); 353 #endif 354 DPRINTF(("halt_output: csr=%s\n", 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(void *addr, void *start, void *end, int blksize, 367 void (*intr)(void *), void *arg, 368 const audio_params_t *param) 369 { 370 struct cs4231_sbus_softc *sbsc; 371 struct cs4231_softc *sc; 372 struct cs_transfer *t; 373 uint32_t csr; 374 bus_addr_t dmaaddr; 375 bus_size_t dmasize; 376 int ret; 377 #ifdef AUDIO_DEBUG 378 char bits[128]; 379 #endif 380 381 sbsc = addr; 382 sc = &sbsc->sc_cs4231; 383 t = &sc->sc_capture; 384 ret = cs4231_transfer_init(sc, t, &dmaaddr, &dmasize, 385 start, end, blksize, intr, arg); 386 if (ret != 0) 387 return ret; 388 389 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 390 #ifdef AUDIO_DEBUG 391 snprintb(bits, sizeof(bits), APC_BITS, csr); 392 #endif 393 DPRINTF(("trigger_input: csr=%s\n", bits)); 394 DPRINTF(("trigger_input: was: %x %d, %x %d\n", 395 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CVA), 396 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CC), 397 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA), 398 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC))); 399 400 /* supply first block */ 401 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA, dmaaddr); 402 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC, dmasize); 403 404 DPRINTF(("trigger_input: 1st: %x %d, %x %d\n", 405 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CVA), 406 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CC), 407 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA), 408 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC))); 409 410 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 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, APC_DMA_CSR, csr); 416 417 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 418 csr &= ~APC_INTR_MASK; 419 csr |= APC_ENABLE | APC_CIE | CDMA_GO; 420 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, 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 #ifdef AUDIO_DEBUG 430 snprintb(bits, sizeof(bits), APC_BITS, csr); 431 #endif 432 DPRINTF(("trigger_input: already: csr=%s\n", bits)); 433 } 434 435 /* supply next block if we can */ 436 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 437 if (csr & APC_CD) { 438 cs4231_transfer_advance(t, &dmaaddr, &dmasize); 439 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA, dmaaddr); 440 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC, dmasize); 441 DPRINTF(("trigger_input: 2nd: %x %d, %x %d\n", 442 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CVA), 443 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CC), 444 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA), 445 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC))); 446 } 447 448 return 0; 449 } 450 451 452 static int 453 cs4231_sbus_halt_input(void *addr) 454 { 455 struct cs4231_sbus_softc *sbsc; 456 struct cs4231_softc *sc; 457 uint32_t csr; 458 int cfg; 459 #ifdef AUDIO_DEBUG 460 char bits[128]; 461 #endif 462 463 sbsc = addr; 464 sc = &sbsc->sc_cs4231; 465 sc->sc_capture.t_active = 0; 466 467 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 468 #ifdef AUDIO_DEBUG 469 snprintb(bits, sizeof(bits), APC_BITS, csr); 470 #endif 471 DPRINTF(("halt_input: csr=%s\n", bits)); 472 473 474 csr &= ~APC_INTR_MASK; /* do not clear interrupts accidentally */ 475 csr |= APC_CPAUSE; 476 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 477 478 /* let the curernt transfer complete */ 479 if (csr & CDMA_GO) 480 do { 481 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, 482 APC_DMA_CSR); 483 #ifdef AUDIO_DEBUG 484 snprintb(bits, sizeof(bits), APC_BITS, csr); 485 #endif 486 DPRINTF(("halt_input: csr=%s\n", bits)); 487 488 489 } while ((csr & APC_CM) == 0); 490 491 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 492 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG, (cfg & ~CAPTURE_ENABLE)); 493 494 return 0; 495 } 496 497 498 static int 499 cs4231_sbus_intr(void *arg) 500 { 501 struct cs4231_sbus_softc *sbsc; 502 struct cs4231_softc *sc; 503 uint32_t csr; 504 int status; 505 bus_addr_t dmaaddr; 506 bus_size_t dmasize; 507 int served; 508 #if defined(AUDIO_DEBUG) || defined(DIAGNOSTIC) 509 char bits[128]; 510 #endif 511 512 sbsc = arg; 513 sc = &sbsc->sc_cs4231; 514 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 515 if ((csr & APC_INTR_MASK) == 0) /* any interrupt pedning? */ 516 return 0; 517 518 /* write back DMA status to clear interrupt */ 519 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 520 ++sc->sc_intrcnt.ev_count; 521 served = 0; 522 523 #ifdef AUDIO_DEBUG 524 if (cs4231_sbus_debug > 1) 525 cs4231_sbus_regdump("audiointr", sbsc); 526 #endif 527 528 status = ADREAD(&sc->sc_ad1848, AD1848_STATUS); 529 #ifdef AUDIO_DEBUG 530 snprintb(bits, sizeof(bits), AD_R2_BITS, status); 531 #endif 532 DPRINTF(("%s: status: %s\n", device_xname(&sc->sc_ad1848.sc_dev), 533 bits)); 534 if (status & INTERRUPT_STATUS) { 535 #ifdef AUDIO_DEBUG 536 int reason; 537 538 reason = ad_read(&sc->sc_ad1848, CS_IRQ_STATUS); 539 snprintb(bits, sizeof(bits), CS_I24_BITS, reason); 540 DPRINTF(("%s: i24: %s\n", device_xname(&sc->sc_ad1848.sc_dev), 541 bits)); 542 #endif 543 /* clear ad1848 interrupt */ 544 ADWRITE(&sc->sc_ad1848, AD1848_STATUS, 0); 545 } 546 547 if (csr & APC_CI) { 548 if (csr & APC_CD) { /* can supply new block */ 549 struct cs_transfer *t = &sc->sc_capture; 550 551 cs4231_transfer_advance(t, &dmaaddr, &dmasize); 552 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, 553 APC_DMA_CNVA, dmaaddr); 554 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, 555 APC_DMA_CNC, dmasize); 556 557 if (t->t_intr != NULL) 558 sparc_softintr_schedule(sbsc->sc_rint); 559 ++t->t_intrcnt.ev_count; 560 served = 1; 561 } 562 } 563 564 if (csr & APC_PMI) { 565 if (!sc->sc_playback.t_active) 566 served = 1; /* draining in halt_output() */ 567 } 568 569 if (csr & APC_PI) { 570 if (csr & APC_PD) { /* can load new block */ 571 struct cs_transfer *t = &sc->sc_playback; 572 573 if (t->t_active) { 574 cs4231_transfer_advance(t, &dmaaddr, &dmasize); 575 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, 576 APC_DMA_PNVA, dmaaddr); 577 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, 578 APC_DMA_PNC, dmasize); 579 } 580 581 if (t->t_intr != NULL) 582 sparc_softintr_schedule(sbsc->sc_pint); 583 ++t->t_intrcnt.ev_count; 584 served = 1; 585 } 586 } 587 588 /* got an interrupt we don't know how to handle */ 589 if (!served) { 590 #ifdef DIAGNOSTIC 591 snprintb(bits, sizeof(bits), APC_BITS, csr); 592 printf("%s: unhandled csr=%s\n", 593 device_xname(&sc->sc_ad1848.sc_dev), bits); 594 #endif 595 /* evcnt? */ 596 } 597 598 return 1; 599 } 600 601 static int 602 cs4231_sbus_pint(void *cookie) 603 { 604 struct cs4231_softc *sc = cookie; 605 struct cs_transfer *t; 606 607 KERNEL_LOCK(1, NULL); 608 t = &sc->sc_playback; 609 if (t->t_intr != NULL) 610 (*t->t_intr)(t->t_arg); 611 KERNEL_UNLOCK_ONE(NULL); 612 return 0; 613 } 614 615 static int 616 cs4231_sbus_rint(void *cookie) 617 { 618 struct cs4231_softc *sc = cookie; 619 struct cs_transfer *t; 620 621 KERNEL_LOCK(1, NULL); 622 t = &sc->sc_capture; 623 if (t->t_intr != NULL) 624 (*t->t_intr)(t->t_arg); 625 KERNEL_UNLOCK_ONE(NULL); 626 return 0; 627 } 628 629 #endif /* NAUDIO > 0 */ 630