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