1 /* $NetBSD: dbri.c,v 1.25 2009/09/20 08:24:04 tsutsui Exp $ */ 2 3 /* 4 * Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de) 5 * Copyright (c) 1998, 1999 Brent Baccala (baccala@freesoft.org) 6 * Copyright (c) 2001, 2002 Jared D. McNeill <jmcneill@netbsd.org> 7 * Copyright (c) 2005 Michael Lorenz <macallan@netbsd.org> 8 * All rights reserved. 9 * 10 * This driver is losely based on a Linux driver written by Rudolf Koenig and 11 * Brent Baccala who kindly gave their permission to use their code in a 12 * BSD-licensed driver. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in the 21 * documentation and/or other materials provided with the distribution. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 29 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 * 34 */ 35 36 #include <sys/cdefs.h> 37 __KERNEL_RCSID(0, "$NetBSD: dbri.c,v 1.25 2009/09/20 08:24:04 tsutsui Exp $"); 38 39 #include "audio.h" 40 #if NAUDIO > 0 41 42 #include <sys/param.h> 43 #include <sys/systm.h> 44 #include <sys/errno.h> 45 #include <sys/device.h> 46 #include <sys/malloc.h> 47 #include <sys/proc.h> 48 #include <sys/kernel.h> 49 #include <sys/bus.h> 50 #include <sys/intr.h> 51 52 #include <dev/sbus/sbusvar.h> 53 #include <sparc/sparc/auxreg.h> 54 #include <machine/autoconf.h> 55 56 #include <sys/audioio.h> 57 #include <dev/audio_if.h> 58 #include <dev/auconv.h> 59 60 #include <dev/ic/cs4215reg.h> 61 #include <dev/ic/cs4215var.h> 62 #include <dev/sbus/dbrireg.h> 63 #include <dev/sbus/dbrivar.h> 64 65 #include "opt_sbus_dbri.h" 66 67 #define DBRI_ROM_NAME_PREFIX "SUNW,DBRI" 68 69 #ifdef DBRI_DEBUG 70 # define DPRINTF aprint_normal 71 #else 72 # define DPRINTF while (0) printf 73 #endif 74 75 static const char *dbri_supported[] = { 76 "e", 77 "s3", 78 "" 79 }; 80 81 enum ms { 82 CHImaster, 83 CHIslave 84 }; 85 86 enum io { 87 PIPEinput, 88 PIPEoutput 89 }; 90 91 /* 92 * Function prototypes 93 */ 94 95 /* softc stuff */ 96 static void dbri_attach_sbus(device_t, device_t, void *); 97 static int dbri_match_sbus(device_t, cfdata_t, void *); 98 99 static void dbri_config_interrupts(device_t); 100 101 /* interrupt handler */ 102 static int dbri_intr(void *); 103 static void dbri_softint(void *); 104 105 /* supporting subroutines */ 106 static int dbri_init(struct dbri_softc *); 107 static int dbri_reset(struct dbri_softc *); 108 static volatile uint32_t *dbri_command_lock(struct dbri_softc *); 109 static void dbri_command_send(struct dbri_softc *, volatile uint32_t *); 110 static void dbri_process_interrupt_buffer(struct dbri_softc *); 111 static void dbri_process_interrupt(struct dbri_softc *, int32_t); 112 113 /* mmcodec subroutines */ 114 static int mmcodec_init(struct dbri_softc *); 115 static void mmcodec_init_data(struct dbri_softc *); 116 static void mmcodec_pipe_init(struct dbri_softc *); 117 static void mmcodec_default(struct dbri_softc *); 118 static void mmcodec_setgain(struct dbri_softc *, int); 119 static int mmcodec_setcontrol(struct dbri_softc *); 120 121 /* chi subroutines */ 122 static void chi_reset(struct dbri_softc *, enum ms, int); 123 124 /* pipe subroutines */ 125 static void pipe_setup(struct dbri_softc *, int, int); 126 static void pipe_reset(struct dbri_softc *, int); 127 static void pipe_receive_fixed(struct dbri_softc *, int, 128 volatile uint32_t *); 129 static void pipe_transmit_fixed(struct dbri_softc *, int, uint32_t); 130 131 static void pipe_ts_link(struct dbri_softc *, int, enum io, int, int, int); 132 static int pipe_active(struct dbri_softc *, int); 133 134 /* audio(9) stuff */ 135 static int dbri_query_encoding(void *, struct audio_encoding *); 136 static int dbri_set_params(void *, int, int, struct audio_params *, 137 struct audio_params *,stream_filter_list_t *, stream_filter_list_t *); 138 static int dbri_round_blocksize(void *, int, int, const audio_params_t *); 139 static int dbri_halt_output(void *); 140 static int dbri_halt_input(void *); 141 static int dbri_getdev(void *, struct audio_device *); 142 static int dbri_set_port(void *, mixer_ctrl_t *); 143 static int dbri_get_port(void *, mixer_ctrl_t *); 144 static int dbri_query_devinfo(void *, mixer_devinfo_t *); 145 static size_t dbri_round_buffersize(void *, int, size_t); 146 static int dbri_get_props(void *); 147 static int dbri_open(void *, int); 148 static void dbri_close(void *); 149 150 static void setup_ring_xmit(struct dbri_softc *, int, int, int, int, 151 void (*)(void *), void *); 152 static void setup_ring_recv(struct dbri_softc *, int, int, int, int, 153 void (*)(void *), void *); 154 155 static int dbri_trigger_output(void *, void *, void *, int, 156 void (*)(void *), void *, const struct audio_params *); 157 static int dbri_trigger_input(void *, void *, void *, int, 158 void (*)(void *), void *, const struct audio_params *); 159 160 static void *dbri_malloc(void *, int, size_t, struct malloc_type *, int); 161 static void dbri_free(void *, void *, struct malloc_type *); 162 static paddr_t dbri_mappage(void *, void *, off_t, int); 163 static void dbri_set_power(struct dbri_softc *, int); 164 static void dbri_bring_up(struct dbri_softc *); 165 static void dbri_powerhook(int, void *); 166 167 /* stupid support routines */ 168 static uint32_t reverse_bytes(uint32_t, int); 169 170 struct audio_device dbri_device = { 171 "CS4215", 172 "", 173 "dbri" 174 }; 175 176 struct audio_hw_if dbri_hw_if = { 177 dbri_open, 178 dbri_close, 179 NULL, /* drain */ 180 dbri_query_encoding, 181 dbri_set_params, 182 dbri_round_blocksize, 183 NULL, /* commit_settings */ 184 NULL, /* init_output */ 185 NULL, /* init_input */ 186 NULL, /* start_output */ 187 NULL, /* start_input */ 188 dbri_halt_output, 189 dbri_halt_input, 190 NULL, /* speaker_ctl */ 191 dbri_getdev, 192 NULL, /* setfd */ 193 dbri_set_port, 194 dbri_get_port, 195 dbri_query_devinfo, 196 dbri_malloc, 197 dbri_free, 198 dbri_round_buffersize, 199 dbri_mappage, 200 dbri_get_props, 201 dbri_trigger_output, 202 dbri_trigger_input 203 }; 204 205 CFATTACH_DECL_NEW(dbri, sizeof(struct dbri_softc), 206 dbri_match_sbus, dbri_attach_sbus, NULL, NULL); 207 208 #define DBRI_NFORMATS 4 209 static const struct audio_format dbri_formats[DBRI_NFORMATS] = { 210 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_SLINEAR_BE, 16, 16, 211 2, AUFMT_STEREO, 8, {8000, 9600, 11025, 16000, 22050, 32000, 44100, 212 48000}}, 213 /* {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ULAW, 8, 8, 214 2, AUFMT_STEREO, 8, {8000, 9600, 11025, 16000, 22050, 32000, 44100, 215 48000}}, 216 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ALAW, 8, 8, 217 2, AUFMT_STEREO, 8, {8000, 9600, 11025, 16000, 22050, 32000, 44100, 218 48000}}, 219 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ULINEAR, 8, 8, 220 2, AUFMT_STEREO, 8, {8000, 9600, 11025, 16000, 22050, 32000, 44100, 221 48000}},*/ 222 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ULAW, 8, 8, 223 1, AUFMT_MONAURAL, 8, {8000, 9600, 11025, 16000, 22050, 32000, 44100, 224 48000}}, 225 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ALAW, 8, 8, 226 1, AUFMT_MONAURAL, 8, {8000, 9600, 11025, 16000, 22050, 32000, 44100, 227 48000}}, 228 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ULINEAR, 8, 8, 229 1, AUFMT_MONAURAL, 8, {8000, 9600, 11025, 16000, 22050, 32000, 44100, 230 48000}}, 231 }; 232 233 enum { 234 DBRI_OUTPUT_CLASS, 235 DBRI_VOL_OUTPUT, 236 DBRI_ENABLE_MONO, 237 DBRI_ENABLE_HEADPHONE, 238 DBRI_ENABLE_LINE, 239 DBRI_MONITOR_CLASS, 240 DBRI_VOL_MONITOR, 241 DBRI_INPUT_CLASS, 242 DBRI_INPUT_GAIN, 243 DBRI_INPUT_SELECT, 244 DBRI_RECORD_CLASS, 245 DBRI_ENUM_LAST 246 }; 247 248 /* 249 * Autoconfig routines 250 */ 251 static int 252 dbri_match_sbus(device_t parent, cfdata_t match, void *aux) 253 { 254 struct sbus_attach_args *sa = aux; 255 char *ver; 256 int i; 257 258 if (strncmp(DBRI_ROM_NAME_PREFIX, sa->sa_name, 9)) 259 return (0); 260 261 ver = &sa->sa_name[9]; 262 263 for (i = 0; dbri_supported[i][0] != '\0'; i++) 264 if (strcmp(dbri_supported[i], ver) == 0) 265 return (1); 266 267 return (0); 268 } 269 270 static void 271 dbri_attach_sbus(device_t parent, device_t self, void *aux) 272 { 273 struct dbri_softc *sc = device_private(self); 274 struct sbus_attach_args *sa = aux; 275 bus_space_handle_t ioh; 276 bus_size_t size; 277 int error, rseg, pwr, i; 278 char *ver = &sa->sa_name[9]; 279 280 sc->sc_dev = self; 281 sc->sc_iot = sa->sa_bustag; 282 sc->sc_dmat = sa->sa_dmatag; 283 sc->sc_powerstate = 1; 284 285 pwr = prom_getpropint(sa->sa_node,"pwr-on-auxio",0); 286 aprint_normal(": rev %s\n", ver); 287 288 if (pwr) { 289 /* 290 * we can control DBRI power via auxio and we're initially 291 * powered down 292 */ 293 294 sc->sc_have_powerctl = 1; 295 sc->sc_powerstate = 0; 296 dbri_set_power(sc, 1); 297 powerhook_establish(device_xname(self), dbri_powerhook, sc); 298 } else { 299 /* we can't control power so we're always up */ 300 sc->sc_have_powerctl = 0; 301 sc->sc_powerstate = 1; 302 } 303 304 for (i = 0; i < DBRI_NUM_DESCRIPTORS; i++) { 305 sc->sc_desc[i].softint = softint_establish(SOFTINT_SERIAL, 306 dbri_softint, &sc->sc_desc[i]); 307 } 308 309 if (sa->sa_npromvaddrs) 310 ioh = (bus_space_handle_t)sa->sa_promvaddrs[0]; 311 else { 312 if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, 313 sa->sa_offset, sa->sa_size, 314 BUS_SPACE_MAP_LINEAR, /*0,*/ &ioh) != 0) { 315 aprint_error("%s @ sbus: cannot map registers\n", 316 device_xname(self)); 317 return; 318 } 319 } 320 321 sc->sc_ioh = ioh; 322 323 size = sizeof(struct dbri_dma); 324 325 /* get a DMA handle */ 326 if ((error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, 327 BUS_DMA_NOWAIT, &sc->sc_dmamap)) != 0) { 328 aprint_error_dev(self, "DMA map create error %d\n", 329 error); 330 return; 331 } 332 333 /* allocate DMA buffer */ 334 if ((error = bus_dmamem_alloc(sc->sc_dmat, size, 0, 0, &sc->sc_dmaseg, 335 1, &rseg, BUS_DMA_NOWAIT)) != 0) { 336 aprint_error_dev(self, "DMA buffer alloc error %d\n", 337 error); 338 return; 339 } 340 341 /* map DMA buffer into CPU addressable space */ 342 if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_dmaseg, rseg, size, 343 &sc->sc_membase, 344 BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) { 345 aprint_error_dev(self, "DMA buffer map error %d\n", 346 error); 347 return; 348 } 349 350 /* load the buffer */ 351 if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, 352 sc->sc_membase, size, NULL, 353 BUS_DMA_NOWAIT)) != 0) { 354 aprint_error_dev(self, "DMA buffer map load error %d\n", 355 error); 356 bus_dmamem_unmap(sc->sc_dmat, sc->sc_membase, size); 357 bus_dmamem_free(sc->sc_dmat, &sc->sc_dmaseg, rseg); 358 return; 359 } 360 361 /* map the registers into memory */ 362 363 /* kernel virtual address of DMA buffer */ 364 sc->sc_dma = (struct dbri_dma *)sc->sc_membase; 365 /* physical address of DMA buffer */ 366 sc->sc_dmabase = sc->sc_dmamap->dm_segs[0].ds_addr; 367 sc->sc_bufsiz = size; 368 369 bus_intr_establish(sa->sa_bustag, sa->sa_pri, IPL_SCHED, dbri_intr, 370 sc); 371 372 sc->sc_locked = 0; 373 sc->sc_desc_used = 0; 374 sc->sc_refcount = 0; 375 sc->sc_playing = 0; 376 sc->sc_recording = 0; 377 sc->sc_pmgrstate = PWR_RESUME; 378 config_interrupts(self, &dbri_config_interrupts); 379 380 return; 381 } 382 383 /* 384 * lowlevel routine to switch power for the DBRI chip 385 */ 386 static void 387 dbri_set_power(struct dbri_softc *sc, int state) 388 { 389 int s; 390 391 if (sc->sc_have_powerctl == 0) 392 return; 393 if (sc->sc_powerstate == state) 394 return; 395 396 if (state) { 397 DPRINTF("%s: waiting to power up... ", 398 device_xname(sc->sc_dev)); 399 s = splhigh(); 400 *AUXIO4M_REG |= (AUXIO4M_MMX); 401 splx(s); 402 delay(10000); 403 DPRINTF("done (%02x)\n", *AUXIO4M_REG); 404 } else { 405 DPRINTF("%s: powering down\n", device_xname(sc->sc_dev)); 406 s = splhigh(); 407 *AUXIO4M_REG &= ~AUXIO4M_MMX; 408 splx(s); 409 DPRINTF("done (%02x})\n", *AUXIO4M_REG); 410 } 411 sc->sc_powerstate = state; 412 } 413 414 /* 415 * power up and re-initialize the chip 416 */ 417 static void 418 dbri_bring_up(struct dbri_softc *sc) 419 { 420 421 if (sc->sc_have_powerctl == 0) 422 return; 423 424 if (sc->sc_powerstate == 1) 425 return; 426 427 /* ok, we really need to do something */ 428 dbri_set_power(sc, 1); 429 430 /* 431 * re-initialize the chip but skip all the probing, don't overwrite 432 * any other settings either 433 */ 434 dbri_init(sc); 435 mmcodec_setgain(sc, 1); 436 mmcodec_pipe_init(sc); 437 mmcodec_init_data(sc); 438 mmcodec_setgain(sc, 0); 439 } 440 441 static void 442 dbri_config_interrupts(device_t dev) 443 { 444 struct dbri_softc *sc = device_private(dev); 445 446 dbri_init(sc); 447 mmcodec_init(sc); 448 449 /* Attach ourselves to the high level audio interface */ 450 audio_attach_mi(&dbri_hw_if, sc, sc->sc_dev); 451 452 /* power down until open() */ 453 dbri_set_power(sc, 0); 454 return; 455 } 456 457 static int 458 dbri_intr(void *hdl) 459 { 460 struct dbri_softc *sc = hdl; 461 bus_space_tag_t iot = sc->sc_iot; 462 bus_space_handle_t ioh = sc->sc_ioh; 463 int x; 464 465 /* clear interrupt */ 466 x = bus_space_read_4(iot, ioh, DBRI_REG1); 467 if (x & (DBRI_MRR | DBRI_MLE | DBRI_LBG | DBRI_MBE)) { 468 uint32_t tmp; 469 470 if (x & DBRI_MRR) 471 aprint_debug_dev(sc->sc_dev, 472 "multiple ack error on sbus\n"); 473 if (x & DBRI_MLE) 474 aprint_debug_dev(sc->sc_dev, 475 "multiple late error on sbus\n"); 476 if (x & DBRI_LBG) 477 aprint_debug_dev(sc->sc_dev, 478 "lost bus grant on sbus\n"); 479 if (x & DBRI_MBE) 480 aprint_debug_dev(sc->sc_dev, "burst error on sbus\n"); 481 482 /* 483 * Some of these errors disable the chip's circuitry. 484 * Re-enable the circuitry and keep on going. 485 */ 486 487 tmp = bus_space_read_4(iot, ioh, DBRI_REG0); 488 tmp &= ~(DBRI_DISABLE_MASTER); 489 bus_space_write_4(iot, ioh, DBRI_REG0, tmp); 490 } 491 492 #if 0 493 if (!x & 1) /* XXX: DBRI_INTR_REQ */ 494 return (1); 495 #endif 496 497 dbri_process_interrupt_buffer(sc); 498 499 return (1); 500 } 501 502 static void 503 dbri_softint(void *cookie) 504 { 505 struct dbri_desc *dd = cookie; 506 507 if (dd->callback != NULL) 508 dd->callback(dd->callback_args); 509 } 510 511 static int 512 dbri_init(struct dbri_softc *sc) 513 { 514 bus_space_tag_t iot = sc->sc_iot; 515 bus_space_handle_t ioh = sc->sc_ioh; 516 uint32_t reg; 517 volatile uint32_t *cmd; 518 bus_addr_t dmaaddr; 519 int n; 520 521 dbri_reset(sc); 522 523 cmd = dbri_command_lock(sc); 524 525 /* XXX: Initialize interrupt ring buffer */ 526 sc->sc_dma->intr[0] = (uint32_t)sc->sc_dmabase + dbri_dma_off(intr, 0); 527 sc->sc_irqp = 1; 528 529 /* Initialize pipes */ 530 for (n = 0; n < DBRI_PIPE_MAX; n++) 531 sc->sc_pipe[n].desc = sc->sc_pipe[n].next = -1; 532 533 for (n = 1; n < DBRI_INT_BLOCKS; n++) { 534 sc->sc_dma->intr[n] = 0; 535 } 536 537 /* Disable all SBus bursts */ 538 /* XXX 16 byte bursts cause errors, the rest works */ 539 reg = bus_space_read_4(iot, ioh, DBRI_REG0); 540 541 /*reg &= ~(DBRI_BURST_4 | DBRI_BURST_8 | DBRI_BURST_16);*/ 542 reg |= (DBRI_BURST_4 | DBRI_BURST_8); 543 bus_space_write_4(iot, ioh, DBRI_REG0, reg); 544 545 /* setup interrupt queue */ 546 dmaaddr = (uint32_t)sc->sc_dmabase + dbri_dma_off(intr, 0); 547 *(cmd++) = DBRI_CMD(DBRI_COMMAND_IIQ, 0, 0); 548 *(cmd++) = dmaaddr; 549 550 dbri_command_send(sc, cmd); 551 return (0); 552 } 553 554 static int 555 dbri_reset(struct dbri_softc *sc) 556 { 557 int bail = 0; 558 559 bus_space_tag_t iot = sc->sc_iot; 560 bus_space_handle_t ioh = sc->sc_ioh; 561 562 bus_space_write_4(iot, ioh, DBRI_REG0, DBRI_SOFT_RESET); 563 while ((bus_space_read_4(iot, ioh, DBRI_REG0) & DBRI_SOFT_RESET) && 564 (bail < 100000)) { 565 bail++; 566 delay(10); 567 } 568 if (bail == 100000) 569 aprint_error_dev(sc->sc_dev, "reset timed out\n"); 570 return (0); 571 } 572 573 static volatile uint32_t * 574 dbri_command_lock(struct dbri_softc *sc) 575 { 576 577 if (sc->sc_locked) 578 aprint_debug_dev(sc->sc_dev, "command buffer locked\n"); 579 580 sc->sc_locked++; 581 582 return (&sc->sc_dma->command[0]); 583 } 584 585 static void 586 dbri_command_send(struct dbri_softc *sc, volatile uint32_t *cmd) 587 { 588 bus_space_handle_t ioh = sc->sc_ioh; 589 bus_space_tag_t iot = sc->sc_iot; 590 int maxloops = 1000000; 591 int x; 592 593 x = splsched(); 594 595 sc->sc_locked--; 596 597 if (sc->sc_locked != 0) { 598 aprint_error_dev(sc->sc_dev, 599 "command buffer improperly locked\n"); 600 } else if ((cmd - &sc->sc_dma->command[0]) >= DBRI_NUM_COMMANDS - 1) { 601 aprint_error_dev(sc->sc_dev, "command buffer overflow\n"); 602 } else { 603 *(cmd++) = DBRI_CMD(DBRI_COMMAND_PAUSE, 0, 0); 604 *(cmd++) = DBRI_CMD(DBRI_COMMAND_WAIT, 1, 0); 605 sc->sc_waitseen = 0; 606 bus_space_write_4(iot, ioh, DBRI_REG8, sc->sc_dmabase); 607 while ((--maxloops) > 0 && 608 (bus_space_read_4(iot, ioh, DBRI_REG0) 609 & DBRI_COMMAND_VALID)) { 610 bus_space_barrier(iot, ioh, DBRI_REG0, 4, 611 BUS_SPACE_BARRIER_READ); 612 delay(1000); 613 } 614 615 if (maxloops == 0) { 616 aprint_error_dev(sc->sc_dev, 617 "chip never completed command buffer\n"); 618 } else { 619 620 DPRINTF("%s: command completed\n", 621 device_xname(sc->sc_dev)); 622 623 while ((--maxloops) > 0 && (!sc->sc_waitseen)) 624 dbri_process_interrupt_buffer(sc); 625 if (maxloops == 0) { 626 aprint_error_dev(sc->sc_dev, "chip never acked WAIT\n"); 627 } 628 } 629 } 630 631 splx(x); 632 633 return; 634 } 635 636 static void 637 dbri_process_interrupt_buffer(struct dbri_softc *sc) 638 { 639 int32_t i; 640 641 while ((i = sc->sc_dma->intr[sc->sc_irqp]) != 0) { 642 sc->sc_dma->intr[sc->sc_irqp] = 0; 643 sc->sc_irqp++; 644 645 if (sc->sc_irqp == DBRI_INT_BLOCKS) 646 sc->sc_irqp = 1; 647 else if ((sc->sc_irqp & (DBRI_INT_BLOCKS - 1)) == 0) 648 sc->sc_irqp++; 649 650 dbri_process_interrupt(sc, i); 651 } 652 653 return; 654 } 655 656 static void 657 dbri_process_interrupt(struct dbri_softc *sc, int32_t i) 658 { 659 #if 0 660 const int liu_states[] = { 1, 0, 8, 3, 4, 5, 6, 7 }; 661 #endif 662 int val = DBRI_INTR_GETVAL(i); 663 int channel = DBRI_INTR_GETCHAN(i); 664 int command = DBRI_INTR_GETCMD(i); 665 int code = DBRI_INTR_GETCODE(i); 666 #if 0 667 int rval = DBRI_INTR_GETRVAL(i); 668 #endif 669 if (channel == DBRI_INTR_CMD && command == DBRI_COMMAND_WAIT) 670 sc->sc_waitseen++; 671 672 switch (code) { 673 case DBRI_INTR_XCMP: /* transmission complete */ 674 { 675 int td; 676 struct dbri_desc *dd; 677 678 td = sc->sc_pipe[channel].desc; 679 dd = &sc->sc_desc[td]; 680 681 if (dd->callback != NULL) 682 softint_schedule(dd->softint); 683 break; 684 } 685 case DBRI_INTR_FXDT: /* fixed data change */ 686 DPRINTF("dbri_intr: Fixed data change (%d: %x)\n", channel, 687 val); 688 #if 0 689 printf("reg: %08x\n", sc->sc_mm.status); 690 #endif 691 if (sc->sc_pipe[channel].sdp & DBRI_SDP_MSB) 692 val = reverse_bytes(val, sc->sc_pipe[channel].length); 693 if (sc->sc_pipe[channel].prec) 694 *(sc->sc_pipe[channel].prec) = val; 695 #ifndef DBRI_SPIN 696 DPRINTF("%s: wakeup %p\n", device_xname(sc->sc_dev), sc); 697 wakeup(sc); 698 #endif 699 break; 700 case DBRI_INTR_SBRI: 701 DPRINTF("dbri_intr: SBRI\n"); 702 break; 703 case DBRI_INTR_BRDY: 704 { 705 int td; 706 struct dbri_desc *dd; 707 708 td = sc->sc_pipe[channel].desc; 709 dd = &sc->sc_desc[td]; 710 711 if (dd->callback != NULL) 712 softint_schedule(dd->softint); 713 break; 714 } 715 case DBRI_INTR_UNDR: 716 { 717 volatile uint32_t *cmd; 718 int td = sc->sc_pipe[channel].desc; 719 720 DPRINTF("%s: DBRI_INTR_UNDR\n", device_xname(sc->sc_dev)); 721 722 sc->sc_dma->xmit[td].status = 0; 723 724 cmd = dbri_command_lock(sc); 725 *(cmd++) = DBRI_CMD(DBRI_COMMAND_SDP, 0, 726 sc->sc_pipe[channel].sdp | 727 DBRI_SDP_VALID_POINTER | 728 DBRI_SDP_CLEAR | 729 DBRI_SDP_2SAME); 730 *(cmd++) = sc->sc_dmabase + dbri_dma_off(xmit, td); 731 dbri_command_send(sc, cmd); 732 break; 733 } 734 case DBRI_INTR_CMDI: 735 DPRINTF("ok"); 736 break; 737 default: 738 739 aprint_error_dev(sc->sc_dev, "unknown interrupt code %d\n", 740 code); 741 break; 742 } 743 744 return; 745 } 746 747 /* 748 * mmcodec stuff 749 */ 750 751 static int 752 mmcodec_init(struct dbri_softc *sc) 753 { 754 bus_space_handle_t ioh = sc->sc_ioh; 755 bus_space_tag_t iot = sc->sc_iot; 756 uint32_t reg2; 757 int bail; 758 759 reg2 = bus_space_read_4(iot, ioh, DBRI_REG2); 760 DPRINTF("mmcodec_init: PIO reads %x\n", reg2); 761 762 if (reg2 & DBRI_PIO2) { 763 aprint_normal_dev(sc->sc_dev, " onboard CS4215 detected\n"); 764 sc->sc_mm.onboard = 1; 765 } 766 767 if (reg2 & DBRI_PIO0) { 768 aprint_normal_dev(sc->sc_dev, "speakerbox detected\n"); 769 bus_space_write_4(iot, ioh, DBRI_REG2, DBRI_PIO2_ENABLE); 770 sc->sc_mm.onboard = 0; 771 } 772 773 if ((reg2 & DBRI_PIO2) && (reg2 & DBRI_PIO0)) { 774 aprint_normal_dev(sc->sc_dev, "using speakerbox\n"); 775 bus_space_write_4(iot, ioh, DBRI_REG2, DBRI_PIO2_ENABLE); 776 sc->sc_mm.onboard = 0; 777 } 778 779 if (!(reg2 & (DBRI_PIO0|DBRI_PIO2))) { 780 aprint_normal_dev(sc->sc_dev, "no mmcodec found\n"); 781 return -1; 782 } 783 784 sc->sc_version = 0xff; 785 786 mmcodec_pipe_init(sc); 787 mmcodec_default(sc); 788 789 sc->sc_mm.offset = sc->sc_mm.onboard ? 0 : 8; 790 791 /* 792 * mmcodec_setcontrol() sometimes fails right after powerup 793 * so we just try again until we either get a useful response or run 794 * out of time 795 */ 796 bail = 0; 797 while (mmcodec_setcontrol(sc) == -1 || sc->sc_version == 0xff) { 798 799 bail++; 800 if (bail > 100) { 801 DPRINTF("%s: cs4215 probe failed at offset %d\n", 802 device_xname(sc->sc_dev), sc->sc_mm.offset); 803 return (-1); 804 } 805 delay(10000); 806 } 807 808 aprint_normal_dev(sc->sc_dev, "cs4215 rev %c found at offset %d\n", 809 0x43 + (sc->sc_version & 0xf), sc->sc_mm.offset); 810 811 /* set some sane defaults for mmcodec_init_data */ 812 sc->sc_params.channels = 2; 813 sc->sc_params.precision = 16; 814 815 mmcodec_init_data(sc); 816 817 return (0); 818 } 819 820 static void 821 mmcodec_init_data(struct dbri_softc *sc) 822 { 823 bus_space_tag_t iot = sc->sc_iot; 824 bus_space_handle_t ioh = sc->sc_ioh; 825 uint32_t tmp; 826 int data_width; 827 828 tmp = bus_space_read_4(iot, ioh, DBRI_REG0); 829 tmp &= ~(DBRI_CHI_ACTIVATE); /* disable CHI */ 830 bus_space_write_4(iot, ioh, DBRI_REG0, tmp); 831 832 /* switch CS4215 to data mode - set PIO3 to 1 */ 833 tmp = DBRI_PIO_ENABLE_ALL | DBRI_PIO1 | DBRI_PIO3; 834 835 /* XXX */ 836 tmp |= (sc->sc_mm.onboard ? DBRI_PIO0 : DBRI_PIO2); 837 838 bus_space_write_4(iot, ioh, DBRI_REG2, tmp); 839 chi_reset(sc, CHIslave, 128); 840 841 data_width = sc->sc_params.channels * sc->sc_params.precision; 842 843 if ((data_width != 32) && (data_width != 8)) 844 aprint_error("%s: data_width is %d\n", __func__, data_width); 845 846 pipe_ts_link(sc, 20, PIPEoutput, 16, 32, sc->sc_mm.offset + 32); 847 pipe_ts_link(sc, 4, PIPEoutput, 16, data_width, sc->sc_mm.offset); 848 pipe_ts_link(sc, 6, PIPEinput, 16, data_width, sc->sc_mm.offset); 849 pipe_ts_link(sc, 21, PIPEinput, 16, 32, sc->sc_mm.offset + 32); 850 851 pipe_receive_fixed(sc, 21, &sc->sc_mm.status); 852 853 mmcodec_setgain(sc, 0); 854 855 tmp = bus_space_read_4(iot, ioh, DBRI_REG0); 856 tmp |= DBRI_CHI_ACTIVATE; 857 bus_space_write_4(iot, ioh, DBRI_REG0, tmp); 858 859 return; 860 } 861 862 static void 863 mmcodec_pipe_init(struct dbri_softc *sc) 864 { 865 866 pipe_setup(sc, 4, DBRI_SDP_MEM | DBRI_SDP_TO_SER | DBRI_SDP_MSB); 867 pipe_setup(sc, 20, DBRI_SDP_FIXED | DBRI_SDP_TO_SER | DBRI_SDP_MSB); 868 pipe_setup(sc, 6, DBRI_SDP_MEM | DBRI_SDP_FROM_SER | DBRI_SDP_MSB); 869 pipe_setup(sc, 21, DBRI_SDP_FIXED | DBRI_SDP_FROM_SER | DBRI_SDP_MSB); 870 871 pipe_setup(sc, 17, DBRI_SDP_FIXED | DBRI_SDP_TO_SER | DBRI_SDP_MSB); 872 pipe_setup(sc, 18, DBRI_SDP_FIXED | DBRI_SDP_FROM_SER | DBRI_SDP_MSB); 873 pipe_setup(sc, 19, DBRI_SDP_FIXED | DBRI_SDP_FROM_SER | DBRI_SDP_MSB); 874 875 sc->sc_mm.status = 0; 876 877 pipe_receive_fixed(sc, 18, &sc->sc_mm.status); 878 pipe_receive_fixed(sc, 19, &sc->sc_mm.version); 879 880 return; 881 } 882 883 static void 884 mmcodec_default(struct dbri_softc *sc) 885 { 886 struct cs4215_state *mm = &sc->sc_mm; 887 888 /* 889 * no action, memory resetting only 890 * 891 * data time slots 5-8 892 * speaker, line and headphone enable. set gain to half. 893 * input is line 894 */ 895 mm->d.bdata[0] = sc->sc_latt = 0x20 | CS4215_HE | CS4215_LE; 896 mm->d.bdata[1] = sc->sc_ratt = 0x20 | CS4215_SE; 897 sc->sc_linp = 128; 898 sc->sc_rinp = 128; 899 sc->sc_monitor = 0; 900 sc->sc_input = 1; /* line */ 901 mm->d.bdata[2] = (CS4215_LG((sc->sc_linp >> 4)) & 0x0f) | 902 ((sc->sc_input == 2) ? CS4215_IS : 0) | CS4215_PIO0 | CS4215_PIO1; 903 mm->d.bdata[3] = (CS4215_RG((sc->sc_rinp >> 4) & 0x0f)) | 904 CS4215_MA(15 - ((sc->sc_monitor >> 4) & 0x0f)); 905 906 907 /* 908 * control time slots 1-4 909 * 910 * 0: default I/O voltage scale 911 * 1: 8 bit ulaw, 8kHz, mono, high pass filter disabled 912 * 2: serial enable, CHI master, 128 bits per frame, clock 1 913 * 3: tests disabled 914 */ 915 mm->c.bcontrol[0] = CS4215_RSRVD_1 | CS4215_MLB; 916 mm->c.bcontrol[1] = CS4215_DFR_ULAW | CS4215_FREQ[0].csval; 917 mm->c.bcontrol[2] = CS4215_XCLK | CS4215_BSEL_128 | CS4215_FREQ[0].xtal; 918 mm->c.bcontrol[3] = 0; 919 920 return; 921 } 922 923 static void 924 mmcodec_setgain(struct dbri_softc *sc, int mute) 925 { 926 if (mute) { 927 /* disable all outputs, max. attenuation */ 928 sc->sc_mm.d.bdata[0] = sc->sc_latt | 63; 929 sc->sc_mm.d.bdata[1] = sc->sc_ratt | 63; 930 } else { 931 932 sc->sc_mm.d.bdata[0] = sc->sc_latt; 933 sc->sc_mm.d.bdata[1] = sc->sc_ratt; 934 } 935 936 /* input stuff */ 937 sc->sc_mm.d.bdata[2] = CS4215_LG((sc->sc_linp >> 4) & 0x0f) | 938 ((sc->sc_input == 2) ? CS4215_IS : 0) | CS4215_PIO0 | CS4215_PIO1; 939 sc->sc_mm.d.bdata[3] = (CS4215_RG((sc->sc_rinp >> 4)) & 0x0f) | 940 (CS4215_MA(15 - ((sc->sc_monitor >> 4) & 0x0f))); 941 942 if (sc->sc_powerstate == 0) 943 return; 944 pipe_transmit_fixed(sc, 20, sc->sc_mm.d.ldata); 945 946 DPRINTF("mmcodec_setgain: %08x\n", sc->sc_mm.d.ldata); 947 /* give the chip some time to execute the command */ 948 delay(250); 949 950 return; 951 } 952 953 static int 954 mmcodec_setcontrol(struct dbri_softc *sc) 955 { 956 bus_space_tag_t iot = sc->sc_iot; 957 bus_space_handle_t ioh = sc->sc_ioh; 958 uint32_t val; 959 uint32_t tmp; 960 int bail = 0; 961 #if DBRI_SPIN 962 int i; 963 #endif 964 965 /* 966 * Temporarily mute outputs and wait 125 us to make sure that it 967 * happens. This avoids clicking noises. 968 */ 969 mmcodec_setgain(sc, 1); 970 delay(125); 971 972 bus_space_write_4(iot, ioh, DBRI_REG2, 0); 973 delay(125); 974 975 /* enable control mode */ 976 val = DBRI_PIO_ENABLE_ALL | DBRI_PIO1; /* was PIO1 */ 977 978 /* XXX */ 979 val |= (sc->sc_mm.onboard ? DBRI_PIO0 : DBRI_PIO2); 980 981 bus_space_write_4(iot, ioh, DBRI_REG2, val); 982 983 delay(34); 984 985 /* 986 * in control mode, the cs4215 is the slave device, so the 987 * DBRI must act as the CHI master. 988 * 989 * in data mode, the cs4215 must be the CHI master to insure 990 * that the data stream is in sync with its codec 991 */ 992 tmp = bus_space_read_4(iot, ioh, DBRI_REG0); 993 tmp &= ~DBRI_COMMAND_CHI; 994 bus_space_write_4(iot, ioh, DBRI_REG0, tmp); 995 996 chi_reset(sc, CHImaster, 128); 997 998 /* control mode */ 999 pipe_ts_link(sc, 17, PIPEoutput, 16, 32, sc->sc_mm.offset); 1000 pipe_ts_link(sc, 18, PIPEinput, 16, 8, sc->sc_mm.offset); 1001 pipe_ts_link(sc, 19, PIPEinput, 16, 8, sc->sc_mm.offset + 48); 1002 1003 /* wait for the chip to echo back CLB as zero */ 1004 sc->sc_mm.c.bcontrol[0] &= ~CS4215_CLB; 1005 pipe_transmit_fixed(sc, 17, sc->sc_mm.c.lcontrol); 1006 1007 tmp = bus_space_read_4(iot, ioh, DBRI_REG0); 1008 tmp |= DBRI_CHI_ACTIVATE; 1009 bus_space_write_4(iot, ioh, DBRI_REG0, tmp); 1010 1011 #if DBRI_SPIN 1012 i = 1024; 1013 while (((sc->sc_mm.status & 0xe4) != 0x20) && --i) { 1014 delay(125); 1015 } 1016 1017 if (i == 0) { 1018 DPRINTF("%s: cs4215 didn't respond to CLB (0x%02x)\n", 1019 device_xname(sc->sc_dev), sc->sc_mm.status); 1020 return (-1); 1021 } 1022 #else 1023 while (((sc->sc_mm.status & 0xe4) != 0x20) && (bail < 10)) { 1024 DPRINTF("%s: tsleep %p\n", device_xname(sc->sc_dev), sc); 1025 tsleep(sc, PCATCH | PZERO, "dbrifxdt", hz); 1026 bail++; 1027 } 1028 #endif 1029 if (bail >= 10) { 1030 DPRINTF("%s: switching to control mode timed out (%x %x)\n", 1031 device_xname(sc->sc_dev), sc->sc_mm.status, 1032 bus_space_read_4(iot, ioh, DBRI_REG2)); 1033 return -1; 1034 } 1035 1036 /* copy the version information before it becomes unreadable again */ 1037 sc->sc_version = sc->sc_mm.version; 1038 1039 /* terminate cs4215 control mode */ 1040 sc->sc_mm.c.bcontrol[0] |= CS4215_CLB; 1041 pipe_transmit_fixed(sc, 17, sc->sc_mm.c.lcontrol); 1042 1043 /* two frames of control info @ 8kHz frame rate = 250us delay */ 1044 delay(250); 1045 1046 mmcodec_setgain(sc, 0); 1047 1048 return (0); 1049 1050 } 1051 1052 /* 1053 * CHI combo 1054 */ 1055 static void 1056 chi_reset(struct dbri_softc *sc, enum ms ms, int bpf) 1057 { 1058 volatile uint32_t *cmd; 1059 int val; 1060 int clockrate, divisor; 1061 1062 cmd = dbri_command_lock(sc); 1063 1064 /* set CHI anchor: pipe 16 */ 1065 val = DBRI_DTS_VI | DBRI_DTS_INS | DBRI_DTS_PRVIN(16) | DBRI_PIPE(16); 1066 *(cmd++) = DBRI_CMD(DBRI_COMMAND_DTS, 0, val); 1067 *(cmd++) = DBRI_TS_ANCHOR | DBRI_TS_NEXT(16); 1068 *(cmd++) = 0; 1069 1070 val = DBRI_DTS_VO | DBRI_DTS_INS | DBRI_DTS_PRVOUT(16) | DBRI_PIPE(16); 1071 *(cmd++) = DBRI_CMD(DBRI_COMMAND_DTS, 0, val); 1072 *(cmd++) = 0; 1073 *(cmd++) = DBRI_TS_ANCHOR | DBRI_TS_NEXT(16); 1074 1075 sc->sc_pipe[16].sdp = 1; 1076 sc->sc_pipe[16].next = 16; 1077 sc->sc_chi_pipe_in = 16; 1078 sc->sc_chi_pipe_out = 16; 1079 1080 switch (ms) { 1081 case CHIslave: 1082 *(cmd++) = DBRI_CMD(DBRI_COMMAND_CHI, 0, DBRI_CHI_CHICM(0)); 1083 break; 1084 case CHImaster: 1085 clockrate = bpf * 8; 1086 divisor = 12288 / clockrate; 1087 1088 if (divisor > 255 || divisor * clockrate != 12288) 1089 aprint_error_dev(sc->sc_dev, 1090 "illegal bits-per-frame %d\n", bpf); 1091 1092 *(cmd++) = DBRI_CMD(DBRI_COMMAND_CHI, 0, 1093 DBRI_CHI_CHICM(divisor) | DBRI_CHI_FD | DBRI_CHI_BPF(bpf)); 1094 break; 1095 default: 1096 aprint_error_dev(sc->sc_dev, "unknown value for ms!\n"); 1097 break; 1098 } 1099 1100 sc->sc_chi_bpf = bpf; 1101 1102 /* CHI data mode */ 1103 *(cmd++) = DBRI_CMD(DBRI_COMMAND_PAUSE, 0, 0); 1104 *(cmd++) = DBRI_CMD(DBRI_COMMAND_CDM, 0, 1105 DBRI_CDM_XCE | DBRI_CDM_XEN | DBRI_CDM_REN); 1106 1107 dbri_command_send(sc, cmd); 1108 1109 return; 1110 } 1111 1112 /* 1113 * pipe stuff 1114 */ 1115 static void 1116 pipe_setup(struct dbri_softc *sc, int pipe, int sdp) 1117 { 1118 DPRINTF("pipe setup: %d\n", pipe); 1119 if (pipe < 0 || pipe >= DBRI_PIPE_MAX) { 1120 aprint_error_dev(sc->sc_dev, "illegal pipe number %d\n", 1121 pipe); 1122 return; 1123 } 1124 1125 if ((sdp & 0xf800) != sdp) 1126 aprint_error_dev(sc->sc_dev, "strange SDP value %d\n", 1127 sdp); 1128 1129 if (DBRI_SDP_MODE(sdp) == DBRI_SDP_FIXED && 1130 !(sdp & DBRI_SDP_TO_SER)) 1131 sdp |= DBRI_SDP_CHANGE; 1132 1133 sdp |= DBRI_PIPE(pipe); 1134 1135 sc->sc_pipe[pipe].sdp = sdp; 1136 sc->sc_pipe[pipe].desc = -1; 1137 1138 pipe_reset(sc, pipe); 1139 1140 return; 1141 } 1142 1143 static void 1144 pipe_reset(struct dbri_softc *sc, int pipe) 1145 { 1146 struct dbri_desc *dd; 1147 int sdp; 1148 int desc; 1149 volatile uint32_t *cmd; 1150 1151 if (pipe < 0 || pipe >= DBRI_PIPE_MAX) { 1152 aprint_error_dev(sc->sc_dev, "illegal pipe number %d\n", 1153 pipe); 1154 return; 1155 } 1156 1157 sdp = sc->sc_pipe[pipe].sdp; 1158 if (sdp == 0) { 1159 aprint_error_dev(sc->sc_dev, "can not reset uninitialized pipe %d\n", 1160 pipe); 1161 return; 1162 } 1163 1164 cmd = dbri_command_lock(sc); 1165 *(cmd++) = DBRI_CMD(DBRI_COMMAND_SDP, 0, 1166 sdp | DBRI_SDP_CLEAR | DBRI_SDP_VALID_POINTER); 1167 *(cmd++) = 0; 1168 dbri_command_send(sc, cmd); 1169 1170 desc = sc->sc_pipe[pipe].desc; 1171 1172 dd = &sc->sc_desc[desc]; 1173 1174 dd->busy = 0; 1175 1176 #if 0 1177 if (dd->callback) 1178 softint_schedule(dd->softint); 1179 #endif 1180 1181 sc->sc_pipe[pipe].desc = -1; 1182 1183 return; 1184 } 1185 1186 static void 1187 pipe_receive_fixed(struct dbri_softc *sc, int pipe, volatile uint32_t *prec) 1188 { 1189 1190 if (pipe < DBRI_PIPE_MAX / 2 || pipe >= DBRI_PIPE_MAX) { 1191 aprint_error_dev(sc->sc_dev, "illegal pipe number %d\n", 1192 pipe); 1193 return; 1194 } 1195 1196 if (DBRI_SDP_MODE(sc->sc_pipe[pipe].sdp) != DBRI_SDP_FIXED) { 1197 aprint_error_dev(sc->sc_dev, "non-fixed pipe %d\n", 1198 pipe); 1199 return; 1200 } 1201 1202 if (sc->sc_pipe[pipe].sdp & DBRI_SDP_TO_SER) { 1203 aprint_error_dev(sc->sc_dev, "can not receive on transmit pipe %d\b", 1204 pipe); 1205 return; 1206 } 1207 1208 sc->sc_pipe[pipe].prec = prec; 1209 1210 return; 1211 } 1212 1213 static void 1214 pipe_transmit_fixed(struct dbri_softc *sc, int pipe, uint32_t data) 1215 { 1216 volatile uint32_t *cmd; 1217 1218 if (pipe < DBRI_PIPE_MAX / 2 || pipe >= DBRI_PIPE_MAX) { 1219 aprint_error_dev(sc->sc_dev, "illegal pipe number %d\n", 1220 pipe); 1221 return; 1222 } 1223 1224 if (DBRI_SDP_MODE(sc->sc_pipe[pipe].sdp) == 0) { 1225 aprint_error_dev(sc->sc_dev, "uninitialized pipe %d\n", 1226 pipe); 1227 return; 1228 } 1229 1230 if (DBRI_SDP_MODE(sc->sc_pipe[pipe].sdp) != DBRI_SDP_FIXED) { 1231 aprint_error_dev(sc->sc_dev, "non-fixed pipe %d\n", 1232 pipe); 1233 return; 1234 } 1235 1236 if (!(sc->sc_pipe[pipe].sdp & DBRI_SDP_TO_SER)) { 1237 aprint_error_dev(sc->sc_dev, "called on receive pipe %d\n", 1238 pipe); 1239 return; 1240 } 1241 1242 if (sc->sc_pipe[pipe].sdp & DBRI_SDP_MSB) 1243 data = reverse_bytes(data, sc->sc_pipe[pipe].length); 1244 1245 cmd = dbri_command_lock(sc); 1246 *(cmd++) = DBRI_CMD(DBRI_COMMAND_SSP, 0, pipe); 1247 *(cmd++) = data; 1248 1249 dbri_command_send(sc, cmd); 1250 1251 return; 1252 } 1253 1254 static void 1255 setup_ring_xmit(struct dbri_softc *sc, int pipe, int which, int num, int blksz, 1256 void (*callback)(void *), void *callback_args) 1257 { 1258 volatile uint32_t *cmd; 1259 int x, i; 1260 int td; 1261 int td_first, td_last; 1262 bus_addr_t dmabuf, dmabase; 1263 struct dbri_desc *dd = &sc->sc_desc[which]; 1264 1265 switch (pipe) { 1266 case 4: 1267 /* output, offset 0 */ 1268 break; 1269 default: 1270 aprint_error("%s: illegal pipe number (%d)\n", 1271 __func__, pipe); 1272 return; 1273 } 1274 1275 td = 0; 1276 td_first = td_last = -1; 1277 1278 if (sc->sc_pipe[pipe].sdp == 0) { 1279 aprint_error_dev(sc->sc_dev, "uninitialized pipe %d\n", 1280 pipe); 1281 return; 1282 } 1283 1284 dmabuf = dd->dmabase; 1285 dmabase = sc->sc_dmabase; 1286 td = 0; 1287 1288 for (i = 0; i < (num - 1); i++) { 1289 1290 sc->sc_dma->xmit[i].flags = TX_BCNT(blksz) 1291 | TX_EOF | TX_BINT; 1292 sc->sc_dma->xmit[i].ba = dmabuf; 1293 sc->sc_dma->xmit[i].nda = dmabase + dbri_dma_off(xmit, i + 1); 1294 sc->sc_dma->xmit[i].status = 0; 1295 1296 td_last = td; 1297 dmabuf += blksz; 1298 } 1299 1300 sc->sc_dma->xmit[i].flags = TX_BCNT(blksz) | TX_EOF | TX_BINT; 1301 1302 sc->sc_dma->xmit[i].ba = dmabuf; 1303 sc->sc_dma->xmit[i].nda = dmabase + dbri_dma_off(xmit, 0); 1304 sc->sc_dma->xmit[i].status = 0; 1305 1306 dd->callback = callback; 1307 dd->callback_args = callback_args; 1308 1309 x = splsched(); 1310 1311 /* the pipe shouldn't be active */ 1312 if (pipe_active(sc, pipe)) { 1313 aprint_error("pipe active (CDP)\n"); 1314 /* pipe is already active */ 1315 #if 0 1316 td_last = sc->sc_pipe[pipe].desc; 1317 while (sc->sc_desc[td_last].next != -1) 1318 td_last = sc->sc_desc[td_last].next; 1319 1320 sc->sc_desc[td_last].next = td_first; 1321 sc->sc_dma->desc[td_last].nda = 1322 sc->sc_dmabase + dbri_dma_off(desc, td_first); 1323 1324 cmd = dbri_command_lock(sc); 1325 *(cmd++) = DBRI_CMD(DBRI_COMMAND_CDP, 0, pipe); 1326 dbri_command_send(sc, cmd); 1327 #endif 1328 } else { 1329 /* 1330 * pipe isn't active - issue an SDP command to start our 1331 * chain of TDs running 1332 */ 1333 sc->sc_pipe[pipe].desc = which; 1334 cmd = dbri_command_lock(sc); 1335 *(cmd++) = DBRI_CMD(DBRI_COMMAND_SDP, 0, 1336 sc->sc_pipe[pipe].sdp | 1337 DBRI_SDP_VALID_POINTER | 1338 DBRI_SDP_EVERY | 1339 DBRI_SDP_CLEAR); 1340 *(cmd++) = sc->sc_dmabase + dbri_dma_off(xmit, 0); 1341 dbri_command_send(sc, cmd); 1342 DPRINTF("%s: starting DMA\n", __func__); 1343 } 1344 1345 splx(x); 1346 1347 return; 1348 } 1349 1350 static void 1351 setup_ring_recv(struct dbri_softc *sc, int pipe, int which, int num, int blksz, 1352 void (*callback)(void *), void *callback_args) 1353 { 1354 volatile uint32_t *cmd; 1355 int x, i; 1356 int td_first, td_last; 1357 bus_addr_t dmabuf, dmabase; 1358 struct dbri_desc *dd = &sc->sc_desc[which]; 1359 1360 switch (pipe) { 1361 case 6: 1362 break; 1363 default: 1364 aprint_error("%s: illegal pipe number (%d)\n", 1365 __func__, pipe); 1366 return; 1367 } 1368 1369 td_first = td_last = -1; 1370 1371 if (sc->sc_pipe[pipe].sdp == 0) { 1372 aprint_error_dev(sc->sc_dev, "uninitialized pipe %d\n", 1373 pipe); 1374 return; 1375 } 1376 1377 dmabuf = dd->dmabase; 1378 dmabase = sc->sc_dmabase; 1379 1380 for (i = 0; i < (num - 1); i++) { 1381 1382 sc->sc_dma->recv[i].flags = RX_BSIZE(blksz) | RX_FINAL; 1383 sc->sc_dma->recv[i].ba = dmabuf; 1384 sc->sc_dma->recv[i].nda = dmabase + dbri_dma_off(recv, i + 1); 1385 sc->sc_dma->recv[i].status = RX_EOF; 1386 1387 td_last = i; 1388 dmabuf += blksz; 1389 } 1390 1391 sc->sc_dma->recv[i].flags = RX_BSIZE(blksz) | RX_FINAL; 1392 1393 sc->sc_dma->recv[i].ba = dmabuf; 1394 sc->sc_dma->recv[i].nda = dmabase + dbri_dma_off(recv, 0); 1395 sc->sc_dma->recv[i].status = RX_EOF; 1396 1397 dd->callback = callback; 1398 dd->callback_args = callback_args; 1399 1400 x = splsched(); 1401 1402 /* the pipe shouldn't be active */ 1403 if (pipe_active(sc, pipe)) { 1404 aprint_error("pipe active (CDP)\n"); 1405 /* pipe is already active */ 1406 #if 0 1407 td_last = sc->sc_pipe[pipe].desc; 1408 while (sc->sc_desc[td_last].next != -1) 1409 td_last = sc->sc_desc[td_last].next; 1410 1411 sc->sc_desc[td_last].next = td_first; 1412 sc->sc_dma->desc[td_last].nda = 1413 sc->sc_dmabase + dbri_dma_off(desc, td_first); 1414 1415 cmd = dbri_command_lock(sc); 1416 *(cmd++) = DBRI_CMD(DBRI_COMMAND_CDP, 0, pipe); 1417 dbri_command_send(sc, cmd); 1418 #endif 1419 } else { 1420 /* 1421 * pipe isn't active - issue an SDP command to start our 1422 * chain of TDs running 1423 */ 1424 sc->sc_pipe[pipe].desc = which; 1425 cmd = dbri_command_lock(sc); 1426 *(cmd++) = DBRI_CMD(DBRI_COMMAND_SDP, 0, 1427 sc->sc_pipe[pipe].sdp | 1428 DBRI_SDP_VALID_POINTER | 1429 DBRI_SDP_EVERY | 1430 DBRI_SDP_CLEAR); 1431 *(cmd++) = sc->sc_dmabase + dbri_dma_off(recv, 0); 1432 dbri_command_send(sc, cmd); 1433 DPRINTF("%s: starting DMA\n", __func__); 1434 } 1435 1436 splx(x); 1437 1438 return; 1439 } 1440 1441 static void 1442 pipe_ts_link(struct dbri_softc *sc, int pipe, enum io dir, int basepipe, 1443 int len, int cycle) 1444 { 1445 volatile uint32_t *cmd; 1446 int prevpipe, nextpipe; 1447 int val; 1448 1449 DPRINTF("%s: %d\n", __func__, pipe); 1450 if (pipe < 0 || pipe >= DBRI_PIPE_MAX || 1451 basepipe < 0 || basepipe >= DBRI_PIPE_MAX) { 1452 aprint_error_dev(sc->sc_dev, "illegal pipe numbers (%d, %d)\n", 1453 pipe, basepipe); 1454 return; 1455 } 1456 1457 if (sc->sc_pipe[pipe].sdp == 0 || sc->sc_pipe[basepipe].sdp == 0) { 1458 aprint_error_dev(sc->sc_dev, "uninitialized pipe (%d, %d)\n", 1459 pipe, basepipe); 1460 return; 1461 } 1462 1463 if (basepipe == 16 && dir == PIPEoutput && cycle == 0) 1464 cycle = sc->sc_chi_bpf; 1465 1466 if (basepipe == pipe) 1467 prevpipe = nextpipe = pipe; 1468 else { 1469 if (basepipe == 16) { 1470 if (dir == PIPEinput) { 1471 prevpipe = sc->sc_chi_pipe_in; 1472 } else { 1473 prevpipe = sc->sc_chi_pipe_out; 1474 } 1475 } else 1476 prevpipe = basepipe; 1477 1478 nextpipe = sc->sc_pipe[prevpipe].next; 1479 1480 while (sc->sc_pipe[nextpipe].cycle < cycle && 1481 sc->sc_pipe[nextpipe].next != basepipe) { 1482 prevpipe = nextpipe; 1483 nextpipe = sc->sc_pipe[nextpipe].next; 1484 } 1485 } 1486 1487 if (prevpipe == 16) { 1488 if (dir == PIPEinput) { 1489 sc->sc_chi_pipe_in = pipe; 1490 } else { 1491 sc->sc_chi_pipe_out = pipe; 1492 } 1493 } else 1494 sc->sc_pipe[prevpipe].next = pipe; 1495 1496 sc->sc_pipe[pipe].next = nextpipe; 1497 sc->sc_pipe[pipe].cycle = cycle; 1498 sc->sc_pipe[pipe].length = len; 1499 1500 cmd = dbri_command_lock(sc); 1501 1502 switch (dir) { 1503 case PIPEinput: 1504 val = DBRI_DTS_VI | DBRI_DTS_INS | DBRI_DTS_PRVIN(prevpipe); 1505 val |= pipe; 1506 *(cmd++) = DBRI_CMD(DBRI_COMMAND_DTS, 0, val); 1507 *(cmd++) = DBRI_TS_LEN(len) | DBRI_TS_CYCLE(cycle) | 1508 DBRI_TS_NEXT(nextpipe); 1509 *(cmd++) = 0; 1510 break; 1511 case PIPEoutput: 1512 val = DBRI_DTS_VO | DBRI_DTS_INS | DBRI_DTS_PRVOUT(prevpipe); 1513 val |= pipe; 1514 *(cmd++) = DBRI_CMD(DBRI_COMMAND_DTS, 0, val); 1515 *(cmd++) = 0; 1516 *(cmd++) = DBRI_TS_LEN(len) | DBRI_TS_CYCLE(cycle) | 1517 DBRI_TS_NEXT(nextpipe); 1518 break; 1519 default: 1520 DPRINTF("%s: should not have happened!\n", 1521 device_xname(sc->sc_dev)); 1522 break; 1523 } 1524 1525 dbri_command_send(sc, cmd); 1526 1527 return; 1528 } 1529 1530 static int 1531 pipe_active(struct dbri_softc *sc, int pipe) 1532 { 1533 1534 return (sc->sc_pipe[pipe].desc != -1); 1535 } 1536 1537 /* 1538 * subroutines required to interface with audio(9) 1539 */ 1540 1541 static int 1542 dbri_query_encoding(void *hdl, struct audio_encoding *ae) 1543 { 1544 1545 switch (ae->index) { 1546 case 0: 1547 strcpy(ae->name, AudioEulinear); 1548 ae->encoding = AUDIO_ENCODING_ULINEAR; 1549 ae->precision = 8; 1550 ae->flags = 0; 1551 break; 1552 case 1: 1553 strcpy(ae->name, AudioEmulaw); 1554 ae->encoding = AUDIO_ENCODING_ULAW; 1555 ae->precision = 8; 1556 ae->flags = 0; 1557 break; 1558 case 2: 1559 strcpy(ae->name, AudioEalaw); 1560 ae->encoding = AUDIO_ENCODING_ALAW; 1561 ae->precision = 8; 1562 ae->flags = 0; 1563 break; 1564 case 3: 1565 strcpy(ae->name, AudioEslinear); 1566 ae->encoding = AUDIO_ENCODING_SLINEAR; 1567 ae->precision = 8; 1568 ae->flags = AUDIO_ENCODINGFLAG_EMULATED; 1569 break; 1570 case 4: 1571 strcpy(ae->name, AudioEslinear_le); 1572 ae->encoding = AUDIO_ENCODING_SLINEAR_LE; 1573 ae->precision = 16; 1574 ae->flags = AUDIO_ENCODINGFLAG_EMULATED; 1575 break; 1576 case 5: 1577 strcpy(ae->name, AudioEulinear_le); 1578 ae->encoding = AUDIO_ENCODING_ULINEAR_LE; 1579 ae->precision = 16; 1580 ae->flags = AUDIO_ENCODINGFLAG_EMULATED; 1581 break; 1582 case 6: 1583 strcpy(ae->name, AudioEslinear_be); 1584 ae->encoding = AUDIO_ENCODING_SLINEAR_BE; 1585 ae->precision = 16; 1586 ae->flags = 0; 1587 break; 1588 case 7: 1589 strcpy(ae->name, AudioEulinear_be); 1590 ae->encoding = AUDIO_ENCODING_ULINEAR_BE; 1591 ae->precision = 16; 1592 ae->flags = AUDIO_ENCODINGFLAG_EMULATED; 1593 break; 1594 case 8: 1595 strcpy(ae->name, AudioEslinear); 1596 ae->encoding = AUDIO_ENCODING_SLINEAR; 1597 ae->precision = 16; 1598 ae->flags = 0; 1599 break; 1600 default: 1601 return (EINVAL); 1602 } 1603 1604 return (0); 1605 } 1606 1607 static int 1608 dbri_set_params(void *hdl, int setmode, int usemode, 1609 struct audio_params *play, struct audio_params *rec, 1610 stream_filter_list_t *pfil, stream_filter_list_t *rfil) 1611 { 1612 struct dbri_softc *sc = hdl; 1613 int rate; 1614 audio_params_t *p = NULL; 1615 stream_filter_list_t *fil; 1616 int mode; 1617 1618 /* 1619 * This device only has one clock, so make the sample rates match. 1620 */ 1621 if (play->sample_rate != rec->sample_rate && 1622 usemode == (AUMODE_PLAY | AUMODE_RECORD)) { 1623 if (setmode == AUMODE_PLAY) { 1624 rec->sample_rate = play->sample_rate; 1625 setmode |= AUMODE_RECORD; 1626 } else if (setmode == AUMODE_RECORD) { 1627 play->sample_rate = rec->sample_rate; 1628 setmode |= AUMODE_PLAY; 1629 } else 1630 return EINVAL; 1631 } 1632 1633 for (mode = AUMODE_RECORD; mode != -1; 1634 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) { 1635 if ((setmode & mode) == 0) 1636 continue; 1637 1638 p = mode == AUMODE_PLAY ? play : rec; 1639 if (p->sample_rate < 4000 || p->sample_rate > 50000) { 1640 DPRINTF("dbri_set_params: invalid rate %d\n", 1641 p->sample_rate); 1642 return EINVAL; 1643 } 1644 1645 fil = mode == AUMODE_PLAY ? pfil : rfil; 1646 DPRINTF("requested enc: %d rate: %d prec: %d chan: %d\n", p->encoding, 1647 p->sample_rate, p->precision, p->channels); 1648 if (auconv_set_converter(dbri_formats, DBRI_NFORMATS, 1649 mode, p, true, fil) < 0) { 1650 aprint_debug("dbri_set_params: auconv_set_converter failed\n"); 1651 return EINVAL; 1652 } 1653 if (fil->req_size > 0) 1654 p = &fil->filters[0].param; 1655 } 1656 1657 if (p == NULL) { 1658 DPRINTF("dbri_set_params: no parameters to set\n"); 1659 return 0; 1660 } 1661 1662 DPRINTF("native enc: %d rate: %d prec: %d chan: %d\n", p->encoding, 1663 p->sample_rate, p->precision, p->channels); 1664 1665 for (rate = 0; CS4215_FREQ[rate].freq; rate++) 1666 if (CS4215_FREQ[rate].freq == p->sample_rate) 1667 break; 1668 1669 if (CS4215_FREQ[rate].freq == 0) 1670 return (EINVAL); 1671 1672 /* set frequency */ 1673 sc->sc_mm.c.bcontrol[1] &= ~0x38; 1674 sc->sc_mm.c.bcontrol[1] |= CS4215_FREQ[rate].csval; 1675 sc->sc_mm.c.bcontrol[2] &= ~0x70; 1676 sc->sc_mm.c.bcontrol[2] |= CS4215_FREQ[rate].xtal; 1677 1678 switch (p->encoding) { 1679 case AUDIO_ENCODING_ULAW: 1680 sc->sc_mm.c.bcontrol[1] &= ~3; 1681 sc->sc_mm.c.bcontrol[1] |= CS4215_DFR_ULAW; 1682 break; 1683 case AUDIO_ENCODING_ALAW: 1684 sc->sc_mm.c.bcontrol[1] &= ~3; 1685 sc->sc_mm.c.bcontrol[1] |= CS4215_DFR_ALAW; 1686 break; 1687 case AUDIO_ENCODING_ULINEAR: 1688 sc->sc_mm.c.bcontrol[1] &= ~3; 1689 if (p->precision == 8) { 1690 sc->sc_mm.c.bcontrol[1] |= CS4215_DFR_LINEAR8; 1691 } else { 1692 sc->sc_mm.c.bcontrol[1] |= CS4215_DFR_LINEAR16; 1693 } 1694 break; 1695 case AUDIO_ENCODING_SLINEAR_BE: 1696 case AUDIO_ENCODING_SLINEAR: 1697 sc->sc_mm.c.bcontrol[1] &= ~3; 1698 sc->sc_mm.c.bcontrol[1] |= CS4215_DFR_LINEAR16; 1699 break; 1700 } 1701 1702 switch (p->channels) { 1703 case 1: 1704 sc->sc_mm.c.bcontrol[1] &= ~CS4215_DFR_STEREO; 1705 break; 1706 case 2: 1707 sc->sc_mm.c.bcontrol[1] |= CS4215_DFR_STEREO; 1708 break; 1709 } 1710 1711 return (0); 1712 } 1713 1714 static int 1715 dbri_round_blocksize(void *hdl, int bs, int mode, 1716 const audio_params_t *param) 1717 { 1718 1719 /* DBRI DMA segment size, rounded down to 32bit alignment */ 1720 return 0x1ffc; 1721 } 1722 1723 static int 1724 dbri_halt_output(void *hdl) 1725 { 1726 struct dbri_softc *sc = hdl; 1727 1728 if (!sc->sc_playing) 1729 return 0; 1730 1731 sc->sc_playing = 0; 1732 pipe_reset(sc, 4); 1733 return (0); 1734 } 1735 1736 static int 1737 dbri_getdev(void *hdl, struct audio_device *ret) 1738 { 1739 1740 *ret = dbri_device; 1741 return (0); 1742 } 1743 1744 static int 1745 dbri_set_port(void *hdl, mixer_ctrl_t *mc) 1746 { 1747 struct dbri_softc *sc = hdl; 1748 int latt = sc->sc_latt, ratt = sc->sc_ratt; 1749 1750 switch (mc->dev) { 1751 case DBRI_VOL_OUTPUT: /* master volume */ 1752 latt = (latt & 0xc0) | (63 - 1753 min(mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] >> 2, 63)); 1754 ratt = (ratt & 0xc0) | (63 - 1755 min(mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] >> 2, 63)); 1756 break; 1757 case DBRI_ENABLE_MONO: /* built-in speaker */ 1758 if (mc->un.ord == 1) { 1759 ratt |= CS4215_SE; 1760 } else 1761 ratt &= ~CS4215_SE; 1762 break; 1763 case DBRI_ENABLE_HEADPHONE: /* headphones output */ 1764 if (mc->un.ord == 1) { 1765 latt |= CS4215_HE; 1766 } else 1767 latt &= ~CS4215_HE; 1768 break; 1769 case DBRI_ENABLE_LINE: /* line out */ 1770 if (mc->un.ord == 1) { 1771 latt |= CS4215_LE; 1772 } else 1773 latt &= ~CS4215_LE; 1774 break; 1775 case DBRI_VOL_MONITOR: 1776 if (mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] == 1777 sc->sc_monitor) 1778 return 0; 1779 sc->sc_monitor = mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT]; 1780 break; 1781 case DBRI_INPUT_GAIN: 1782 sc->sc_linp = mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT]; 1783 sc->sc_rinp = mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]; 1784 break; 1785 case DBRI_INPUT_SELECT: 1786 if (mc->un.mask == sc->sc_input) 1787 return 0; 1788 sc->sc_input = mc->un.mask; 1789 break; 1790 } 1791 1792 sc->sc_latt = latt; 1793 sc->sc_ratt = ratt; 1794 1795 mmcodec_setgain(sc, 0); 1796 1797 return (0); 1798 } 1799 1800 static int 1801 dbri_get_port(void *hdl, mixer_ctrl_t *mc) 1802 { 1803 struct dbri_softc *sc = hdl; 1804 1805 switch (mc->dev) { 1806 case DBRI_VOL_OUTPUT: /* master volume */ 1807 mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = 1808 (63 - (sc->sc_latt & 0x3f)) << 2; 1809 mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 1810 (63 - (sc->sc_ratt & 0x3f)) << 2; 1811 return (0); 1812 case DBRI_ENABLE_MONO: /* built-in speaker */ 1813 mc->un.ord = (sc->sc_ratt & CS4215_SE) ? 1 : 0; 1814 return 0; 1815 case DBRI_ENABLE_HEADPHONE: /* headphones output */ 1816 mc->un.ord = (sc->sc_latt & CS4215_HE) ? 1 : 0; 1817 return 0; 1818 case DBRI_ENABLE_LINE: /* line out */ 1819 mc->un.ord = (sc->sc_latt & CS4215_LE) ? 1 : 0; 1820 return 0; 1821 case DBRI_VOL_MONITOR: 1822 mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = sc->sc_monitor; 1823 return 0; 1824 case DBRI_INPUT_GAIN: 1825 mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = sc->sc_linp; 1826 mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = sc->sc_rinp; 1827 return 0; 1828 case DBRI_INPUT_SELECT: 1829 mc->un.mask = sc->sc_input; 1830 return 0; 1831 } 1832 return (EINVAL); 1833 } 1834 1835 static int 1836 dbri_query_devinfo(void *hdl, mixer_devinfo_t *di) 1837 { 1838 1839 switch (di->index) { 1840 case DBRI_MONITOR_CLASS: 1841 di->mixer_class = DBRI_MONITOR_CLASS; 1842 strcpy(di->label.name, AudioCmonitor); 1843 di->type = AUDIO_MIXER_CLASS; 1844 di->next = di->prev = AUDIO_MIXER_LAST; 1845 return 0; 1846 case DBRI_OUTPUT_CLASS: 1847 di->mixer_class = DBRI_OUTPUT_CLASS; 1848 strcpy(di->label.name, AudioCoutputs); 1849 di->type = AUDIO_MIXER_CLASS; 1850 di->next = di->prev = AUDIO_MIXER_LAST; 1851 return 0; 1852 case DBRI_INPUT_CLASS: 1853 di->mixer_class = DBRI_INPUT_CLASS; 1854 strcpy(di->label.name, AudioCinputs); 1855 di->type = AUDIO_MIXER_CLASS; 1856 di->next = di->prev = AUDIO_MIXER_LAST; 1857 return 0; 1858 case DBRI_VOL_OUTPUT: /* master volume */ 1859 di->mixer_class = DBRI_OUTPUT_CLASS; 1860 di->next = di->prev = AUDIO_MIXER_LAST; 1861 strcpy(di->label.name, AudioNmaster); 1862 di->type = AUDIO_MIXER_VALUE; 1863 di->un.v.num_channels = 2; 1864 strcpy(di->un.v.units.name, AudioNvolume); 1865 return (0); 1866 case DBRI_INPUT_GAIN: /* input gain */ 1867 di->mixer_class = DBRI_INPUT_CLASS; 1868 di->next = di->prev = AUDIO_MIXER_LAST; 1869 strcpy(di->label.name, AudioNrecord); 1870 di->type = AUDIO_MIXER_VALUE; 1871 di->un.v.num_channels = 2; 1872 strcpy(di->un.v.units.name, AudioNvolume); 1873 return (0); 1874 case DBRI_VOL_MONITOR: /* monitor volume */ 1875 di->mixer_class = DBRI_MONITOR_CLASS; 1876 di->next = di->prev = AUDIO_MIXER_LAST; 1877 strcpy(di->label.name, AudioNmonitor); 1878 di->type = AUDIO_MIXER_VALUE; 1879 di->un.v.num_channels = 1; 1880 strcpy(di->un.v.units.name, AudioNvolume); 1881 return (0); 1882 case DBRI_ENABLE_MONO: /* built-in speaker */ 1883 di->mixer_class = DBRI_OUTPUT_CLASS; 1884 di->next = di->prev = AUDIO_MIXER_LAST; 1885 strcpy(di->label.name, AudioNmono); 1886 di->type = AUDIO_MIXER_ENUM; 1887 di->un.e.num_mem = 2; 1888 strcpy(di->un.e.member[0].label.name, AudioNoff); 1889 di->un.e.member[0].ord = 0; 1890 strcpy(di->un.e.member[1].label.name, AudioNon); 1891 di->un.e.member[1].ord = 1; 1892 return (0); 1893 case DBRI_ENABLE_HEADPHONE: /* headphones output */ 1894 di->mixer_class = DBRI_OUTPUT_CLASS; 1895 di->next = di->prev = AUDIO_MIXER_LAST; 1896 strcpy(di->label.name, AudioNheadphone); 1897 di->type = AUDIO_MIXER_ENUM; 1898 di->un.e.num_mem = 2; 1899 strcpy(di->un.e.member[0].label.name, AudioNoff); 1900 di->un.e.member[0].ord = 0; 1901 strcpy(di->un.e.member[1].label.name, AudioNon); 1902 di->un.e.member[1].ord = 1; 1903 return (0); 1904 case DBRI_ENABLE_LINE: /* line out */ 1905 di->mixer_class = DBRI_OUTPUT_CLASS; 1906 di->next = di->prev = AUDIO_MIXER_LAST; 1907 strcpy(di->label.name, AudioNline); 1908 di->type = AUDIO_MIXER_ENUM; 1909 di->un.e.num_mem = 2; 1910 strcpy(di->un.e.member[0].label.name, AudioNoff); 1911 di->un.e.member[0].ord = 0; 1912 strcpy(di->un.e.member[1].label.name, AudioNon); 1913 di->un.e.member[1].ord = 1; 1914 return (0); 1915 case DBRI_INPUT_SELECT: 1916 di->mixer_class = DBRI_INPUT_CLASS; 1917 strcpy(di->label.name, AudioNsource); 1918 di->type = AUDIO_MIXER_SET; 1919 di->prev = di->next = AUDIO_MIXER_LAST; 1920 di->un.s.num_mem = 2; 1921 strcpy(di->un.s.member[0].label.name, AudioNline); 1922 di->un.s.member[0].mask = 1 << 0; 1923 strcpy(di->un.s.member[1].label.name, AudioNmicrophone); 1924 di->un.s.member[1].mask = 1 << 1; 1925 return 0; 1926 } 1927 1928 return (ENXIO); 1929 } 1930 1931 static size_t 1932 dbri_round_buffersize(void *hdl, int dir, size_t bufsize) 1933 { 1934 #ifdef DBRI_BIG_BUFFER 1935 return 16*0x1ffc; /* use ~128KB buffer */ 1936 #else 1937 return bufsize; 1938 #endif 1939 } 1940 1941 static int 1942 dbri_get_props(void *hdl) 1943 { 1944 1945 return AUDIO_PROP_MMAP | AUDIO_PROP_FULLDUPLEX; 1946 } 1947 1948 static int 1949 dbri_trigger_output(void *hdl, void *start, void *end, int blksize, 1950 void (*intr)(void *), void *intrarg, 1951 const struct audio_params *param) 1952 { 1953 struct dbri_softc *sc = hdl; 1954 unsigned long count, num; 1955 1956 if (sc->sc_playing) 1957 return 0; 1958 1959 count = (unsigned long)(((char *)end - (char *)start)); 1960 num = count / blksize; 1961 1962 DPRINTF("trigger_output(%lx %lx) : %d %ld %ld\n", 1963 (unsigned long)intr, 1964 (unsigned long)intrarg, blksize, count, num); 1965 1966 sc->sc_params = *param; 1967 1968 if (sc->sc_recording == 0) { 1969 /* do not muck with the codec when it's already in use */ 1970 if (mmcodec_setcontrol(sc) != 0) 1971 return -1; 1972 mmcodec_init_data(sc); 1973 } 1974 1975 /* 1976 * always use DMA descriptor 0 for output 1977 * no need to allocate them dynamically since we only ever have 1978 * exactly one input stream and exactly one output stream 1979 */ 1980 setup_ring_xmit(sc, 4, 0, num, blksize, intr, intrarg); 1981 sc->sc_playing = 1; 1982 return 0; 1983 } 1984 1985 static int 1986 dbri_halt_input(void *cookie) 1987 { 1988 struct dbri_softc *sc = cookie; 1989 1990 if (!sc->sc_recording) 1991 return 0; 1992 1993 sc->sc_recording = 0; 1994 pipe_reset(sc, 6); 1995 return 0; 1996 } 1997 1998 static int 1999 dbri_trigger_input(void *hdl, void *start, void *end, int blksize, 2000 void (*intr)(void *), void *intrarg, 2001 const struct audio_params *param) 2002 { 2003 struct dbri_softc *sc = hdl; 2004 unsigned long count, num; 2005 2006 if (sc->sc_recording) 2007 return 0; 2008 2009 count = (unsigned long)(((char *)end - (char *)start)); 2010 num = count / blksize; 2011 2012 DPRINTF("trigger_input(%lx %lx) : %d %ld %ld\n", 2013 (unsigned long)intr, 2014 (unsigned long)intrarg, blksize, count, num); 2015 2016 sc->sc_params = *param; 2017 2018 if (sc->sc_playing == 0) { 2019 2020 /* 2021 * we don't support different parameters for playing and 2022 * recording anyway so don't bother whacking the codec if 2023 * it's already set up 2024 */ 2025 mmcodec_setcontrol(sc); 2026 mmcodec_init_data(sc); 2027 } 2028 2029 sc->sc_recording = 1; 2030 setup_ring_recv(sc, 6, 1, num, blksize, intr, intrarg); 2031 return 0; 2032 } 2033 2034 2035 static uint32_t 2036 reverse_bytes(uint32_t b, int len) 2037 { 2038 switch (len) { 2039 case 32: 2040 b = ((b & 0xffff0000) >> 16) | ((b & 0x0000ffff) << 16); 2041 case 16: 2042 b = ((b & 0xff00ff00) >> 8) | ((b & 0x00ff00ff) << 8); 2043 case 8: 2044 b = ((b & 0xf0f0f0f0) >> 4) | ((b & 0x0f0f0f0f) << 4); 2045 case 4: 2046 b = ((b & 0xcccccccc) >> 2) | ((b & 0x33333333) << 2); 2047 case 2: 2048 b = ((b & 0xaaaaaaaa) >> 1) | ((b & 0x55555555) << 1); 2049 case 1: 2050 case 0: 2051 break; 2052 default: 2053 DPRINTF("reverse_bytes: unsupported length\n"); 2054 }; 2055 2056 return (b); 2057 } 2058 2059 static void * 2060 dbri_malloc(void *v, int dir, size_t s, struct malloc_type *mt, int flags) 2061 { 2062 struct dbri_softc *sc = v; 2063 struct dbri_desc *dd = &sc->sc_desc[sc->sc_desc_used]; 2064 int rseg; 2065 2066 if (bus_dmamap_create(sc->sc_dmat, s, 1, s, 0, BUS_DMA_NOWAIT, 2067 &dd->dmamap) == 0) { 2068 if (bus_dmamem_alloc(sc->sc_dmat, s, 0, 0, &dd->dmaseg, 2069 1, &rseg, BUS_DMA_NOWAIT) == 0) { 2070 if (bus_dmamem_map(sc->sc_dmat, &dd->dmaseg, rseg, s, 2071 &dd->buf, BUS_DMA_NOWAIT|BUS_DMA_COHERENT) == 0) { 2072 if (dd->buf != NULL) { 2073 if (bus_dmamap_load(sc->sc_dmat, 2074 dd->dmamap, dd->buf, s, NULL, 2075 BUS_DMA_NOWAIT) == 0) { 2076 dd->len = s; 2077 dd->busy = 0; 2078 dd->callback = NULL; 2079 dd->dmabase = 2080 dd->dmamap->dm_segs[0].ds_addr; 2081 DPRINTF("dbri_malloc: using buffer %d %08x\n", 2082 sc->sc_desc_used, (uint32_t)dd->buf); 2083 sc->sc_desc_used++; 2084 return dd->buf; 2085 } else 2086 aprint_error("dbri_malloc: load failed\n"); 2087 } else 2088 aprint_error("dbri_malloc: map returned NULL\n"); 2089 } else 2090 aprint_error("dbri_malloc: map failed\n"); 2091 bus_dmamem_free(sc->sc_dmat, &dd->dmaseg, rseg); 2092 } else 2093 aprint_error("dbri_malloc: malloc() failed\n"); 2094 bus_dmamap_destroy(sc->sc_dmat, dd->dmamap); 2095 } else 2096 aprint_error("dbri_malloc: bus_dmamap_create() failed\n"); 2097 return NULL; 2098 } 2099 2100 static void 2101 dbri_free(void *v, void *p, struct malloc_type *mt) 2102 { 2103 struct dbri_softc *sc = v; 2104 struct dbri_desc *dd; 2105 int i; 2106 2107 for (i = 0; i < sc->sc_desc_used; i++) { 2108 dd = &sc->sc_desc[i]; 2109 if (dd->buf == p) 2110 break; 2111 } 2112 if (i >= sc->sc_desc_used) 2113 return; 2114 bus_dmamap_unload(sc->sc_dmat, dd->dmamap); 2115 bus_dmamap_destroy(sc->sc_dmat, dd->dmamap); 2116 } 2117 2118 static paddr_t 2119 dbri_mappage(void *v, void *mem, off_t off, int prot) 2120 { 2121 struct dbri_softc *sc = v; 2122 int current; 2123 2124 if (off < 0) 2125 return -1; 2126 2127 current = 0; 2128 while ((current < sc->sc_desc_used) && 2129 (sc->sc_desc[current].buf != mem)) 2130 current++; 2131 2132 if (current < sc->sc_desc_used) { 2133 return bus_dmamem_mmap(sc->sc_dmat, 2134 &sc->sc_desc[current].dmaseg, 1, off, prot, BUS_DMA_WAITOK); 2135 } 2136 2137 return -1; 2138 } 2139 2140 static int 2141 dbri_open(void *cookie, int flags) 2142 { 2143 struct dbri_softc *sc = cookie; 2144 2145 DPRINTF("%s: %d\n", __func__, sc->sc_refcount); 2146 2147 if (sc->sc_refcount == 0) 2148 dbri_bring_up(sc); 2149 2150 sc->sc_refcount++; 2151 2152 return 0; 2153 } 2154 2155 static void 2156 dbri_close(void *cookie) 2157 { 2158 struct dbri_softc *sc = cookie; 2159 2160 DPRINTF("%s: %d\n", __func__, sc->sc_refcount); 2161 2162 sc->sc_refcount--; 2163 KASSERT(sc->sc_refcount >= 0); 2164 if (sc->sc_refcount > 0) 2165 return; 2166 2167 dbri_set_power(sc, 0); 2168 sc->sc_playing = 0; 2169 sc->sc_recording = 0; 2170 } 2171 2172 static void 2173 dbri_powerhook(int why, void *cookie) 2174 { 2175 struct dbri_softc *sc = cookie; 2176 2177 if (why == sc->sc_pmgrstate) 2178 return; 2179 2180 switch(why) 2181 { 2182 case PWR_SUSPEND: 2183 dbri_set_power(sc, 0); 2184 break; 2185 case PWR_RESUME: 2186 if (sc->sc_powerstate != 0) 2187 break; 2188 aprint_verbose("resume: %d\n", sc->sc_refcount); 2189 sc->sc_pmgrstate = PWR_RESUME; 2190 if (sc->sc_playing) { 2191 volatile uint32_t *cmd; 2192 int s; 2193 2194 dbri_bring_up(sc); 2195 s = splsched(); 2196 cmd = dbri_command_lock(sc); 2197 *(cmd++) = DBRI_CMD(DBRI_COMMAND_SDP, 2198 0, sc->sc_pipe[4].sdp | 2199 DBRI_SDP_VALID_POINTER | 2200 DBRI_SDP_EVERY | DBRI_SDP_CLEAR); 2201 *(cmd++) = sc->sc_dmabase + 2202 dbri_dma_off(xmit, 0); 2203 dbri_command_send(sc, cmd); 2204 splx(s); 2205 } 2206 break; 2207 default: 2208 return; 2209 } 2210 sc->sc_pmgrstate = why; 2211 } 2212 2213 #endif /* NAUDIO > 0 */ 2214