1 /* $NetBSD: sv.c,v 1.48 2013/07/17 21:26:29 soren Exp $ */ 2 /* $OpenBSD: sv.c,v 1.2 1998/07/13 01:50:15 csapuntz Exp $ */ 3 4 /* 5 * Copyright (c) 1999, 2008 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Charles M. Hannum. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * Copyright (c) 1998 Constantine Paul Sapuntzakis 35 * All rights reserved 36 * 37 * Author: Constantine Paul Sapuntzakis (csapuntz@cvs.openbsd.org) 38 * 39 * Redistribution and use in source and binary forms, with or without 40 * modification, are permitted provided that the following conditions 41 * are met: 42 * 1. Redistributions of source code must retain the above copyright 43 * notice, this list of conditions and the following disclaimer. 44 * 2. Redistributions in binary form must reproduce the above copyright 45 * notice, this list of conditions and the following disclaimer in the 46 * documentation and/or other materials provided with the distribution. 47 * 3. The author's name or those of the contributors may be used to 48 * endorse or promote products derived from this software without 49 * specific prior written permission. 50 * 51 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS 52 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 53 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 54 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 55 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 56 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 57 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 58 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 59 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 60 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 61 * POSSIBILITY OF SUCH DAMAGE. 62 */ 63 64 /* 65 * S3 SonicVibes driver 66 * Heavily based on the eap driver by Lennart Augustsson 67 */ 68 69 #include <sys/cdefs.h> 70 __KERNEL_RCSID(0, "$NetBSD: sv.c,v 1.48 2013/07/17 21:26:29 soren Exp $"); 71 72 #include <sys/param.h> 73 #include <sys/systm.h> 74 #include <sys/kernel.h> 75 #include <sys/kmem.h> 76 #include <sys/device.h> 77 78 #include <dev/pci/pcireg.h> 79 #include <dev/pci/pcivar.h> 80 #include <dev/pci/pcidevs.h> 81 82 #include <sys/audioio.h> 83 #include <dev/audio_if.h> 84 #include <dev/mulaw.h> 85 #include <dev/auconv.h> 86 87 #include <dev/ic/i8237reg.h> 88 #include <dev/pci/svreg.h> 89 #include <dev/pci/svvar.h> 90 91 #include <sys/bus.h> 92 93 /* XXX 94 * The SonicVibes DMA is broken and only works on 24-bit addresses. 95 * As long as bus_dmamem_alloc_range() is missing we use the ISA 96 * DMA tag on i386. 97 */ 98 #if defined(amd64) || defined(i386) 99 #include <dev/isa/isavar.h> 100 #endif 101 102 #ifdef AUDIO_DEBUG 103 #define DPRINTF(x) if (svdebug) printf x 104 #define DPRINTFN(n,x) if (svdebug>(n)) printf x 105 int svdebug = 0; 106 #else 107 #define DPRINTF(x) 108 #define DPRINTFN(n,x) 109 #endif 110 111 static int sv_match(device_t, cfdata_t, void *); 112 static void sv_attach(device_t, device_t, void *); 113 static int sv_intr(void *); 114 115 struct sv_dma { 116 bus_dmamap_t map; 117 void *addr; 118 bus_dma_segment_t segs[1]; 119 int nsegs; 120 size_t size; 121 struct sv_dma *next; 122 }; 123 #define DMAADDR(p) ((p)->map->dm_segs[0].ds_addr) 124 #define KERNADDR(p) ((void *)((p)->addr)) 125 126 CFATTACH_DECL_NEW(sv, sizeof(struct sv_softc), 127 sv_match, sv_attach, NULL, NULL); 128 129 static struct audio_device sv_device = { 130 "S3 SonicVibes", 131 "", 132 "sv" 133 }; 134 135 #define ARRAY_SIZE(foo) ((sizeof(foo)) / sizeof(foo[0])) 136 137 static int sv_allocmem(struct sv_softc *, size_t, size_t, int, 138 struct sv_dma *); 139 static int sv_freemem(struct sv_softc *, struct sv_dma *); 140 141 static void sv_init_mixer(struct sv_softc *); 142 143 static int sv_open(void *, int); 144 static int sv_query_encoding(void *, struct audio_encoding *); 145 static int sv_set_params(void *, int, int, audio_params_t *, 146 audio_params_t *, stream_filter_list_t *, 147 stream_filter_list_t *); 148 static int sv_round_blocksize(void *, int, int, const audio_params_t *); 149 static int sv_trigger_output(void *, void *, void *, int, void (*)(void *), 150 void *, const audio_params_t *); 151 static int sv_trigger_input(void *, void *, void *, int, void (*)(void *), 152 void *, const audio_params_t *); 153 static int sv_halt_output(void *); 154 static int sv_halt_input(void *); 155 static int sv_getdev(void *, struct audio_device *); 156 static int sv_mixer_set_port(void *, mixer_ctrl_t *); 157 static int sv_mixer_get_port(void *, mixer_ctrl_t *); 158 static int sv_query_devinfo(void *, mixer_devinfo_t *); 159 static void * sv_malloc(void *, int, size_t); 160 static void sv_free(void *, void *, size_t); 161 static size_t sv_round_buffersize(void *, int, size_t); 162 static paddr_t sv_mappage(void *, void *, off_t, int); 163 static int sv_get_props(void *); 164 static void sv_get_locks(void *, kmutex_t **, kmutex_t **); 165 166 #ifdef AUDIO_DEBUG 167 void sv_dumpregs(struct sv_softc *sc); 168 #endif 169 170 static const struct audio_hw_if sv_hw_if = { 171 sv_open, 172 NULL, /* close */ 173 NULL, 174 sv_query_encoding, 175 sv_set_params, 176 sv_round_blocksize, 177 NULL, 178 NULL, 179 NULL, 180 NULL, 181 NULL, 182 sv_halt_output, 183 sv_halt_input, 184 NULL, 185 sv_getdev, 186 NULL, 187 sv_mixer_set_port, 188 sv_mixer_get_port, 189 sv_query_devinfo, 190 sv_malloc, 191 sv_free, 192 sv_round_buffersize, 193 sv_mappage, 194 sv_get_props, 195 sv_trigger_output, 196 sv_trigger_input, 197 NULL, 198 sv_get_locks, 199 }; 200 201 #define SV_NFORMATS 4 202 static const struct audio_format sv_formats[SV_NFORMATS] = { 203 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_SLINEAR_LE, 16, 16, 204 2, AUFMT_STEREO, 0, {2000, 48000}}, 205 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_SLINEAR_LE, 16, 16, 206 1, AUFMT_MONAURAL, 0, {2000, 48000}}, 207 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ULINEAR_LE, 8, 8, 208 2, AUFMT_STEREO, 0, {2000, 48000}}, 209 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ULINEAR_LE, 8, 8, 210 1, AUFMT_MONAURAL, 0, {2000, 48000}}, 211 }; 212 213 214 static void 215 sv_write(struct sv_softc *sc, uint8_t reg, uint8_t val) 216 { 217 218 DPRINTFN(8,("sv_write(0x%x, 0x%x)\n", reg, val)); 219 bus_space_write_1(sc->sc_iot, sc->sc_ioh, reg, val); 220 } 221 222 static uint8_t 223 sv_read(struct sv_softc *sc, uint8_t reg) 224 { 225 uint8_t val; 226 227 val = bus_space_read_1(sc->sc_iot, sc->sc_ioh, reg); 228 DPRINTFN(8,("sv_read(0x%x) = 0x%x\n", reg, val)); 229 return val; 230 } 231 232 static uint8_t 233 sv_read_indirect(struct sv_softc *sc, uint8_t reg) 234 { 235 uint8_t val; 236 237 sv_write(sc, SV_CODEC_IADDR, reg & SV_IADDR_MASK); 238 val = sv_read(sc, SV_CODEC_IDATA); 239 return val; 240 } 241 242 static void 243 sv_write_indirect(struct sv_softc *sc, uint8_t reg, uint8_t val) 244 { 245 uint8_t iaddr; 246 247 iaddr = reg & SV_IADDR_MASK; 248 if (reg == SV_DMA_DATA_FORMAT) 249 iaddr |= SV_IADDR_MCE; 250 251 sv_write(sc, SV_CODEC_IADDR, iaddr); 252 sv_write(sc, SV_CODEC_IDATA, val); 253 } 254 255 static int 256 sv_match(device_t parent, cfdata_t match, void *aux) 257 { 258 struct pci_attach_args *pa; 259 260 pa = aux; 261 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_S3 && 262 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_S3_SONICVIBES) 263 return 1; 264 265 return 0; 266 } 267 268 static pcireg_t pci_io_alloc_low, pci_io_alloc_high; 269 270 static int 271 pci_alloc_io(pci_chipset_tag_t pc, pcitag_t pt, int pcioffs, 272 bus_space_tag_t iot, bus_size_t size, bus_size_t align, 273 bus_size_t bound, int flags, bus_space_handle_t *ioh) 274 { 275 bus_addr_t addr; 276 int error; 277 278 error = bus_space_alloc(iot, pci_io_alloc_low, pci_io_alloc_high, 279 size, align, bound, flags, &addr, ioh); 280 if (error) 281 return error; 282 283 pci_conf_write(pc, pt, pcioffs, addr); 284 return 0; 285 } 286 287 /* 288 * Allocate IO addresses when all other configuration is done. 289 */ 290 static void 291 sv_defer(device_t self) 292 { 293 struct sv_softc *sc; 294 pci_chipset_tag_t pc; 295 pcitag_t pt; 296 pcireg_t dmaio; 297 298 sc = device_private(self); 299 pc = sc->sc_pa.pa_pc; 300 pt = sc->sc_pa.pa_tag; 301 DPRINTF(("sv_defer: %p\n", sc)); 302 303 /* XXX 304 * Get a reasonable default for the I/O range. 305 * Assume the range around SB_PORTBASE is valid on this PCI bus. 306 */ 307 pci_io_alloc_low = pci_conf_read(pc, pt, SV_SB_PORTBASE_SLOT); 308 pci_io_alloc_high = pci_io_alloc_low + 0x1000; 309 310 if (pci_alloc_io(pc, pt, SV_DMAA_CONFIG_OFF, 311 sc->sc_iot, SV_DMAA_SIZE, SV_DMAA_ALIGN, 0, 312 0, &sc->sc_dmaa_ioh)) { 313 printf("sv_attach: cannot allocate DMA A range\n"); 314 return; 315 } 316 dmaio = pci_conf_read(pc, pt, SV_DMAA_CONFIG_OFF); 317 DPRINTF(("sv_attach: addr a dmaio=0x%lx\n", (u_long)dmaio)); 318 pci_conf_write(pc, pt, SV_DMAA_CONFIG_OFF, 319 dmaio | SV_DMA_CHANNEL_ENABLE | SV_DMAA_EXTENDED_ADDR); 320 321 if (pci_alloc_io(pc, pt, SV_DMAC_CONFIG_OFF, 322 sc->sc_iot, SV_DMAC_SIZE, SV_DMAC_ALIGN, 0, 323 0, &sc->sc_dmac_ioh)) { 324 printf("sv_attach: cannot allocate DMA C range\n"); 325 return; 326 } 327 dmaio = pci_conf_read(pc, pt, SV_DMAC_CONFIG_OFF); 328 DPRINTF(("sv_attach: addr c dmaio=0x%lx\n", (u_long)dmaio)); 329 pci_conf_write(pc, pt, SV_DMAC_CONFIG_OFF, 330 dmaio | SV_DMA_CHANNEL_ENABLE); 331 332 sc->sc_dmaset = 1; 333 } 334 335 static void 336 sv_attach(device_t parent, device_t self, void *aux) 337 { 338 struct sv_softc *sc; 339 struct pci_attach_args *pa; 340 pci_chipset_tag_t pc; 341 pcitag_t pt; 342 pci_intr_handle_t ih; 343 pcireg_t csr; 344 char const *intrstr; 345 uint8_t reg; 346 struct audio_attach_args arg; 347 348 sc = device_private(self); 349 pa = aux; 350 pc = pa->pa_pc; 351 pt = pa->pa_tag; 352 printf ("\n"); 353 354 /* Map I/O registers */ 355 if (pci_mapreg_map(pa, SV_ENHANCED_PORTBASE_SLOT, 356 PCI_MAPREG_TYPE_IO, 0, 357 &sc->sc_iot, &sc->sc_ioh, NULL, NULL)) { 358 aprint_error_dev(self, "can't map enhanced i/o space\n"); 359 return; 360 } 361 if (pci_mapreg_map(pa, SV_FM_PORTBASE_SLOT, 362 PCI_MAPREG_TYPE_IO, 0, 363 &sc->sc_opliot, &sc->sc_oplioh, NULL, NULL)) { 364 aprint_error_dev(self, "can't map FM i/o space\n"); 365 return; 366 } 367 if (pci_mapreg_map(pa, SV_MIDI_PORTBASE_SLOT, 368 PCI_MAPREG_TYPE_IO, 0, 369 &sc->sc_midiiot, &sc->sc_midiioh, NULL, NULL)) { 370 aprint_error_dev(self, "can't map MIDI i/o space\n"); 371 return; 372 } 373 DPRINTF(("sv: IO ports: enhanced=0x%x, OPL=0x%x, MIDI=0x%x\n", 374 (int)sc->sc_ioh, (int)sc->sc_oplioh, (int)sc->sc_midiioh)); 375 376 #if defined(alpha) 377 /* XXX Force allocation through the SGMAP. */ 378 sc->sc_dmatag = alphabus_dma_get_tag(pa->pa_dmat, ALPHA_BUS_ISA); 379 #elif defined(amd64) || defined(i386) 380 /* XXX 381 * The SonicVibes DMA is broken and only works on 24-bit addresses. 382 * As long as bus_dmamem_alloc_range() is missing we use the ISA 383 * DMA tag on i386. 384 */ 385 sc->sc_dmatag = &isa_bus_dma_tag; 386 #else 387 sc->sc_dmatag = pa->pa_dmat; 388 #endif 389 390 pci_conf_write(pc, pt, SV_DMAA_CONFIG_OFF, SV_DMAA_EXTENDED_ADDR); 391 pci_conf_write(pc, pt, SV_DMAC_CONFIG_OFF, 0); 392 393 /* Enable the device. */ 394 csr = pci_conf_read(pc, pt, PCI_COMMAND_STATUS_REG); 395 pci_conf_write(pc, pt, PCI_COMMAND_STATUS_REG, 396 csr | PCI_COMMAND_MASTER_ENABLE); 397 398 sv_write_indirect(sc, SV_ANALOG_POWER_DOWN_CONTROL, 0); 399 sv_write_indirect(sc, SV_DIGITAL_POWER_DOWN_CONTROL, 0); 400 401 /* initialize codec registers */ 402 reg = sv_read(sc, SV_CODEC_CONTROL); 403 reg |= SV_CTL_RESET; 404 sv_write(sc, SV_CODEC_CONTROL, reg); 405 delay(50); 406 407 reg = sv_read(sc, SV_CODEC_CONTROL); 408 reg &= ~SV_CTL_RESET; 409 reg |= SV_CTL_INTA | SV_CTL_ENHANCED; 410 411 /* This write clears the reset */ 412 sv_write(sc, SV_CODEC_CONTROL, reg); 413 delay(50); 414 415 /* This write actually shoves the new values in */ 416 sv_write(sc, SV_CODEC_CONTROL, reg); 417 418 DPRINTF(("sv_attach: control=0x%x\n", sv_read(sc, SV_CODEC_CONTROL))); 419 420 /* Map and establish the interrupt. */ 421 if (pci_intr_map(pa, &ih)) { 422 aprint_error_dev(self, "couldn't map interrupt\n"); 423 return; 424 } 425 426 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 427 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_AUDIO); 428 429 intrstr = pci_intr_string(pc, ih); 430 sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO, sv_intr, sc); 431 if (sc->sc_ih == NULL) { 432 aprint_error_dev(self, "couldn't establish interrupt"); 433 if (intrstr != NULL) 434 aprint_error(" at %s", intrstr); 435 aprint_error("\n"); 436 mutex_destroy(&sc->sc_lock); 437 mutex_destroy(&sc->sc_intr_lock); 438 return; 439 } 440 printf("%s: interrupting at %s\n", device_xname(self), intrstr); 441 printf("%s: rev %d", device_xname(self), 442 sv_read_indirect(sc, SV_REVISION_LEVEL)); 443 if (sv_read(sc, SV_CODEC_CONTROL) & SV_CTL_MD1) 444 printf(", reverb SRAM present"); 445 if (!(sv_read_indirect(sc, SV_WAVETABLE_SOURCE_SELECT) & SV_WSS_WT0)) 446 printf(", wavetable ROM present"); 447 printf("\n"); 448 449 /* Enable DMA interrupts */ 450 reg = sv_read(sc, SV_CODEC_INTMASK); 451 reg &= ~(SV_INTMASK_DMAA | SV_INTMASK_DMAC); 452 reg |= SV_INTMASK_UD | SV_INTMASK_SINT | SV_INTMASK_MIDI; 453 sv_write(sc, SV_CODEC_INTMASK, reg); 454 sv_read(sc, SV_CODEC_STATUS); 455 456 sv_init_mixer(sc); 457 458 audio_attach_mi(&sv_hw_if, sc, self); 459 460 arg.type = AUDIODEV_TYPE_OPL; 461 arg.hwif = 0; 462 arg.hdl = 0; 463 (void)config_found(self, &arg, audioprint); 464 465 sc->sc_pa = *pa; /* for deferred setup */ 466 config_defer(self, sv_defer); 467 } 468 469 #ifdef AUDIO_DEBUG 470 void 471 sv_dumpregs(struct sv_softc *sc) 472 { 473 int idx; 474 475 #if 0 476 for (idx = 0; idx < 0x50; idx += 4) 477 printf ("%02x = %x\n", idx, 478 pci_conf_read(pa->pa_pc, pa->pa_tag, idx)); 479 #endif 480 481 for (idx = 0; idx < 6; idx++) 482 printf ("REG %02x = %02x\n", idx, sv_read(sc, idx)); 483 484 for (idx = 0; idx < 0x32; idx++) 485 printf ("IREG %02x = %02x\n", idx, sv_read_indirect(sc, idx)); 486 487 for (idx = 0; idx < 0x10; idx++) 488 printf ("DMA %02x = %02x\n", idx, 489 bus_space_read_1(sc->sc_iot, sc->sc_dmaa_ioh, idx)); 490 } 491 #endif 492 493 static int 494 sv_intr(void *p) 495 { 496 struct sv_softc *sc; 497 uint8_t intr; 498 499 sc = p; 500 501 mutex_spin_enter(&sc->sc_intr_lock); 502 503 intr = sv_read(sc, SV_CODEC_STATUS); 504 DPRINTFN(5,("sv_intr: intr=0x%x\n", intr)); 505 506 if (intr & SV_INTSTATUS_DMAA) { 507 if (sc->sc_pintr) 508 sc->sc_pintr(sc->sc_parg); 509 } 510 511 if (intr & SV_INTSTATUS_DMAC) { 512 if (sc->sc_rintr) 513 sc->sc_rintr(sc->sc_rarg); 514 } 515 516 mutex_spin_exit(&sc->sc_intr_lock); 517 518 return (intr & (SV_INTSTATUS_DMAA | SV_INTSTATUS_DMAC)) != 0; 519 } 520 521 static int 522 sv_allocmem(struct sv_softc *sc, size_t size, size_t align, 523 int direction, struct sv_dma *p) 524 { 525 int error; 526 527 p->size = size; 528 error = bus_dmamem_alloc(sc->sc_dmatag, p->size, align, 0, 529 p->segs, ARRAY_SIZE(p->segs), &p->nsegs, BUS_DMA_WAITOK); 530 if (error) 531 return error; 532 533 error = bus_dmamem_map(sc->sc_dmatag, p->segs, p->nsegs, p->size, 534 &p->addr, BUS_DMA_WAITOK|BUS_DMA_COHERENT); 535 if (error) 536 goto free; 537 538 error = bus_dmamap_create(sc->sc_dmatag, p->size, 1, p->size, 539 0, BUS_DMA_WAITOK, &p->map); 540 if (error) 541 goto unmap; 542 543 error = bus_dmamap_load(sc->sc_dmatag, p->map, p->addr, p->size, NULL, 544 BUS_DMA_WAITOK | (direction == AUMODE_RECORD) ? BUS_DMA_READ : BUS_DMA_WRITE); 545 if (error) 546 goto destroy; 547 DPRINTF(("sv_allocmem: pa=%lx va=%lx pba=%lx\n", 548 (long)p->segs[0].ds_addr, (long)KERNADDR(p), (long)DMAADDR(p))); 549 return 0; 550 551 destroy: 552 bus_dmamap_destroy(sc->sc_dmatag, p->map); 553 unmap: 554 bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size); 555 free: 556 bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs); 557 return error; 558 } 559 560 static int 561 sv_freemem(struct sv_softc *sc, struct sv_dma *p) 562 { 563 564 bus_dmamap_unload(sc->sc_dmatag, p->map); 565 bus_dmamap_destroy(sc->sc_dmatag, p->map); 566 bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size); 567 bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs); 568 return 0; 569 } 570 571 static int 572 sv_open(void *addr, int flags) 573 { 574 struct sv_softc *sc; 575 576 sc = addr; 577 DPRINTF(("sv_open\n")); 578 if (!sc->sc_dmaset) 579 return ENXIO; 580 581 return 0; 582 } 583 584 static int 585 sv_query_encoding(void *addr, struct audio_encoding *fp) 586 { 587 588 switch (fp->index) { 589 case 0: 590 strcpy(fp->name, AudioEulinear); 591 fp->encoding = AUDIO_ENCODING_ULINEAR; 592 fp->precision = 8; 593 fp->flags = 0; 594 return 0; 595 case 1: 596 strcpy(fp->name, AudioEmulaw); 597 fp->encoding = AUDIO_ENCODING_ULAW; 598 fp->precision = 8; 599 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 600 return 0; 601 case 2: 602 strcpy(fp->name, AudioEalaw); 603 fp->encoding = AUDIO_ENCODING_ALAW; 604 fp->precision = 8; 605 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 606 return 0; 607 case 3: 608 strcpy(fp->name, AudioEslinear); 609 fp->encoding = AUDIO_ENCODING_SLINEAR; 610 fp->precision = 8; 611 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 612 return 0; 613 case 4: 614 strcpy(fp->name, AudioEslinear_le); 615 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 616 fp->precision = 16; 617 fp->flags = 0; 618 return 0; 619 case 5: 620 strcpy(fp->name, AudioEulinear_le); 621 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 622 fp->precision = 16; 623 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 624 return 0; 625 case 6: 626 strcpy(fp->name, AudioEslinear_be); 627 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 628 fp->precision = 16; 629 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 630 return 0; 631 case 7: 632 strcpy(fp->name, AudioEulinear_be); 633 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 634 fp->precision = 16; 635 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 636 return 0; 637 default: 638 return EINVAL; 639 } 640 } 641 642 static int 643 sv_set_params(void *addr, int setmode, int usemode, audio_params_t *play, 644 audio_params_t *rec, stream_filter_list_t *pfil, stream_filter_list_t *rfil) 645 { 646 struct sv_softc *sc; 647 audio_params_t *p; 648 uint32_t val; 649 650 sc = addr; 651 p = NULL; 652 /* 653 * This device only has one clock, so make the sample rates match. 654 */ 655 if (play->sample_rate != rec->sample_rate && 656 usemode == (AUMODE_PLAY | AUMODE_RECORD)) { 657 if (setmode == AUMODE_PLAY) { 658 rec->sample_rate = play->sample_rate; 659 setmode |= AUMODE_RECORD; 660 } else if (setmode == AUMODE_RECORD) { 661 play->sample_rate = rec->sample_rate; 662 setmode |= AUMODE_PLAY; 663 } else 664 return EINVAL; 665 } 666 667 if (setmode & AUMODE_RECORD) { 668 p = rec; 669 if (auconv_set_converter(sv_formats, SV_NFORMATS, 670 AUMODE_RECORD, rec, FALSE, rfil) < 0) 671 return EINVAL; 672 } 673 if (setmode & AUMODE_PLAY) { 674 p = play; 675 if (auconv_set_converter(sv_formats, SV_NFORMATS, 676 AUMODE_PLAY, play, FALSE, pfil) < 0) 677 return EINVAL; 678 } 679 680 if (p == NULL) 681 return 0; 682 683 val = p->sample_rate * 65536 / 48000; 684 /* 685 * If the sample rate is exactly 48 kHz, the fraction would overflow the 686 * register, so we have to bias it. This causes a little clock drift. 687 * The drift is below normal crystal tolerance (.0001%), so although 688 * this seems a little silly, we can pretty much ignore it. 689 * (I tested the output speed with values of 1-20, just to be sure this 690 * register isn't *supposed* to have a bias. It isn't.) 691 * - mycroft 692 */ 693 if (val > 65535) 694 val = 65535; 695 696 mutex_spin_enter(&sc->sc_intr_lock); 697 sv_write_indirect(sc, SV_PCM_SAMPLE_RATE_0, val & 0xff); 698 sv_write_indirect(sc, SV_PCM_SAMPLE_RATE_1, val >> 8); 699 mutex_spin_exit(&sc->sc_intr_lock); 700 701 #define F_REF 24576000 702 703 #define ABS(x) (((x) < 0) ? (-x) : (x)) 704 705 if (setmode & AUMODE_RECORD) { 706 /* The ADC reference frequency (f_out) is 512 * sample rate */ 707 708 /* f_out is dervied from the 24.576MHz crystal by three values: 709 M & N & R. The equation is as follows: 710 711 f_out = (m + 2) * f_ref / ((n + 2) * (2 ^ a)) 712 713 with the constraint that: 714 715 80 MHz < (m + 2) / (n + 2) * f_ref <= 150MHz 716 and n, m >= 1 717 */ 718 719 int goal_f_out; 720 int a, n, m, best_n, best_m, best_error; 721 int pll_sample; 722 int error; 723 724 goal_f_out = 512 * rec->sample_rate; 725 best_n = 0; 726 best_m = 0; 727 best_error = 10000000; 728 for (a = 0; a < 8; a++) { 729 if ((goal_f_out * (1 << a)) >= 80000000) 730 break; 731 } 732 733 /* a != 8 because sample_rate >= 2000 */ 734 735 for (n = 33; n > 2; n--) { 736 m = (goal_f_out * n * (1 << a)) / F_REF; 737 if ((m > 257) || (m < 3)) 738 continue; 739 740 pll_sample = (m * F_REF) / (n * (1 << a)); 741 pll_sample /= 512; 742 743 /* Threshold might be good here */ 744 error = pll_sample - rec->sample_rate; 745 error = ABS(error); 746 747 if (error < best_error) { 748 best_error = error; 749 best_n = n; 750 best_m = m; 751 if (error == 0) break; 752 } 753 } 754 755 best_n -= 2; 756 best_m -= 2; 757 758 mutex_spin_enter(&sc->sc_intr_lock); 759 sv_write_indirect(sc, SV_ADC_PLL_M, best_m); 760 sv_write_indirect(sc, SV_ADC_PLL_N, 761 best_n | (a << SV_PLL_R_SHIFT)); 762 mutex_spin_exit(&sc->sc_intr_lock); 763 } 764 765 return 0; 766 } 767 768 static int 769 sv_round_blocksize(void *addr, int blk, int mode, 770 const audio_params_t *param) 771 { 772 773 return blk & -32; /* keep good alignment */ 774 } 775 776 static int 777 sv_trigger_output(void *addr, void *start, void *end, int blksize, 778 void (*intr)(void *), void *arg, const audio_params_t *param) 779 { 780 struct sv_softc *sc; 781 struct sv_dma *p; 782 uint8_t mode; 783 int dma_count; 784 785 DPRINTFN(1, ("sv_trigger_output: sc=%p start=%p end=%p blksize=%d " 786 "intr=%p(%p)\n", addr, start, end, blksize, intr, arg)); 787 sc = addr; 788 sc->sc_pintr = intr; 789 sc->sc_parg = arg; 790 791 mode = sv_read_indirect(sc, SV_DMA_DATA_FORMAT); 792 mode &= ~(SV_DMAA_FORMAT16 | SV_DMAA_STEREO); 793 if (param->precision == 16) 794 mode |= SV_DMAA_FORMAT16; 795 if (param->channels == 2) 796 mode |= SV_DMAA_STEREO; 797 sv_write_indirect(sc, SV_DMA_DATA_FORMAT, mode); 798 799 for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next) 800 continue; 801 if (p == NULL) { 802 printf("sv_trigger_output: bad addr %p\n", start); 803 return EINVAL; 804 } 805 806 dma_count = ((char *)end - (char *)start) - 1; 807 DPRINTF(("sv_trigger_output: DMA start loop input addr=%x cc=%d\n", 808 (int)DMAADDR(p), dma_count)); 809 810 bus_space_write_4(sc->sc_iot, sc->sc_dmaa_ioh, SV_DMA_ADDR0, 811 DMAADDR(p)); 812 bus_space_write_4(sc->sc_iot, sc->sc_dmaa_ioh, SV_DMA_COUNT0, 813 dma_count); 814 bus_space_write_1(sc->sc_iot, sc->sc_dmaa_ioh, SV_DMA_MODE, 815 DMA37MD_READ | DMA37MD_LOOP); 816 817 DPRINTF(("sv_trigger_output: current addr=%x\n", 818 bus_space_read_4(sc->sc_iot, sc->sc_dmaa_ioh, SV_DMA_ADDR0))); 819 820 dma_count = blksize - 1; 821 822 sv_write_indirect(sc, SV_DMAA_COUNT1, dma_count >> 8); 823 sv_write_indirect(sc, SV_DMAA_COUNT0, dma_count & 0xFF); 824 825 mode = sv_read_indirect(sc, SV_PLAY_RECORD_ENABLE); 826 sv_write_indirect(sc, SV_PLAY_RECORD_ENABLE, mode | SV_PLAY_ENABLE); 827 828 return 0; 829 } 830 831 static int 832 sv_trigger_input(void *addr, void *start, void *end, int blksize, 833 void (*intr)(void *), void *arg, const audio_params_t *param) 834 { 835 struct sv_softc *sc; 836 struct sv_dma *p; 837 uint8_t mode; 838 int dma_count; 839 840 DPRINTFN(1, ("sv_trigger_input: sc=%p start=%p end=%p blksize=%d " 841 "intr=%p(%p)\n", addr, start, end, blksize, intr, arg)); 842 sc = addr; 843 sc->sc_rintr = intr; 844 sc->sc_rarg = arg; 845 846 mode = sv_read_indirect(sc, SV_DMA_DATA_FORMAT); 847 mode &= ~(SV_DMAC_FORMAT16 | SV_DMAC_STEREO); 848 if (param->precision == 16) 849 mode |= SV_DMAC_FORMAT16; 850 if (param->channels == 2) 851 mode |= SV_DMAC_STEREO; 852 sv_write_indirect(sc, SV_DMA_DATA_FORMAT, mode); 853 854 for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next) 855 continue; 856 if (!p) { 857 printf("sv_trigger_input: bad addr %p\n", start); 858 return EINVAL; 859 } 860 861 dma_count = (((char *)end - (char *)start) >> 1) - 1; 862 DPRINTF(("sv_trigger_input: DMA start loop input addr=%x cc=%d\n", 863 (int)DMAADDR(p), dma_count)); 864 865 bus_space_write_4(sc->sc_iot, sc->sc_dmac_ioh, SV_DMA_ADDR0, 866 DMAADDR(p)); 867 bus_space_write_4(sc->sc_iot, sc->sc_dmac_ioh, SV_DMA_COUNT0, 868 dma_count); 869 bus_space_write_1(sc->sc_iot, sc->sc_dmac_ioh, SV_DMA_MODE, 870 DMA37MD_WRITE | DMA37MD_LOOP); 871 872 DPRINTF(("sv_trigger_input: current addr=%x\n", 873 bus_space_read_4(sc->sc_iot, sc->sc_dmac_ioh, SV_DMA_ADDR0))); 874 875 dma_count = (blksize >> 1) - 1; 876 877 sv_write_indirect(sc, SV_DMAC_COUNT1, dma_count >> 8); 878 sv_write_indirect(sc, SV_DMAC_COUNT0, dma_count & 0xFF); 879 880 mode = sv_read_indirect(sc, SV_PLAY_RECORD_ENABLE); 881 sv_write_indirect(sc, SV_PLAY_RECORD_ENABLE, mode | SV_RECORD_ENABLE); 882 883 return 0; 884 } 885 886 static int 887 sv_halt_output(void *addr) 888 { 889 struct sv_softc *sc; 890 uint8_t mode; 891 892 DPRINTF(("sv: sv_halt_output\n")); 893 sc = addr; 894 mode = sv_read_indirect(sc, SV_PLAY_RECORD_ENABLE); 895 sv_write_indirect(sc, SV_PLAY_RECORD_ENABLE, mode & ~SV_PLAY_ENABLE); 896 sc->sc_pintr = 0; 897 898 return 0; 899 } 900 901 static int 902 sv_halt_input(void *addr) 903 { 904 struct sv_softc *sc; 905 uint8_t mode; 906 907 DPRINTF(("sv: sv_halt_input\n")); 908 sc = addr; 909 mode = sv_read_indirect(sc, SV_PLAY_RECORD_ENABLE); 910 sv_write_indirect(sc, SV_PLAY_RECORD_ENABLE, mode & ~SV_RECORD_ENABLE); 911 sc->sc_rintr = 0; 912 913 return 0; 914 } 915 916 static int 917 sv_getdev(void *addr, struct audio_device *retp) 918 { 919 920 *retp = sv_device; 921 return 0; 922 } 923 924 925 /* 926 * Mixer related code is here 927 * 928 */ 929 930 #define SV_INPUT_CLASS 0 931 #define SV_OUTPUT_CLASS 1 932 #define SV_RECORD_CLASS 2 933 934 #define SV_LAST_CLASS 2 935 936 static const char *mixer_classes[] = 937 { AudioCinputs, AudioCoutputs, AudioCrecord }; 938 939 static const struct { 940 uint8_t l_port; 941 uint8_t r_port; 942 uint8_t mask; 943 uint8_t class; 944 const char *audio; 945 } ports[] = { 946 { SV_LEFT_AUX1_INPUT_CONTROL, SV_RIGHT_AUX1_INPUT_CONTROL, SV_AUX1_MASK, 947 SV_INPUT_CLASS, "aux1" }, 948 { SV_LEFT_CD_INPUT_CONTROL, SV_RIGHT_CD_INPUT_CONTROL, SV_CD_MASK, 949 SV_INPUT_CLASS, AudioNcd }, 950 { SV_LEFT_LINE_IN_INPUT_CONTROL, SV_RIGHT_LINE_IN_INPUT_CONTROL, SV_LINE_IN_MASK, 951 SV_INPUT_CLASS, AudioNline }, 952 { SV_MIC_INPUT_CONTROL, 0, SV_MIC_MASK, SV_INPUT_CLASS, AudioNmicrophone }, 953 { SV_LEFT_SYNTH_INPUT_CONTROL, SV_RIGHT_SYNTH_INPUT_CONTROL, 954 SV_SYNTH_MASK, SV_INPUT_CLASS, AudioNfmsynth }, 955 { SV_LEFT_AUX2_INPUT_CONTROL, SV_RIGHT_AUX2_INPUT_CONTROL, SV_AUX2_MASK, 956 SV_INPUT_CLASS, "aux2" }, 957 { SV_LEFT_PCM_INPUT_CONTROL, SV_RIGHT_PCM_INPUT_CONTROL, SV_PCM_MASK, 958 SV_INPUT_CLASS, AudioNdac }, 959 { SV_LEFT_MIXER_OUTPUT_CONTROL, SV_RIGHT_MIXER_OUTPUT_CONTROL, 960 SV_MIXER_OUT_MASK, SV_OUTPUT_CLASS, AudioNmaster } 961 }; 962 963 964 static const struct { 965 int idx; 966 const char *name; 967 } record_sources[] = { 968 { SV_REC_CD, AudioNcd }, 969 { SV_REC_DAC, AudioNdac }, 970 { SV_REC_AUX2, "aux2" }, 971 { SV_REC_LINE, AudioNline }, 972 { SV_REC_AUX1, "aux1" }, 973 { SV_REC_MIC, AudioNmicrophone }, 974 { SV_REC_MIXER, AudioNmixerout } 975 }; 976 977 978 #define SV_DEVICES_PER_PORT 2 979 #define SV_FIRST_MIXER (SV_LAST_CLASS + 1) 980 #define SV_LAST_MIXER (SV_DEVICES_PER_PORT * (ARRAY_SIZE(ports)) + SV_LAST_CLASS) 981 #define SV_RECORD_SOURCE (SV_LAST_MIXER + 1) 982 #define SV_MIC_BOOST (SV_LAST_MIXER + 2) 983 #define SV_RECORD_GAIN (SV_LAST_MIXER + 3) 984 #define SV_SRS_MODE (SV_LAST_MIXER + 4) 985 986 static int 987 sv_query_devinfo(void *addr, mixer_devinfo_t *dip) 988 { 989 int i; 990 991 /* It's a class */ 992 if (dip->index <= SV_LAST_CLASS) { 993 dip->type = AUDIO_MIXER_CLASS; 994 dip->mixer_class = dip->index; 995 dip->next = dip->prev = AUDIO_MIXER_LAST; 996 strcpy(dip->label.name, mixer_classes[dip->index]); 997 return 0; 998 } 999 1000 if (dip->index >= SV_FIRST_MIXER && 1001 dip->index <= SV_LAST_MIXER) { 1002 int off, mute ,idx; 1003 1004 off = dip->index - SV_FIRST_MIXER; 1005 mute = (off % SV_DEVICES_PER_PORT); 1006 idx = off / SV_DEVICES_PER_PORT; 1007 dip->mixer_class = ports[idx].class; 1008 strcpy(dip->label.name, ports[idx].audio); 1009 1010 if (!mute) { 1011 dip->type = AUDIO_MIXER_VALUE; 1012 dip->prev = AUDIO_MIXER_LAST; 1013 dip->next = dip->index + 1; 1014 1015 if (ports[idx].r_port != 0) 1016 dip->un.v.num_channels = 2; 1017 else 1018 dip->un.v.num_channels = 1; 1019 1020 strcpy(dip->un.v.units.name, AudioNvolume); 1021 } else { 1022 dip->type = AUDIO_MIXER_ENUM; 1023 dip->prev = dip->index - 1; 1024 dip->next = AUDIO_MIXER_LAST; 1025 1026 strcpy(dip->label.name, AudioNmute); 1027 dip->un.e.num_mem = 2; 1028 strcpy(dip->un.e.member[0].label.name, AudioNoff); 1029 dip->un.e.member[0].ord = 0; 1030 strcpy(dip->un.e.member[1].label.name, AudioNon); 1031 dip->un.e.member[1].ord = 1; 1032 } 1033 1034 return 0; 1035 } 1036 1037 switch (dip->index) { 1038 case SV_RECORD_SOURCE: 1039 dip->mixer_class = SV_RECORD_CLASS; 1040 dip->prev = AUDIO_MIXER_LAST; 1041 dip->next = SV_RECORD_GAIN; 1042 strcpy(dip->label.name, AudioNsource); 1043 dip->type = AUDIO_MIXER_ENUM; 1044 1045 dip->un.e.num_mem = ARRAY_SIZE(record_sources); 1046 for (i = 0; i < ARRAY_SIZE(record_sources); i++) { 1047 strcpy(dip->un.e.member[i].label.name, 1048 record_sources[i].name); 1049 dip->un.e.member[i].ord = record_sources[i].idx; 1050 } 1051 return 0; 1052 1053 case SV_RECORD_GAIN: 1054 dip->mixer_class = SV_RECORD_CLASS; 1055 dip->prev = SV_RECORD_SOURCE; 1056 dip->next = AUDIO_MIXER_LAST; 1057 strcpy(dip->label.name, "gain"); 1058 dip->type = AUDIO_MIXER_VALUE; 1059 dip->un.v.num_channels = 1; 1060 strcpy(dip->un.v.units.name, AudioNvolume); 1061 return 0; 1062 1063 case SV_MIC_BOOST: 1064 dip->mixer_class = SV_RECORD_CLASS; 1065 dip->prev = AUDIO_MIXER_LAST; 1066 dip->next = AUDIO_MIXER_LAST; 1067 strcpy(dip->label.name, "micboost"); 1068 goto on_off; 1069 1070 case SV_SRS_MODE: 1071 dip->mixer_class = SV_OUTPUT_CLASS; 1072 dip->prev = dip->next = AUDIO_MIXER_LAST; 1073 strcpy(dip->label.name, AudioNspatial); 1074 1075 on_off: 1076 dip->type = AUDIO_MIXER_ENUM; 1077 dip->un.e.num_mem = 2; 1078 strcpy(dip->un.e.member[0].label.name, AudioNoff); 1079 dip->un.e.member[0].ord = 0; 1080 strcpy(dip->un.e.member[1].label.name, AudioNon); 1081 dip->un.e.member[1].ord = 1; 1082 return 0; 1083 } 1084 1085 return ENXIO; 1086 } 1087 1088 static int 1089 sv_mixer_set_port(void *addr, mixer_ctrl_t *cp) 1090 { 1091 struct sv_softc *sc; 1092 uint8_t reg; 1093 int idx; 1094 1095 sc = addr; 1096 if (cp->dev >= SV_FIRST_MIXER && 1097 cp->dev <= SV_LAST_MIXER) { 1098 int off, mute; 1099 1100 off = cp->dev - SV_FIRST_MIXER; 1101 mute = (off % SV_DEVICES_PER_PORT); 1102 idx = off / SV_DEVICES_PER_PORT; 1103 1104 if (mute) { 1105 if (cp->type != AUDIO_MIXER_ENUM) 1106 return EINVAL; 1107 1108 mutex_spin_enter(&sc->sc_intr_lock); 1109 reg = sv_read_indirect(sc, ports[idx].l_port); 1110 if (cp->un.ord) 1111 reg |= SV_MUTE_BIT; 1112 else 1113 reg &= ~SV_MUTE_BIT; 1114 sv_write_indirect(sc, ports[idx].l_port, reg); 1115 1116 if (ports[idx].r_port) { 1117 reg = sv_read_indirect(sc, ports[idx].r_port); 1118 if (cp->un.ord) 1119 reg |= SV_MUTE_BIT; 1120 else 1121 reg &= ~SV_MUTE_BIT; 1122 sv_write_indirect(sc, ports[idx].r_port, reg); 1123 } 1124 mutex_spin_exit(&sc->sc_intr_lock); 1125 } else { 1126 int lval, rval; 1127 1128 if (cp->type != AUDIO_MIXER_VALUE) 1129 return EINVAL; 1130 1131 if (cp->un.value.num_channels != 1 && 1132 cp->un.value.num_channels != 2) 1133 return (EINVAL); 1134 1135 if (ports[idx].r_port == 0) { 1136 if (cp->un.value.num_channels != 1) 1137 return (EINVAL); 1138 lval = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 1139 rval = 0; /* shut up GCC */ 1140 } else { 1141 if (cp->un.value.num_channels != 2) 1142 return (EINVAL); 1143 1144 lval = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]; 1145 rval = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]; 1146 } 1147 1148 mutex_spin_enter(&sc->sc_intr_lock); 1149 reg = sv_read_indirect(sc, ports[idx].l_port); 1150 reg &= ~(ports[idx].mask); 1151 lval = (AUDIO_MAX_GAIN - lval) * ports[idx].mask / 1152 AUDIO_MAX_GAIN; 1153 reg |= lval; 1154 sv_write_indirect(sc, ports[idx].l_port, reg); 1155 1156 if (ports[idx].r_port != 0) { 1157 reg = sv_read_indirect(sc, ports[idx].r_port); 1158 reg &= ~(ports[idx].mask); 1159 1160 rval = (AUDIO_MAX_GAIN - rval) * ports[idx].mask / 1161 AUDIO_MAX_GAIN; 1162 reg |= rval; 1163 1164 sv_write_indirect(sc, ports[idx].r_port, reg); 1165 } 1166 1167 sv_read_indirect(sc, ports[idx].l_port); 1168 mutex_spin_exit(&sc->sc_intr_lock); 1169 } 1170 1171 return 0; 1172 } 1173 1174 1175 switch (cp->dev) { 1176 case SV_RECORD_SOURCE: 1177 if (cp->type != AUDIO_MIXER_ENUM) 1178 return EINVAL; 1179 1180 for (idx = 0; idx < ARRAY_SIZE(record_sources); idx++) { 1181 if (record_sources[idx].idx == cp->un.ord) 1182 goto found; 1183 } 1184 1185 return EINVAL; 1186 1187 found: 1188 mutex_spin_enter(&sc->sc_intr_lock); 1189 reg = sv_read_indirect(sc, SV_LEFT_ADC_INPUT_CONTROL); 1190 reg &= ~SV_REC_SOURCE_MASK; 1191 reg |= (((cp->un.ord) << SV_REC_SOURCE_SHIFT) & SV_REC_SOURCE_MASK); 1192 sv_write_indirect(sc, SV_LEFT_ADC_INPUT_CONTROL, reg); 1193 1194 reg = sv_read_indirect(sc, SV_RIGHT_ADC_INPUT_CONTROL); 1195 reg &= ~SV_REC_SOURCE_MASK; 1196 reg |= (((cp->un.ord) << SV_REC_SOURCE_SHIFT) & SV_REC_SOURCE_MASK); 1197 sv_write_indirect(sc, SV_RIGHT_ADC_INPUT_CONTROL, reg); 1198 mutex_spin_exit(&sc->sc_intr_lock); 1199 return 0; 1200 1201 case SV_RECORD_GAIN: 1202 { 1203 int val; 1204 1205 if (cp->type != AUDIO_MIXER_VALUE) 1206 return EINVAL; 1207 1208 if (cp->un.value.num_channels != 1) 1209 return EINVAL; 1210 1211 val = (cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] 1212 * SV_REC_GAIN_MASK) / AUDIO_MAX_GAIN; 1213 1214 mutex_spin_enter(&sc->sc_intr_lock); 1215 reg = sv_read_indirect(sc, SV_LEFT_ADC_INPUT_CONTROL); 1216 reg &= ~SV_REC_GAIN_MASK; 1217 reg |= val; 1218 sv_write_indirect(sc, SV_LEFT_ADC_INPUT_CONTROL, reg); 1219 1220 reg = sv_read_indirect(sc, SV_RIGHT_ADC_INPUT_CONTROL); 1221 reg &= ~SV_REC_GAIN_MASK; 1222 reg |= val; 1223 sv_write_indirect(sc, SV_RIGHT_ADC_INPUT_CONTROL, reg); 1224 mutex_spin_exit(&sc->sc_intr_lock); 1225 } 1226 return (0); 1227 1228 case SV_MIC_BOOST: 1229 if (cp->type != AUDIO_MIXER_ENUM) 1230 return EINVAL; 1231 1232 mutex_spin_enter(&sc->sc_intr_lock); 1233 reg = sv_read_indirect(sc, SV_LEFT_ADC_INPUT_CONTROL); 1234 if (cp->un.ord) { 1235 reg |= SV_MIC_BOOST_BIT; 1236 } else { 1237 reg &= ~SV_MIC_BOOST_BIT; 1238 } 1239 1240 sv_write_indirect(sc, SV_LEFT_ADC_INPUT_CONTROL, reg); 1241 mutex_spin_exit(&sc->sc_intr_lock); 1242 return 0; 1243 1244 case SV_SRS_MODE: 1245 if (cp->type != AUDIO_MIXER_ENUM) 1246 return EINVAL; 1247 1248 mutex_spin_enter(&sc->sc_intr_lock); 1249 reg = sv_read_indirect(sc, SV_SRS_SPACE_CONTROL); 1250 if (cp->un.ord) { 1251 reg &= ~SV_SRS_SPACE_ONOFF; 1252 } else { 1253 reg |= SV_SRS_SPACE_ONOFF; 1254 } 1255 1256 sv_write_indirect(sc, SV_SRS_SPACE_CONTROL, reg); 1257 mutex_spin_exit(&sc->sc_intr_lock); 1258 return 0; 1259 } 1260 1261 return EINVAL; 1262 } 1263 1264 static int 1265 sv_mixer_get_port(void *addr, mixer_ctrl_t *cp) 1266 { 1267 struct sv_softc *sc; 1268 int val, error; 1269 uint8_t reg; 1270 1271 sc = addr; 1272 error = 0; 1273 1274 mutex_spin_enter(&sc->sc_intr_lock); 1275 1276 if (cp->dev >= SV_FIRST_MIXER && 1277 cp->dev <= SV_LAST_MIXER) { 1278 int off = cp->dev - SV_FIRST_MIXER; 1279 int mute = (off % 2); 1280 int idx = off / 2; 1281 1282 off = cp->dev - SV_FIRST_MIXER; 1283 mute = (off % 2); 1284 idx = off / 2; 1285 if (mute) { 1286 if (cp->type != AUDIO_MIXER_ENUM) 1287 error = EINVAL; 1288 else { 1289 reg = sv_read_indirect(sc, ports[idx].l_port); 1290 cp->un.ord = ((reg & SV_MUTE_BIT) ? 1 : 0); 1291 } 1292 } else { 1293 if (cp->type != AUDIO_MIXER_VALUE || 1294 (cp->un.value.num_channels != 1 && 1295 cp->un.value.num_channels != 2) || 1296 ((ports[idx].r_port == 0 && 1297 cp->un.value.num_channels != 1) || 1298 (ports[idx].r_port != 0 && 1299 cp->un.value.num_channels != 2))) 1300 error = EINVAL; 1301 else { 1302 reg = sv_read_indirect(sc, ports[idx].l_port); 1303 reg &= ports[idx].mask; 1304 1305 val = AUDIO_MAX_GAIN - 1306 ((reg * AUDIO_MAX_GAIN) / ports[idx].mask); 1307 1308 if (ports[idx].r_port != 0) { 1309 cp->un.value.level 1310 [AUDIO_MIXER_LEVEL_LEFT] = val; 1311 1312 reg = sv_read_indirect(sc, 1313 ports[idx].r_port); 1314 reg &= ports[idx].mask; 1315 1316 val = AUDIO_MAX_GAIN - 1317 ((reg * AUDIO_MAX_GAIN) 1318 / ports[idx].mask); 1319 cp->un.value.level 1320 [AUDIO_MIXER_LEVEL_RIGHT] = val; 1321 } else 1322 cp->un.value.level 1323 [AUDIO_MIXER_LEVEL_MONO] = val; 1324 } 1325 } 1326 1327 return error; 1328 } 1329 1330 switch (cp->dev) { 1331 case SV_RECORD_SOURCE: 1332 if (cp->type != AUDIO_MIXER_ENUM) { 1333 error = EINVAL; 1334 break; 1335 } 1336 1337 reg = sv_read_indirect(sc, SV_LEFT_ADC_INPUT_CONTROL); 1338 cp->un.ord = ((reg & SV_REC_SOURCE_MASK) >> SV_REC_SOURCE_SHIFT); 1339 1340 break; 1341 1342 case SV_RECORD_GAIN: 1343 if (cp->type != AUDIO_MIXER_VALUE) { 1344 error = EINVAL; 1345 break; 1346 } 1347 if (cp->un.value.num_channels != 1) { 1348 error = EINVAL; 1349 break; 1350 } 1351 1352 reg = sv_read_indirect(sc, SV_LEFT_ADC_INPUT_CONTROL) & SV_REC_GAIN_MASK; 1353 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 1354 (((unsigned int)reg) * AUDIO_MAX_GAIN) / SV_REC_GAIN_MASK; 1355 1356 break; 1357 1358 case SV_MIC_BOOST: 1359 if (cp->type != AUDIO_MIXER_ENUM) { 1360 error = EINVAL; 1361 break; 1362 } 1363 reg = sv_read_indirect(sc, SV_LEFT_ADC_INPUT_CONTROL); 1364 cp->un.ord = ((reg & SV_MIC_BOOST_BIT) ? 1 : 0); 1365 break; 1366 1367 case SV_SRS_MODE: 1368 if (cp->type != AUDIO_MIXER_ENUM) { 1369 error = EINVAL; 1370 break; 1371 } 1372 reg = sv_read_indirect(sc, SV_SRS_SPACE_CONTROL); 1373 cp->un.ord = ((reg & SV_SRS_SPACE_ONOFF) ? 0 : 1); 1374 break; 1375 default: 1376 error = EINVAL; 1377 break; 1378 } 1379 1380 mutex_spin_exit(&sc->sc_intr_lock); 1381 return error; 1382 } 1383 1384 static void 1385 sv_init_mixer(struct sv_softc *sc) 1386 { 1387 mixer_ctrl_t cp; 1388 int i; 1389 1390 cp.type = AUDIO_MIXER_ENUM; 1391 cp.dev = SV_SRS_MODE; 1392 cp.un.ord = 0; 1393 1394 sv_mixer_set_port(sc, &cp); 1395 1396 for (i = 0; i < ARRAY_SIZE(ports); i++) { 1397 if (!strcmp(ports[i].audio, AudioNdac)) { 1398 cp.type = AUDIO_MIXER_ENUM; 1399 cp.dev = SV_FIRST_MIXER + i * SV_DEVICES_PER_PORT + 1; 1400 cp.un.ord = 0; 1401 sv_mixer_set_port(sc, &cp); 1402 break; 1403 } 1404 } 1405 } 1406 1407 static void * 1408 sv_malloc(void *addr, int direction, size_t size) 1409 { 1410 struct sv_softc *sc; 1411 struct sv_dma *p; 1412 int error; 1413 1414 sc = addr; 1415 p = kmem_alloc(sizeof(*p), KM_SLEEP); 1416 if (p == NULL) 1417 return NULL; 1418 error = sv_allocmem(sc, size, 16, direction, p); 1419 if (error) { 1420 kmem_free(p, sizeof(*p)); 1421 return 0; 1422 } 1423 p->next = sc->sc_dmas; 1424 sc->sc_dmas = p; 1425 return KERNADDR(p); 1426 } 1427 1428 static void 1429 sv_free(void *addr, void *ptr, size_t size) 1430 { 1431 struct sv_softc *sc; 1432 struct sv_dma **pp, *p; 1433 1434 sc = addr; 1435 for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &p->next) { 1436 if (KERNADDR(p) == ptr) { 1437 sv_freemem(sc, p); 1438 *pp = p->next; 1439 kmem_free(p, sizeof(*p)); 1440 return; 1441 } 1442 } 1443 } 1444 1445 static size_t 1446 sv_round_buffersize(void *addr, int direction, size_t size) 1447 { 1448 1449 return size; 1450 } 1451 1452 static paddr_t 1453 sv_mappage(void *addr, void *mem, off_t off, int prot) 1454 { 1455 struct sv_softc *sc; 1456 struct sv_dma *p; 1457 1458 sc = addr; 1459 if (off < 0) 1460 return -1; 1461 for (p = sc->sc_dmas; p && KERNADDR(p) != mem; p = p->next) 1462 continue; 1463 if (p == NULL) 1464 return -1; 1465 return bus_dmamem_mmap(sc->sc_dmatag, p->segs, p->nsegs, 1466 off, prot, BUS_DMA_WAITOK); 1467 } 1468 1469 static int 1470 sv_get_props(void *addr) 1471 { 1472 return AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX; 1473 } 1474 1475 static void 1476 sv_get_locks(void *addr, kmutex_t **intr, kmutex_t **thread) 1477 { 1478 struct sv_softc *sc; 1479 1480 sc = addr; 1481 *intr = &sc->sc_intr_lock; 1482 *thread = &sc->sc_lock; 1483 } 1484