1 /* $OpenBSD: yds.c,v 1.3 2001/06/12 15:40:33 niklas Exp $ */ 2 /* $NetBSD: yds.c,v 1.5 2001/05/21 23:55:04 minoura Exp $ */ 3 4 /* 5 * Copyright (c) 2000, 2001 Kazuki Sakamoto and Minoura Makoto. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /* 30 * Yamaha YMF724[B-F]/740[B-C]/744/754 31 * 32 * Documentation links: 33 * - ftp://ftp.alsa-project.org/pub/manuals/yamaha/ 34 * - ftp://ftp.alsa-project.org/pub/manuals/yamaha/pci/ 35 * 36 * TODO: 37 * - FM synth volume (difficult: mixed before ac97) 38 * - Digital in/out (SPDIF) support 39 * - Effect?? 40 */ 41 42 #include <sys/param.h> 43 #include <sys/systm.h> 44 #include <sys/kernel.h> 45 #include <sys/malloc.h> 46 #include <sys/device.h> 47 #include <sys/proc.h> 48 #include <sys/queue.h> 49 #include <sys/fcntl.h> 50 51 #include <dev/pci/pcidevs.h> 52 #include <dev/pci/pcireg.h> 53 #include <dev/pci/pcivar.h> 54 55 #include <sys/audioio.h> 56 #include <dev/audio_if.h> 57 #include <dev/midi_if.h> 58 #include <dev/mulaw.h> 59 #include <dev/auconv.h> 60 #include <dev/ic/ac97.h> 61 #include <dev/ic/mpuvar.h> 62 63 #include <machine/bus.h> 64 #include <machine/intr.h> 65 66 #include <dev/microcode/yds/yds_hwmcode.h> 67 68 #include <dev/pci/ydsreg.h> 69 #include <dev/pci/ydsvar.h> 70 71 /* Debug */ 72 #undef YDS_USE_REC_SLOT 73 #define YDS_USE_P44 74 75 #ifdef AUDIO_DEBUG 76 # define DPRINTF(x) if (ydsdebug) printf x 77 # define DPRINTFN(n,x) if (ydsdebug>(n)) printf x 78 int ydsdebug = 0; 79 #else 80 # define DPRINTF(x) 81 # define DPRINTFN(n,x) 82 #endif 83 #ifdef YDS_USE_REC_SLOT 84 # define YDS_INPUT_SLOT 0 /* REC slot = ADC + loopbacks */ 85 #else 86 # define YDS_INPUT_SLOT 1 /* ADC slot */ 87 #endif 88 89 int yds_match __P((struct device *, void *, void *)); 90 void yds_attach __P((struct device *, struct device *, void *)); 91 int yds_intr __P((void *)); 92 93 #define DMAADDR(p) ((p)->map->dm_segs[0].ds_addr) 94 #define KERNADDR(p) ((void *)((p)->addr)) 95 96 int yds_allocmem __P((struct yds_softc *, size_t, size_t, struct yds_dma *)); 97 int yds_freemem __P((struct yds_softc *, struct yds_dma *)); 98 99 #ifndef AUDIO_DEBUG 100 #define YWRITE1(sc, r, x) bus_space_write_1((sc)->memt, (sc)->memh, (r), (x)) 101 #define YWRITE2(sc, r, x) bus_space_write_2((sc)->memt, (sc)->memh, (r), (x)) 102 #define YWRITE4(sc, r, x) bus_space_write_4((sc)->memt, (sc)->memh, (r), (x)) 103 #define YREAD1(sc, r) bus_space_read_1((sc)->memt, (sc)->memh, (r)) 104 #define YREAD2(sc, r) bus_space_read_2((sc)->memt, (sc)->memh, (r)) 105 #define YREAD4(sc, r) bus_space_read_4((sc)->memt, (sc)->memh, (r)) 106 #else 107 108 u_int16_t YREAD2(struct yds_softc *sc,bus_size_t r); 109 u_int32_t YREAD4(struct yds_softc *sc,bus_size_t r); 110 void YWRITE1(struct yds_softc *sc,bus_size_t r,u_int8_t x); 111 void YWRITE2(struct yds_softc *sc,bus_size_t r,u_int16_t x); 112 void YWRITE4(struct yds_softc *sc,bus_size_t r,u_int32_t x); 113 114 u_int16_t YREAD2(struct yds_softc *sc,bus_size_t r) 115 { 116 DPRINTFN(5, (" YREAD2(0x%lX)\n",(unsigned long)r)); 117 return bus_space_read_2(sc->memt,sc->memh,r); 118 } 119 u_int32_t YREAD4(struct yds_softc *sc,bus_size_t r) 120 { 121 DPRINTFN(5, (" YREAD4(0x%lX)\n",(unsigned long)r)); 122 return bus_space_read_4(sc->memt,sc->memh,r); 123 } 124 void YWRITE1(struct yds_softc *sc,bus_size_t r,u_int8_t x) 125 { 126 DPRINTFN(5, (" YWRITE1(0x%lX,0x%lX)\n",(unsigned long)r,(unsigned long)x)); 127 bus_space_write_1(sc->memt,sc->memh,r,x); 128 } 129 void YWRITE2(struct yds_softc *sc,bus_size_t r,u_int16_t x) 130 { 131 DPRINTFN(5, (" YWRITE2(0x%lX,0x%lX)\n",(unsigned long)r,(unsigned long)x)); 132 bus_space_write_2(sc->memt,sc->memh,r,x); 133 } 134 void YWRITE4(struct yds_softc *sc,bus_size_t r,u_int32_t x) 135 { 136 DPRINTFN(5, (" YWRITE4(0x%lX,0x%lX)\n",(unsigned long)r,(unsigned long)x)); 137 bus_space_write_4(sc->memt,sc->memh,r,x); 138 } 139 #endif 140 141 #define YWRITEREGION4(sc, r, x, c) \ 142 bus_space_write_region_4((sc)->memt, (sc)->memh, (r), (x), (c) / 4) 143 144 struct cfdriver yds_cd = { 145 NULL, "yds", DV_DULL 146 }; 147 148 struct cfattach yds_ca = { 149 sizeof(struct yds_softc), yds_match, yds_attach 150 }; 151 152 int yds_open __P((void *, int)); 153 void yds_close __P((void *)); 154 int yds_query_encoding __P((void *, struct audio_encoding *)); 155 int yds_set_params __P((void *, int, int, struct audio_params *, struct audio_params *)); 156 int yds_round_blocksize __P((void *, int)); 157 int yds_trigger_output __P((void *, void *, void *, int, void (*)(void *), 158 void *, struct audio_params *)); 159 int yds_trigger_input __P((void *, void *, void *, int, void (*)(void *), 160 void *, struct audio_params *)); 161 int yds_halt_output __P((void *)); 162 int yds_halt_input __P((void *)); 163 int yds_getdev __P((void *, struct audio_device *)); 164 int yds_mixer_set_port __P((void *, mixer_ctrl_t *)); 165 int yds_mixer_get_port __P((void *, mixer_ctrl_t *)); 166 void *yds_malloc __P((void *, u_long, int, int)); 167 void yds_free __P((void *, void *, int)); 168 u_long yds_round_buffersize __P((void *, u_long)); 169 int yds_mappage __P((void *, void *, int, int)); 170 int yds_get_props __P((void *)); 171 int yds_query_devinfo __P((void *addr, mixer_devinfo_t *dip)); 172 173 int yds_attach_codec __P((void *sc, struct ac97_codec_if *)); 174 int yds_read_codec __P((void *sc, u_int8_t a, u_int16_t *d)); 175 int yds_write_codec __P((void *sc, u_int8_t a, u_int16_t d)); 176 void yds_reset_codec __P((void *sc)); 177 int yds_get_portnum_by_name __P((struct yds_softc *, char *, char *, 178 char *)); 179 180 static u_int yds_get_dstype __P((int)); 181 static int yds_download_mcode __P((struct yds_softc *)); 182 static int yds_allocate_slots __P((struct yds_softc *)); 183 static void yds_configure_legacy __P((struct device *arg)); 184 static void yds_enable_dsp __P((struct yds_softc *)); 185 static int yds_disable_dsp __P((struct yds_softc *)); 186 static int yds_ready_codec __P((struct yds_codec_softc *)); 187 static int yds_halt __P((struct yds_softc *)); 188 static u_int32_t yds_get_lpfq __P((u_int)); 189 static u_int32_t yds_get_lpfk __P((u_int)); 190 static struct yds_dma *yds_find_dma __P((struct yds_softc *, void *)); 191 192 #ifdef AUDIO_DEBUG 193 static void yds_dump_play_slot __P((struct yds_softc *, int)); 194 #define YDS_DUMP_PLAY_SLOT(n,sc,bank) \ 195 if (ydsdebug > (n)) yds_dump_play_slot(sc, bank) 196 #else 197 #define YDS_DUMP_PLAY_SLOT(n,sc,bank) 198 #endif /* AUDIO_DEBUG */ 199 200 static struct audio_hw_if yds_hw_if = { 201 yds_open, 202 yds_close, 203 NULL, 204 yds_query_encoding, 205 yds_set_params, 206 yds_round_blocksize, 207 NULL, 208 NULL, 209 NULL, 210 NULL, 211 NULL, 212 yds_halt_output, 213 yds_halt_input, 214 NULL, 215 yds_getdev, 216 NULL, 217 yds_mixer_set_port, 218 yds_mixer_get_port, 219 yds_query_devinfo, 220 yds_malloc, 221 yds_free, 222 yds_round_buffersize, 223 yds_mappage, 224 yds_get_props, 225 yds_trigger_output, 226 yds_trigger_input, 227 }; 228 229 struct audio_device yds_device = { 230 "Yamaha DS-1", 231 "", 232 "yds" 233 }; 234 235 const static struct { 236 u_int id; 237 u_int flags; 238 #define YDS_CAP_MCODE_1 0x0001 239 #define YDS_CAP_MCODE_1E 0x0002 240 #define YDS_CAP_LEGACY_SELECTABLE 0x0004 241 #define YDS_CAP_LEGACY_FLEXIBLE 0x0008 242 #define YDS_CAP_HAS_P44 0x0010 243 } yds_chip_capability_list[] = { 244 { PCI_PRODUCT_YAMAHA_YMF724, 245 YDS_CAP_MCODE_1|YDS_CAP_LEGACY_SELECTABLE }, 246 /* 740[C] has only 32 slots. But anyway we use only 2 */ 247 { PCI_PRODUCT_YAMAHA_YMF740, 248 YDS_CAP_MCODE_1|YDS_CAP_LEGACY_SELECTABLE }, /* XXX NOT TESTED */ 249 { PCI_PRODUCT_YAMAHA_YMF740C, 250 YDS_CAP_MCODE_1E|YDS_CAP_LEGACY_SELECTABLE }, 251 { PCI_PRODUCT_YAMAHA_YMF724F, 252 YDS_CAP_MCODE_1E|YDS_CAP_LEGACY_SELECTABLE }, 253 { PCI_PRODUCT_YAMAHA_YMF744, 254 YDS_CAP_MCODE_1E|YDS_CAP_LEGACY_FLEXIBLE }, 255 { PCI_PRODUCT_YAMAHA_YMF754, 256 YDS_CAP_MCODE_1E|YDS_CAP_LEGACY_FLEXIBLE|YDS_CAP_HAS_P44 }, 257 /* How about 734/737/738?? */ 258 { 0, 0 } 259 }; 260 #ifdef AUDIO_DEBUG 261 #define YDS_CAP_BITS "\020\005P44\004LEGFLEX\003LEGSEL\002MCODE1E\001MCODE1" 262 #endif 263 264 #ifdef AUDIO_DEBUG 265 static void 266 yds_dump_play_slot(sc, bank) 267 struct yds_softc *sc; 268 int bank; 269 { 270 int i, j; 271 u_int32_t *p; 272 u_int32_t num; 273 struct yds_dma *dma; 274 275 for (i = 0; i < N_PLAY_SLOTS; i++) { 276 printf("pbankp[%d] = %p,", i*2, sc->pbankp[i*2]); 277 printf("pbankp[%d] = %p\n", i*2+1, sc->pbankp[i*2+1]); 278 } 279 280 p = (u_int32_t*)sc->ptbl; 281 for (i = 0; i < N_PLAY_SLOTS+1; i++) { 282 printf("ptbl + %d:0x%x\n", i, *p); 283 p++; 284 } 285 286 num = *(u_int32_t*)sc->ptbl; 287 printf("num = %d\n", num); 288 289 for (i = 0; i < num; i++) { 290 291 p = (u_int32_t *)sc->pbankp[i]; 292 293 dma = yds_find_dma(sc,(void*)p); 294 295 printf(" pbankp[%d] : %p(%p)\n", 296 i, p, (void*)vtophys((vaddr_t)p)); 297 for (j = 0; j < sizeof(struct play_slot_ctrl_bank) / 298 sizeof(u_int32_t); j++) { 299 printf(" 0x%02x: 0x%08x\n", 300 (unsigned) (j * sizeof(u_int32_t)), 301 (unsigned) *p++); 302 } 303 /* 304 p = (u_int32_t *)sc->pbankp[i*2 + 1]; 305 printf(" pbankp[%d] : %p\n", i*2 + 1, p); 306 for (j = 0; j < sizeof(struct play_slot_ctrl_bank) / 307 sizeof(u_int32_t); j++) { 308 printf(" 0x%02x: 0x%08x\n", 309 j * sizeof(u_int32_t), *p++); 310 delay(1); 311 } 312 */ 313 } 314 } 315 #endif /* AUDIO_DEBUG */ 316 317 static u_int 318 yds_get_dstype(id) 319 int id; 320 { 321 int i; 322 323 for (i = 0; yds_chip_capability_list[i].id; i++) { 324 if (PCI_PRODUCT(id) == yds_chip_capability_list[i].id) 325 return yds_chip_capability_list[i].flags; 326 } 327 328 return -1; 329 } 330 331 static int 332 yds_download_mcode(sc) 333 struct yds_softc *sc; 334 { 335 u_int ctrl; 336 const u_int32_t *p; 337 size_t size; 338 int dstype; 339 340 static struct { 341 const u_int32_t *mcode; 342 size_t size; 343 } ctrls[] = { 344 {yds_ds1_ctrl_mcode, sizeof(yds_ds1_ctrl_mcode)}, 345 {yds_ds1e_ctrl_mcode, sizeof(yds_ds1e_ctrl_mcode)}, 346 }; 347 348 if (sc->sc_flags & YDS_CAP_MCODE_1) 349 dstype = YDS_DS_1; 350 else if (sc->sc_flags & YDS_CAP_MCODE_1E) 351 dstype = YDS_DS_1E; 352 else 353 return 1; /* unknown */ 354 355 if (yds_disable_dsp(sc)) 356 return 1; 357 358 /* Software reset */ 359 YWRITE4(sc, YDS_MODE, YDS_MODE_RESET); 360 YWRITE4(sc, YDS_MODE, 0); 361 362 YWRITE4(sc, YDS_MAPOF_REC, 0); 363 YWRITE4(sc, YDS_MAPOF_EFFECT, 0); 364 YWRITE4(sc, YDS_PLAY_CTRLBASE, 0); 365 YWRITE4(sc, YDS_REC_CTRLBASE, 0); 366 YWRITE4(sc, YDS_EFFECT_CTRLBASE, 0); 367 YWRITE4(sc, YDS_WORK_BASE, 0); 368 369 ctrl = YREAD2(sc, YDS_GLOBAL_CONTROL); 370 YWRITE2(sc, YDS_GLOBAL_CONTROL, 371 ctrl & ~0x0007); 372 373 /* Download DSP microcode. */ 374 p = yds_dsp_mcode; 375 size = sizeof(yds_dsp_mcode); 376 YWRITEREGION4(sc, YDS_DSP_INSTRAM, p, size); 377 378 /* Download CONTROL microcode. */ 379 p = ctrls[dstype].mcode; 380 size = ctrls[dstype].size; 381 YWRITEREGION4(sc, YDS_CTRL_INSTRAM, p, size); 382 383 yds_enable_dsp(sc); 384 delay(10*1000); /* nessesary on my 724F (??) */ 385 386 return 0; 387 } 388 389 static int 390 yds_allocate_slots(sc) 391 struct yds_softc *sc; 392 { 393 size_t pcs, rcs, ecs, ws, memsize; 394 void *mp; 395 u_int32_t da; /* DMA address */ 396 char *va; /* KVA */ 397 off_t cb; 398 int i; 399 struct yds_dma *p; 400 401 /* Alloc DSP Control Data */ 402 pcs = YREAD4(sc, YDS_PLAY_CTRLSIZE) * sizeof(u_int32_t); 403 rcs = YREAD4(sc, YDS_REC_CTRLSIZE) * sizeof(u_int32_t); 404 ecs = YREAD4(sc, YDS_EFFECT_CTRLSIZE) * sizeof(u_int32_t); 405 ws = WORK_SIZE; 406 YWRITE4(sc, YDS_WORK_SIZE, ws / sizeof(u_int32_t)); 407 408 DPRINTF(("play control size : %d\n", (unsigned int)pcs)); 409 DPRINTF(("rec control size : %d\n", (unsigned int)rcs)); 410 DPRINTF(("eff control size : %d\n", (unsigned int)ecs)); 411 DPRINTF(("work size : %d\n", (unsigned int)ws)); 412 #ifdef DIAGNOSTIC 413 if (pcs != sizeof(struct play_slot_ctrl_bank)) { 414 printf("%s: invalid play slot ctrldata %d != %d\n", 415 sc->sc_dev.dv_xname, (unsigned int)pcs, 416 (unsigned int)sizeof(struct play_slot_ctrl_bank)); 417 } 418 if (rcs != sizeof(struct rec_slot_ctrl_bank)) { 419 printf("%s: invalid rec slot ctrldata %d != %d\n", 420 sc->sc_dev.dv_xname, (unsigned int)rcs, 421 (unsigned int)sizeof(struct rec_slot_ctrl_bank)); 422 } 423 #endif 424 425 memsize = N_PLAY_SLOTS*N_PLAY_SLOT_CTRL_BANK*pcs + 426 N_REC_SLOT_CTRL*N_REC_SLOT_CTRL_BANK*rcs + ws; 427 memsize += (N_PLAY_SLOTS+1)*sizeof(u_int32_t); 428 429 p = &sc->sc_ctrldata; 430 i = yds_allocmem(sc, memsize, 16, p); 431 if (i) { 432 printf("%s: couldn't alloc/map DSP DMA buffer, reason %d\n", 433 sc->sc_dev.dv_xname, i); 434 free(p, M_DEVBUF); 435 return 1; 436 } 437 mp = KERNADDR(p); 438 da = DMAADDR(p); 439 440 DPRINTF(("mp:%p, DMA addr:%p\n", 441 mp, (void*) sc->sc_ctrldata.map->dm_segs[0].ds_addr)); 442 443 bzero(mp, memsize); 444 445 /* Work space */ 446 cb = 0; 447 va = (u_int8_t*)mp; 448 YWRITE4(sc, YDS_WORK_BASE, da + cb); 449 cb += ws; 450 451 /* Play control data table */ 452 sc->ptbl = (u_int32_t *)(va + cb); 453 sc->ptbloff = cb; 454 YWRITE4(sc, YDS_PLAY_CTRLBASE, da + cb); 455 cb += (N_PLAY_SLOT_CTRL + 1) * sizeof(u_int32_t); 456 457 /* Record slot control data */ 458 sc->rbank = (struct rec_slot_ctrl_bank *)(va + cb); 459 YWRITE4(sc, YDS_REC_CTRLBASE, da + cb); 460 sc->rbankoff = cb; 461 cb += N_REC_SLOT_CTRL * N_REC_SLOT_CTRL_BANK * rcs; 462 463 #if 0 464 /* Effect slot control data -- unused */ 465 YWRITE4(sc, YDS_EFFECT_CTRLBASE, da + cb); 466 cb += N_EFFECT_SLOT_CTRL * N_EFFECT_SLOT_CTRL_BANK * ecs; 467 #endif 468 469 /* Play slot control data */ 470 sc->pbankoff = da + cb; 471 for (i=0; i<N_PLAY_SLOT_CTRL; i++) { 472 sc->pbankp[i*2] = (struct play_slot_ctrl_bank *)(va + cb); 473 *(sc->ptbl + i+1) = da + cb; 474 cb += pcs; 475 476 sc->pbankp[i*2+1] = (struct play_slot_ctrl_bank *)(va + cb); 477 cb += pcs; 478 } 479 /* Sync play control data table */ 480 bus_dmamap_sync(sc->sc_dmatag, p->map, BUS_DMASYNC_PREWRITE); 481 482 return 0; 483 } 484 485 static void 486 yds_enable_dsp(sc) 487 struct yds_softc *sc; 488 { 489 YWRITE4(sc, YDS_CONFIG, YDS_DSP_SETUP); 490 } 491 492 static int 493 yds_disable_dsp(sc) 494 struct yds_softc *sc; 495 { 496 int to; 497 u_int32_t data; 498 499 data = YREAD4(sc, YDS_CONFIG); 500 if (data) 501 YWRITE4(sc, YDS_CONFIG, YDS_DSP_DISABLE); 502 503 for (to = 0; to < YDS_WORK_TIMEOUT; to++) { 504 if ((YREAD4(sc, YDS_STATUS) & YDS_STAT_WORK) == 0) 505 return 0; 506 delay(1); 507 } 508 509 return 1; 510 } 511 512 int 513 yds_match(parent, match, aux) 514 struct device *parent; 515 void *match; 516 void *aux; 517 { 518 struct pci_attach_args *pa = (struct pci_attach_args *) aux; 519 520 switch (PCI_VENDOR(pa->pa_id)) { 521 case PCI_VENDOR_YAMAHA: 522 switch (PCI_PRODUCT(pa->pa_id)) { 523 case PCI_PRODUCT_YAMAHA_YMF724: 524 case PCI_PRODUCT_YAMAHA_YMF740: 525 case PCI_PRODUCT_YAMAHA_YMF740C: 526 case PCI_PRODUCT_YAMAHA_YMF724F: 527 case PCI_PRODUCT_YAMAHA_YMF744: 528 case PCI_PRODUCT_YAMAHA_YMF754: 529 /* 734, 737, 738?? */ 530 return (1); 531 } 532 break; 533 } 534 535 return (0); 536 } 537 538 /* 539 * This routine is called after all the ISA devices are configured, 540 * to avoid conflict. 541 */ 542 static void 543 yds_configure_legacy (arg) 544 struct device *arg; 545 #define FLEXIBLE (sc->sc_flags & YDS_CAP_LEGACY_FLEXIBLE) 546 #define SELECTABLE (sc->sc_flags & YDS_CAP_LEGACY_SELECTABLE) 547 { 548 struct yds_softc *sc = (struct yds_softc*) arg; 549 pcireg_t reg; 550 struct device *dev; 551 int i; 552 bus_addr_t opl_addrs[] = {0x388, 0x398, 0x3A0, 0x3A8}; 553 bus_addr_t mpu_addrs[] = {0x330, 0x300, 0x332, 0x334}; 554 555 if (!FLEXIBLE && !SELECTABLE) 556 return; 557 558 reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, YDS_PCI_LEGACY); 559 reg &= ~0x8133c03f; /* these bits are out of interest */ 560 reg |= ((YDS_PCI_EX_LEGACY_IMOD) | 561 (YDS_PCI_LEGACY_FMEN | 562 YDS_PCI_LEGACY_MEN /*| YDS_PCI_LEGACY_MIEN*/)); 563 if (FLEXIBLE) { 564 pci_conf_write(sc->sc_pc, sc->sc_pcitag, YDS_PCI_LEGACY, reg); 565 delay(100*1000); 566 } 567 568 /* Look for OPL */ 569 dev = 0; 570 for (i = 0; i < sizeof(opl_addrs) / sizeof (bus_addr_t); i++) { 571 if (SELECTABLE) { 572 pci_conf_write(sc->sc_pc, sc->sc_pcitag, 573 YDS_PCI_LEGACY, reg | (i << (0+16))); 574 delay(100*1000); /* wait 100ms */ 575 } else 576 pci_conf_write(sc->sc_pc, sc->sc_pcitag, 577 YDS_PCI_FM_BA, opl_addrs[i]); 578 if (bus_space_map(sc->sc_opl_iot, 579 opl_addrs[i], 4, 0, &sc->sc_opl_ioh) == 0) { 580 struct audio_attach_args aa; 581 582 aa.type = AUDIODEV_TYPE_OPL; 583 aa.hwif = aa.hdl = NULL; 584 dev = config_found(&sc->sc_dev, &aa, audioprint); 585 if (dev == 0) 586 bus_space_unmap(sc->sc_opl_iot, 587 sc->sc_opl_ioh, 4); 588 else { 589 if (SELECTABLE) 590 reg |= (i << (0+16)); 591 break; 592 } 593 } 594 } 595 if (dev == 0) { 596 reg &= ~YDS_PCI_LEGACY_FMEN; 597 pci_conf_write(sc->sc_pc, sc->sc_pcitag, 598 YDS_PCI_LEGACY, reg); 599 } else { 600 /* Max. volume */ 601 YWRITE4(sc, YDS_LEGACY_OUT_VOLUME, 0x3fff3fff); 602 YWRITE4(sc, YDS_LEGACY_REC_VOLUME, 0x3fff3fff); 603 } 604 605 /* Look for MPU */ 606 dev = 0; 607 for (i = 0; i < sizeof(mpu_addrs) / sizeof (bus_addr_t); i++) { 608 if (SELECTABLE) 609 pci_conf_write(sc->sc_pc, sc->sc_pcitag, 610 YDS_PCI_LEGACY, reg | (i << (4+16))); 611 else 612 pci_conf_write(sc->sc_pc, sc->sc_pcitag, 613 YDS_PCI_MPU_BA, mpu_addrs[i]); 614 if (bus_space_map(sc->sc_mpu_iot, 615 mpu_addrs[i], 2, 0, &sc->sc_mpu_ioh) == 0) { 616 struct audio_attach_args aa; 617 618 aa.type = AUDIODEV_TYPE_MPU; 619 aa.hwif = aa.hdl = NULL; 620 dev = config_found(&sc->sc_dev, &aa, audioprint); 621 if (dev == 0) 622 bus_space_unmap(sc->sc_mpu_iot, 623 sc->sc_mpu_ioh, 2); 624 else { 625 if (SELECTABLE) 626 reg |= (i << (4+16)); 627 break; 628 } 629 } 630 } 631 if (dev == 0) { 632 reg &= ~(YDS_PCI_LEGACY_MEN | YDS_PCI_LEGACY_MIEN); 633 pci_conf_write(sc->sc_pc, sc->sc_pcitag, 634 YDS_PCI_LEGACY, reg); 635 } 636 sc->sc_mpu = dev; 637 } 638 #undef FLEXIBLE 639 #undef SELECTABLE 640 641 void 642 yds_attach(parent, self, aux) 643 struct device *parent; 644 struct device *self; 645 void *aux; 646 { 647 struct yds_softc *sc = (struct yds_softc *)self; 648 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 649 pci_chipset_tag_t pc = pa->pa_pc; 650 char const *intrstr; 651 pci_intr_handle_t ih; 652 pcireg_t reg; 653 struct yds_codec_softc *codec; 654 mixer_ctrl_t ctl; 655 int i, r, to; 656 int ac97_id2; 657 658 /* Map register to memory */ 659 if (pci_mapreg_map(pa, YDS_PCI_MBA, PCI_MAPREG_TYPE_MEM, 0, 660 &sc->memt, &sc->memh, NULL, NULL, 0)) { 661 printf("%s: can't map memory space\n", sc->sc_dev.dv_xname); 662 return; 663 } 664 665 /* Map and establish the interrupt. */ 666 if (pci_intr_map(pc, pa->pa_intrtag, pa->pa_intrpin, pa->pa_intrline, 667 &ih)) { 668 printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname); 669 return; 670 } 671 intrstr = pci_intr_string(pc, ih); 672 sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO, yds_intr, sc, 673 self->dv_xname); 674 if (sc->sc_ih == NULL) { 675 printf("%s: couldn't establish interrupt", 676 sc->sc_dev.dv_xname); 677 if (intrstr != NULL) 678 printf(" at %s", intrstr); 679 printf("\n"); 680 return; 681 } 682 printf(": %s\n", intrstr); 683 684 sc->sc_dmatag = pa->pa_dmat; 685 sc->sc_pc = pc; 686 sc->sc_pcitag = pa->pa_tag; 687 sc->sc_id = pa->pa_id; 688 sc->sc_flags = yds_get_dstype(sc->sc_id); 689 #ifdef AUDIO_DEBUG 690 if (ydsdebug) { 691 char bits[80]; 692 693 printf("%s: chip has %s\n", sc->sc_dev.dv_xname, 694 bitmask_snprintf(sc->sc_flags, YDS_CAP_BITS, bits, 695 sizeof(bits))); 696 } 697 #endif 698 699 /* Disable legacy mode */ 700 reg = pci_conf_read(pc, pa->pa_tag, YDS_PCI_LEGACY); 701 pci_conf_write(pc, pa->pa_tag, YDS_PCI_LEGACY, 702 reg & YDS_PCI_LEGACY_LAD); 703 704 /* Enable the device. */ 705 reg = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); 706 reg |= (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE | 707 PCI_COMMAND_MASTER_ENABLE); 708 pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, reg); 709 reg = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); 710 711 /* Mute all volumes */ 712 for (i = 0x80; i < 0xc0; i += 2) 713 YWRITE2(sc, i, 0); 714 715 /* Download microcode */ 716 if (yds_download_mcode(sc)) { 717 printf("%s: download microcode failed\n", sc->sc_dev.dv_xname); 718 return; 719 } 720 /* Allocate DMA buffers */ 721 if (yds_allocate_slots(sc)) { 722 printf("%s: could not allocate slots\n", sc->sc_dev.dv_xname); 723 return; 724 } 725 726 /* Warm reset */ 727 reg = pci_conf_read(pc, pa->pa_tag, YDS_PCI_DSCTRL); 728 pci_conf_write(pc, pa->pa_tag, YDS_PCI_DSCTRL, reg | YDS_DSCTRL_WRST); 729 delay(50000); 730 731 /* 732 * Detect primary/secondary AC97 733 * YMF754 Hardware Specification Rev 1.01 page 24 734 */ 735 reg = pci_conf_read(pc, pa->pa_tag, YDS_PCI_DSCTRL); 736 pci_conf_write(pc, pa->pa_tag, YDS_PCI_DSCTRL, 737 reg & ~YDS_DSCTRL_CRST); 738 delay(400000); /* Needed for 740C. */ 739 740 /* Primary */ 741 for (to = 0; to < AC97_TIMEOUT; to++) { 742 if ((YREAD2(sc, AC97_STAT_ADDR1) & AC97_BUSY) == 0) 743 break; 744 delay(1); 745 } 746 if (to == AC97_TIMEOUT) { 747 printf("%s: no AC97 avaliable\n", sc->sc_dev.dv_xname); 748 return; 749 } 750 751 /* Secondary */ 752 /* Secondary AC97 is used for 4ch audio. Currently unused. */ 753 ac97_id2 = -1; 754 if ((YREAD2(sc, YDS_ACTIVITY) & YDS_ACTIVITY_DOCKA) == 0) 755 goto detected; 756 #if 0 /* reset secondary... */ 757 YWRITE2(sc, YDS_GPIO_OCTRL, 758 YREAD2(sc, YDS_GPIO_OCTRL) & ~YDS_GPIO_GPO2); 759 YWRITE2(sc, YDS_GPIO_FUNCE, 760 (YREAD2(sc, YDS_GPIO_FUNCE)&(~YDS_GPIO_GPC2))|YDS_GPIO_GPE2); 761 #endif 762 for (to = 0; to < AC97_TIMEOUT; to++) { 763 if ((YREAD2(sc, AC97_STAT_ADDR2) & AC97_BUSY) == 0) 764 break; 765 delay(1); 766 } 767 if (to < AC97_TIMEOUT) { 768 /* detect id */ 769 for (ac97_id2 = 1; ac97_id2 < 4; ac97_id2++) { 770 YWRITE2(sc, AC97_CMD_ADDR, 771 AC97_CMD_READ | AC97_ID(ac97_id2) | 0x28); 772 773 for (to = 0; to < AC97_TIMEOUT; to++) { 774 if ((YREAD2(sc, AC97_STAT_ADDR2) & AC97_BUSY) 775 == 0) 776 goto detected; 777 delay(1); 778 } 779 } 780 if (ac97_id2 == 4) 781 ac97_id2 = -1; 782 detected: 783 ; 784 } 785 786 pci_conf_write(pc, pa->pa_tag, YDS_PCI_DSCTRL, 787 reg | YDS_DSCTRL_CRST); 788 delay (20); 789 pci_conf_write(pc, pa->pa_tag, YDS_PCI_DSCTRL, 790 reg & ~YDS_DSCTRL_CRST); 791 delay (400000); 792 for (to = 0; to < AC97_TIMEOUT; to++) { 793 if ((YREAD2(sc, AC97_STAT_ADDR1) & AC97_BUSY) == 0) 794 break; 795 delay(1); 796 } 797 798 /* 799 * Attach ac97 codec 800 */ 801 for (i = 0; i < 2; i++) { 802 static struct { 803 int data; 804 int addr; 805 } statregs[] = { 806 {AC97_STAT_DATA1, AC97_STAT_ADDR1}, 807 {AC97_STAT_DATA2, AC97_STAT_ADDR2}, 808 }; 809 810 if (i == 1 && ac97_id2 == -1) 811 break; /* secondary ac97 not available */ 812 813 codec = &sc->sc_codec[i]; 814 memcpy(&codec->sc_dev, &sc->sc_dev, sizeof(codec->sc_dev)); 815 codec->sc = sc; 816 codec->id = i == 1 ? ac97_id2 : 0; 817 codec->status_data = statregs[i].data; 818 codec->status_addr = statregs[i].addr; 819 codec->host_if.arg = codec; 820 codec->host_if.attach = yds_attach_codec; 821 codec->host_if.read = yds_read_codec; 822 codec->host_if.write = yds_write_codec; 823 codec->host_if.reset = yds_reset_codec; 824 825 if ((r = ac97_attach(&codec->host_if)) != 0) { 826 printf("%s: can't attach codec (error 0x%X)\n", 827 sc->sc_dev.dv_xname, r); 828 return; 829 } 830 } 831 832 /* Just enable the DAC and master volumes by default */ 833 ctl.type = AUDIO_MIXER_ENUM; 834 ctl.un.ord = 0; /* off */ 835 ctl.dev = yds_get_portnum_by_name(sc, AudioCoutputs, 836 AudioNmaster, AudioNmute); 837 yds_mixer_set_port(sc, &ctl); 838 ctl.dev = yds_get_portnum_by_name(sc, AudioCinputs, 839 AudioNdac, AudioNmute); 840 yds_mixer_set_port(sc, &ctl); 841 ctl.dev = yds_get_portnum_by_name(sc, AudioCinputs, 842 AudioNcd, AudioNmute); 843 yds_mixer_set_port(sc, &ctl); 844 ctl.dev = yds_get_portnum_by_name(sc, AudioCrecord, 845 AudioNvolume, AudioNmute); 846 yds_mixer_set_port(sc, &ctl); 847 848 ctl.dev = yds_get_portnum_by_name(sc, AudioCrecord, 849 AudioNsource, NULL); 850 ctl.type = AUDIO_MIXER_ENUM; 851 ctl.un.ord = 0; 852 yds_mixer_set_port(sc, &ctl); 853 854 /* Set a reasonable default volume */ 855 ctl.type = AUDIO_MIXER_VALUE; 856 ctl.un.value.num_channels = 2; 857 ctl.un.value.level[AUDIO_MIXER_LEVEL_LEFT] = 858 ctl.un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 127; 859 860 ctl.dev = sc->sc_codec[0].codec_if->vtbl->get_portnum_by_name( 861 sc->sc_codec[0].codec_if, AudioCoutputs, AudioNmaster, NULL); 862 yds_mixer_set_port(sc, &ctl); 863 864 audio_attach_mi(&yds_hw_if, sc, &sc->sc_dev); 865 866 sc->sc_legacy_iot = pa->pa_iot; 867 config_defer((struct device*) sc, yds_configure_legacy); 868 } 869 870 int 871 yds_attach_codec(sc_, codec_if) 872 void *sc_; 873 struct ac97_codec_if *codec_if; 874 { 875 struct yds_codec_softc *sc = sc_; 876 877 sc->codec_if = codec_if; 878 return 0; 879 } 880 881 static int 882 yds_ready_codec(sc) 883 struct yds_codec_softc *sc; 884 { 885 int to; 886 887 for (to = 0; to < AC97_TIMEOUT; to++) { 888 if ((YREAD2(sc->sc, sc->status_addr) & AC97_BUSY) == 0) 889 return 0; 890 delay(1); 891 } 892 893 return 1; 894 } 895 896 int 897 yds_read_codec(sc_, reg, data) 898 void *sc_; 899 u_int8_t reg; 900 u_int16_t *data; 901 { 902 struct yds_codec_softc *sc = sc_; 903 904 YWRITE2(sc->sc, AC97_CMD_ADDR, AC97_CMD_READ | AC97_ID(sc->id) | reg); 905 906 if (yds_ready_codec(sc)) { 907 printf("%s: yds_read_codec timeout\n", 908 sc->sc->sc_dev.dv_xname); 909 return EIO; 910 } 911 912 *data = YREAD2(sc->sc, sc->status_data); 913 914 return 0; 915 } 916 917 int 918 yds_write_codec(sc_, reg, data) 919 void *sc_; 920 u_int8_t reg; 921 u_int16_t data; 922 { 923 struct yds_codec_softc *sc = sc_; 924 925 YWRITE2(sc->sc, AC97_CMD_ADDR, AC97_CMD_WRITE | AC97_ID(sc->id) | reg); 926 YWRITE2(sc->sc, AC97_CMD_DATA, data); 927 928 if (yds_ready_codec(sc)) { 929 printf("%s: yds_write_codec timeout\n", 930 sc->sc->sc_dev.dv_xname); 931 return EIO; 932 } 933 934 return 0; 935 } 936 937 /* 938 * XXX: Must handle the secondary differntly!! 939 */ 940 void 941 yds_reset_codec(sc_) 942 void *sc_; 943 { 944 struct yds_codec_softc *codec = sc_; 945 struct yds_softc *sc = codec->sc; 946 pcireg_t reg; 947 948 /* reset AC97 codec */ 949 reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, YDS_PCI_DSCTRL); 950 if (reg & 0x03) { 951 pci_conf_write(sc->sc_pc, sc->sc_pcitag, 952 YDS_PCI_DSCTRL, reg & ~0x03); 953 pci_conf_write(sc->sc_pc, sc->sc_pcitag, 954 YDS_PCI_DSCTRL, reg | 0x03); 955 pci_conf_write(sc->sc_pc, sc->sc_pcitag, 956 YDS_PCI_DSCTRL, reg & ~0x03); 957 delay(50000); 958 } 959 960 yds_ready_codec(sc_); 961 } 962 963 int 964 yds_intr(p) 965 void *p; 966 { 967 struct yds_softc *sc = p; 968 u_int status; 969 970 status = YREAD4(sc, YDS_STATUS); 971 DPRINTFN(1, ("yds_intr: status=%08x\n", status)); 972 if ((status & (YDS_STAT_INT|YDS_STAT_TINT)) == 0) { 973 #if NMPU > 0 974 if (sc->sc_mpu) 975 return mpu_intr(sc->sc_mpu); 976 #endif 977 return 0; 978 } 979 980 if (status & YDS_STAT_TINT) { 981 YWRITE4(sc, YDS_STATUS, YDS_STAT_TINT); 982 printf ("yds_intr: timeout!\n"); 983 } 984 985 if (status & YDS_STAT_INT) { 986 int nbank = (YREAD4(sc, YDS_CONTROL_SELECT) == 0); 987 988 /* Clear interrupt flag */ 989 YWRITE4(sc, YDS_STATUS, YDS_STAT_INT); 990 991 /* Buffer for the next frame is always ready. */ 992 YWRITE4(sc, YDS_MODE, YREAD4(sc, YDS_MODE) | YDS_MODE_ACTV2); 993 994 if (sc->sc_play.intr) { 995 u_int dma, cpu, blk, len; 996 997 /* Sync play slot control data */ 998 bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map, 999 BUS_DMASYNC_POSTWRITE|BUS_DMASYNC_POSTREAD); 1000 dma = sc->pbankp[nbank]->pgstart * sc->sc_play.factor; 1001 cpu = sc->sc_play.offset; 1002 blk = sc->sc_play.blksize; 1003 len = sc->sc_play.length; 1004 1005 if (((dma > cpu) && (dma - cpu > blk * 2)) || 1006 ((cpu > dma) && (dma + len - cpu > blk * 2))) { 1007 /* We can fill the next block */ 1008 /* Sync ring buffer first for previous write */ 1009 bus_dmamap_sync(sc->sc_dmatag, 1010 sc->sc_play.dma->map, 1011 BUS_DMASYNC_POSTWRITE); 1012 sc->sc_play.intr(sc->sc_play.intr_arg); 1013 sc->sc_play.offset += blk; 1014 if (sc->sc_play.offset >= len) { 1015 sc->sc_play.offset -= len; 1016 #ifdef DIAGNOSTIC 1017 if (sc->sc_play.offset != 0) 1018 printf ("Audio ringbuffer botch\n"); 1019 #endif 1020 } 1021 /* Sync ring buffer for next write */ 1022 bus_dmamap_sync(sc->sc_dmatag, 1023 sc->sc_play.dma->map, 1024 BUS_DMASYNC_PREWRITE); 1025 } 1026 } 1027 if (sc->sc_rec.intr) { 1028 u_int dma, cpu, blk, len; 1029 1030 /* Sync rec slot control data */ 1031 bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map, 1032 BUS_DMASYNC_POSTWRITE|BUS_DMASYNC_POSTREAD); 1033 dma = sc->rbank[YDS_INPUT_SLOT*2 + nbank].pgstartadr; 1034 cpu = sc->sc_rec.offset; 1035 blk = sc->sc_rec.blksize; 1036 len = sc->sc_rec.length; 1037 1038 if (((dma > cpu) && (dma - cpu > blk * 2)) || 1039 ((cpu > dma) && (dma + len - cpu > blk * 2))) { 1040 /* We can drain the current block */ 1041 /* Sync ring buffer first */ 1042 bus_dmamap_sync(sc->sc_dmatag, 1043 sc->sc_rec.dma->map, BUS_DMASYNC_POSTREAD); 1044 sc->sc_rec.intr(sc->sc_rec.intr_arg); 1045 sc->sc_rec.offset += blk; 1046 if (sc->sc_rec.offset >= len) { 1047 sc->sc_rec.offset -= len; 1048 #ifdef DIAGNOSTIC 1049 if (sc->sc_rec.offset != 0) 1050 printf ("Audio ringbuffer botch\n"); 1051 #endif 1052 } 1053 /* Sync ring buffer for next read */ 1054 bus_dmamap_sync(sc->sc_dmatag, 1055 sc->sc_rec.dma->map, BUS_DMASYNC_PREREAD); 1056 } 1057 } 1058 } 1059 1060 return 1; 1061 } 1062 1063 int 1064 yds_allocmem(sc, size, align, p) 1065 struct yds_softc *sc; 1066 size_t size; 1067 size_t align; 1068 struct yds_dma *p; 1069 { 1070 int error; 1071 1072 p->size = size; 1073 error = bus_dmamem_alloc(sc->sc_dmatag, p->size, align, 0, 1074 p->segs, sizeof(p->segs)/sizeof(p->segs[0]), 1075 &p->nsegs, BUS_DMA_NOWAIT); 1076 if (error) 1077 return (error); 1078 1079 error = bus_dmamem_map(sc->sc_dmatag, p->segs, p->nsegs, p->size, 1080 &p->addr, BUS_DMA_NOWAIT|BUS_DMA_COHERENT); 1081 if (error) 1082 goto free; 1083 1084 error = bus_dmamap_create(sc->sc_dmatag, p->size, 1, p->size, 1085 0, BUS_DMA_NOWAIT, &p->map); 1086 if (error) 1087 goto unmap; 1088 1089 error = bus_dmamap_load(sc->sc_dmatag, p->map, p->addr, p->size, NULL, 1090 BUS_DMA_NOWAIT); 1091 if (error) 1092 goto destroy; 1093 return (0); 1094 1095 destroy: 1096 bus_dmamap_destroy(sc->sc_dmatag, p->map); 1097 unmap: 1098 bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size); 1099 free: 1100 bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs); 1101 return (error); 1102 } 1103 1104 int 1105 yds_freemem(sc, p) 1106 struct yds_softc *sc; 1107 struct yds_dma *p; 1108 { 1109 bus_dmamap_unload(sc->sc_dmatag, p->map); 1110 bus_dmamap_destroy(sc->sc_dmatag, p->map); 1111 bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size); 1112 bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs); 1113 return 0; 1114 } 1115 1116 int 1117 yds_open(addr, flags) 1118 void *addr; 1119 int flags; 1120 { 1121 struct yds_softc *sc = addr; 1122 int mode; 1123 1124 /* Select bank 0. */ 1125 YWRITE4(sc, YDS_CONTROL_SELECT, 0); 1126 1127 /* Start the DSP operation. */ 1128 mode = YREAD4(sc, YDS_MODE); 1129 mode |= YDS_MODE_ACTV; 1130 mode &= ~YDS_MODE_ACTV2; 1131 YWRITE4(sc, YDS_MODE, mode); 1132 1133 return 0; 1134 } 1135 1136 /* 1137 * Close function is called at splaudio(). 1138 */ 1139 void 1140 yds_close(addr) 1141 void *addr; 1142 { 1143 struct yds_softc *sc = addr; 1144 1145 yds_halt_output(sc); 1146 yds_halt_input(sc); 1147 yds_halt(sc); 1148 } 1149 1150 int 1151 yds_query_encoding(addr, fp) 1152 void *addr; 1153 struct audio_encoding *fp; 1154 { 1155 switch (fp->index) { 1156 case 0: 1157 strcpy(fp->name, AudioEulinear); 1158 fp->encoding = AUDIO_ENCODING_ULINEAR; 1159 fp->precision = 8; 1160 fp->flags = 0; 1161 return (0); 1162 case 1: 1163 strcpy(fp->name, AudioEmulaw); 1164 fp->encoding = AUDIO_ENCODING_ULAW; 1165 fp->precision = 8; 1166 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 1167 return (0); 1168 case 2: 1169 strcpy(fp->name, AudioEalaw); 1170 fp->encoding = AUDIO_ENCODING_ALAW; 1171 fp->precision = 8; 1172 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 1173 return (0); 1174 case 3: 1175 strcpy(fp->name, AudioEslinear); 1176 fp->encoding = AUDIO_ENCODING_SLINEAR; 1177 fp->precision = 8; 1178 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 1179 return (0); 1180 case 4: 1181 strcpy(fp->name, AudioEslinear_le); 1182 fp->encoding = AUDIO_ENCODING_SLINEAR_LE; 1183 fp->precision = 16; 1184 fp->flags = 0; 1185 return (0); 1186 case 5: 1187 strcpy(fp->name, AudioEulinear_le); 1188 fp->encoding = AUDIO_ENCODING_ULINEAR_LE; 1189 fp->precision = 16; 1190 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 1191 return (0); 1192 case 6: 1193 strcpy(fp->name, AudioEslinear_be); 1194 fp->encoding = AUDIO_ENCODING_SLINEAR_BE; 1195 fp->precision = 16; 1196 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 1197 return (0); 1198 case 7: 1199 strcpy(fp->name, AudioEulinear_be); 1200 fp->encoding = AUDIO_ENCODING_ULINEAR_BE; 1201 fp->precision = 16; 1202 fp->flags = AUDIO_ENCODINGFLAG_EMULATED; 1203 return (0); 1204 default: 1205 return (EINVAL); 1206 } 1207 } 1208 1209 int 1210 yds_set_params(addr, setmode, usemode, play, rec) 1211 void *addr; 1212 int setmode, usemode; 1213 struct audio_params *play, *rec; 1214 { 1215 struct audio_params *p; 1216 int mode; 1217 1218 for (mode = AUMODE_RECORD; mode != -1; 1219 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) { 1220 if ((setmode & mode) == 0) 1221 continue; 1222 1223 p = mode == AUMODE_PLAY ? play : rec; 1224 1225 if (p->sample_rate < 4000 || p->sample_rate > 48000 || 1226 (p->precision != 8 && p->precision != 16) || 1227 (p->channels != 1 && p->channels != 2)) 1228 return (EINVAL); 1229 1230 p->factor = 1; 1231 p->sw_code = 0; 1232 switch (p->encoding) { 1233 case AUDIO_ENCODING_SLINEAR_BE: 1234 if (p->precision == 16) 1235 p->sw_code = swap_bytes; 1236 else 1237 p->sw_code = change_sign8; 1238 break; 1239 case AUDIO_ENCODING_SLINEAR_LE: 1240 if (p->precision != 16) 1241 p->sw_code = change_sign8; 1242 break; 1243 case AUDIO_ENCODING_ULINEAR_BE: 1244 if (p->precision == 16) { 1245 if (mode == AUMODE_PLAY) 1246 p->sw_code = swap_bytes_change_sign16_le; 1247 else 1248 p->sw_code = change_sign16_swap_bytes_le; 1249 } 1250 break; 1251 case AUDIO_ENCODING_ULINEAR_LE: 1252 if (p->precision == 16) 1253 p->sw_code = change_sign16_le; 1254 break; 1255 case AUDIO_ENCODING_ULAW: 1256 if (mode == AUMODE_PLAY) { 1257 p->factor = 2; 1258 p->precision = 16; 1259 p->sw_code = mulaw_to_slinear16_le; 1260 } else 1261 p->sw_code = ulinear8_to_mulaw; 1262 break; 1263 case AUDIO_ENCODING_ALAW: 1264 if (mode == AUMODE_PLAY) { 1265 p->factor = 2; 1266 p->precision = 16; 1267 p->sw_code = alaw_to_slinear16_le; 1268 } else 1269 p->sw_code = ulinear8_to_alaw; 1270 break; 1271 default: 1272 return (EINVAL); 1273 } 1274 } 1275 1276 return 0; 1277 } 1278 1279 int 1280 yds_round_blocksize(addr, blk) 1281 void *addr; 1282 int blk; 1283 { 1284 /* 1285 * Block size must be bigger than a frame. 1286 * That is 1024bytes at most, i.e. for 48000Hz, 16bit, 2ch. 1287 */ 1288 if (blk < 1024) 1289 blk = 1024; 1290 1291 return blk & ~4; 1292 } 1293 1294 static u_int32_t 1295 yds_get_lpfq(sample_rate) 1296 u_int sample_rate; 1297 { 1298 int i; 1299 static struct lpfqt { 1300 u_int rate; 1301 u_int32_t lpfq; 1302 } lpfqt[] = { 1303 {8000, 0x32020000}, 1304 {11025, 0x31770000}, 1305 {16000, 0x31390000}, 1306 {22050, 0x31c90000}, 1307 {32000, 0x33d00000}, 1308 {48000, 0x40000000}, 1309 {0, 0} 1310 }; 1311 1312 if (sample_rate == 44100) /* for P44 slot? */ 1313 return 0x370A0000; 1314 1315 for (i = 0; lpfqt[i].rate != 0; i++) 1316 if (sample_rate <= lpfqt[i].rate) 1317 break; 1318 1319 return lpfqt[i].lpfq; 1320 } 1321 1322 static u_int32_t 1323 yds_get_lpfk(sample_rate) 1324 u_int sample_rate; 1325 { 1326 int i; 1327 static struct lpfkt { 1328 u_int rate; 1329 u_int32_t lpfk; 1330 } lpfkt[] = { 1331 {8000, 0x18b20000}, 1332 {11025, 0x20930000}, 1333 {16000, 0x2b9a0000}, 1334 {22050, 0x35a10000}, 1335 {32000, 0x3eaa0000}, 1336 {48000, 0x40000000}, 1337 {0, 0} 1338 }; 1339 1340 if (sample_rate == 44100) /* for P44 slot? */ 1341 return 0x46460000; 1342 1343 for (i = 0; lpfkt[i].rate != 0; i++) 1344 if (sample_rate <= lpfkt[i].rate) 1345 break; 1346 1347 return lpfkt[i].lpfk; 1348 } 1349 1350 int 1351 yds_trigger_output(addr, start, end, blksize, intr, arg, param) 1352 void *addr; 1353 void *start, *end; 1354 int blksize; 1355 void (*intr) __P((void *)); 1356 void *arg; 1357 struct audio_params *param; 1358 #define P44 (sc->sc_flags & YDS_CAP_HAS_P44) 1359 { 1360 struct yds_softc *sc = addr; 1361 struct yds_dma *p; 1362 struct play_slot_ctrl_bank *psb; 1363 const u_int gain = 0x40000000; 1364 bus_addr_t s; 1365 size_t l; 1366 int i; 1367 int p44, channels; 1368 1369 #ifdef DIAGNOSTIC 1370 if (sc->sc_play.intr) 1371 panic("yds_trigger_output: already running"); 1372 #endif 1373 1374 sc->sc_play.intr = intr; 1375 sc->sc_play.intr_arg = arg; 1376 sc->sc_play.offset = 0; 1377 sc->sc_play.blksize = blksize; 1378 1379 DPRINTFN(1, ("yds_trigger_output: sc=%p start=%p end=%p " 1380 "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg)); 1381 1382 p = yds_find_dma(sc, start); 1383 if (!p) { 1384 printf("yds_trigger_output: bad addr %p\n", start); 1385 return (EINVAL); 1386 } 1387 sc->sc_play.dma = p; 1388 1389 #ifdef DIAGNOSTIC 1390 { 1391 u_int32_t ctrlsize; 1392 if ((ctrlsize = YREAD4(sc, YDS_PLAY_CTRLSIZE)) != 1393 sizeof(struct play_slot_ctrl_bank) / sizeof(u_int32_t)) 1394 panic("%s: invalid play slot ctrldata %d %d", 1395 sc->sc_dev.dv_xname, ctrlsize, 1396 sizeof(struct play_slot_ctrl_bank)); 1397 } 1398 #endif 1399 1400 #ifdef YDS_USE_P44 1401 /* The document says the P44 SRC supports only stereo, 16bit PCM. */ 1402 if (P44) 1403 p44 = ((param->sample_rate == 44100) && 1404 (param->channels == 2) && 1405 (param->precision == 16)); 1406 else 1407 #endif 1408 p44 = 0; 1409 channels = p44 ? 1 : param->channels; 1410 1411 s = DMAADDR(p); 1412 l = ((char *)end - (char *)start); 1413 sc->sc_play.length = l; 1414 1415 *sc->ptbl = channels; /* Num of play */ 1416 1417 sc->sc_play.factor = 1; 1418 if (param->channels == 2) 1419 sc->sc_play.factor *= 2; 1420 if (param->precision != 8) 1421 sc->sc_play.factor *= 2; 1422 l /= sc->sc_play.factor; 1423 1424 psb = sc->pbankp[0]; 1425 memset(psb, 0, sizeof(*psb)); 1426 psb->format = ((channels == 2 ? PSLT_FORMAT_STEREO : 0) | 1427 (param->precision == 8 ? PSLT_FORMAT_8BIT : 0) | 1428 (p44 ? PSLT_FORMAT_SRC441 : 0)); 1429 psb->pgbase = s; 1430 psb->pgloopend = l; 1431 if (!p44) { 1432 psb->pgdeltaend = (param->sample_rate * 65536 / 48000) << 12; 1433 psb->lpfkend = yds_get_lpfk(param->sample_rate); 1434 psb->eggainend = gain; 1435 psb->lpfq = yds_get_lpfq(param->sample_rate); 1436 psb->pgdelta = psb->pgdeltaend; 1437 psb->lpfk = yds_get_lpfk(param->sample_rate); 1438 psb->eggain = gain; 1439 } 1440 1441 for (i = 0; i < channels; i++) { 1442 /* i == 0: left or mono, i == 1: right */ 1443 psb = sc->pbankp[i*2]; 1444 if (i) 1445 /* copy from left */ 1446 *psb = *(sc->pbankp[0]); 1447 if (channels == 2) { 1448 /* stereo */ 1449 if (i == 0) { 1450 psb->lchgain = psb->lchgainend = gain; 1451 } else { 1452 psb->lchgain = psb->lchgainend = 0; 1453 psb->rchgain = psb->rchgainend = gain; 1454 psb->format |= PSLT_FORMAT_RCH; 1455 } 1456 } else if (!p44) { 1457 /* mono */ 1458 psb->lchgain = psb->rchgain = gain; 1459 psb->lchgainend = psb->rchgainend = gain; 1460 } 1461 /* copy to the other bank */ 1462 *(sc->pbankp[i*2+1]) = *psb; 1463 } 1464 1465 YDS_DUMP_PLAY_SLOT(5, sc, 0); 1466 YDS_DUMP_PLAY_SLOT(5, sc, 1); 1467 1468 if (p44) 1469 YWRITE4(sc, YDS_P44_OUT_VOLUME, 0x3fff3fff); 1470 else 1471 YWRITE4(sc, YDS_DAC_OUT_VOLUME, 0x3fff3fff); 1472 1473 /* Now the play slot for the next frame is set up!! */ 1474 /* Sync play slot control data for both directions */ 1475 bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map, 1476 BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD); 1477 /* Sync ring buffer */ 1478 bus_dmamap_sync(sc->sc_dmatag, p->map, BUS_DMASYNC_PREWRITE); 1479 /* HERE WE GO!! */ 1480 YWRITE4(sc, YDS_MODE, 1481 YREAD4(sc, YDS_MODE) | YDS_MODE_ACTV | YDS_MODE_ACTV2); 1482 1483 return 0; 1484 } 1485 #undef P44 1486 1487 int 1488 yds_trigger_input(addr, start, end, blksize, intr, arg, param) 1489 void *addr; 1490 void *start, *end; 1491 int blksize; 1492 void (*intr) __P((void *)); 1493 void *arg; 1494 struct audio_params *param; 1495 { 1496 struct yds_softc *sc = addr; 1497 struct yds_dma *p; 1498 u_int srate, format; 1499 struct rec_slot_ctrl_bank *rsb; 1500 bus_addr_t s; 1501 size_t l; 1502 1503 #ifdef DIAGNOSTIC 1504 if (sc->sc_rec.intr) 1505 panic("yds_trigger_input: already running"); 1506 #endif 1507 sc->sc_rec.intr = intr; 1508 sc->sc_rec.intr_arg = arg; 1509 sc->sc_rec.offset = 0; 1510 sc->sc_rec.blksize = blksize; 1511 1512 DPRINTFN(1, ("yds_trigger_input: " 1513 "sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n", 1514 addr, start, end, blksize, intr, arg)); 1515 DPRINTFN(1, (" parameters: rate=%lu, precision=%u, channels=%u\n", 1516 param->sample_rate, param->precision, param->channels)); 1517 1518 p = yds_find_dma(sc, start); 1519 if (!p) { 1520 printf("yds_trigger_input: bad addr %p\n", start); 1521 return (EINVAL); 1522 } 1523 sc->sc_rec.dma = p; 1524 1525 #ifdef DIAGNOSTIC 1526 { 1527 u_int32_t ctrlsize; 1528 if ((ctrlsize = YREAD4(sc, YDS_REC_CTRLSIZE)) != 1529 sizeof(struct rec_slot) / sizeof(u_int32_t)) 1530 panic("%s: invalid rec slot ctrldata %d", 1531 sc->sc_dev.dv_xname, ctrlsize); 1532 } 1533 #endif 1534 1535 s = DMAADDR(p); 1536 l = ((char *)end - (char *)start); 1537 sc->sc_rec.length = l; 1538 1539 sc->sc_rec.factor = 1; 1540 if (param->channels == 2) 1541 sc->sc_rec.factor *= 2; 1542 if (param->precision != 8) 1543 sc->sc_rec.factor *= 2; 1544 1545 rsb = &sc->rbank[0]; 1546 memset(rsb, 0, sizeof(*rsb)); 1547 rsb->pgbase = s; 1548 rsb->pgloopendadr = l; 1549 /* Seems all 4 banks must be set up... */ 1550 sc->rbank[1] = *rsb; 1551 sc->rbank[2] = *rsb; 1552 sc->rbank[3] = *rsb; 1553 1554 YWRITE4(sc, YDS_ADC_IN_VOLUME, 0x3fff3fff); 1555 YWRITE4(sc, YDS_REC_IN_VOLUME, 0x3fff3fff); 1556 srate = 48000 * 4096 / param->sample_rate - 1; 1557 format = ((param->precision == 8 ? YDS_FORMAT_8BIT : 0) | 1558 (param->channels == 2 ? YDS_FORMAT_STEREO : 0)); 1559 DPRINTF(("srate=%d, format=%08x\n", srate, format)); 1560 #ifdef YDS_USE_REC_SLOT 1561 YWRITE4(sc, YDS_DAC_REC_VOLUME, 0x3fff3fff); 1562 YWRITE4(sc, YDS_P44_REC_VOLUME, 0x3fff3fff); 1563 YWRITE4(sc, YDS_MAPOF_REC, YDS_RECSLOT_VALID); 1564 YWRITE4(sc, YDS_REC_SAMPLE_RATE, srate); 1565 YWRITE4(sc, YDS_REC_FORMAT, format); 1566 #else 1567 YWRITE4(sc, YDS_MAPOF_REC, YDS_ADCSLOT_VALID); 1568 YWRITE4(sc, YDS_ADC_SAMPLE_RATE, srate); 1569 YWRITE4(sc, YDS_ADC_FORMAT, format); 1570 #endif 1571 /* Now the rec slot for the next frame is set up!! */ 1572 /* Sync record slot control data */ 1573 bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map, 1574 BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD); 1575 /* Sync ring buffer */ 1576 bus_dmamap_sync(sc->sc_dmatag, p->map, BUS_DMASYNC_PREREAD); 1577 /* HERE WE GO!! */ 1578 YWRITE4(sc, YDS_MODE, 1579 YREAD4(sc, YDS_MODE) | YDS_MODE_ACTV | YDS_MODE_ACTV2); 1580 1581 return 0; 1582 } 1583 1584 static int 1585 yds_halt(sc) 1586 struct yds_softc *sc; 1587 { 1588 u_int32_t mode; 1589 1590 /* Stop the DSP operation. */ 1591 mode = YREAD4(sc, YDS_MODE); 1592 YWRITE4(sc, YDS_MODE, mode & ~(YDS_MODE_ACTV|YDS_MODE_ACTV2)); 1593 1594 /* Paranoia... mute all */ 1595 YWRITE4(sc, YDS_P44_OUT_VOLUME, 0); 1596 YWRITE4(sc, YDS_DAC_OUT_VOLUME, 0); 1597 YWRITE4(sc, YDS_ADC_IN_VOLUME, 0); 1598 YWRITE4(sc, YDS_REC_IN_VOLUME, 0); 1599 YWRITE4(sc, YDS_DAC_REC_VOLUME, 0); 1600 YWRITE4(sc, YDS_P44_REC_VOLUME, 0); 1601 1602 return 0; 1603 } 1604 1605 int 1606 yds_halt_output(addr) 1607 void *addr; 1608 { 1609 struct yds_softc *sc = addr; 1610 1611 DPRINTF(("yds: yds_halt_output\n")); 1612 if (sc->sc_play.intr) { 1613 sc->sc_play.intr = 0; 1614 /* Sync play slot control data */ 1615 bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map, 1616 BUS_DMASYNC_POSTWRITE|BUS_DMASYNC_POSTREAD); 1617 /* Stop the play slot operation */ 1618 sc->pbankp[0]->status = 1619 sc->pbankp[1]->status = 1620 sc->pbankp[2]->status = 1621 sc->pbankp[3]->status = 1; 1622 /* Sync ring buffer */ 1623 bus_dmamap_sync(sc->sc_dmatag, sc->sc_play.dma->map, 1624 BUS_DMASYNC_POSTWRITE); 1625 } 1626 1627 return 0; 1628 } 1629 1630 int 1631 yds_halt_input(addr) 1632 void *addr; 1633 { 1634 struct yds_softc *sc = addr; 1635 1636 DPRINTF(("yds: yds_halt_input\n")); 1637 sc->sc_rec.intr = NULL; 1638 if (sc->sc_rec.intr) { 1639 /* Stop the rec slot operation */ 1640 YWRITE4(sc, YDS_MAPOF_REC, 0); 1641 sc->sc_rec.intr = 0; 1642 /* Sync rec slot control data */ 1643 bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map, 1644 BUS_DMASYNC_POSTWRITE|BUS_DMASYNC_POSTREAD); 1645 /* Sync ring buffer */ 1646 bus_dmamap_sync(sc->sc_dmatag, sc->sc_rec.dma->map, 1647 BUS_DMASYNC_POSTREAD); 1648 } 1649 1650 return 0; 1651 } 1652 1653 int 1654 yds_getdev(addr, retp) 1655 void *addr; 1656 struct audio_device *retp; 1657 { 1658 *retp = yds_device; 1659 1660 return 0; 1661 } 1662 1663 int 1664 yds_mixer_set_port(addr, cp) 1665 void *addr; 1666 mixer_ctrl_t *cp; 1667 { 1668 struct yds_softc *sc = addr; 1669 1670 return (sc->sc_codec[0].codec_if->vtbl->mixer_set_port( 1671 sc->sc_codec[0].codec_if, cp)); 1672 } 1673 1674 int 1675 yds_mixer_get_port(addr, cp) 1676 void *addr; 1677 mixer_ctrl_t *cp; 1678 { 1679 struct yds_softc *sc = addr; 1680 1681 return (sc->sc_codec[0].codec_if->vtbl->mixer_get_port( 1682 sc->sc_codec[0].codec_if, cp)); 1683 } 1684 1685 int 1686 yds_query_devinfo(addr, dip) 1687 void *addr; 1688 mixer_devinfo_t *dip; 1689 { 1690 struct yds_softc *sc = addr; 1691 1692 return (sc->sc_codec[0].codec_if->vtbl->query_devinfo( 1693 sc->sc_codec[0].codec_if, dip)); 1694 } 1695 1696 int 1697 yds_get_portnum_by_name(sc, class, device, qualifier) 1698 struct yds_softc *sc; 1699 char *class, *device, *qualifier; 1700 { 1701 return (sc->sc_codec[0].codec_if->vtbl->get_portnum_by_name( 1702 sc->sc_codec[0].codec_if, class, device, qualifier)); 1703 } 1704 1705 void * 1706 yds_malloc(addr, size, pool, flags) 1707 void *addr; 1708 u_long size; 1709 int pool, flags; 1710 { 1711 struct yds_softc *sc = addr; 1712 struct yds_dma *p; 1713 int error; 1714 1715 p = malloc(sizeof(*p), pool, flags); 1716 if (!p) 1717 return (0); 1718 error = yds_allocmem(sc, size, 16, p); 1719 if (error) { 1720 free(p, pool); 1721 return (0); 1722 } 1723 p->next = sc->sc_dmas; 1724 sc->sc_dmas = p; 1725 return (KERNADDR(p)); 1726 } 1727 1728 void 1729 yds_free(addr, ptr, pool) 1730 void *addr; 1731 void *ptr; 1732 int pool; 1733 { 1734 struct yds_softc *sc = addr; 1735 struct yds_dma **pp, *p; 1736 1737 for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &p->next) { 1738 if (KERNADDR(p) == ptr) { 1739 yds_freemem(sc, p); 1740 *pp = p->next; 1741 free(p, pool); 1742 return; 1743 } 1744 } 1745 } 1746 1747 static struct yds_dma * 1748 yds_find_dma(sc, addr) 1749 struct yds_softc *sc; 1750 void *addr; 1751 { 1752 struct yds_dma *p; 1753 1754 for (p = sc->sc_dmas; p && KERNADDR(p) != addr; p = p->next) 1755 ; 1756 1757 return p; 1758 } 1759 1760 u_long 1761 yds_round_buffersize(addr, size) 1762 void *addr; 1763 u_long size; 1764 { 1765 /* 1766 * Buffer size should be at least twice as bigger as a frame. 1767 */ 1768 if (size < 1024 * 3) 1769 size = 1024 * 3; 1770 return (size); 1771 } 1772 1773 int 1774 yds_mappage(addr, mem, off, prot) 1775 void *addr; 1776 void *mem; 1777 int off; 1778 int prot; 1779 { 1780 struct yds_softc *sc = addr; 1781 struct yds_dma *p; 1782 1783 if (off < 0) 1784 return (-1); 1785 p = yds_find_dma(sc, mem); 1786 if (!p) 1787 return (-1); 1788 return (bus_dmamem_mmap(sc->sc_dmatag, p->segs, p->nsegs, 1789 off, prot, BUS_DMA_WAITOK)); 1790 } 1791 1792 int 1793 yds_get_props(addr) 1794 void *addr; 1795 { 1796 return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | 1797 AUDIO_PROP_FULLDUPLEX); 1798 } 1799