1 /* $NetBSD: cs4231_sbus.c,v 1.50 2017/05/02 08:11:16 martin 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.50 2017/05/02 08:11:16 martin 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_NEW(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 ad1848_get_locks, 128 }; 129 130 131 #ifdef AUDIO_DEBUG 132 static void cs4231_sbus_regdump(const 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_SCHED, 164 (void *)cs4231_sbus_pint, sc); 165 sbsc->sc_rint = sparc_softintr_establish(IPL_SCHED, 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, self, bh); 188 printf("\n"); 189 190 ad1848_init_locks(&sc->sc_ad1848, IPL_SCHED); 191 /* Establish interrupt channel */ 192 if (sa->sa_nintr) 193 bus_intr_establish(sa->sa_bustag, 194 sa->sa_pri, IPL_SCHED, 195 cs4231_sbus_intr, sbsc); 196 197 audio_attach_mi(&audiocs_sbus_hw_if, sbsc, self); 198 } 199 200 201 #ifdef AUDIO_DEBUG 202 static void 203 cs4231_sbus_regdump(const 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_bt, sc->sc_bh, APC_DMA_PVA)); 210 printf("dmapc: 0x%x; ", 211 bus_space_read_4(sc->sc_bt, sc->sc_bh, APC_DMA_PC)); 212 printf("dmapnva: 0x%x; ", 213 bus_space_read_4(sc->sc_bt, sc->sc_bh, APC_DMA_PNVA)); 214 printf("dmapnc: 0x%x\n", 215 bus_space_read_4(sc->sc_bt, sc->sc_bh, APC_DMA_PNC)); 216 printf("dmacva: 0x%x; ", 217 bus_space_read_4(sc->sc_bt, sc->sc_bh, APC_DMA_CVA)); 218 printf("dmacc: 0x%x; ", 219 bus_space_read_4(sc->sc_bt, sc->sc_bh, APC_DMA_CC)); 220 printf("dmacnva: 0x%x; ", 221 bus_space_read_4(sc->sc_bt, sc->sc_bh, APC_DMA_CNVA)); 222 printf("dmacnc: 0x%x\n", 223 bus_space_read_4(sc->sc_bt, sc->sc_bh, APC_DMA_CNC)); 224 225 snprintb(bits, sizeof(bits), APC_BITS, 226 bus_space_read_4(sc->sc_bt, sc->sc_bh, APC_DMA_CSR)); 227 printf("apc_dmacsr=%s\n", bits); 228 229 ad1848_dump_regs(&sc->sc_cs4231.sc_ad1848); 230 } 231 #endif /* AUDIO_DEBUG */ 232 233 234 static int 235 cs4231_sbus_trigger_output(void *addr, void *start, void *end, int blksize, 236 void (*intr)(void *), void *arg, 237 const audio_params_t *param) 238 { 239 struct cs4231_sbus_softc *sbsc; 240 struct cs4231_softc *sc; 241 struct cs_transfer *t; 242 uint32_t csr; 243 bus_addr_t dmaaddr; 244 bus_size_t dmasize; 245 int ret; 246 #ifdef AUDIO_DEBUG 247 char bits[128]; 248 #endif 249 250 sbsc = addr; 251 sc = &sbsc->sc_cs4231; 252 t = &sc->sc_playback; 253 ret = cs4231_transfer_init(sc, t, &dmaaddr, &dmasize, 254 start, end, blksize, intr, arg); 255 if (ret != 0) 256 return ret; 257 258 DPRINTF(("trigger_output: was: %x %d, %x %d\n", 259 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PVA), 260 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PC), 261 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA), 262 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC))); 263 264 /* load first block */ 265 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA, dmaaddr); 266 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC, dmasize); 267 268 DPRINTF(("trigger_output: 1st: %x %d, %x %d\n", 269 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PVA), 270 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PC), 271 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA), 272 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC))); 273 274 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 275 #ifdef AUDIO_DEBUG 276 snprintb(bits, sizeof(bits), APC_BITS, csr); 277 #endif 278 DPRINTF(("trigger_output: csr=%s\n", bits)); 279 if ((csr & PDMA_GO) == 0 || (csr & APC_PPAUSE) != 0) { 280 int cfg; 281 282 csr &= ~(APC_PPAUSE | APC_PMIE | APC_INTR_MASK); 283 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 284 285 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 286 csr &= ~APC_INTR_MASK; 287 csr |= APC_ENABLE | APC_PIE | APC_PMIE | PDMA_GO; 288 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 289 290 ad_write(&sc->sc_ad1848, SP_LOWER_BASE_COUNT, 0xff); 291 ad_write(&sc->sc_ad1848, SP_UPPER_BASE_COUNT, 0xff); 292 293 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 294 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG, 295 (cfg | PLAYBACK_ENABLE)); 296 } else { 297 #ifdef AUDIO_DEBUG 298 snprintb(bits, sizeof(bits), APC_BITS, csr); 299 #endif 300 DPRINTF(("trigger_output: already: csr=%s\n", bits)); 301 302 } 303 304 /* load next block if we can */ 305 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 306 if (csr & APC_PD) { 307 cs4231_transfer_advance(t, &dmaaddr, &dmasize); 308 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA, dmaaddr); 309 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC, dmasize); 310 311 DPRINTF(("trigger_output: 2nd: %x %d, %x %d\n", 312 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PVA), 313 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PC), 314 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA), 315 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC))); 316 } 317 318 return 0; 319 } 320 321 322 static int 323 cs4231_sbus_halt_output(void *addr) 324 { 325 struct cs4231_sbus_softc *sbsc; 326 struct cs4231_softc *sc; 327 uint32_t csr; 328 int cfg; 329 #ifdef AUDIO_DEBUG 330 char bits[128]; 331 #endif 332 333 sbsc = addr; 334 sc = &sbsc->sc_cs4231; 335 sc->sc_playback.t_active = 0; 336 337 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 338 #ifdef AUDIO_DEBUG 339 snprintb(bits, sizeof(bits), APC_BITS, csr); 340 #endif 341 DPRINTF(("halt_output: csr=%s\n", 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, APC_DMA_CSR, 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 APC_DMA_CSR); 352 #ifdef AUDIO_DEBUG 353 snprintb(bits, sizeof(bits), APC_BITS, csr); 354 #endif 355 DPRINTF(("halt_output: csr=%s\n", bits)); 356 } while ((csr & APC_PM) == 0); 357 358 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 359 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG,(cfg & ~PLAYBACK_ENABLE)); 360 361 return 0; 362 } 363 364 365 /* NB: we don't enable APC_CMIE and won't use APC_CM */ 366 static int 367 cs4231_sbus_trigger_input(void *addr, void *start, void *end, int blksize, 368 void (*intr)(void *), void *arg, 369 const audio_params_t *param) 370 { 371 struct cs4231_sbus_softc *sbsc; 372 struct cs4231_softc *sc; 373 struct cs_transfer *t; 374 uint32_t csr; 375 bus_addr_t dmaaddr; 376 bus_size_t dmasize; 377 int ret; 378 #ifdef AUDIO_DEBUG 379 char bits[128]; 380 #endif 381 382 sbsc = addr; 383 sc = &sbsc->sc_cs4231; 384 t = &sc->sc_capture; 385 ret = cs4231_transfer_init(sc, t, &dmaaddr, &dmasize, 386 start, end, blksize, intr, arg); 387 if (ret != 0) 388 return ret; 389 390 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 391 #ifdef AUDIO_DEBUG 392 snprintb(bits, sizeof(bits), APC_BITS, csr); 393 #endif 394 DPRINTF(("trigger_input: csr=%s\n", bits)); 395 DPRINTF(("trigger_input: was: %x %d, %x %d\n", 396 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CVA), 397 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CC), 398 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA), 399 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC))); 400 401 /* supply first block */ 402 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA, dmaaddr); 403 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC, dmasize); 404 405 DPRINTF(("trigger_input: 1st: %x %d, %x %d\n", 406 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CVA), 407 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CC), 408 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA), 409 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC))); 410 411 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 412 if ((csr & CDMA_GO) == 0 || (csr & APC_CPAUSE) != 0) { 413 int cfg; 414 415 csr &= ~(APC_CPAUSE | APC_CMIE | APC_INTR_MASK); 416 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 417 418 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 419 csr &= ~APC_INTR_MASK; 420 csr |= APC_ENABLE | APC_CIE | CDMA_GO; 421 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 422 423 ad_write(&sc->sc_ad1848, CS_LOWER_REC_CNT, 0xff); 424 ad_write(&sc->sc_ad1848, CS_UPPER_REC_CNT, 0xff); 425 426 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 427 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG, 428 (cfg | CAPTURE_ENABLE)); 429 } else { 430 #ifdef AUDIO_DEBUG 431 snprintb(bits, sizeof(bits), APC_BITS, csr); 432 #endif 433 DPRINTF(("trigger_input: already: csr=%s\n", bits)); 434 } 435 436 /* supply next block if we can */ 437 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 438 if (csr & APC_CD) { 439 cs4231_transfer_advance(t, &dmaaddr, &dmasize); 440 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA, dmaaddr); 441 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC, dmasize); 442 DPRINTF(("trigger_input: 2nd: %x %d, %x %d\n", 443 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CVA), 444 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CC), 445 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA), 446 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC))); 447 } 448 449 return 0; 450 } 451 452 453 static int 454 cs4231_sbus_halt_input(void *addr) 455 { 456 struct cs4231_sbus_softc *sbsc; 457 struct cs4231_softc *sc; 458 uint32_t csr; 459 int cfg; 460 #ifdef AUDIO_DEBUG 461 char bits[128]; 462 #endif 463 464 sbsc = addr; 465 sc = &sbsc->sc_cs4231; 466 sc->sc_capture.t_active = 0; 467 468 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 469 #ifdef AUDIO_DEBUG 470 snprintb(bits, sizeof(bits), APC_BITS, csr); 471 #endif 472 DPRINTF(("halt_input: csr=%s\n", bits)); 473 474 475 csr &= ~APC_INTR_MASK; /* do not clear interrupts accidentally */ 476 csr |= APC_CPAUSE; 477 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 478 479 /* let the curernt transfer complete */ 480 if (csr & CDMA_GO) 481 do { 482 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, 483 APC_DMA_CSR); 484 #ifdef AUDIO_DEBUG 485 snprintb(bits, sizeof(bits), APC_BITS, csr); 486 #endif 487 DPRINTF(("halt_input: csr=%s\n", bits)); 488 489 490 } while ((csr & APC_CM) == 0); 491 492 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 493 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG, (cfg & ~CAPTURE_ENABLE)); 494 495 return 0; 496 } 497 498 499 static int 500 cs4231_sbus_intr(void *arg) 501 { 502 struct cs4231_sbus_softc *sbsc; 503 struct cs4231_softc *sc; 504 uint32_t csr; 505 int status; 506 bus_addr_t dmaaddr; 507 bus_size_t dmasize; 508 int served; 509 #if defined(AUDIO_DEBUG) || defined(DIAGNOSTIC) 510 char bits[128]; 511 #endif 512 513 sbsc = arg; 514 sc = &sbsc->sc_cs4231; 515 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 516 if ((csr & APC_INTR_MASK) == 0) /* any interrupt pedning? */ 517 return 0; 518 519 mutex_spin_enter(&sc->sc_ad1848.sc_intr_lock); 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 mutex_spin_exit(&sc->sc_ad1848.sc_intr_lock); 602 603 return 1; 604 } 605 606 static int 607 cs4231_sbus_pint(void *cookie) 608 { 609 struct cs4231_softc *sc = cookie; 610 struct cs_transfer *t; 611 612 mutex_spin_enter(&sc->sc_ad1848.sc_intr_lock); 613 t = &sc->sc_playback; 614 if (t->t_intr != NULL) 615 (*t->t_intr)(t->t_arg); 616 mutex_spin_exit(&sc->sc_ad1848.sc_intr_lock); 617 return 0; 618 } 619 620 static int 621 cs4231_sbus_rint(void *cookie) 622 { 623 struct cs4231_softc *sc = cookie; 624 struct cs_transfer *t; 625 626 mutex_spin_enter(&sc->sc_ad1848.sc_intr_lock); 627 t = &sc->sc_capture; 628 if (t->t_intr != NULL) 629 (*t->t_intr)(t->t_arg); 630 mutex_spin_exit(&sc->sc_ad1848.sc_intr_lock); 631 return 0; 632 } 633 634 #endif /* NAUDIO > 0 */ 635