1 1.53 andvar /* $NetBSD: cs4231_sbus.c,v 1.53 2022/07/21 14:41:59 andvar Exp $ */ 2 1.2 pk 3 1.2 pk /*- 4 1.36 ad * Copyright (c) 1998, 1999, 2002, 2007 The NetBSD Foundation, Inc. 5 1.2 pk * All rights reserved. 6 1.2 pk * 7 1.2 pk * This code is derived from software contributed to The NetBSD Foundation 8 1.2 pk * by Paul Kranenburg. 9 1.2 pk * 10 1.2 pk * Redistribution and use in source and binary forms, with or without 11 1.2 pk * modification, are permitted provided that the following conditions 12 1.2 pk * are met: 13 1.2 pk * 1. Redistributions of source code must retain the above copyright 14 1.2 pk * notice, this list of conditions and the following disclaimer. 15 1.2 pk * 2. Redistributions in binary form must reproduce the above copyright 16 1.2 pk * notice, this list of conditions and the following disclaimer in the 17 1.2 pk * documentation and/or other materials provided with the distribution. 18 1.2 pk * 19 1.2 pk * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.2 pk * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.2 pk * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.2 pk * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.2 pk * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.2 pk * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.2 pk * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.2 pk * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.2 pk * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.2 pk * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.2 pk * POSSIBILITY OF SUCH DAMAGE. 30 1.2 pk */ 31 1.16 lukem 32 1.16 lukem #include <sys/cdefs.h> 33 1.53 andvar __KERNEL_RCSID(0, "$NetBSD: cs4231_sbus.c,v 1.53 2022/07/21 14:41:59 andvar Exp $"); 34 1.1 pk 35 1.1 pk #include "audio.h" 36 1.1 pk #if NAUDIO > 0 37 1.1 pk 38 1.1 pk #include <sys/param.h> 39 1.1 pk #include <sys/systm.h> 40 1.1 pk #include <sys/errno.h> 41 1.1 pk #include <sys/device.h> 42 1.1 pk #include <sys/malloc.h> 43 1.35 ad #include <sys/bus.h> 44 1.35 ad #include <sys/intr.h> 45 1.15 pk 46 1.15 pk #include <dev/sbus/sbusvar.h> 47 1.1 pk 48 1.1 pk #include <sys/audioio.h> 49 1.52 isaki #include <dev/audio/audio_if.h> 50 1.1 pk 51 1.1 pk #include <dev/ic/ad1848reg.h> 52 1.1 pk #include <dev/ic/cs4231reg.h> 53 1.1 pk #include <dev/ic/ad1848var.h> 54 1.11 mrg #include <dev/ic/cs4231var.h> 55 1.1 pk 56 1.18 uwe #include <dev/ic/apcdmareg.h> 57 1.1 pk 58 1.18 uwe #ifdef AUDIO_DEBUG 59 1.18 uwe int cs4231_sbus_debug = 0; 60 1.18 uwe #define DPRINTF(x) if (cs4231_sbus_debug) printf x 61 1.18 uwe #else 62 1.18 uwe #define DPRINTF(x) 63 1.18 uwe #endif 64 1.18 uwe 65 1.18 uwe /* where APC DMA registers are located */ 66 1.18 uwe #define CS4231_APCDMA_OFFSET 16 67 1.18 uwe 68 1.18 uwe /* interrupt enable bits except those specific for playback/capture */ 69 1.18 uwe #define APC_ENABLE (APC_EI | APC_IE | APC_EIE) 70 1.18 uwe 71 1.18 uwe struct cs4231_sbus_softc { 72 1.18 uwe struct cs4231_softc sc_cs4231; 73 1.18 uwe 74 1.36 ad void *sc_pint; 75 1.36 ad void *sc_rint; 76 1.19 eeh bus_space_tag_t sc_bt; /* DMA controller tag */ 77 1.19 eeh bus_space_handle_t sc_bh; /* DMA controller registers */ 78 1.18 uwe }; 79 1.18 uwe 80 1.18 uwe 81 1.45 cegger static int cs4231_sbus_match(device_t, cfdata_t, void *); 82 1.45 cegger static void cs4231_sbus_attach(device_t, device_t, void *); 83 1.40 martin static int cs4231_sbus_pint(void *); 84 1.40 martin static int cs4231_sbus_rint(void *); 85 1.1 pk 86 1.48 christos CFATTACH_DECL_NEW(audiocs_sbus, sizeof(struct cs4231_sbus_softc), 87 1.24 thorpej cs4231_sbus_match, cs4231_sbus_attach, NULL, NULL); 88 1.18 uwe 89 1.28 wiz /* audio_hw_if methods specific to apc DMA */ 90 1.18 uwe static int cs4231_sbus_trigger_output(void *, void *, void *, int, 91 1.18 uwe void (*)(void *), void *, 92 1.31 kent const audio_params_t *); 93 1.18 uwe static int cs4231_sbus_trigger_input(void *, void *, void *, int, 94 1.18 uwe void (*)(void *), void *, 95 1.31 kent const audio_params_t *); 96 1.18 uwe static int cs4231_sbus_halt_output(void *); 97 1.18 uwe static int cs4231_sbus_halt_input(void *); 98 1.18 uwe 99 1.30 yamt const struct audio_hw_if audiocs_sbus_hw_if = { 100 1.51 isaki .open = cs4231_open, 101 1.51 isaki .close = cs4231_close, 102 1.52 isaki .query_format = ad1848_query_format, 103 1.52 isaki .set_format = ad1848_set_format, 104 1.51 isaki .commit_settings = ad1848_commit_settings, 105 1.51 isaki .halt_output = cs4231_sbus_halt_output, 106 1.51 isaki .halt_input = cs4231_sbus_halt_input, 107 1.51 isaki .getdev = cs4231_getdev, 108 1.51 isaki .set_port = cs4231_set_port, 109 1.51 isaki .get_port = cs4231_get_port, 110 1.51 isaki .query_devinfo = cs4231_query_devinfo, 111 1.51 isaki .allocm = cs4231_malloc, 112 1.51 isaki .freem = cs4231_free, 113 1.51 isaki .get_props = cs4231_get_props, 114 1.51 isaki .trigger_output = cs4231_sbus_trigger_output, 115 1.51 isaki .trigger_input = cs4231_sbus_trigger_input, 116 1.51 isaki .get_locks = ad1848_get_locks, 117 1.1 pk }; 118 1.1 pk 119 1.1 pk 120 1.18 uwe #ifdef AUDIO_DEBUG 121 1.50 martin static void cs4231_sbus_regdump(const char *, struct cs4231_sbus_softc *); 122 1.18 uwe #endif 123 1.18 uwe 124 1.18 uwe static int cs4231_sbus_intr(void *); 125 1.18 uwe 126 1.18 uwe 127 1.18 uwe 128 1.18 uwe static int 129 1.45 cegger cs4231_sbus_match(device_t parent, cfdata_t cf, void *aux) 130 1.1 pk { 131 1.32 kent struct sbus_attach_args *sa; 132 1.1 pk 133 1.32 kent sa = aux; 134 1.32 kent return strcmp(sa->sa_name, AUDIOCS_PROM_NAME) == 0; 135 1.1 pk } 136 1.1 pk 137 1.18 uwe 138 1.18 uwe static void 139 1.45 cegger cs4231_sbus_attach(device_t parent, device_t self, void *aux) 140 1.1 pk { 141 1.32 kent struct cs4231_sbus_softc *sbsc; 142 1.32 kent struct cs4231_softc *sc; 143 1.32 kent struct sbus_attach_args *sa; 144 1.1 pk bus_space_handle_t bh; 145 1.1 pk 146 1.47 tsutsui sbsc = device_private(self); 147 1.32 kent sc = &sbsc->sc_cs4231; 148 1.32 kent sa = aux; 149 1.19 eeh sbsc->sc_bt = sc->sc_bustag = sa->sa_bustag; 150 1.1 pk sc->sc_dmatag = sa->sa_dmatag; 151 1.1 pk 152 1.49 jmcneill sbsc->sc_pint = sparc_softintr_establish(IPL_SCHED, 153 1.42 ad (void *)cs4231_sbus_pint, sc); 154 1.49 jmcneill sbsc->sc_rint = sparc_softintr_establish(IPL_SCHED, 155 1.42 ad (void *)cs4231_sbus_rint, sc); 156 1.36 ad 157 1.1 pk /* 158 1.1 pk * Map my registers in, if they aren't already in virtual 159 1.1 pk * address space. 160 1.1 pk */ 161 1.1 pk if (sa->sa_npromvaddrs) { 162 1.19 eeh sbus_promaddr_to_handle(sa->sa_bustag, 163 1.19 eeh sa->sa_promvaddrs[0], &bh); 164 1.1 pk } else { 165 1.19 eeh if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, 166 1.19 eeh sa->sa_offset, sa->sa_size, 0, &bh) != 0) { 167 1.37 cegger aprint_error("%s @ sbus: cannot map registers\n", 168 1.37 cegger device_xname(self)); 169 1.1 pk return; 170 1.1 pk } 171 1.1 pk } 172 1.1 pk 173 1.19 eeh bus_space_subregion(sa->sa_bustag, bh, CS4231_APCDMA_OFFSET, 174 1.29 uwe APC_DMA_SIZE, &sbsc->sc_bh); 175 1.1 pk 176 1.48 christos cs4231_common_attach(sc, self, bh); 177 1.1 pk printf("\n"); 178 1.1 pk 179 1.49 jmcneill ad1848_init_locks(&sc->sc_ad1848, IPL_SCHED); 180 1.1 pk /* Establish interrupt channel */ 181 1.12 pk if (sa->sa_nintr) 182 1.12 pk bus_intr_establish(sa->sa_bustag, 183 1.36 ad sa->sa_pri, IPL_SCHED, 184 1.18 uwe cs4231_sbus_intr, sbsc); 185 1.18 uwe 186 1.47 tsutsui audio_attach_mi(&audiocs_sbus_hw_if, sbsc, self); 187 1.18 uwe } 188 1.18 uwe 189 1.18 uwe 190 1.18 uwe #ifdef AUDIO_DEBUG 191 1.18 uwe static void 192 1.50 martin cs4231_sbus_regdump(const char *label, struct cs4231_sbus_softc *sc) 193 1.18 uwe { 194 1.18 uwe char bits[128]; 195 1.18 uwe 196 1.18 uwe printf("cs4231regdump(%s): regs:", label); 197 1.19 eeh printf("dmapva: 0x%x; ", 198 1.50 martin bus_space_read_4(sc->sc_bt, sc->sc_bh, APC_DMA_PVA)); 199 1.19 eeh printf("dmapc: 0x%x; ", 200 1.50 martin bus_space_read_4(sc->sc_bt, sc->sc_bh, APC_DMA_PC)); 201 1.19 eeh printf("dmapnva: 0x%x; ", 202 1.50 martin bus_space_read_4(sc->sc_bt, sc->sc_bh, APC_DMA_PNVA)); 203 1.19 eeh printf("dmapnc: 0x%x\n", 204 1.50 martin bus_space_read_4(sc->sc_bt, sc->sc_bh, APC_DMA_PNC)); 205 1.32 kent printf("dmacva: 0x%x; ", 206 1.50 martin bus_space_read_4(sc->sc_bt, sc->sc_bh, APC_DMA_CVA)); 207 1.32 kent printf("dmacc: 0x%x; ", 208 1.50 martin bus_space_read_4(sc->sc_bt, sc->sc_bh, APC_DMA_CC)); 209 1.32 kent printf("dmacnva: 0x%x; ", 210 1.50 martin bus_space_read_4(sc->sc_bt, sc->sc_bh, APC_DMA_CNVA)); 211 1.32 kent printf("dmacnc: 0x%x\n", 212 1.50 martin bus_space_read_4(sc->sc_bt, sc->sc_bh, APC_DMA_CNC)); 213 1.18 uwe 214 1.43 christos snprintb(bits, sizeof(bits), APC_BITS, 215 1.50 martin bus_space_read_4(sc->sc_bt, sc->sc_bh, APC_DMA_CSR)); 216 1.43 christos printf("apc_dmacsr=%s\n", bits); 217 1.18 uwe 218 1.18 uwe ad1848_dump_regs(&sc->sc_cs4231.sc_ad1848); 219 1.18 uwe } 220 1.18 uwe #endif /* AUDIO_DEBUG */ 221 1.18 uwe 222 1.18 uwe 223 1.18 uwe static int 224 1.32 kent cs4231_sbus_trigger_output(void *addr, void *start, void *end, int blksize, 225 1.32 kent void (*intr)(void *), void *arg, 226 1.32 kent const audio_params_t *param) 227 1.18 uwe { 228 1.32 kent struct cs4231_sbus_softc *sbsc; 229 1.32 kent struct cs4231_softc *sc; 230 1.32 kent struct cs_transfer *t; 231 1.32 kent uint32_t csr; 232 1.18 uwe bus_addr_t dmaaddr; 233 1.18 uwe bus_size_t dmasize; 234 1.18 uwe int ret; 235 1.18 uwe #ifdef AUDIO_DEBUG 236 1.18 uwe char bits[128]; 237 1.18 uwe #endif 238 1.18 uwe 239 1.32 kent sbsc = addr; 240 1.32 kent sc = &sbsc->sc_cs4231; 241 1.32 kent t = &sc->sc_playback; 242 1.18 uwe ret = cs4231_transfer_init(sc, t, &dmaaddr, &dmasize, 243 1.18 uwe start, end, blksize, intr, arg); 244 1.18 uwe if (ret != 0) 245 1.32 kent return ret; 246 1.18 uwe 247 1.18 uwe DPRINTF(("trigger_output: was: %x %d, %x %d\n", 248 1.32 kent bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PVA), 249 1.29 uwe bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PC), 250 1.29 uwe bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA), 251 1.29 uwe bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC))); 252 1.18 uwe 253 1.18 uwe /* load first block */ 254 1.29 uwe bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA, dmaaddr); 255 1.29 uwe bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC, dmasize); 256 1.18 uwe 257 1.18 uwe DPRINTF(("trigger_output: 1st: %x %d, %x %d\n", 258 1.29 uwe bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PVA), 259 1.29 uwe bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PC), 260 1.29 uwe bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA), 261 1.29 uwe bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC))); 262 1.18 uwe 263 1.29 uwe csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 264 1.43 christos #ifdef AUDIO_DEBUG 265 1.43 christos snprintb(bits, sizeof(bits), APC_BITS, csr); 266 1.43 christos #endif 267 1.43 christos DPRINTF(("trigger_output: csr=%s\n", bits)); 268 1.18 uwe if ((csr & PDMA_GO) == 0 || (csr & APC_PPAUSE) != 0) { 269 1.18 uwe int cfg; 270 1.18 uwe 271 1.19 eeh csr &= ~(APC_PPAUSE | APC_PMIE | APC_INTR_MASK); 272 1.29 uwe bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 273 1.18 uwe 274 1.29 uwe csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 275 1.19 eeh csr &= ~APC_INTR_MASK; 276 1.18 uwe csr |= APC_ENABLE | APC_PIE | APC_PMIE | PDMA_GO; 277 1.29 uwe bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 278 1.18 uwe 279 1.18 uwe ad_write(&sc->sc_ad1848, SP_LOWER_BASE_COUNT, 0xff); 280 1.18 uwe ad_write(&sc->sc_ad1848, SP_UPPER_BASE_COUNT, 0xff); 281 1.18 uwe 282 1.18 uwe cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 283 1.18 uwe ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG, 284 1.18 uwe (cfg | PLAYBACK_ENABLE)); 285 1.18 uwe } else { 286 1.43 christos #ifdef AUDIO_DEBUG 287 1.43 christos snprintb(bits, sizeof(bits), APC_BITS, csr); 288 1.43 christos #endif 289 1.43 christos DPRINTF(("trigger_output: already: csr=%s\n", bits)); 290 1.43 christos 291 1.18 uwe } 292 1.18 uwe 293 1.18 uwe /* load next block if we can */ 294 1.29 uwe csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 295 1.19 eeh if (csr & APC_PD) { 296 1.21 mrg cs4231_transfer_advance(t, &dmaaddr, &dmasize); 297 1.29 uwe bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA, dmaaddr); 298 1.29 uwe bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC, dmasize); 299 1.19 eeh 300 1.21 mrg DPRINTF(("trigger_output: 2nd: %x %d, %x %d\n", 301 1.29 uwe bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PVA), 302 1.29 uwe bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PC), 303 1.29 uwe bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNVA), 304 1.29 uwe bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_PNC))); 305 1.18 uwe } 306 1.18 uwe 307 1.32 kent return 0; 308 1.18 uwe } 309 1.18 uwe 310 1.18 uwe 311 1.18 uwe static int 312 1.32 kent cs4231_sbus_halt_output(void *addr) 313 1.18 uwe { 314 1.32 kent struct cs4231_sbus_softc *sbsc; 315 1.32 kent struct cs4231_softc *sc; 316 1.32 kent uint32_t csr; 317 1.18 uwe int cfg; 318 1.18 uwe #ifdef AUDIO_DEBUG 319 1.18 uwe char bits[128]; 320 1.18 uwe #endif 321 1.18 uwe 322 1.32 kent sbsc = addr; 323 1.32 kent sc = &sbsc->sc_cs4231; 324 1.18 uwe sc->sc_playback.t_active = 0; 325 1.18 uwe 326 1.29 uwe csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 327 1.43 christos #ifdef AUDIO_DEBUG 328 1.43 christos snprintb(bits, sizeof(bits), APC_BITS, csr); 329 1.43 christos #endif 330 1.43 christos DPRINTF(("halt_output: csr=%s\n", bits)); 331 1.18 uwe 332 1.18 uwe csr &= ~APC_INTR_MASK; /* do not clear interrupts accidentally */ 333 1.18 uwe csr |= APC_PPAUSE; /* pause playback (let current complete) */ 334 1.29 uwe bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 335 1.32 kent 336 1.18 uwe /* let the curernt transfer complete */ 337 1.18 uwe if (csr & PDMA_GO) 338 1.18 uwe do { 339 1.32 kent csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, 340 1.29 uwe APC_DMA_CSR); 341 1.43 christos #ifdef AUDIO_DEBUG 342 1.43 christos snprintb(bits, sizeof(bits), APC_BITS, csr); 343 1.43 christos #endif 344 1.43 christos DPRINTF(("halt_output: csr=%s\n", bits)); 345 1.18 uwe } while ((csr & APC_PM) == 0); 346 1.1 pk 347 1.18 uwe cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 348 1.18 uwe ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG,(cfg & ~PLAYBACK_ENABLE)); 349 1.18 uwe 350 1.32 kent return 0; 351 1.1 pk } 352 1.18 uwe 353 1.18 uwe 354 1.18 uwe /* NB: we don't enable APC_CMIE and won't use APC_CM */ 355 1.18 uwe static int 356 1.32 kent cs4231_sbus_trigger_input(void *addr, void *start, void *end, int blksize, 357 1.32 kent void (*intr)(void *), void *arg, 358 1.32 kent const audio_params_t *param) 359 1.18 uwe { 360 1.32 kent struct cs4231_sbus_softc *sbsc; 361 1.32 kent struct cs4231_softc *sc; 362 1.32 kent struct cs_transfer *t; 363 1.32 kent uint32_t csr; 364 1.18 uwe bus_addr_t dmaaddr; 365 1.18 uwe bus_size_t dmasize; 366 1.18 uwe int ret; 367 1.18 uwe #ifdef AUDIO_DEBUG 368 1.18 uwe char bits[128]; 369 1.1 pk #endif 370 1.18 uwe 371 1.32 kent sbsc = addr; 372 1.32 kent sc = &sbsc->sc_cs4231; 373 1.32 kent t = &sc->sc_capture; 374 1.18 uwe ret = cs4231_transfer_init(sc, t, &dmaaddr, &dmasize, 375 1.18 uwe start, end, blksize, intr, arg); 376 1.18 uwe if (ret != 0) 377 1.32 kent return ret; 378 1.18 uwe 379 1.29 uwe csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 380 1.43 christos #ifdef AUDIO_DEBUG 381 1.43 christos snprintb(bits, sizeof(bits), APC_BITS, csr); 382 1.43 christos #endif 383 1.43 christos DPRINTF(("trigger_input: csr=%s\n", bits)); 384 1.18 uwe DPRINTF(("trigger_input: was: %x %d, %x %d\n", 385 1.32 kent bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CVA), 386 1.29 uwe bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CC), 387 1.29 uwe bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA), 388 1.29 uwe bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC))); 389 1.18 uwe 390 1.18 uwe /* supply first block */ 391 1.29 uwe bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA, dmaaddr); 392 1.29 uwe bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC, dmasize); 393 1.18 uwe 394 1.18 uwe DPRINTF(("trigger_input: 1st: %x %d, %x %d\n", 395 1.32 kent bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CVA), 396 1.29 uwe bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CC), 397 1.29 uwe bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA), 398 1.29 uwe bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC))); 399 1.18 uwe 400 1.29 uwe csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 401 1.18 uwe if ((csr & CDMA_GO) == 0 || (csr & APC_CPAUSE) != 0) { 402 1.18 uwe int cfg; 403 1.18 uwe 404 1.19 eeh csr &= ~(APC_CPAUSE | APC_CMIE | APC_INTR_MASK); 405 1.29 uwe bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 406 1.18 uwe 407 1.29 uwe csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 408 1.19 eeh csr &= ~APC_INTR_MASK; 409 1.18 uwe csr |= APC_ENABLE | APC_CIE | CDMA_GO; 410 1.29 uwe bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 411 1.18 uwe 412 1.18 uwe ad_write(&sc->sc_ad1848, CS_LOWER_REC_CNT, 0xff); 413 1.18 uwe ad_write(&sc->sc_ad1848, CS_UPPER_REC_CNT, 0xff); 414 1.18 uwe 415 1.18 uwe cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 416 1.18 uwe ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG, 417 1.18 uwe (cfg | CAPTURE_ENABLE)); 418 1.18 uwe } else { 419 1.43 christos #ifdef AUDIO_DEBUG 420 1.43 christos snprintb(bits, sizeof(bits), APC_BITS, csr); 421 1.43 christos #endif 422 1.43 christos DPRINTF(("trigger_input: already: csr=%s\n", bits)); 423 1.18 uwe } 424 1.18 uwe 425 1.18 uwe /* supply next block if we can */ 426 1.29 uwe csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 427 1.21 mrg if (csr & APC_CD) { 428 1.21 mrg cs4231_transfer_advance(t, &dmaaddr, &dmasize); 429 1.29 uwe bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA, dmaaddr); 430 1.29 uwe bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC, dmasize); 431 1.21 mrg DPRINTF(("trigger_input: 2nd: %x %d, %x %d\n", 432 1.29 uwe bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CVA), 433 1.29 uwe bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CC), 434 1.29 uwe bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNVA), 435 1.29 uwe bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CNC))); 436 1.18 uwe } 437 1.18 uwe 438 1.32 kent return 0; 439 1.18 uwe } 440 1.18 uwe 441 1.18 uwe 442 1.18 uwe static int 443 1.32 kent cs4231_sbus_halt_input(void *addr) 444 1.18 uwe { 445 1.32 kent struct cs4231_sbus_softc *sbsc; 446 1.32 kent struct cs4231_softc *sc; 447 1.32 kent uint32_t csr; 448 1.18 uwe int cfg; 449 1.18 uwe #ifdef AUDIO_DEBUG 450 1.18 uwe char bits[128]; 451 1.18 uwe #endif 452 1.18 uwe 453 1.32 kent sbsc = addr; 454 1.32 kent sc = &sbsc->sc_cs4231; 455 1.18 uwe sc->sc_capture.t_active = 0; 456 1.18 uwe 457 1.29 uwe csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 458 1.43 christos #ifdef AUDIO_DEBUG 459 1.43 christos snprintb(bits, sizeof(bits), APC_BITS, csr); 460 1.43 christos #endif 461 1.43 christos DPRINTF(("halt_input: csr=%s\n", bits)); 462 1.43 christos 463 1.18 uwe 464 1.18 uwe csr &= ~APC_INTR_MASK; /* do not clear interrupts accidentally */ 465 1.18 uwe csr |= APC_CPAUSE; 466 1.29 uwe bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 467 1.18 uwe 468 1.18 uwe /* let the curernt transfer complete */ 469 1.18 uwe if (csr & CDMA_GO) 470 1.18 uwe do { 471 1.19 eeh csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, 472 1.29 uwe APC_DMA_CSR); 473 1.43 christos #ifdef AUDIO_DEBUG 474 1.43 christos snprintb(bits, sizeof(bits), APC_BITS, csr); 475 1.43 christos #endif 476 1.43 christos DPRINTF(("halt_input: csr=%s\n", bits)); 477 1.43 christos 478 1.43 christos 479 1.18 uwe } while ((csr & APC_CM) == 0); 480 1.18 uwe 481 1.18 uwe cfg = ad_read(&sc->sc_ad1848, SP_INTERFACE_CONFIG); 482 1.18 uwe ad_write(&sc->sc_ad1848, SP_INTERFACE_CONFIG, (cfg & ~CAPTURE_ENABLE)); 483 1.18 uwe 484 1.32 kent return 0; 485 1.18 uwe } 486 1.18 uwe 487 1.18 uwe 488 1.18 uwe static int 489 1.32 kent cs4231_sbus_intr(void *arg) 490 1.18 uwe { 491 1.32 kent struct cs4231_sbus_softc *sbsc; 492 1.32 kent struct cs4231_softc *sc; 493 1.32 kent uint32_t csr; 494 1.18 uwe int status; 495 1.18 uwe bus_addr_t dmaaddr; 496 1.18 uwe bus_size_t dmasize; 497 1.18 uwe int served; 498 1.18 uwe #if defined(AUDIO_DEBUG) || defined(DIAGNOSTIC) 499 1.18 uwe char bits[128]; 500 1.18 uwe #endif 501 1.18 uwe 502 1.32 kent sbsc = arg; 503 1.32 kent sc = &sbsc->sc_cs4231; 504 1.29 uwe csr = bus_space_read_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR); 505 1.53 andvar if ((csr & APC_INTR_MASK) == 0) /* any interrupt pending? */ 506 1.32 kent return 0; 507 1.18 uwe 508 1.49 jmcneill mutex_spin_enter(&sc->sc_ad1848.sc_intr_lock); 509 1.49 jmcneill 510 1.19 eeh /* write back DMA status to clear interrupt */ 511 1.29 uwe bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, APC_DMA_CSR, csr); 512 1.18 uwe ++sc->sc_intrcnt.ev_count; 513 1.18 uwe served = 0; 514 1.18 uwe 515 1.18 uwe #ifdef AUDIO_DEBUG 516 1.18 uwe if (cs4231_sbus_debug > 1) 517 1.18 uwe cs4231_sbus_regdump("audiointr", sbsc); 518 1.18 uwe #endif 519 1.18 uwe 520 1.18 uwe status = ADREAD(&sc->sc_ad1848, AD1848_STATUS); 521 1.43 christos #ifdef AUDIO_DEBUG 522 1.43 christos snprintb(bits, sizeof(bits), AD_R2_BITS, status); 523 1.43 christos #endif 524 1.48 christos DPRINTF(("%s: status: %s\n", device_xname(sc->sc_ad1848.sc_dev), 525 1.43 christos bits)); 526 1.18 uwe if (status & INTERRUPT_STATUS) { 527 1.18 uwe #ifdef AUDIO_DEBUG 528 1.18 uwe int reason; 529 1.18 uwe 530 1.18 uwe reason = ad_read(&sc->sc_ad1848, CS_IRQ_STATUS); 531 1.43 christos snprintb(bits, sizeof(bits), CS_I24_BITS, reason); 532 1.48 christos DPRINTF(("%s: i24: %s\n", device_xname(sc->sc_ad1848.sc_dev), 533 1.43 christos bits)); 534 1.18 uwe #endif 535 1.18 uwe /* clear ad1848 interrupt */ 536 1.18 uwe ADWRITE(&sc->sc_ad1848, AD1848_STATUS, 0); 537 1.18 uwe } 538 1.32 kent 539 1.18 uwe if (csr & APC_CI) { 540 1.18 uwe if (csr & APC_CD) { /* can supply new block */ 541 1.18 uwe struct cs_transfer *t = &sc->sc_capture; 542 1.18 uwe 543 1.18 uwe cs4231_transfer_advance(t, &dmaaddr, &dmasize); 544 1.19 eeh bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, 545 1.29 uwe APC_DMA_CNVA, dmaaddr); 546 1.19 eeh bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, 547 1.29 uwe APC_DMA_CNC, dmasize); 548 1.18 uwe 549 1.18 uwe if (t->t_intr != NULL) 550 1.39 ad sparc_softintr_schedule(sbsc->sc_rint); 551 1.18 uwe ++t->t_intrcnt.ev_count; 552 1.18 uwe served = 1; 553 1.18 uwe } 554 1.18 uwe } 555 1.18 uwe 556 1.18 uwe if (csr & APC_PMI) { 557 1.18 uwe if (!sc->sc_playback.t_active) 558 1.18 uwe served = 1; /* draining in halt_output() */ 559 1.18 uwe } 560 1.18 uwe 561 1.18 uwe if (csr & APC_PI) { 562 1.18 uwe if (csr & APC_PD) { /* can load new block */ 563 1.18 uwe struct cs_transfer *t = &sc->sc_playback; 564 1.18 uwe 565 1.18 uwe if (t->t_active) { 566 1.18 uwe cs4231_transfer_advance(t, &dmaaddr, &dmasize); 567 1.19 eeh bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, 568 1.29 uwe APC_DMA_PNVA, dmaaddr); 569 1.19 eeh bus_space_write_4(sbsc->sc_bt, sbsc->sc_bh, 570 1.29 uwe APC_DMA_PNC, dmasize); 571 1.18 uwe } 572 1.18 uwe 573 1.18 uwe if (t->t_intr != NULL) 574 1.39 ad sparc_softintr_schedule(sbsc->sc_pint); 575 1.18 uwe ++t->t_intrcnt.ev_count; 576 1.18 uwe served = 1; 577 1.18 uwe } 578 1.18 uwe } 579 1.18 uwe 580 1.18 uwe /* got an interrupt we don't know how to handle */ 581 1.18 uwe if (!served) { 582 1.18 uwe #ifdef DIAGNOSTIC 583 1.43 christos snprintb(bits, sizeof(bits), APC_BITS, csr); 584 1.43 christos printf("%s: unhandled csr=%s\n", 585 1.48 christos device_xname(sc->sc_ad1848.sc_dev), bits); 586 1.18 uwe #endif 587 1.18 uwe /* evcnt? */ 588 1.18 uwe } 589 1.18 uwe 590 1.49 jmcneill mutex_spin_exit(&sc->sc_ad1848.sc_intr_lock); 591 1.49 jmcneill 592 1.32 kent return 1; 593 1.18 uwe } 594 1.18 uwe 595 1.40 martin static int 596 1.36 ad cs4231_sbus_pint(void *cookie) 597 1.36 ad { 598 1.36 ad struct cs4231_softc *sc = cookie; 599 1.39 ad struct cs_transfer *t; 600 1.36 ad 601 1.49 jmcneill mutex_spin_enter(&sc->sc_ad1848.sc_intr_lock); 602 1.39 ad t = &sc->sc_playback; 603 1.36 ad if (t->t_intr != NULL) 604 1.36 ad (*t->t_intr)(t->t_arg); 605 1.49 jmcneill mutex_spin_exit(&sc->sc_ad1848.sc_intr_lock); 606 1.40 martin return 0; 607 1.36 ad } 608 1.36 ad 609 1.40 martin static int 610 1.36 ad cs4231_sbus_rint(void *cookie) 611 1.36 ad { 612 1.36 ad struct cs4231_softc *sc = cookie; 613 1.39 ad struct cs_transfer *t; 614 1.36 ad 615 1.49 jmcneill mutex_spin_enter(&sc->sc_ad1848.sc_intr_lock); 616 1.39 ad t = &sc->sc_capture; 617 1.36 ad if (t->t_intr != NULL) 618 1.36 ad (*t->t_intr)(t->t_arg); 619 1.49 jmcneill mutex_spin_exit(&sc->sc_ad1848.sc_intr_lock); 620 1.40 martin return 0; 621 1.36 ad } 622 1.36 ad 623 1.18 uwe #endif /* NAUDIO > 0 */ 624