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