1 /* $NetBSD: cs4231_sbus.c,v 1.43 2008/12/16 22:35:35 christos 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.43 2008/12/16 22:35:35 christos 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 snprintb(bits, sizeof(bits), APC_BITS, 228 bus_space_read_4(sc->sc_bh, sc->sc_bh, APC_DMA_CSR)); 229 printf("apc_dmacsr=%s\n", 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 #ifdef AUDIO_DEBUG 278 snprintb(bits, sizeof(bits), APC_BITS, csr); 279 #endif 280 DPRINTF(("trigger_output: csr=%s\n", bits)); 281 if ((csr & PDMA_GO) == 0 || (csr & APC_PPAUSE) != 0) { 282 int cfg; 283 284 csr &= ~(APC_PPAUSE | APC_PMIE | APC_INTR_MASK); 285 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 286 287 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 288 csr &= ~APC_INTR_MASK; 289 csr |= APC_ENABLE | APC_PIE | APC_PMIE | PDMA_GO; 290 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 291 292 ad_write(&sc->sc_ad1848, SP_LOWER_BASE_COUNT, 0xff); 293 ad_write(&sc->sc_ad1848, SP_UPPER_BASE_COUNT, 0xff); 294 295 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 296 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG, 297 (cfg | PLAYBACK_ENABLE)); 298 } else { 299 #ifdef AUDIO_DEBUG 300 snprintb(bits, sizeof(bits), APC_BITS, csr); 301 #endif 302 DPRINTF(("trigger_output: already: csr=%s\n", bits)); 303 304 } 305 306 /* load next block if we can */ 307 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 308 if (csr & APC_PD) { 309 cs4231_transfer_advance(t, &dmaaddr, &dmasize); 310 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA, dmaaddr); 311 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC, dmasize); 312 313 DPRINTF(("trigger_output: 2nd: %x %d, %x %d\n", 314 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PVA), 315 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PC), 316 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA), 317 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC))); 318 } 319 320 return 0; 321 } 322 323 324 static int 325 cs4231_sbus_halt_output(void *addr) 326 { 327 struct cs4231_sbus_softc *sbsc; 328 struct cs4231_softc *sc; 329 uint32_t csr; 330 int cfg; 331 #ifdef AUDIO_DEBUG 332 char bits[128]; 333 #endif 334 335 sbsc = addr; 336 sc = &sbsc->sc_cs4231; 337 sc->sc_playback.t_active = 0; 338 339 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 340 #ifdef AUDIO_DEBUG 341 snprintb(bits, sizeof(bits), APC_BITS, csr); 342 #endif 343 DPRINTF(("halt_output: csr=%s\n", bits)); 344 345 csr &= ~APC_INTR_MASK; /* do not clear interrupts accidentally */ 346 csr |= APC_PPAUSE; /* pause playback (let current complete) */ 347 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 348 349 /* let the curernt transfer complete */ 350 if (csr & PDMA_GO) 351 do { 352 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, 353 APC_DMA_CSR); 354 #ifdef AUDIO_DEBUG 355 snprintb(bits, sizeof(bits), APC_BITS, csr); 356 #endif 357 DPRINTF(("halt_output: csr=%s\n", bits)); 358 } while ((csr & APC_PM) == 0); 359 360 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 361 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG,(cfg & ~PLAYBACK_ENABLE)); 362 363 return 0; 364 } 365 366 367 /* NB: we don't enable APC_CMIE and won't use APC_CM */ 368 static int 369 cs4231_sbus_trigger_input(void *addr, void *start, void *end, int blksize, 370 void (*intr)(void *), void *arg, 371 const audio_params_t *param) 372 { 373 struct cs4231_sbus_softc *sbsc; 374 struct cs4231_softc *sc; 375 struct cs_transfer *t; 376 uint32_t csr; 377 bus_addr_t dmaaddr; 378 bus_size_t dmasize; 379 int ret; 380 #ifdef AUDIO_DEBUG 381 char bits[128]; 382 #endif 383 384 sbsc = addr; 385 sc = &sbsc->sc_cs4231; 386 t = &sc->sc_capture; 387 ret = cs4231_transfer_init(sc, t, &dmaaddr, &dmasize, 388 start, end, blksize, intr, arg); 389 if (ret != 0) 390 return ret; 391 392 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 393 #ifdef AUDIO_DEBUG 394 snprintb(bits, sizeof(bits), APC_BITS, csr); 395 #endif 396 DPRINTF(("trigger_input: csr=%s\n", bits)); 397 DPRINTF(("trigger_input: was: %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 /* supply first block */ 404 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA, dmaaddr); 405 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC, dmasize); 406 407 DPRINTF(("trigger_input: 1st: %x %d, %x %d\n", 408 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CVA), 409 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CC), 410 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA), 411 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC))); 412 413 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 414 if ((csr & CDMA_GO) == 0 || (csr & APC_CPAUSE) != 0) { 415 int cfg; 416 417 csr &= ~(APC_CPAUSE | APC_CMIE | APC_INTR_MASK); 418 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 419 420 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 421 csr &= ~APC_INTR_MASK; 422 csr |= APC_ENABLE | APC_CIE | CDMA_GO; 423 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 424 425 ad_write(&sc->sc_ad1848, CS_LOWER_REC_CNT, 0xff); 426 ad_write(&sc->sc_ad1848, CS_UPPER_REC_CNT, 0xff); 427 428 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 429 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG, 430 (cfg | CAPTURE_ENABLE)); 431 } else { 432 #ifdef AUDIO_DEBUG 433 snprintb(bits, sizeof(bits), APC_BITS, csr); 434 #endif 435 DPRINTF(("trigger_input: already: csr=%s\n", bits)); 436 } 437 438 /* supply next block if we can */ 439 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 440 if (csr & APC_CD) { 441 cs4231_transfer_advance(t, &dmaaddr, &dmasize); 442 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA, dmaaddr); 443 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC, dmasize); 444 DPRINTF(("trigger_input: 2nd: %x %d, %x %d\n", 445 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CVA), 446 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CC), 447 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA), 448 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC))); 449 } 450 451 return 0; 452 } 453 454 455 static int 456 cs4231_sbus_halt_input(void *addr) 457 { 458 struct cs4231_sbus_softc *sbsc; 459 struct cs4231_softc *sc; 460 uint32_t csr; 461 int cfg; 462 #ifdef AUDIO_DEBUG 463 char bits[128]; 464 #endif 465 466 sbsc = addr; 467 sc = &sbsc->sc_cs4231; 468 sc->sc_capture.t_active = 0; 469 470 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 471 #ifdef AUDIO_DEBUG 472 snprintb(bits, sizeof(bits), APC_BITS, csr); 473 #endif 474 DPRINTF(("halt_input: csr=%s\n", bits)); 475 476 477 csr &= ~APC_INTR_MASK; /* do not clear interrupts accidentally */ 478 csr |= APC_CPAUSE; 479 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 480 481 /* let the curernt transfer complete */ 482 if (csr & CDMA_GO) 483 do { 484 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, 485 APC_DMA_CSR); 486 #ifdef AUDIO_DEBUG 487 snprintb(bits, sizeof(bits), APC_BITS, csr); 488 #endif 489 DPRINTF(("halt_input: csr=%s\n", bits)); 490 491 492 } while ((csr & APC_CM) == 0); 493 494 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 495 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG, (cfg & ~CAPTURE_ENABLE)); 496 497 return 0; 498 } 499 500 501 static int 502 cs4231_sbus_intr(void *arg) 503 { 504 struct cs4231_sbus_softc *sbsc; 505 struct cs4231_softc *sc; 506 uint32_t csr; 507 int status; 508 bus_addr_t dmaaddr; 509 bus_size_t dmasize; 510 int served; 511 #if defined(AUDIO_DEBUG) || defined(DIAGNOSTIC) 512 char bits[128]; 513 #endif 514 515 sbsc = arg; 516 sc = &sbsc->sc_cs4231; 517 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 518 if ((csr & APC_INTR_MASK) == 0) /* any interrupt pedning? */ 519 return 0; 520 521 /* write back DMA status to clear interrupt */ 522 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 523 ++sc->sc_intrcnt.ev_count; 524 served = 0; 525 526 #ifdef AUDIO_DEBUG 527 if (cs4231_sbus_debug > 1) 528 cs4231_sbus_regdump("audiointr", sbsc); 529 #endif 530 531 status = ADREAD(&sc->sc_ad1848, AD1848_STATUS); 532 #ifdef AUDIO_DEBUG 533 snprintb(bits, sizeof(bits), AD_R2_BITS, status); 534 #endif 535 DPRINTF(("%s: status: %s\n", device_xname(&sc->sc_ad1848.sc_dev), 536 bits)); 537 if (status & INTERRUPT_STATUS) { 538 #ifdef AUDIO_DEBUG 539 int reason; 540 541 reason = ad_read(&sc->sc_ad1848, CS_IRQ_STATUS); 542 snprintb(bits, sizeof(bits), CS_I24_BITS, reason); 543 DPRINTF(("%s: i24: %s\n", device_xname(&sc->sc_ad1848.sc_dev), 544 bits)); 545 #endif 546 /* clear ad1848 interrupt */ 547 ADWRITE(&sc->sc_ad1848, AD1848_STATUS, 0); 548 } 549 550 if (csr & APC_CI) { 551 if (csr & APC_CD) { /* can supply new block */ 552 struct cs_transfer *t = &sc->sc_capture; 553 554 cs4231_transfer_advance(t, &dmaaddr, &dmasize); 555 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, 556 APC_DMA_CNVA, dmaaddr); 557 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, 558 APC_DMA_CNC, dmasize); 559 560 if (t->t_intr != NULL) 561 sparc_softintr_schedule(sbsc->sc_rint); 562 ++t->t_intrcnt.ev_count; 563 served = 1; 564 } 565 } 566 567 if (csr & APC_PMI) { 568 if (!sc->sc_playback.t_active) 569 served = 1; /* draining in halt_output() */ 570 } 571 572 if (csr & APC_PI) { 573 if (csr & APC_PD) { /* can load new block */ 574 struct cs_transfer *t = &sc->sc_playback; 575 576 if (t->t_active) { 577 cs4231_transfer_advance(t, &dmaaddr, &dmasize); 578 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, 579 APC_DMA_PNVA, dmaaddr); 580 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, 581 APC_DMA_PNC, dmasize); 582 } 583 584 if (t->t_intr != NULL) 585 sparc_softintr_schedule(sbsc->sc_pint); 586 ++t->t_intrcnt.ev_count; 587 served = 1; 588 } 589 } 590 591 /* got an interrupt we don't know how to handle */ 592 if (!served) { 593 #ifdef DIAGNOSTIC 594 snprintb(bits, sizeof(bits), APC_BITS, csr); 595 printf("%s: unhandled csr=%s\n", 596 device_xname(&sc->sc_ad1848.sc_dev), bits); 597 #endif 598 /* evcnt? */ 599 } 600 601 return 1; 602 } 603 604 static int 605 cs4231_sbus_pint(void *cookie) 606 { 607 struct cs4231_softc *sc = cookie; 608 struct cs_transfer *t; 609 610 KERNEL_LOCK(1, NULL); 611 t = &sc->sc_playback; 612 if (t->t_intr != NULL) 613 (*t->t_intr)(t->t_arg); 614 KERNEL_UNLOCK_ONE(NULL); 615 return 0; 616 } 617 618 static int 619 cs4231_sbus_rint(void *cookie) 620 { 621 struct cs4231_softc *sc = cookie; 622 struct cs_transfer *t; 623 624 KERNEL_LOCK(1, NULL); 625 t = &sc->sc_capture; 626 if (t->t_intr != NULL) 627 (*t->t_intr)(t->t_arg); 628 KERNEL_UNLOCK_ONE(NULL); 629 return 0; 630 } 631 632 #endif /* NAUDIO > 0 */ 633