1 /* $NetBSD: cs4231_sbus.c,v 1.52 2019/05/08 13:40:19 isaki 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.52 2019/05/08 13:40:19 isaki 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/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 .open = cs4231_open, 101 .close = cs4231_close, 102 .query_format = ad1848_query_format, 103 .set_format = ad1848_set_format, 104 .commit_settings = ad1848_commit_settings, 105 .halt_output = cs4231_sbus_halt_output, 106 .halt_input = cs4231_sbus_halt_input, 107 .getdev = cs4231_getdev, 108 .set_port = cs4231_set_port, 109 .get_port = cs4231_get_port, 110 .query_devinfo = cs4231_query_devinfo, 111 .allocm = cs4231_malloc, 112 .freem = cs4231_free, 113 .get_props = cs4231_get_props, 114 .trigger_output = cs4231_sbus_trigger_output, 115 .trigger_input = cs4231_sbus_trigger_input, 116 .get_locks = ad1848_get_locks, 117 }; 118 119 120 #ifdef AUDIO_DEBUG 121 static void cs4231_sbus_regdump(const char *, struct cs4231_sbus_softc *); 122 #endif 123 124 static int cs4231_sbus_intr(void *); 125 126 127 128 static int 129 cs4231_sbus_match(device_t parent, cfdata_t cf, void *aux) 130 { 131 struct sbus_attach_args *sa; 132 133 sa = aux; 134 return strcmp(sa->sa_name, AUDIOCS_PROM_NAME) == 0; 135 } 136 137 138 static void 139 cs4231_sbus_attach(device_t parent, device_t self, void *aux) 140 { 141 struct cs4231_sbus_softc *sbsc; 142 struct cs4231_softc *sc; 143 struct sbus_attach_args *sa; 144 bus_space_handle_t bh; 145 146 sbsc = device_private(self); 147 sc = &sbsc->sc_cs4231; 148 sa = aux; 149 sbsc->sc_bt = sc->sc_bustag = sa->sa_bustag; 150 sc->sc_dmatag = sa->sa_dmatag; 151 152 sbsc->sc_pint = sparc_softintr_establish(IPL_SCHED, 153 (void *)cs4231_sbus_pint, sc); 154 sbsc->sc_rint = sparc_softintr_establish(IPL_SCHED, 155 (void *)cs4231_sbus_rint, sc); 156 157 /* 158 * Map my registers in, if they aren't already in virtual 159 * address space. 160 */ 161 if (sa->sa_npromvaddrs) { 162 sbus_promaddr_to_handle(sa->sa_bustag, 163 sa->sa_promvaddrs[0], &bh); 164 } else { 165 if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, 166 sa->sa_offset, sa->sa_size, 0, &bh) != 0) { 167 aprint_error("%s @ sbus: cannot map registers\n", 168 device_xname(self)); 169 return; 170 } 171 } 172 173 bus_space_subregion(sa->sa_bustag, bh, CS4231_APCDMA_OFFSET, 174 APC_DMA_SIZE, &sbsc->sc_bh); 175 176 cs4231_common_attach(sc, self, bh); 177 printf("\n"); 178 179 ad1848_init_locks(&sc->sc_ad1848, IPL_SCHED); 180 /* Establish interrupt channel */ 181 if (sa->sa_nintr) 182 bus_intr_establish(sa->sa_bustag, 183 sa->sa_pri, IPL_SCHED, 184 cs4231_sbus_intr, sbsc); 185 186 audio_attach_mi(&audiocs_sbus_hw_if, sbsc, self); 187 } 188 189 190 #ifdef AUDIO_DEBUG 191 static void 192 cs4231_sbus_regdump(const char *label, struct cs4231_sbus_softc *sc) 193 { 194 char bits[128]; 195 196 printf("cs4231regdump(%s): regs:", label); 197 printf("dmapva: 0x%x; ", 198 bus_space_read_4(sc->sc_bt, sc->sc_bh, APC_DMA_PVA)); 199 printf("dmapc: 0x%x; ", 200 bus_space_read_4(sc->sc_bt, sc->sc_bh, APC_DMA_PC)); 201 printf("dmapnva: 0x%x; ", 202 bus_space_read_4(sc->sc_bt, sc->sc_bh, APC_DMA_PNVA)); 203 printf("dmapnc: 0x%x\n", 204 bus_space_read_4(sc->sc_bt, sc->sc_bh, APC_DMA_PNC)); 205 printf("dmacva: 0x%x; ", 206 bus_space_read_4(sc->sc_bt, sc->sc_bh, APC_DMA_CVA)); 207 printf("dmacc: 0x%x; ", 208 bus_space_read_4(sc->sc_bt, sc->sc_bh, APC_DMA_CC)); 209 printf("dmacnva: 0x%x; ", 210 bus_space_read_4(sc->sc_bt, sc->sc_bh, APC_DMA_CNVA)); 211 printf("dmacnc: 0x%x\n", 212 bus_space_read_4(sc->sc_bt, sc->sc_bh, APC_DMA_CNC)); 213 214 snprintb(bits, sizeof(bits), APC_BITS, 215 bus_space_read_4(sc->sc_bt, sc->sc_bh, APC_DMA_CSR)); 216 printf("apc_dmacsr=%s\n", bits); 217 218 ad1848_dump_regs(&sc->sc_cs4231.sc_ad1848); 219 } 220 #endif /* AUDIO_DEBUG */ 221 222 223 static int 224 cs4231_sbus_trigger_output(void *addr, void *start, void *end, int blksize, 225 void (*intr)(void *), void *arg, 226 const audio_params_t *param) 227 { 228 struct cs4231_sbus_softc *sbsc; 229 struct cs4231_softc *sc; 230 struct cs_transfer *t; 231 uint32_t csr; 232 bus_addr_t dmaaddr; 233 bus_size_t dmasize; 234 int ret; 235 #ifdef AUDIO_DEBUG 236 char bits[128]; 237 #endif 238 239 sbsc = addr; 240 sc = &sbsc->sc_cs4231; 241 t = &sc->sc_playback; 242 ret = cs4231_transfer_init(sc, t, &dmaaddr, &dmasize, 243 start, end, blksize, intr, arg); 244 if (ret != 0) 245 return ret; 246 247 DPRINTF(("trigger_output: was: %x %d, %x %d\n", 248 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PVA), 249 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PC), 250 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA), 251 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC))); 252 253 /* load first block */ 254 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA, dmaaddr); 255 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC, dmasize); 256 257 DPRINTF(("trigger_output: 1st: %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 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 264 #ifdef AUDIO_DEBUG 265 snprintb(bits, sizeof(bits), APC_BITS, csr); 266 #endif 267 DPRINTF(("trigger_output: csr=%s\n", bits)); 268 if ((csr & PDMA_GO) == 0 || (csr & APC_PPAUSE) != 0) { 269 int cfg; 270 271 csr &= ~(APC_PPAUSE | APC_PMIE | APC_INTR_MASK); 272 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 273 274 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 275 csr &= ~APC_INTR_MASK; 276 csr |= APC_ENABLE | APC_PIE | APC_PMIE | PDMA_GO; 277 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 278 279 ad_write(&sc->sc_ad1848, SP_LOWER_BASE_COUNT, 0xff); 280 ad_write(&sc->sc_ad1848, SP_UPPER_BASE_COUNT, 0xff); 281 282 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 283 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG, 284 (cfg | PLAYBACK_ENABLE)); 285 } else { 286 #ifdef AUDIO_DEBUG 287 snprintb(bits, sizeof(bits), APC_BITS, csr); 288 #endif 289 DPRINTF(("trigger_output: already: csr=%s\n", bits)); 290 291 } 292 293 /* load next block if we can */ 294 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 295 if (csr & APC_PD) { 296 cs4231_transfer_advance(t, &dmaaddr, &dmasize); 297 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA, dmaaddr); 298 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC, dmasize); 299 300 DPRINTF(("trigger_output: 2nd: %x %d, %x %d\n", 301 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PVA), 302 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PC), 303 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA), 304 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC))); 305 } 306 307 return 0; 308 } 309 310 311 static int 312 cs4231_sbus_halt_output(void *addr) 313 { 314 struct cs4231_sbus_softc *sbsc; 315 struct cs4231_softc *sc; 316 uint32_t csr; 317 int cfg; 318 #ifdef AUDIO_DEBUG 319 char bits[128]; 320 #endif 321 322 sbsc = addr; 323 sc = &sbsc->sc_cs4231; 324 sc->sc_playback.t_active = 0; 325 326 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 327 #ifdef AUDIO_DEBUG 328 snprintb(bits, sizeof(bits), APC_BITS, csr); 329 #endif 330 DPRINTF(("halt_output: csr=%s\n", bits)); 331 332 csr &= ~APC_INTR_MASK; /* do not clear interrupts accidentally */ 333 csr |= APC_PPAUSE; /* pause playback (let current complete) */ 334 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 335 336 /* let the curernt transfer complete */ 337 if (csr & PDMA_GO) 338 do { 339 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, 340 APC_DMA_CSR); 341 #ifdef AUDIO_DEBUG 342 snprintb(bits, sizeof(bits), APC_BITS, csr); 343 #endif 344 DPRINTF(("halt_output: csr=%s\n", bits)); 345 } while ((csr & APC_PM) == 0); 346 347 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 348 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG,(cfg & ~PLAYBACK_ENABLE)); 349 350 return 0; 351 } 352 353 354 /* NB: we don't enable APC_CMIE and won't use APC_CM */ 355 static int 356 cs4231_sbus_trigger_input(void *addr, void *start, void *end, int blksize, 357 void (*intr)(void *), void *arg, 358 const audio_params_t *param) 359 { 360 struct cs4231_sbus_softc *sbsc; 361 struct cs4231_softc *sc; 362 struct cs_transfer *t; 363 uint32_t csr; 364 bus_addr_t dmaaddr; 365 bus_size_t dmasize; 366 int ret; 367 #ifdef AUDIO_DEBUG 368 char bits[128]; 369 #endif 370 371 sbsc = addr; 372 sc = &sbsc->sc_cs4231; 373 t = &sc->sc_capture; 374 ret = cs4231_transfer_init(sc, t, &dmaaddr, &dmasize, 375 start, end, blksize, intr, arg); 376 if (ret != 0) 377 return ret; 378 379 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 380 #ifdef AUDIO_DEBUG 381 snprintb(bits, sizeof(bits), APC_BITS, csr); 382 #endif 383 DPRINTF(("trigger_input: csr=%s\n", bits)); 384 DPRINTF(("trigger_input: was: %x %d, %x %d\n", 385 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CVA), 386 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CC), 387 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA), 388 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC))); 389 390 /* supply first block */ 391 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA, dmaaddr); 392 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC, dmasize); 393 394 DPRINTF(("trigger_input: 1st: %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 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 401 if ((csr & CDMA_GO) == 0 || (csr & APC_CPAUSE) != 0) { 402 int cfg; 403 404 csr &= ~(APC_CPAUSE | APC_CMIE | APC_INTR_MASK); 405 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 406 407 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 408 csr &= ~APC_INTR_MASK; 409 csr |= APC_ENABLE | APC_CIE | CDMA_GO; 410 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 411 412 ad_write(&sc->sc_ad1848, CS_LOWER_REC_CNT, 0xff); 413 ad_write(&sc->sc_ad1848, CS_UPPER_REC_CNT, 0xff); 414 415 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 416 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG, 417 (cfg | CAPTURE_ENABLE)); 418 } else { 419 #ifdef AUDIO_DEBUG 420 snprintb(bits, sizeof(bits), APC_BITS, csr); 421 #endif 422 DPRINTF(("trigger_input: already: csr=%s\n", bits)); 423 } 424 425 /* supply next block if we can */ 426 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 427 if (csr & APC_CD) { 428 cs4231_transfer_advance(t, &dmaaddr, &dmasize); 429 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA, dmaaddr); 430 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC, dmasize); 431 DPRINTF(("trigger_input: 2nd: %x %d, %x %d\n", 432 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CVA), 433 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CC), 434 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA), 435 bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC))); 436 } 437 438 return 0; 439 } 440 441 442 static int 443 cs4231_sbus_halt_input(void *addr) 444 { 445 struct cs4231_sbus_softc *sbsc; 446 struct cs4231_softc *sc; 447 uint32_t csr; 448 int cfg; 449 #ifdef AUDIO_DEBUG 450 char bits[128]; 451 #endif 452 453 sbsc = addr; 454 sc = &sbsc->sc_cs4231; 455 sc->sc_capture.t_active = 0; 456 457 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 458 #ifdef AUDIO_DEBUG 459 snprintb(bits, sizeof(bits), APC_BITS, csr); 460 #endif 461 DPRINTF(("halt_input: csr=%s\n", bits)); 462 463 464 csr &= ~APC_INTR_MASK; /* do not clear interrupts accidentally */ 465 csr |= APC_CPAUSE; 466 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 467 468 /* let the curernt transfer complete */ 469 if (csr & CDMA_GO) 470 do { 471 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, 472 APC_DMA_CSR); 473 #ifdef AUDIO_DEBUG 474 snprintb(bits, sizeof(bits), APC_BITS, csr); 475 #endif 476 DPRINTF(("halt_input: csr=%s\n", bits)); 477 478 479 } while ((csr & APC_CM) == 0); 480 481 cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 482 ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG, (cfg & ~CAPTURE_ENABLE)); 483 484 return 0; 485 } 486 487 488 static int 489 cs4231_sbus_intr(void *arg) 490 { 491 struct cs4231_sbus_softc *sbsc; 492 struct cs4231_softc *sc; 493 uint32_t csr; 494 int status; 495 bus_addr_t dmaaddr; 496 bus_size_t dmasize; 497 int served; 498 #if defined(AUDIO_DEBUG) || defined(DIAGNOSTIC) 499 char bits[128]; 500 #endif 501 502 sbsc = arg; 503 sc = &sbsc->sc_cs4231; 504 csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 505 if ((csr & APC_INTR_MASK) == 0) /* any interrupt pedning? */ 506 return 0; 507 508 mutex_spin_enter(&sc->sc_ad1848.sc_intr_lock); 509 510 /* write back DMA status to clear interrupt */ 511 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, 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 #ifdef AUDIO_DEBUG 522 snprintb(bits, sizeof(bits), AD_R2_BITS, status); 523 #endif 524 DPRINTF(("%s: status: %s\n", device_xname(sc->sc_ad1848.sc_dev), 525 bits)); 526 if (status & INTERRUPT_STATUS) { 527 #ifdef AUDIO_DEBUG 528 int reason; 529 530 reason = ad_read(&sc->sc_ad1848, CS_IRQ_STATUS); 531 snprintb(bits, sizeof(bits), CS_I24_BITS, reason); 532 DPRINTF(("%s: i24: %s\n", device_xname(sc->sc_ad1848.sc_dev), 533 bits)); 534 #endif 535 /* clear ad1848 interrupt */ 536 ADWRITE(&sc->sc_ad1848, AD1848_STATUS, 0); 537 } 538 539 if (csr & APC_CI) { 540 if (csr & APC_CD) { /* can supply new block */ 541 struct cs_transfer *t = &sc->sc_capture; 542 543 cs4231_transfer_advance(t, &dmaaddr, &dmasize); 544 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, 545 APC_DMA_CNVA, dmaaddr); 546 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, 547 APC_DMA_CNC, dmasize); 548 549 if (t->t_intr != NULL) 550 sparc_softintr_schedule(sbsc->sc_rint); 551 ++t->t_intrcnt.ev_count; 552 served = 1; 553 } 554 } 555 556 if (csr & APC_PMI) { 557 if (!sc->sc_playback.t_active) 558 served = 1; /* draining in halt_output() */ 559 } 560 561 if (csr & APC_PI) { 562 if (csr & APC_PD) { /* can load new block */ 563 struct cs_transfer *t = &sc->sc_playback; 564 565 if (t->t_active) { 566 cs4231_transfer_advance(t, &dmaaddr, &dmasize); 567 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, 568 APC_DMA_PNVA, dmaaddr); 569 bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, 570 APC_DMA_PNC, dmasize); 571 } 572 573 if (t->t_intr != NULL) 574 sparc_softintr_schedule(sbsc->sc_pint); 575 ++t->t_intrcnt.ev_count; 576 served = 1; 577 } 578 } 579 580 /* got an interrupt we don't know how to handle */ 581 if (!served) { 582 #ifdef DIAGNOSTIC 583 snprintb(bits, sizeof(bits), APC_BITS, csr); 584 printf("%s: unhandled csr=%s\n", 585 device_xname(sc->sc_ad1848.sc_dev), bits); 586 #endif 587 /* evcnt? */ 588 } 589 590 mutex_spin_exit(&sc->sc_ad1848.sc_intr_lock); 591 592 return 1; 593 } 594 595 static int 596 cs4231_sbus_pint(void *cookie) 597 { 598 struct cs4231_softc *sc = cookie; 599 struct cs_transfer *t; 600 601 mutex_spin_enter(&sc->sc_ad1848.sc_intr_lock); 602 t = &sc->sc_playback; 603 if (t->t_intr != NULL) 604 (*t->t_intr)(t->t_arg); 605 mutex_spin_exit(&sc->sc_ad1848.sc_intr_lock); 606 return 0; 607 } 608 609 static int 610 cs4231_sbus_rint(void *cookie) 611 { 612 struct cs4231_softc *sc = cookie; 613 struct cs_transfer *t; 614 615 mutex_spin_enter(&sc->sc_ad1848.sc_intr_lock); 616 t = &sc->sc_capture; 617 if (t->t_intr != NULL) 618 (*t->t_intr)(t->t_arg); 619 mutex_spin_exit(&sc->sc_ad1848.sc_intr_lock); 620 return 0; 621 } 622 623 #endif /* NAUDIO > 0 */ 624