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