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