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