1 /* $NetBSD: sv.c,v 1.52 2017/06/01 02:45:11 chs 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.52 2017/06/01 02:45:11 chs 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 char intrbuf[PCI_INTRSTR_LEN]; 348 349 sc = device_private(self); 350 pa = aux; 351 pc = pa->pa_pc; 352 pt = pa->pa_tag; 353 aprint_naive("\n"); 354 aprint_normal("\n"); 355 356 /* Map I/O registers */ 357 if (pci_mapreg_map(pa, SV_ENHANCED_PORTBASE_SLOT, 358 PCI_MAPREG_TYPE_IO, 0, 359 &sc->sc_iot, &sc->sc_ioh, NULL, NULL)) { 360 aprint_error_dev(self, "can't map enhanced i/o space\n"); 361 return; 362 } 363 if (pci_mapreg_map(pa, SV_FM_PORTBASE_SLOT, 364 PCI_MAPREG_TYPE_IO, 0, 365 &sc->sc_opliot, &sc->sc_oplioh, NULL, NULL)) { 366 aprint_error_dev(self, "can't map FM i/o space\n"); 367 return; 368 } 369 if (pci_mapreg_map(pa, SV_MIDI_PORTBASE_SLOT, 370 PCI_MAPREG_TYPE_IO, 0, 371 &sc->sc_midiiot, &sc->sc_midiioh, NULL, NULL)) { 372 aprint_error_dev(self, "can't map MIDI i/o space\n"); 373 return; 374 } 375 DPRINTF(("sv: IO ports: enhanced=0x%x, OPL=0x%x, MIDI=0x%x\n", 376 (int)sc->sc_ioh, (int)sc->sc_oplioh, (int)sc->sc_midiioh)); 377 378 #if defined(alpha) 379 /* XXX Force allocation through the SGMAP. */ 380 sc->sc_dmatag = alphabus_dma_get_tag(pa->pa_dmat, ALPHA_BUS_ISA); 381 #elif defined(amd64) || defined(i386) 382 /* XXX 383 * The SonicVibes DMA is broken and only works on 24-bit addresses. 384 * As long as bus_dmamem_alloc_range() is missing we use the ISA 385 * DMA tag on i386. 386 */ 387 sc->sc_dmatag = &isa_bus_dma_tag; 388 #else 389 sc->sc_dmatag = pa->pa_dmat; 390 #endif 391 392 pci_conf_write(pc, pt, SV_DMAA_CONFIG_OFF, SV_DMAA_EXTENDED_ADDR); 393 pci_conf_write(pc, pt, SV_DMAC_CONFIG_OFF, 0); 394 395 /* Enable the device. */ 396 csr = pci_conf_read(pc, pt, PCI_COMMAND_STATUS_REG); 397 pci_conf_write(pc, pt, PCI_COMMAND_STATUS_REG, 398 csr | PCI_COMMAND_MASTER_ENABLE); 399 400 sv_write_indirect(sc, SV_ANALOG_POWER_DOWN_CONTROL, 0); 401 sv_write_indirect(sc, SV_DIGITAL_POWER_DOWN_CONTROL, 0); 402 403 /* initialize codec registers */ 404 reg = sv_read(sc, SV_CODEC_CONTROL); 405 reg |= SV_CTL_RESET; 406 sv_write(sc, SV_CODEC_CONTROL, reg); 407 delay(50); 408 409 reg = sv_read(sc, SV_CODEC_CONTROL); 410 reg &= ~SV_CTL_RESET; 411 reg |= SV_CTL_INTA | SV_CTL_ENHANCED; 412 413 /* This write clears the reset */ 414 sv_write(sc, SV_CODEC_CONTROL, reg); 415 delay(50); 416 417 /* This write actually shoves the new values in */ 418 sv_write(sc, SV_CODEC_CONTROL, reg); 419 420 DPRINTF(("sv_attach: control=0x%x\n", sv_read(sc, SV_CODEC_CONTROL))); 421 422 /* Map and establish the interrupt. */ 423 if (pci_intr_map(pa, &ih)) { 424 aprint_error_dev(self, "couldn't map interrupt\n"); 425 return; 426 } 427 428 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 429 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_AUDIO); 430 431 intrstr = pci_intr_string(pc, ih, intrbuf, sizeof(intrbuf)); 432 sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO, sv_intr, sc); 433 if (sc->sc_ih == NULL) { 434 aprint_error_dev(self, "couldn't establish interrupt"); 435 if (intrstr != NULL) 436 aprint_error(" at %s", intrstr); 437 aprint_error("\n"); 438 mutex_destroy(&sc->sc_lock); 439 mutex_destroy(&sc->sc_intr_lock); 440 return; 441 } 442 aprint_normal_dev(self, "interrupting at %s\n", intrstr); 443 aprint_normal_dev(self, "rev %d", 444 sv_read_indirect(sc, SV_REVISION_LEVEL)); 445 if (sv_read(sc, SV_CODEC_CONTROL) & SV_CTL_MD1) 446 aprint_normal(", reverb SRAM present"); 447 if (!(sv_read_indirect(sc, SV_WAVETABLE_SOURCE_SELECT) & SV_WSS_WT0)) 448 aprint_normal(", wavetable ROM present"); 449 aprint_normal("\n"); 450 451 /* Enable DMA interrupts */ 452 reg = sv_read(sc, SV_CODEC_INTMASK); 453 reg &= ~(SV_INTMASK_DMAA | SV_INTMASK_DMAC); 454 reg |= SV_INTMASK_UD | SV_INTMASK_SINT | SV_INTMASK_MIDI; 455 sv_write(sc, SV_CODEC_INTMASK, reg); 456 sv_read(sc, SV_CODEC_STATUS); 457 458 sv_init_mixer(sc); 459 460 audio_attach_mi(&sv_hw_if, sc, self); 461 462 arg.type = AUDIODEV_TYPE_OPL; 463 arg.hwif = 0; 464 arg.hdl = 0; 465 (void)config_found(self, &arg, audioprint); 466 467 sc->sc_pa = *pa; /* for deferred setup */ 468 config_defer(self, sv_defer); 469 } 470 471 #ifdef AUDIO_DEBUG 472 void 473 sv_dumpregs(struct sv_softc *sc) 474 { 475 int idx; 476 477 #if 0 478 for (idx = 0; idx < 0x50; idx += 4) 479 printf ("%02x = %x\n", idx, 480 pci_conf_read(pa->pa_pc, pa->pa_tag, idx)); 481 #endif 482 483 for (idx = 0; idx < 6; idx++) 484 printf ("REG %02x = %02x\n", idx, sv_read(sc, idx)); 485 486 for (idx = 0; idx < 0x32; idx++) 487 printf ("IREG %02x = %02x\n", idx, sv_read_indirect(sc, idx)); 488 489 for (idx = 0; idx < 0x10; idx++) 490 printf ("DMA %02x = %02x\n", idx, 491 bus_space_read_1(sc->sc_iot, sc->sc_dmaa_ioh, idx)); 492 } 493 #endif 494 495 static int 496 sv_intr(void *p) 497 { 498 struct sv_softc *sc; 499 uint8_t intr; 500 501 sc = p; 502 503 mutex_spin_enter(&sc->sc_intr_lock); 504 505 intr = sv_read(sc, SV_CODEC_STATUS); 506 DPRINTFN(5,("sv_intr: intr=0x%x\n", intr)); 507 508 if (intr & SV_INTSTATUS_DMAA) { 509 if (sc->sc_pintr) 510 sc->sc_pintr(sc->sc_parg); 511 } 512 513 if (intr & SV_INTSTATUS_DMAC) { 514 if (sc->sc_rintr) 515 sc->sc_rintr(sc->sc_rarg); 516 } 517 518 mutex_spin_exit(&sc->sc_intr_lock); 519 520 return (intr & (SV_INTSTATUS_DMAA | SV_INTSTATUS_DMAC)) != 0; 521 } 522 523 static int 524 sv_allocmem(struct sv_softc *sc, size_t size, size_t align, 525 int direction, struct sv_dma *p) 526 { 527 int error; 528 529 p->size = size; 530 error = bus_dmamem_alloc(sc->sc_dmatag, p->size, align, 0, 531 p->segs, ARRAY_SIZE(p->segs), &p->nsegs, BUS_DMA_WAITOK); 532 if (error) 533 return error; 534 535 error = bus_dmamem_map(sc->sc_dmatag, p->segs, p->nsegs, p->size, 536 &p->addr, BUS_DMA_WAITOK|BUS_DMA_COHERENT); 537 if (error) 538 goto free; 539 540 error = bus_dmamap_create(sc->sc_dmatag, p->size, 1, p->size, 541 0, BUS_DMA_WAITOK, &p->map); 542 if (error) 543 goto unmap; 544 545 error = bus_dmamap_load(sc->sc_dmatag, p->map, p->addr, p->size, NULL, 546 BUS_DMA_WAITOK | (direction == AUMODE_RECORD) ? BUS_DMA_READ : BUS_DMA_WRITE); 547 if (error) 548 goto destroy; 549 DPRINTF(("sv_allocmem: pa=%lx va=%lx pba=%lx\n", 550 (long)p->segs[0].ds_addr, (long)KERNADDR(p), (long)DMAADDR(p))); 551 return 0; 552 553 destroy: 554 bus_dmamap_destroy(sc->sc_dmatag, p->map); 555 unmap: 556 bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size); 557 free: 558 bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs); 559 return error; 560 } 561 562 static int 563 sv_freemem(struct sv_softc *sc, struct sv_dma *p) 564 { 565 566 bus_dmamap_unload(sc->sc_dmatag, p->map); 567 bus_dmamap_destroy(sc->sc_dmatag, p->map); 568 bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size); 569 bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs); 570 return 0; 571 } 572 573 static int 574 sv_open(void *addr, int flags) 575 { 576 struct sv_softc *sc; 577 578 sc = addr; 579 DPRINTF(("sv_open\n")); 580 if (!sc->sc_dmaset) 581 return ENXIO; 582 583 return 0; 584 } 585 586 static int 587 sv_query_encoding(void *addr, struct audio_encoding *fp) 588 { 589 590 switch (fp->index) { 591 case 0: 592 strcpy(fp->name, AudioEulinear); 593 fp->encoding = AUDIO_ENCODING_ULINEAR; 594 fp->precision = 8; 595 fp->flags = 0; 596 return 0; 597 case 1: 598 strcpy(fp->name, AudioEmulaw); 599 fp->encoding = AUDIO_ENCODING_ULAW; 600 fp->precision = 8; 601 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 602 return 0; 603 case 2: 604 strcpy(fp->name, AudioEalaw); 605 fp->encoding = AUDIO_ENCODING_ALAW; 606 fp->precision = 8; 607 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 608 return 0; 609 case 3: 610 strcpy(fp->name, AudioEslinear); 611 fp->encoding = AUDIO_ENCODING_SLINEAR; 612 fp->precision = 8; 613 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 614 return 0; 615 case 4: 616 strcpy(fp->name, AudioEslinear_le); 617 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 618 fp->precision = 16; 619 fp->flags = 0; 620 return 0; 621 case 5: 622 strcpy(fp->name, AudioEulinear_le); 623 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 624 fp->precision = 16; 625 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 626 return 0; 627 case 6: 628 strcpy(fp->name, AudioEslinear_be); 629 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 630 fp->precision = 16; 631 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 632 return 0; 633 case 7: 634 strcpy(fp->name, AudioEulinear_be); 635 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 636 fp->precision = 16; 637 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 638 return 0; 639 default: 640 return EINVAL; 641 } 642 } 643 644 static int 645 sv_set_params(void *addr, int setmode, int usemode, audio_params_t *play, 646 audio_params_t *rec, stream_filter_list_t *pfil, stream_filter_list_t *rfil) 647 { 648 struct sv_softc *sc; 649 audio_params_t *p; 650 uint32_t val; 651 652 sc = addr; 653 p = NULL; 654 /* 655 * This device only has one clock, so make the sample rates match. 656 */ 657 if (play->sample_rate != rec->sample_rate && 658 usemode == (AUMODE_PLAY | AUMODE_RECORD)) { 659 if (setmode == AUMODE_PLAY) { 660 rec->sample_rate = play->sample_rate; 661 setmode |= AUMODE_RECORD; 662 } else if (setmode == AUMODE_RECORD) { 663 play->sample_rate = rec->sample_rate; 664 setmode |= AUMODE_PLAY; 665 } else 666 return EINVAL; 667 } 668 669 if (setmode & AUMODE_RECORD) { 670 p = rec; 671 if (auconv_set_converter(sv_formats, SV_NFORMATS, 672 AUMODE_RECORD, rec, FALSE, rfil) < 0) 673 return EINVAL; 674 } 675 if (setmode & AUMODE_PLAY) { 676 p = play; 677 if (auconv_set_converter(sv_formats, SV_NFORMATS, 678 AUMODE_PLAY, play, FALSE, pfil) < 0) 679 return EINVAL; 680 } 681 682 if (p == NULL) 683 return 0; 684 685 val = p->sample_rate * 65536 / 48000; 686 /* 687 * If the sample rate is exactly 48 kHz, the fraction would overflow the 688 * register, so we have to bias it. This causes a little clock drift. 689 * The drift is below normal crystal tolerance (.0001%), so although 690 * this seems a little silly, we can pretty much ignore it. 691 * (I tested the output speed with values of 1-20, just to be sure this 692 * register isn't *supposed* to have a bias. It isn't.) 693 * - mycroft 694 */ 695 if (val > 65535) 696 val = 65535; 697 698 mutex_spin_enter(&sc->sc_intr_lock); 699 sv_write_indirect(sc, SV_PCM_SAMPLE_RATE_0, val & 0xff); 700 sv_write_indirect(sc, SV_PCM_SAMPLE_RATE_1, val >> 8); 701 mutex_spin_exit(&sc->sc_intr_lock); 702 703 #define F_REF 24576000 704 705 #define ABS(x) (((x) < 0) ? (-x) : (x)) 706 707 if (setmode & AUMODE_RECORD) { 708 /* The ADC reference frequency (f_out) is 512 * sample rate */ 709 710 /* f_out is dervied from the 24.576MHz crystal by three values: 711 M & N & R. The equation is as follows: 712 713 f_out = (m + 2) * f_ref / ((n + 2) * (2 ^ a)) 714 715 with the constraint that: 716 717 80 MHz < (m + 2) / (n + 2) * f_ref <= 150MHz 718 and n, m >= 1 719 */ 720 721 int goal_f_out; 722 int a, n, m, best_n, best_m, best_error; 723 int pll_sample; 724 int error; 725 726 goal_f_out = 512 * rec->sample_rate; 727 best_n = 0; 728 best_m = 0; 729 best_error = 10000000; 730 for (a = 0; a < 8; a++) { 731 if ((goal_f_out * (1 << a)) >= 80000000) 732 break; 733 } 734 735 /* a != 8 because sample_rate >= 2000 */ 736 737 for (n = 33; n > 2; n--) { 738 m = (goal_f_out * n * (1 << a)) / F_REF; 739 if ((m > 257) || (m < 3)) 740 continue; 741 742 pll_sample = (m * F_REF) / (n * (1 << a)); 743 pll_sample /= 512; 744 745 /* Threshold might be good here */ 746 error = pll_sample - rec->sample_rate; 747 error = ABS(error); 748 749 if (error < best_error) { 750 best_error = error; 751 best_n = n; 752 best_m = m; 753 if (error == 0) break; 754 } 755 } 756 757 best_n -= 2; 758 best_m -= 2; 759 760 mutex_spin_enter(&sc->sc_intr_lock); 761 sv_write_indirect(sc, SV_ADC_PLL_M, best_m); 762 sv_write_indirect(sc, SV_ADC_PLL_N, 763 best_n | (a << SV_PLL_R_SHIFT)); 764 mutex_spin_exit(&sc->sc_intr_lock); 765 } 766 767 return 0; 768 } 769 770 static int 771 sv_round_blocksize(void *addr, int blk, int mode, 772 const audio_params_t *param) 773 { 774 775 return blk & -32; /* keep good alignment */ 776 } 777 778 static int 779 sv_trigger_output(void *addr, void *start, void *end, int blksize, 780 void (*intr)(void *), void *arg, const audio_params_t *param) 781 { 782 struct sv_softc *sc; 783 struct sv_dma *p; 784 uint8_t mode; 785 int dma_count; 786 787 DPRINTFN(1, ("sv_trigger_output: sc=%p start=%p end=%p blksize=%d " 788 "intr=%p(%p)\n", addr, start, end, blksize, intr, arg)); 789 sc = addr; 790 sc->sc_pintr = intr; 791 sc->sc_parg = arg; 792 793 mode = sv_read_indirect(sc, SV_DMA_DATA_FORMAT); 794 mode &= ~(SV_DMAA_FORMAT16 | SV_DMAA_STEREO); 795 if (param->precision == 16) 796 mode |= SV_DMAA_FORMAT16; 797 if (param->channels == 2) 798 mode |= SV_DMAA_STEREO; 799 sv_write_indirect(sc, SV_DMA_DATA_FORMAT, mode); 800 801 for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next) 802 continue; 803 if (p == NULL) { 804 printf("sv_trigger_output: bad addr %p\n", start); 805 return EINVAL; 806 } 807 808 dma_count = ((char *)end - (char *)start) - 1; 809 DPRINTF(("sv_trigger_output: DMA start loop input addr=%x cc=%d\n", 810 (int)DMAADDR(p), dma_count)); 811 812 bus_space_write_4(sc->sc_iot, sc->sc_dmaa_ioh, SV_DMA_ADDR0, 813 DMAADDR(p)); 814 bus_space_write_4(sc->sc_iot, sc->sc_dmaa_ioh, SV_DMA_COUNT0, 815 dma_count); 816 bus_space_write_1(sc->sc_iot, sc->sc_dmaa_ioh, SV_DMA_MODE, 817 DMA37MD_READ | DMA37MD_LOOP); 818 819 DPRINTF(("sv_trigger_output: current addr=%x\n", 820 bus_space_read_4(sc->sc_iot, sc->sc_dmaa_ioh, SV_DMA_ADDR0))); 821 822 dma_count = blksize - 1; 823 824 sv_write_indirect(sc, SV_DMAA_COUNT1, dma_count >> 8); 825 sv_write_indirect(sc, SV_DMAA_COUNT0, dma_count & 0xFF); 826 827 mode = sv_read_indirect(sc, SV_PLAY_RECORD_ENABLE); 828 sv_write_indirect(sc, SV_PLAY_RECORD_ENABLE, mode | SV_PLAY_ENABLE); 829 830 return 0; 831 } 832 833 static int 834 sv_trigger_input(void *addr, void *start, void *end, int blksize, 835 void (*intr)(void *), void *arg, const audio_params_t *param) 836 { 837 struct sv_softc *sc; 838 struct sv_dma *p; 839 uint8_t mode; 840 int dma_count; 841 842 DPRINTFN(1, ("sv_trigger_input: sc=%p start=%p end=%p blksize=%d " 843 "intr=%p(%p)\n", addr, start, end, blksize, intr, arg)); 844 sc = addr; 845 sc->sc_rintr = intr; 846 sc->sc_rarg = arg; 847 848 mode = sv_read_indirect(sc, SV_DMA_DATA_FORMAT); 849 mode &= ~(SV_DMAC_FORMAT16 | SV_DMAC_STEREO); 850 if (param->precision == 16) 851 mode |= SV_DMAC_FORMAT16; 852 if (param->channels == 2) 853 mode |= SV_DMAC_STEREO; 854 sv_write_indirect(sc, SV_DMA_DATA_FORMAT, mode); 855 856 for (p = sc->sc_dmas; p && KERNADDR(p) != start; p = p->next) 857 continue; 858 if (!p) { 859 printf("sv_trigger_input: bad addr %p\n", start); 860 return EINVAL; 861 } 862 863 dma_count = (((char *)end - (char *)start) >> 1) - 1; 864 DPRINTF(("sv_trigger_input: DMA start loop input addr=%x cc=%d\n", 865 (int)DMAADDR(p), dma_count)); 866 867 bus_space_write_4(sc->sc_iot, sc->sc_dmac_ioh, SV_DMA_ADDR0, 868 DMAADDR(p)); 869 bus_space_write_4(sc->sc_iot, sc->sc_dmac_ioh, SV_DMA_COUNT0, 870 dma_count); 871 bus_space_write_1(sc->sc_iot, sc->sc_dmac_ioh, SV_DMA_MODE, 872 DMA37MD_WRITE | DMA37MD_LOOP); 873 874 DPRINTF(("sv_trigger_input: current addr=%x\n", 875 bus_space_read_4(sc->sc_iot, sc->sc_dmac_ioh, SV_DMA_ADDR0))); 876 877 dma_count = (blksize >> 1) - 1; 878 879 sv_write_indirect(sc, SV_DMAC_COUNT1, dma_count >> 8); 880 sv_write_indirect(sc, SV_DMAC_COUNT0, dma_count & 0xFF); 881 882 mode = sv_read_indirect(sc, SV_PLAY_RECORD_ENABLE); 883 sv_write_indirect(sc, SV_PLAY_RECORD_ENABLE, mode | SV_RECORD_ENABLE); 884 885 return 0; 886 } 887 888 static int 889 sv_halt_output(void *addr) 890 { 891 struct sv_softc *sc; 892 uint8_t mode; 893 894 DPRINTF(("sv: sv_halt_output\n")); 895 sc = addr; 896 mode = sv_read_indirect(sc, SV_PLAY_RECORD_ENABLE); 897 sv_write_indirect(sc, SV_PLAY_RECORD_ENABLE, mode & ~SV_PLAY_ENABLE); 898 sc->sc_pintr = 0; 899 900 return 0; 901 } 902 903 static int 904 sv_halt_input(void *addr) 905 { 906 struct sv_softc *sc; 907 uint8_t mode; 908 909 DPRINTF(("sv: sv_halt_input\n")); 910 sc = addr; 911 mode = sv_read_indirect(sc, SV_PLAY_RECORD_ENABLE); 912 sv_write_indirect(sc, SV_PLAY_RECORD_ENABLE, mode & ~SV_RECORD_ENABLE); 913 sc->sc_rintr = 0; 914 915 return 0; 916 } 917 918 static int 919 sv_getdev(void *addr, struct audio_device *retp) 920 { 921 922 *retp = sv_device; 923 return 0; 924 } 925 926 927 /* 928 * Mixer related code is here 929 * 930 */ 931 932 #define SV_INPUT_CLASS 0 933 #define SV_OUTPUT_CLASS 1 934 #define SV_RECORD_CLASS 2 935 936 #define SV_LAST_CLASS 2 937 938 static const char *mixer_classes[] = 939 { AudioCinputs, AudioCoutputs, AudioCrecord }; 940 941 static const struct { 942 uint8_t l_port; 943 uint8_t r_port; 944 uint8_t mask; 945 uint8_t class; 946 const char *audio; 947 } ports[] = { 948 { SV_LEFT_AUX1_INPUT_CONTROL, SV_RIGHT_AUX1_INPUT_CONTROL, SV_AUX1_MASK, 949 SV_INPUT_CLASS, "aux1" }, 950 { SV_LEFT_CD_INPUT_CONTROL, SV_RIGHT_CD_INPUT_CONTROL, SV_CD_MASK, 951 SV_INPUT_CLASS, AudioNcd }, 952 { SV_LEFT_LINE_IN_INPUT_CONTROL, SV_RIGHT_LINE_IN_INPUT_CONTROL, SV_LINE_IN_MASK, 953 SV_INPUT_CLASS, AudioNline }, 954 { SV_MIC_INPUT_CONTROL, 0, SV_MIC_MASK, SV_INPUT_CLASS, AudioNmicrophone }, 955 { SV_LEFT_SYNTH_INPUT_CONTROL, SV_RIGHT_SYNTH_INPUT_CONTROL, 956 SV_SYNTH_MASK, SV_INPUT_CLASS, AudioNfmsynth }, 957 { SV_LEFT_AUX2_INPUT_CONTROL, SV_RIGHT_AUX2_INPUT_CONTROL, SV_AUX2_MASK, 958 SV_INPUT_CLASS, "aux2" }, 959 { SV_LEFT_PCM_INPUT_CONTROL, SV_RIGHT_PCM_INPUT_CONTROL, SV_PCM_MASK, 960 SV_INPUT_CLASS, AudioNdac }, 961 { SV_LEFT_MIXER_OUTPUT_CONTROL, SV_RIGHT_MIXER_OUTPUT_CONTROL, 962 SV_MIXER_OUT_MASK, SV_OUTPUT_CLASS, AudioNmaster } 963 }; 964 965 966 static const struct { 967 int idx; 968 const char *name; 969 } record_sources[] = { 970 { SV_REC_CD, AudioNcd }, 971 { SV_REC_DAC, AudioNdac }, 972 { SV_REC_AUX2, "aux2" }, 973 { SV_REC_LINE, AudioNline }, 974 { SV_REC_AUX1, "aux1" }, 975 { SV_REC_MIC, AudioNmicrophone }, 976 { SV_REC_MIXER, AudioNmixerout } 977 }; 978 979 980 #define SV_DEVICES_PER_PORT 2 981 #define SV_FIRST_MIXER (SV_LAST_CLASS + 1) 982 #define SV_LAST_MIXER (SV_DEVICES_PER_PORT * (ARRAY_SIZE(ports)) + SV_LAST_CLASS) 983 #define SV_RECORD_SOURCE (SV_LAST_MIXER + 1) 984 #define SV_MIC_BOOST (SV_LAST_MIXER + 2) 985 #define SV_RECORD_GAIN (SV_LAST_MIXER + 3) 986 #define SV_SRS_MODE (SV_LAST_MIXER + 4) 987 988 static int 989 sv_query_devinfo(void *addr, mixer_devinfo_t *dip) 990 { 991 int i; 992 993 /* It's a class */ 994 if (dip->index <= SV_LAST_CLASS) { 995 dip->type = AUDIO_MIXER_CLASS; 996 dip->mixer_class = dip->index; 997 dip->next = dip->prev = AUDIO_MIXER_LAST; 998 strcpy(dip->label.name, mixer_classes[dip->index]); 999 return 0; 1000 } 1001 1002 if (dip->index >= SV_FIRST_MIXER && 1003 dip->index <= SV_LAST_MIXER) { 1004 int off, mute ,idx; 1005 1006 off = dip->index - SV_FIRST_MIXER; 1007 mute = (off % SV_DEVICES_PER_PORT); 1008 idx = off / SV_DEVICES_PER_PORT; 1009 dip->mixer_class = ports[idx].class; 1010 strcpy(dip->label.name, ports[idx].audio); 1011 1012 if (!mute) { 1013 dip->type = AUDIO_MIXER_VALUE; 1014 dip->prev = AUDIO_MIXER_LAST; 1015 dip->next = dip->index + 1; 1016 1017 if (ports[idx].r_port != 0) 1018 dip->un.v.num_channels = 2; 1019 else 1020 dip->un.v.num_channels = 1; 1021 1022 strcpy(dip->un.v.units.name, AudioNvolume); 1023 } else { 1024 dip->type = AUDIO_MIXER_ENUM; 1025 dip->prev = dip->index - 1; 1026 dip->next = AUDIO_MIXER_LAST; 1027 1028 strcpy(dip->label.name, AudioNmute); 1029 dip->un.e.num_mem = 2; 1030 strcpy(dip->un.e.member[0].label.name, AudioNoff); 1031 dip->un.e.member[0].ord = 0; 1032 strcpy(dip->un.e.member[1].label.name, AudioNon); 1033 dip->un.e.member[1].ord = 1; 1034 } 1035 1036 return 0; 1037 } 1038 1039 switch (dip->index) { 1040 case SV_RECORD_SOURCE: 1041 dip->mixer_class = SV_RECORD_CLASS; 1042 dip->prev = AUDIO_MIXER_LAST; 1043 dip->next = SV_RECORD_GAIN; 1044 strcpy(dip->label.name, AudioNsource); 1045 dip->type = AUDIO_MIXER_ENUM; 1046 1047 dip->un.e.num_mem = ARRAY_SIZE(record_sources); 1048 for (i = 0; i < ARRAY_SIZE(record_sources); i++) { 1049 strcpy(dip->un.e.member[i].label.name, 1050 record_sources[i].name); 1051 dip->un.e.member[i].ord = record_sources[i].idx; 1052 } 1053 return 0; 1054 1055 case SV_RECORD_GAIN: 1056 dip->mixer_class = SV_RECORD_CLASS; 1057 dip->prev = SV_RECORD_SOURCE; 1058 dip->next = AUDIO_MIXER_LAST; 1059 strcpy(dip->label.name, "gain"); 1060 dip->type = AUDIO_MIXER_VALUE; 1061 dip->un.v.num_channels = 1; 1062 strcpy(dip->un.v.units.name, AudioNvolume); 1063 return 0; 1064 1065 case SV_MIC_BOOST: 1066 dip->mixer_class = SV_RECORD_CLASS; 1067 dip->prev = AUDIO_MIXER_LAST; 1068 dip->next = AUDIO_MIXER_LAST; 1069 strcpy(dip->label.name, "micboost"); 1070 goto on_off; 1071 1072 case SV_SRS_MODE: 1073 dip->mixer_class = SV_OUTPUT_CLASS; 1074 dip->prev = dip->next = AUDIO_MIXER_LAST; 1075 strcpy(dip->label.name, AudioNspatial); 1076 1077 on_off: 1078 dip->type = AUDIO_MIXER_ENUM; 1079 dip->un.e.num_mem = 2; 1080 strcpy(dip->un.e.member[0].label.name, AudioNoff); 1081 dip->un.e.member[0].ord = 0; 1082 strcpy(dip->un.e.member[1].label.name, AudioNon); 1083 dip->un.e.member[1].ord = 1; 1084 return 0; 1085 } 1086 1087 return ENXIO; 1088 } 1089 1090 static int 1091 sv_mixer_set_port(void *addr, mixer_ctrl_t *cp) 1092 { 1093 struct sv_softc *sc; 1094 uint8_t reg; 1095 int idx; 1096 1097 sc = addr; 1098 if (cp->dev >= SV_FIRST_MIXER && 1099 cp->dev <= SV_LAST_MIXER) { 1100 int off, mute; 1101 1102 off = cp->dev - SV_FIRST_MIXER; 1103 mute = (off % SV_DEVICES_PER_PORT); 1104 idx = off / SV_DEVICES_PER_PORT; 1105 1106 if (mute) { 1107 if (cp->type != AUDIO_MIXER_ENUM) 1108 return EINVAL; 1109 1110 mutex_spin_enter(&sc->sc_intr_lock); 1111 reg = sv_read_indirect(sc, ports[idx].l_port); 1112 if (cp->un.ord) 1113 reg |= SV_MUTE_BIT; 1114 else 1115 reg &= ~SV_MUTE_BIT; 1116 sv_write_indirect(sc, ports[idx].l_port, reg); 1117 1118 if (ports[idx].r_port) { 1119 reg = sv_read_indirect(sc, ports[idx].r_port); 1120 if (cp->un.ord) 1121 reg |= SV_MUTE_BIT; 1122 else 1123 reg &= ~SV_MUTE_BIT; 1124 sv_write_indirect(sc, ports[idx].r_port, reg); 1125 } 1126 mutex_spin_exit(&sc->sc_intr_lock); 1127 } else { 1128 int lval, rval; 1129 1130 if (cp->type != AUDIO_MIXER_VALUE) 1131 return EINVAL; 1132 1133 if (cp->un.value.num_channels != 1 && 1134 cp->un.value.num_channels != 2) 1135 return (EINVAL); 1136 1137 if (ports[idx].r_port == 0) { 1138 if (cp->un.value.num_channels != 1) 1139 return (EINVAL); 1140 lval = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 1141 rval = 0; /* shut up GCC */ 1142 } else { 1143 if (cp->un.value.num_channels != 2) 1144 return (EINVAL); 1145 1146 lval = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]; 1147 rval = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]; 1148 } 1149 1150 mutex_spin_enter(&sc->sc_intr_lock); 1151 reg = sv_read_indirect(sc, ports[idx].l_port); 1152 reg &= ~(ports[idx].mask); 1153 lval = (AUDIO_MAX_GAIN - lval) * ports[idx].mask / 1154 AUDIO_MAX_GAIN; 1155 reg |= lval; 1156 sv_write_indirect(sc, ports[idx].l_port, reg); 1157 1158 if (ports[idx].r_port != 0) { 1159 reg = sv_read_indirect(sc, ports[idx].r_port); 1160 reg &= ~(ports[idx].mask); 1161 1162 rval = (AUDIO_MAX_GAIN - rval) * ports[idx].mask / 1163 AUDIO_MAX_GAIN; 1164 reg |= rval; 1165 1166 sv_write_indirect(sc, ports[idx].r_port, reg); 1167 } 1168 1169 sv_read_indirect(sc, ports[idx].l_port); 1170 mutex_spin_exit(&sc->sc_intr_lock); 1171 } 1172 1173 return 0; 1174 } 1175 1176 1177 switch (cp->dev) { 1178 case SV_RECORD_SOURCE: 1179 if (cp->type != AUDIO_MIXER_ENUM) 1180 return EINVAL; 1181 1182 for (idx = 0; idx < ARRAY_SIZE(record_sources); idx++) { 1183 if (record_sources[idx].idx == cp->un.ord) 1184 goto found; 1185 } 1186 1187 return EINVAL; 1188 1189 found: 1190 mutex_spin_enter(&sc->sc_intr_lock); 1191 reg = sv_read_indirect(sc, SV_LEFT_ADC_INPUT_CONTROL); 1192 reg &= ~SV_REC_SOURCE_MASK; 1193 reg |= (((cp->un.ord) << SV_REC_SOURCE_SHIFT) & SV_REC_SOURCE_MASK); 1194 sv_write_indirect(sc, SV_LEFT_ADC_INPUT_CONTROL, reg); 1195 1196 reg = sv_read_indirect(sc, SV_RIGHT_ADC_INPUT_CONTROL); 1197 reg &= ~SV_REC_SOURCE_MASK; 1198 reg |= (((cp->un.ord) << SV_REC_SOURCE_SHIFT) & SV_REC_SOURCE_MASK); 1199 sv_write_indirect(sc, SV_RIGHT_ADC_INPUT_CONTROL, reg); 1200 mutex_spin_exit(&sc->sc_intr_lock); 1201 return 0; 1202 1203 case SV_RECORD_GAIN: 1204 { 1205 int val; 1206 1207 if (cp->type != AUDIO_MIXER_VALUE) 1208 return EINVAL; 1209 1210 if (cp->un.value.num_channels != 1) 1211 return EINVAL; 1212 1213 val = (cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] 1214 * SV_REC_GAIN_MASK) / AUDIO_MAX_GAIN; 1215 1216 mutex_spin_enter(&sc->sc_intr_lock); 1217 reg = sv_read_indirect(sc, SV_LEFT_ADC_INPUT_CONTROL); 1218 reg &= ~SV_REC_GAIN_MASK; 1219 reg |= val; 1220 sv_write_indirect(sc, SV_LEFT_ADC_INPUT_CONTROL, reg); 1221 1222 reg = sv_read_indirect(sc, SV_RIGHT_ADC_INPUT_CONTROL); 1223 reg &= ~SV_REC_GAIN_MASK; 1224 reg |= val; 1225 sv_write_indirect(sc, SV_RIGHT_ADC_INPUT_CONTROL, reg); 1226 mutex_spin_exit(&sc->sc_intr_lock); 1227 } 1228 return (0); 1229 1230 case SV_MIC_BOOST: 1231 if (cp->type != AUDIO_MIXER_ENUM) 1232 return EINVAL; 1233 1234 mutex_spin_enter(&sc->sc_intr_lock); 1235 reg = sv_read_indirect(sc, SV_LEFT_ADC_INPUT_CONTROL); 1236 if (cp->un.ord) { 1237 reg |= SV_MIC_BOOST_BIT; 1238 } else { 1239 reg &= ~SV_MIC_BOOST_BIT; 1240 } 1241 1242 sv_write_indirect(sc, SV_LEFT_ADC_INPUT_CONTROL, reg); 1243 mutex_spin_exit(&sc->sc_intr_lock); 1244 return 0; 1245 1246 case SV_SRS_MODE: 1247 if (cp->type != AUDIO_MIXER_ENUM) 1248 return EINVAL; 1249 1250 mutex_spin_enter(&sc->sc_intr_lock); 1251 reg = sv_read_indirect(sc, SV_SRS_SPACE_CONTROL); 1252 if (cp->un.ord) { 1253 reg &= ~SV_SRS_SPACE_ONOFF; 1254 } else { 1255 reg |= SV_SRS_SPACE_ONOFF; 1256 } 1257 1258 sv_write_indirect(sc, SV_SRS_SPACE_CONTROL, reg); 1259 mutex_spin_exit(&sc->sc_intr_lock); 1260 return 0; 1261 } 1262 1263 return EINVAL; 1264 } 1265 1266 static int 1267 sv_mixer_get_port(void *addr, mixer_ctrl_t *cp) 1268 { 1269 struct sv_softc *sc; 1270 int val, error; 1271 uint8_t reg; 1272 1273 sc = addr; 1274 error = 0; 1275 1276 mutex_spin_enter(&sc->sc_intr_lock); 1277 1278 if (cp->dev >= SV_FIRST_MIXER && 1279 cp->dev <= SV_LAST_MIXER) { 1280 int off = cp->dev - SV_FIRST_MIXER; 1281 int mute = (off % 2); 1282 int idx = off / 2; 1283 1284 off = cp->dev - SV_FIRST_MIXER; 1285 mute = (off % 2); 1286 idx = off / 2; 1287 if (mute) { 1288 if (cp->type != AUDIO_MIXER_ENUM) 1289 error = EINVAL; 1290 else { 1291 reg = sv_read_indirect(sc, ports[idx].l_port); 1292 cp->un.ord = ((reg & SV_MUTE_BIT) ? 1 : 0); 1293 } 1294 } else { 1295 if (cp->type != AUDIO_MIXER_VALUE || 1296 (cp->un.value.num_channels != 1 && 1297 cp->un.value.num_channels != 2) || 1298 ((ports[idx].r_port == 0 && 1299 cp->un.value.num_channels != 1) || 1300 (ports[idx].r_port != 0 && 1301 cp->un.value.num_channels != 2))) 1302 error = EINVAL; 1303 else { 1304 reg = sv_read_indirect(sc, ports[idx].l_port); 1305 reg &= ports[idx].mask; 1306 1307 val = AUDIO_MAX_GAIN - 1308 ((reg * AUDIO_MAX_GAIN) / ports[idx].mask); 1309 1310 if (ports[idx].r_port != 0) { 1311 cp->un.value.level 1312 [AUDIO_MIXER_LEVEL_LEFT] = val; 1313 1314 reg = sv_read_indirect(sc, 1315 ports[idx].r_port); 1316 reg &= ports[idx].mask; 1317 1318 val = AUDIO_MAX_GAIN - 1319 ((reg * AUDIO_MAX_GAIN) 1320 / ports[idx].mask); 1321 cp->un.value.level 1322 [AUDIO_MIXER_LEVEL_RIGHT] = val; 1323 } else 1324 cp->un.value.level 1325 [AUDIO_MIXER_LEVEL_MONO] = val; 1326 } 1327 } 1328 1329 return error; 1330 } 1331 1332 switch (cp->dev) { 1333 case SV_RECORD_SOURCE: 1334 if (cp->type != AUDIO_MIXER_ENUM) { 1335 error = EINVAL; 1336 break; 1337 } 1338 1339 reg = sv_read_indirect(sc, SV_LEFT_ADC_INPUT_CONTROL); 1340 cp->un.ord = ((reg & SV_REC_SOURCE_MASK) >> SV_REC_SOURCE_SHIFT); 1341 1342 break; 1343 1344 case SV_RECORD_GAIN: 1345 if (cp->type != AUDIO_MIXER_VALUE) { 1346 error = EINVAL; 1347 break; 1348 } 1349 if (cp->un.value.num_channels != 1) { 1350 error = EINVAL; 1351 break; 1352 } 1353 1354 reg = sv_read_indirect(sc, SV_LEFT_ADC_INPUT_CONTROL) & SV_REC_GAIN_MASK; 1355 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 1356 (((unsigned int)reg) * AUDIO_MAX_GAIN) / SV_REC_GAIN_MASK; 1357 1358 break; 1359 1360 case SV_MIC_BOOST: 1361 if (cp->type != AUDIO_MIXER_ENUM) { 1362 error = EINVAL; 1363 break; 1364 } 1365 reg = sv_read_indirect(sc, SV_LEFT_ADC_INPUT_CONTROL); 1366 cp->un.ord = ((reg & SV_MIC_BOOST_BIT) ? 1 : 0); 1367 break; 1368 1369 case SV_SRS_MODE: 1370 if (cp->type != AUDIO_MIXER_ENUM) { 1371 error = EINVAL; 1372 break; 1373 } 1374 reg = sv_read_indirect(sc, SV_SRS_SPACE_CONTROL); 1375 cp->un.ord = ((reg & SV_SRS_SPACE_ONOFF) ? 0 : 1); 1376 break; 1377 default: 1378 error = EINVAL; 1379 break; 1380 } 1381 1382 mutex_spin_exit(&sc->sc_intr_lock); 1383 return error; 1384 } 1385 1386 static void 1387 sv_init_mixer(struct sv_softc *sc) 1388 { 1389 mixer_ctrl_t cp; 1390 int i; 1391 1392 cp.type = AUDIO_MIXER_ENUM; 1393 cp.dev = SV_SRS_MODE; 1394 cp.un.ord = 0; 1395 1396 sv_mixer_set_port(sc, &cp); 1397 1398 for (i = 0; i < ARRAY_SIZE(ports); i++) { 1399 if (!strcmp(ports[i].audio, AudioNdac)) { 1400 cp.type = AUDIO_MIXER_ENUM; 1401 cp.dev = SV_FIRST_MIXER + i * SV_DEVICES_PER_PORT + 1; 1402 cp.un.ord = 0; 1403 sv_mixer_set_port(sc, &cp); 1404 break; 1405 } 1406 } 1407 } 1408 1409 static void * 1410 sv_malloc(void *addr, int direction, size_t size) 1411 { 1412 struct sv_softc *sc; 1413 struct sv_dma *p; 1414 int error; 1415 1416 sc = addr; 1417 p = kmem_alloc(sizeof(*p), KM_SLEEP); 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