ds1.c revision 70134
1/* 2 * Copyright (c) 2000 Cameron Grant <cg@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHERIN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD: head/sys/dev/sound/pci/ds1.c 70134 2000-12-18 01:36:41Z cg $ 27 */ 28 29#include <dev/sound/pcm/sound.h> 30#include <dev/sound/pcm/ac97.h> 31 32#include <pci/pcireg.h> 33#include <pci/pcivar.h> 34 35#include <dev/sound/pci/ds1.h> 36#include <dev/sound/pci/ds1-fw.h> 37 38/* -------------------------------------------------------------------- */ 39 40#define DS1_CHANS 4 41#define DS1_RECPRIMARY 0 42 43struct pbank { 44 volatile u_int32_t Format; 45 volatile u_int32_t LoopDefault; 46 volatile u_int32_t PgBase; 47 volatile u_int32_t PgLoop; 48 volatile u_int32_t PgLoopEnd; 49 volatile u_int32_t PgLoopFrac; 50 volatile u_int32_t PgDeltaEnd; 51 volatile u_int32_t LpfKEnd; 52 volatile u_int32_t EgGainEnd; 53 volatile u_int32_t LchGainEnd; 54 volatile u_int32_t RchGainEnd; 55 volatile u_int32_t Effect1GainEnd; 56 volatile u_int32_t Effect2GainEnd; 57 volatile u_int32_t Effect3GainEnd; 58 volatile u_int32_t LpfQ; 59 volatile u_int32_t Status; 60 volatile u_int32_t NumOfFrames; 61 volatile u_int32_t LoopCount; 62 volatile u_int32_t PgStart; 63 volatile u_int32_t PgStartFrac; 64 volatile u_int32_t PgDelta; 65 volatile u_int32_t LpfK; 66 volatile u_int32_t EgGain; 67 volatile u_int32_t LchGain; 68 volatile u_int32_t RchGain; 69 volatile u_int32_t Effect1Gain; 70 volatile u_int32_t Effect2Gain; 71 volatile u_int32_t Effect3Gain; 72 volatile u_int32_t LpfD1; 73 volatile u_int32_t LpfD2; 74}; 75 76struct rbank { 77 volatile u_int32_t PgBase; 78 volatile u_int32_t PgLoopEnd; 79 volatile u_int32_t PgStart; 80 volatile u_int32_t NumOfLoops; 81}; 82 83struct sc_info; 84 85/* channel registers */ 86struct sc_pchinfo { 87 int run, spd, dir, fmt; 88 snd_dbuf *buffer; 89 pcm_channel *channel; 90 volatile struct pbank *lslot, *rslot; 91 int lsnum, rsnum; 92 struct sc_info *parent; 93}; 94 95struct sc_rchinfo { 96 int run, spd, dir, fmt, num; 97 snd_dbuf *buffer; 98 pcm_channel *channel; 99 volatile struct rbank *slot; 100 struct sc_info *parent; 101}; 102 103/* device private data */ 104struct sc_info { 105 device_t dev; 106 u_int32_t type, rev; 107 u_int32_t cd2id, ctrlbase; 108 109 bus_space_tag_t st; 110 bus_space_handle_t sh; 111 bus_dma_tag_t parent_dmat; 112 bus_dmamap_t map; 113 114 struct resource *reg, *irq; 115 int regid, irqid; 116 void *ih; 117 118 void *regbase; 119 u_int32_t *pbase, pbankbase, pbanksize; 120 volatile struct pbank *pbank[2 * 64]; 121 volatile struct rbank *rbank; 122 int pslotfree, currbank, pchn, rchn; 123 124 struct sc_pchinfo pch[DS1_CHANS]; 125 struct sc_rchinfo rch[2]; 126}; 127 128struct { 129 u_int32_t dev, subdev; 130 char *name; 131 u_int32_t *mcode; 132} ds_devs[] = { 133 {0x00041073, 0, "Yamaha DS-1 (YMF724)", CntrlInst}, 134 {0x000d1073, 0, "Yamaha DS-1E (YMF724F)", CntrlInst1E}, 135 {0x00051073, 0, "Yamaha DS-1? (YMF734)", CntrlInst}, 136 {0x00081073, 0, "Yamaha DS-1? (YMF737)", CntrlInst}, 137 {0x00201073, 0, "Yamaha DS-1? (YMF738)", CntrlInst}, 138 {0x00061073, 0, "Yamaha DS-1? (YMF738_TEG)", CntrlInst}, 139 {0x000a1073, 0x00041073, "Yamaha DS-1 (YMF740)", CntrlInst}, 140 {0x000a1073, 0x000a1073, "Yamaha DS-1 (YMF740B)", CntrlInst}, 141 {0x000a1073, 0x53328086, "Yamaha DS-1 (YMF740I)", CntrlInst}, 142 {0x000a1073, 0, "Yamaha DS-1 (YMF740?)", CntrlInst}, 143 {0x000c1073, 0, "Yamaha DS-1E (YMF740C)", CntrlInst1E}, 144 {0x00101073, 0, "Yamaha DS-1E (YMF744)", CntrlInst1E}, 145 {0x00121073, 0, "Yamaha DS-1E (YMF754)", CntrlInst1E}, 146 {0, 0, NULL, NULL} 147}; 148 149/* -------------------------------------------------------------------- */ 150 151/* 152 * prototypes 153 */ 154 155/* stuff */ 156static int ds_init(struct sc_info *); 157static void ds_intr(void *); 158 159/* talk to the card */ 160static u_int32_t ds_rd(struct sc_info *, int, int); 161static void ds_wr(struct sc_info *, int, u_int32_t, int); 162 163/* -------------------------------------------------------------------- */ 164 165static u_int32_t ds_recfmt[] = { 166 AFMT_U8, 167 AFMT_STEREO | AFMT_U8, 168 AFMT_S8, 169 AFMT_STEREO | AFMT_S8, 170 AFMT_S16_LE, 171 AFMT_STEREO | AFMT_S16_LE, 172 AFMT_U16_LE, 173 AFMT_STEREO | AFMT_U16_LE, 174 0 175}; 176static pcmchan_caps ds_reccaps = {4000, 48000, ds_recfmt, 0}; 177 178static u_int32_t ds_playfmt[] = { 179 AFMT_U8, 180 AFMT_STEREO | AFMT_U8, 181 /* AFMT_S16_LE, */ 182 AFMT_STEREO | AFMT_S16_LE, 183 0 184}; 185static pcmchan_caps ds_playcaps = {4000, 96000, ds_playfmt, 0}; 186 187/* -------------------------------------------------------------------- */ 188/* Hardware */ 189static u_int32_t 190ds_rd(struct sc_info *sc, int regno, int size) 191{ 192 switch (size) { 193 case 1: 194 return bus_space_read_1(sc->st, sc->sh, regno); 195 case 2: 196 return bus_space_read_2(sc->st, sc->sh, regno); 197 case 4: 198 return bus_space_read_4(sc->st, sc->sh, regno); 199 default: 200 return 0xffffffff; 201 } 202} 203 204static void 205ds_wr(struct sc_info *sc, int regno, u_int32_t data, int size) 206{ 207 switch (size) { 208 case 1: 209 bus_space_write_1(sc->st, sc->sh, regno, data); 210 break; 211 case 2: 212 bus_space_write_2(sc->st, sc->sh, regno, data); 213 break; 214 case 4: 215 bus_space_write_4(sc->st, sc->sh, regno, data); 216 break; 217 } 218} 219 220static void 221wrl(struct sc_info *sc, u_int32_t *ptr, u_int32_t val) 222{ 223 *(volatile u_int32_t *)ptr = val; 224 bus_space_barrier(sc->st, sc->sh, 0, 0, BUS_SPACE_BARRIER_WRITE); 225} 226 227/* -------------------------------------------------------------------- */ 228/* ac97 codec */ 229static int 230ds_cdbusy(struct sc_info *sc, int sec) 231{ 232 int i, reg; 233 234 reg = sec? YDSXGR_SECSTATUSADR : YDSXGR_PRISTATUSADR; 235 i = YDSXG_AC97TIMEOUT; 236 while (i > 0) { 237 if (!(ds_rd(sc, reg, 2) & 0x8000)) 238 return 0; 239 i--; 240 } 241 return ETIMEDOUT; 242} 243 244static u_int32_t 245ds_initcd(kobj_t obj, void *devinfo) 246{ 247 struct sc_info *sc = (struct sc_info *)devinfo; 248 u_int32_t x; 249 250 x = pci_read_config(sc->dev, PCIR_DSXGCTRL, 1); 251 if (x & 0x03) { 252 pci_write_config(sc->dev, PCIR_DSXGCTRL, x & ~0x03, 1); 253 pci_write_config(sc->dev, PCIR_DSXGCTRL, x | 0x03, 1); 254 pci_write_config(sc->dev, PCIR_DSXGCTRL, x & ~0x03, 1); 255 /* 256 * The YMF740 on some Intel motherboards requires a pretty 257 * hefty delay after this reset for some reason... Otherwise: 258 * "pcm0: ac97 codec init failed" 259 * Maybe this is needed for all YMF740's? 260 * 400ms and 500ms here seem to work, 300ms does not. 261 * 262 * do it for all chips -cg 263 */ 264 DELAY(500000); 265 } 266 267 return ds_cdbusy(sc, 0)? 0 : 1; 268} 269 270static int 271ds_rdcd(kobj_t obj, void *devinfo, int regno) 272{ 273 struct sc_info *sc = (struct sc_info *)devinfo; 274 int sec, cid, i; 275 u_int32_t cmd, reg; 276 277 sec = regno & 0x100; 278 regno &= 0xff; 279 cid = sec? (sc->cd2id << 8) : 0; 280 reg = sec? YDSXGR_SECSTATUSDATA : YDSXGR_PRISTATUSDATA; 281 if (sec && cid == 0) 282 return 0xffffffff; 283 284 cmd = YDSXG_AC97READCMD | cid | regno; 285 ds_wr(sc, YDSXGR_AC97CMDADR, cmd, 2); 286 287 if (ds_cdbusy(sc, sec)) 288 return 0xffffffff; 289 290 if (sc->type == 11 && sc->rev < 2) 291 for (i = 0; i < 600; i++) 292 ds_rd(sc, reg, 2); 293 294 return ds_rd(sc, reg, 2); 295} 296 297static int 298ds_wrcd(kobj_t obj, void *devinfo, int regno, u_int32_t data) 299{ 300 struct sc_info *sc = (struct sc_info *)devinfo; 301 int sec, cid; 302 u_int32_t cmd; 303 304 sec = regno & 0x100; 305 regno &= 0xff; 306 cid = sec? (sc->cd2id << 8) : 0; 307 if (sec && cid == 0) 308 return ENXIO; 309 310 cmd = YDSXG_AC97WRITECMD | cid | regno; 311 cmd <<= 16; 312 cmd |= data; 313 ds_wr(sc, YDSXGR_AC97CMDDATA, cmd, 4); 314 315 return ds_cdbusy(sc, sec); 316} 317 318static kobj_method_t ds_ac97_methods[] = { 319 KOBJMETHOD(ac97_init, ds_initcd), 320 KOBJMETHOD(ac97_read, ds_rdcd), 321 KOBJMETHOD(ac97_write, ds_wrcd), 322 { 0, 0 } 323}; 324AC97_DECLARE(ds_ac97); 325 326/* -------------------------------------------------------------------- */ 327 328static void 329ds_enadsp(struct sc_info *sc, int on) 330{ 331 u_int32_t v, i; 332 333 v = on? 1 : 0; 334 if (on) { 335 ds_wr(sc, YDSXGR_CONFIG, 0x00000001, 4); 336 } else { 337 if (ds_rd(sc, YDSXGR_CONFIG, 4)) 338 ds_wr(sc, YDSXGR_CONFIG, 0x00000000, 4); 339 i = YDSXG_WORKBITTIMEOUT; 340 while (i > 0) { 341 if (!(ds_rd(sc, YDSXGR_CONFIG, 4) & 0x00000002)) 342 break; 343 i--; 344 } 345 } 346} 347 348static volatile struct pbank * 349ds_allocpslot(struct sc_info *sc) 350{ 351 int slot; 352 353 if (sc->pslotfree > 63) 354 return NULL; 355 slot = sc->pslotfree++; 356 return sc->pbank[slot * 2]; 357} 358 359static int 360ds_initpbank(volatile struct pbank *pb, int ch, int b16, int stereo, u_int32_t rate, void *base, u_int32_t len) 361{ 362 u_int32_t lv[] = {1, 1, 0, 0, 0}; 363 u_int32_t rv[] = {1, 0, 1, 0, 0}; 364 u_int32_t e1[] = {0, 0, 0, 0, 0}; 365 u_int32_t e2[] = {1, 0, 0, 1, 0}; 366 u_int32_t e3[] = {1, 0, 0, 0, 1}; 367 int ss, i; 368 u_int32_t delta; 369 370 struct { 371 int rate, fK, fQ; 372 } speedinfo[] = { 373 { 100, 0x00570000, 0x35280000}, 374 { 2000, 0x06aa0000, 0x34a70000}, 375 { 8000, 0x18b20000, 0x32020000}, 376 {11025, 0x20930000, 0x31770000}, 377 {16000, 0x2b9a0000, 0x31390000}, 378 {22050, 0x35a10000, 0x31c90000}, 379 {32000, 0x3eaa0000, 0x33d00000}, 380/* {44100, 0x04646000, 0x370a0000}, 381*/ {48000, 0x40000000, 0x40000000}, 382 }; 383 384 ss = b16? 1 : 0; 385 ss += stereo? 1 : 0; 386 delta = (65536 * rate) / 48000; 387 i = 0; 388 while (i < 7 && speedinfo[i].rate < rate) 389 i++; 390 391 pb->Format = stereo? 0x00010000 : 0; 392 pb->Format |= b16? 0 : 0x80000000; 393 pb->Format |= (stereo && (ch == 2 || ch == 4))? 0x00000001 : 0; 394 pb->LoopDefault = 0; 395 pb->PgBase = base? vtophys(base) : 0; 396 pb->PgLoop = 0; 397 pb->PgLoopEnd = len >> ss; 398 pb->PgLoopFrac = 0; 399 pb->Status = 0; 400 pb->NumOfFrames = 0; 401 pb->LoopCount = 0; 402 pb->PgStart = 0; 403 pb->PgStartFrac = 0; 404 pb->PgDelta = pb->PgDeltaEnd = delta << 12; 405 pb->LpfQ = speedinfo[i].fQ; 406 pb->LpfK = pb->LpfKEnd = speedinfo[i].fK; 407 pb->LpfD1 = pb->LpfD2 = 0; 408 pb->EgGain = pb->EgGainEnd = 0x40000000; 409 pb->LchGain = pb->LchGainEnd = lv[ch] * 0x40000000; 410 pb->RchGain = pb->RchGainEnd = rv[ch] * 0x40000000; 411 pb->Effect1Gain = pb->Effect1GainEnd = e1[ch] * 0x40000000; 412 pb->Effect2Gain = pb->Effect2GainEnd = e2[ch] * 0x40000000; 413 pb->Effect3Gain = pb->Effect3GainEnd = e3[ch] * 0x40000000; 414 415 return 0; 416} 417 418static void 419ds_enapslot(struct sc_info *sc, int slot, int go) 420{ 421 wrl(sc, &sc->pbase[slot + 1], go? (sc->pbankbase + 2 * slot * sc->pbanksize) : 0); 422 /* printf("pbase[%d] = 0x%x\n", slot + 1, go? (sc->pbankbase + 2 * slot * sc->pbanksize) : 0); */ 423} 424 425static void 426ds_setuppch(struct sc_pchinfo *ch) 427{ 428 int stereo, b16, c, sz; 429 void *buf; 430 431 stereo = (ch->fmt & AFMT_STEREO)? 1 : 0; 432 b16 = (ch->fmt & AFMT_16BIT)? 1 : 0; 433 c = stereo? 1 : 0; 434 buf = ch->buffer->buf; 435 sz = ch->buffer->bufsize; 436 437 ds_initpbank(ch->lslot, c, stereo, b16, ch->spd, buf, sz); 438 ds_initpbank(ch->lslot + 1, c, stereo, b16, ch->spd, buf, sz); 439 ds_initpbank(ch->rslot, 2, stereo, b16, ch->spd, buf, sz); 440 ds_initpbank(ch->rslot + 1, 2, stereo, b16, ch->spd, buf, sz); 441} 442 443static void 444ds_setuprch(struct sc_rchinfo *ch) 445{ 446 struct sc_info *sc = ch->parent; 447 int stereo, b16, i, sz, pri; 448 u_int32_t x, y; 449 void *buf; 450 451 stereo = (ch->fmt & AFMT_STEREO)? 1 : 0; 452 b16 = (ch->fmt & AFMT_16BIT)? 1 : 0; 453 buf = ch->buffer->buf; 454 sz = ch->buffer->bufsize; 455 pri = (ch->num == DS1_RECPRIMARY)? 1 : 0; 456 457 for (i = 0; i < 2; i++) { 458 ch->slot[i].PgBase = vtophys(buf); 459 ch->slot[i].PgLoopEnd = sz; 460 ch->slot[i].PgStart = 0; 461 ch->slot[i].NumOfLoops = 0; 462 } 463 x = (b16? 0x00 : 0x01) | (stereo? 0x02 : 0x00); 464 y = (48000 * 4096) / ch->spd; 465 y--; 466 /* printf("pri = %d, x = %d, y = %d\n", pri, x, y); */ 467 ds_wr(sc, pri? YDSXGR_ADCFORMAT : YDSXGR_RECFORMAT, x, 4); 468 ds_wr(sc, pri? YDSXGR_ADCSLOTSR : YDSXGR_RECSLOTSR, y, 4); 469} 470 471/* -------------------------------------------------------------------- */ 472/* play channel interface */ 473static void * 474ds1pchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) 475{ 476 struct sc_info *sc = devinfo; 477 struct sc_pchinfo *ch; 478 479 KASSERT(dir == PCMDIR_PLAY, ("ds1pchan_init: bad direction")); 480 481 ch = &sc->pch[sc->pchn++]; 482 ch->buffer = b; 483 ch->buffer->bufsize = 4096; 484 ch->parent = sc; 485 ch->channel = c; 486 ch->dir = dir; 487 ch->fmt = AFMT_U8; 488 ch->spd = 8000; 489 ch->run = 0; 490 if (chn_allocbuf(ch->buffer, sc->parent_dmat) == -1) 491 return NULL; 492 else { 493 ch->lsnum = sc->pslotfree; 494 ch->lslot = ds_allocpslot(sc); 495 ch->rsnum = sc->pslotfree; 496 ch->rslot = ds_allocpslot(sc); 497 ds_setuppch(ch); 498 return ch; 499 } 500} 501 502static int 503ds1pchan_setformat(kobj_t obj, void *data, u_int32_t format) 504{ 505 struct sc_pchinfo *ch = data; 506 507 ch->fmt = format; 508 509 return 0; 510} 511 512static int 513ds1pchan_setspeed(kobj_t obj, void *data, u_int32_t speed) 514{ 515 struct sc_pchinfo *ch = data; 516 517 ch->spd = speed; 518 519 return speed; 520} 521 522static int 523ds1pchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) 524{ 525 return blocksize; 526} 527 528/* semantic note: must start at beginning of buffer */ 529static int 530ds1pchan_trigger(kobj_t obj, void *data, int go) 531{ 532 struct sc_pchinfo *ch = data; 533 struct sc_info *sc = ch->parent; 534 int stereo; 535 536 if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) 537 return 0; 538 stereo = (ch->fmt & AFMT_STEREO)? 1 : 0; 539 if (go == PCMTRIG_START) { 540 ch->run = 1; 541 ds_setuppch(ch); 542 ds_enapslot(sc, ch->lsnum, 1); 543 ds_enapslot(sc, ch->rsnum, stereo); 544 ds_wr(sc, YDSXGR_MODE, 0x00000003, 4); 545 } else { 546 ch->run = 0; 547 /* ds_setuppch(ch); */ 548 ds_enapslot(sc, ch->lsnum, 0); 549 ds_enapslot(sc, ch->rsnum, 0); 550 } 551 552 return 0; 553} 554 555static int 556ds1pchan_getptr(kobj_t obj, void *data) 557{ 558 struct sc_pchinfo *ch = data; 559 struct sc_info *sc = ch->parent; 560 volatile struct pbank *bank; 561 int ss; 562 u_int32_t ptr; 563 564 ss = (ch->fmt & AFMT_STEREO)? 1 : 0; 565 ss += (ch->fmt & AFMT_16BIT)? 1 : 0; 566 567 bank = ch->lslot + sc->currbank; 568 /* printf("getptr: %d\n", bank->PgStart << ss); */ 569 ptr = bank->PgStart; 570 ptr <<= ss; 571 return ptr; 572} 573 574static pcmchan_caps * 575ds1pchan_getcaps(kobj_t obj, void *data) 576{ 577 return &ds_playcaps; 578} 579 580static kobj_method_t ds1pchan_methods[] = { 581 KOBJMETHOD(channel_init, ds1pchan_init), 582 KOBJMETHOD(channel_setformat, ds1pchan_setformat), 583 KOBJMETHOD(channel_setspeed, ds1pchan_setspeed), 584 KOBJMETHOD(channel_setblocksize, ds1pchan_setblocksize), 585 KOBJMETHOD(channel_trigger, ds1pchan_trigger), 586 KOBJMETHOD(channel_getptr, ds1pchan_getptr), 587 KOBJMETHOD(channel_getcaps, ds1pchan_getcaps), 588 { 0, 0 } 589}; 590CHANNEL_DECLARE(ds1pchan); 591 592/* -------------------------------------------------------------------- */ 593/* record channel interface */ 594static void * 595ds1rchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) 596{ 597 struct sc_info *sc = devinfo; 598 struct sc_rchinfo *ch; 599 600 KASSERT(dir == PCMDIR_REC, ("ds1rchan_init: bad direction")); 601 602 ch = &sc->rch[sc->rchn]; 603 ch->num = sc->rchn++; 604 ch->buffer = b; 605 ch->buffer->bufsize = 4096; 606 ch->parent = sc; 607 ch->channel = c; 608 ch->dir = dir; 609 ch->fmt = AFMT_U8; 610 ch->spd = 8000; 611 if (chn_allocbuf(ch->buffer, sc->parent_dmat) == -1) 612 return NULL; 613 else { 614 ch->slot = (ch->num == DS1_RECPRIMARY)? sc->rbank + 2: sc->rbank; 615 ds_setuprch(ch); 616 return ch; 617 } 618} 619 620static int 621ds1rchan_setformat(kobj_t obj, void *data, u_int32_t format) 622{ 623 struct sc_rchinfo *ch = data; 624 625 ch->fmt = format; 626 627 return 0; 628} 629 630static int 631ds1rchan_setspeed(kobj_t obj, void *data, u_int32_t speed) 632{ 633 struct sc_rchinfo *ch = data; 634 635 ch->spd = speed; 636 637 return speed; 638} 639 640static int 641ds1rchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) 642{ 643 return blocksize; 644} 645 646/* semantic note: must start at beginning of buffer */ 647static int 648ds1rchan_trigger(kobj_t obj, void *data, int go) 649{ 650 struct sc_rchinfo *ch = data; 651 struct sc_info *sc = ch->parent; 652 u_int32_t x; 653 654 if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) 655 return 0; 656 if (go == PCMTRIG_START) { 657 ch->run = 1; 658 ds_setuprch(ch); 659 x = ds_rd(sc, YDSXGR_MAPOFREC, 4); 660 x |= (ch->num == DS1_RECPRIMARY)? 0x02 : 0x01; 661 ds_wr(sc, YDSXGR_MAPOFREC, x, 4); 662 ds_wr(sc, YDSXGR_MODE, 0x00000003, 4); 663 } else { 664 ch->run = 0; 665 x = ds_rd(sc, YDSXGR_MAPOFREC, 4); 666 x &= ~((ch->num == DS1_RECPRIMARY)? 0x02 : 0x01); 667 ds_wr(sc, YDSXGR_MAPOFREC, x, 4); 668 } 669 670 return 0; 671} 672 673static int 674ds1rchan_getptr(kobj_t obj, void *data) 675{ 676 struct sc_rchinfo *ch = data; 677 struct sc_info *sc = ch->parent; 678 679 return ch->slot[sc->currbank].PgStart; 680} 681 682static pcmchan_caps * 683ds1rchan_getcaps(kobj_t obj, void *data) 684{ 685 return &ds_reccaps; 686} 687 688static kobj_method_t ds1rchan_methods[] = { 689 KOBJMETHOD(channel_init, ds1rchan_init), 690 KOBJMETHOD(channel_setformat, ds1rchan_setformat), 691 KOBJMETHOD(channel_setspeed, ds1rchan_setspeed), 692 KOBJMETHOD(channel_setblocksize, ds1rchan_setblocksize), 693 KOBJMETHOD(channel_trigger, ds1rchan_trigger), 694 KOBJMETHOD(channel_getptr, ds1rchan_getptr), 695 KOBJMETHOD(channel_getcaps, ds1rchan_getcaps), 696 { 0, 0 } 697}; 698CHANNEL_DECLARE(ds1rchan); 699 700/* -------------------------------------------------------------------- */ 701/* The interrupt handler */ 702static void 703ds_intr(void *p) 704{ 705 struct sc_info *sc = (struct sc_info *)p; 706 u_int32_t i, x; 707 708 i = ds_rd(sc, YDSXGR_STATUS, 4); 709 if (i & 0x00008000) 710 device_printf(sc->dev, "timeout irq\n"); 711 if (i & 0x80008000) { 712 ds_wr(sc, YDSXGR_STATUS, i & 0x80008000, 4); 713 sc->currbank = ds_rd(sc, YDSXGR_CTRLSELECT, 4) & 0x00000001; 714 715 x = 0; 716 for (i = 0; i < DS1_CHANS; i++) { 717 if (sc->pch[i].run) { 718 x = 1; 719 chn_intr(sc->pch[i].channel); 720 } 721 } 722 for (i = 0; i < 2; i++) { 723 if (sc->rch[i].run) { 724 x = 1; 725 chn_intr(sc->rch[i].channel); 726 } 727 } 728 i = ds_rd(sc, YDSXGR_MODE, 4); 729 if (x) 730 ds_wr(sc, YDSXGR_MODE, i | 0x00000002, 4); 731 732 } 733} 734 735/* -------------------------------------------------------------------- */ 736 737/* 738 * Probe and attach the card 739 */ 740 741static void 742ds_setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error) 743{ 744 struct sc_info *sc = arg; 745 746 sc->ctrlbase = error? 0 : (u_int32_t)segs->ds_addr; 747 748 if (bootverbose) { 749 printf("ds1: setmap (%lx, %lx), nseg=%d, error=%d\n", 750 (unsigned long)segs->ds_addr, (unsigned long)segs->ds_len, 751 nseg, error); 752 } 753} 754 755static int 756ds_init(struct sc_info *sc) 757{ 758 int i; 759 u_int32_t *ci, r, pcs, rcs, ecs, ws, memsz, cb; 760 u_int8_t *t; 761 void *buf; 762 763 ci = ds_devs[sc->type].mcode; 764 765 ds_wr(sc, YDSXGR_NATIVEDACOUTVOL, 0x00000000, 4); 766 ds_enadsp(sc, 0); 767 ds_wr(sc, YDSXGR_MODE, 0x00010000, 4); 768 ds_wr(sc, YDSXGR_MODE, 0x00000000, 4); 769 ds_wr(sc, YDSXGR_MAPOFREC, 0x00000000, 4); 770 ds_wr(sc, YDSXGR_MAPOFEFFECT, 0x00000000, 4); 771 ds_wr(sc, YDSXGR_PLAYCTRLBASE, 0x00000000, 4); 772 ds_wr(sc, YDSXGR_RECCTRLBASE, 0x00000000, 4); 773 ds_wr(sc, YDSXGR_EFFCTRLBASE, 0x00000000, 4); 774 r = ds_rd(sc, YDSXGR_GLOBALCTRL, 2); 775 ds_wr(sc, YDSXGR_GLOBALCTRL, r & ~0x0007, 2); 776 777 for (i = 0; i < YDSXG_DSPLENGTH; i += 4) 778 ds_wr(sc, YDSXGR_DSPINSTRAM + i, DspInst[i >> 2], 4); 779 780 for (i = 0; i < YDSXG_CTRLLENGTH; i += 4) 781 ds_wr(sc, YDSXGR_CTRLINSTRAM + i, ci[i >> 2], 4); 782 783 ds_enadsp(sc, 1); 784 785 pcs = 0; 786 for (i = 100; i > 0; i--) { 787 pcs = ds_rd(sc, YDSXGR_PLAYCTRLSIZE, 4) << 2; 788 if (pcs == sizeof(struct pbank)) 789 break; 790 DELAY(1000); 791 } 792 if (pcs != sizeof(struct pbank)) { 793 device_printf(sc->dev, "preposterous playctrlsize (%d)\n", pcs); 794 return -1; 795 } 796 rcs = ds_rd(sc, YDSXGR_RECCTRLSIZE, 4) << 2; 797 ecs = ds_rd(sc, YDSXGR_EFFCTRLSIZE, 4) << 2; 798 ws = ds_rd(sc, YDSXGR_WORKSIZE, 4) << 2; 799 800 memsz = 64 * 2 * pcs + 2 * 2 * rcs + 5 * 2 * ecs + ws; 801 memsz += (64 + 1) * 4; 802 803 if (sc->regbase == NULL) { 804 if (bus_dmamem_alloc(sc->parent_dmat, &buf, BUS_DMA_NOWAIT, &sc->map)) 805 return -1; 806 if (bus_dmamap_load(sc->parent_dmat, sc->map, buf, memsz, ds_setmap, sc, 0) 807 || !sc->ctrlbase) { 808 device_printf(sc->dev, "pcs=%d, rcs=%d, ecs=%d, ws=%d, memsz=%d\n", 809 pcs, rcs, ecs, ws, memsz); 810 return -1; 811 } 812 sc->regbase = buf; 813 } else 814 buf = sc->regbase; 815 816 cb = 0; 817 t = buf; 818 ds_wr(sc, YDSXGR_WORKBASE, sc->ctrlbase + cb, 4); 819 cb += ws; 820 sc->pbase = (u_int32_t *)(t + cb); 821 /* printf("pbase = %p -> 0x%x\n", sc->pbase, sc->ctrlbase + cb); */ 822 ds_wr(sc, YDSXGR_PLAYCTRLBASE, sc->ctrlbase + cb, 4); 823 cb += (64 + 1) * 4; 824 sc->rbank = (struct rbank *)(t + cb); 825 ds_wr(sc, YDSXGR_RECCTRLBASE, sc->ctrlbase + cb, 4); 826 cb += 2 * 2 * rcs; 827 ds_wr(sc, YDSXGR_EFFCTRLBASE, sc->ctrlbase + cb, 4); 828 cb += 5 * 2 * ecs; 829 830 sc->pbankbase = sc->ctrlbase + cb; 831 sc->pbanksize = pcs; 832 for (i = 0; i < 64; i++) { 833 wrl(sc, &sc->pbase[i + 1], 0); 834 sc->pbank[i * 2] = (struct pbank *)(t + cb); 835 /* printf("pbank[%d] = %p -> 0x%x; ", i * 2, (struct pbank *)(t + cb), sc->ctrlbase + cb - vtophys(t + cb)); */ 836 cb += pcs; 837 sc->pbank[i * 2 + 1] = (struct pbank *)(t + cb); 838 /* printf("pbank[%d] = %p -> 0x%x\n", i * 2 + 1, (struct pbank *)(t + cb), sc->ctrlbase + cb - vtophys(t + cb)); */ 839 cb += pcs; 840 } 841 wrl(sc, &sc->pbase[0], DS1_CHANS * 2); 842 843 sc->pchn = sc->rchn = 0; 844 ds_wr(sc, YDSXGR_NATIVEDACOUTVOL, 0x3fff3fff, 4); 845 ds_wr(sc, YDSXGR_NATIVEADCINVOL, 0x3fff3fff, 4); 846 ds_wr(sc, YDSXGR_NATIVEDACINVOL, 0x3fff3fff, 4); 847 return 0; 848} 849 850static int 851ds_uninit(struct sc_info *sc) 852{ 853 ds_wr(sc, YDSXGR_NATIVEDACOUTVOL, 0x00000000, 4); 854 ds_wr(sc, YDSXGR_NATIVEADCINVOL, 0, 4); 855 ds_wr(sc, YDSXGR_NATIVEDACINVOL, 0, 4); 856 ds_enadsp(sc, 0); 857 ds_wr(sc, YDSXGR_MODE, 0x00010000, 4); 858 ds_wr(sc, YDSXGR_MAPOFREC, 0x00000000, 4); 859 ds_wr(sc, YDSXGR_MAPOFEFFECT, 0x00000000, 4); 860 ds_wr(sc, YDSXGR_PLAYCTRLBASE, 0x00000000, 4); 861 ds_wr(sc, YDSXGR_RECCTRLBASE, 0x00000000, 4); 862 ds_wr(sc, YDSXGR_EFFCTRLBASE, 0x00000000, 4); 863 ds_wr(sc, YDSXGR_GLOBALCTRL, 0, 2); 864 865 bus_dmamap_unload(sc->parent_dmat, sc->map); 866 bus_dmamem_free(sc->parent_dmat, sc->regbase, sc->map); 867 868 return 0; 869} 870 871static int 872ds_finddev(u_int32_t dev, u_int32_t subdev) 873{ 874 int i; 875 876 for (i = 0; ds_devs[i].dev; i++) { 877 if (ds_devs[i].dev == dev && 878 (ds_devs[i].subdev == subdev || ds_devs[i].subdev == 0)) 879 return i; 880 } 881 return -1; 882} 883 884static int 885ds_pci_probe(device_t dev) 886{ 887 int i; 888 u_int32_t subdev; 889 890 subdev = (pci_get_subdevice(dev) << 16) | pci_get_subvendor(dev); 891 i = ds_finddev(pci_get_devid(dev), subdev); 892 if (i >= 0) { 893 device_set_desc(dev, ds_devs[i].name); 894 return 0; 895 } else 896 return ENXIO; 897} 898 899static int 900ds_pci_attach(device_t dev) 901{ 902 u_int32_t data; 903 u_int32_t subdev, i; 904 struct sc_info *sc; 905 struct ac97_info *codec = NULL; 906 char status[SND_STATUSLEN]; 907 908 if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT)) == NULL) { 909 device_printf(dev, "cannot allocate softc\n"); 910 return ENXIO; 911 } 912 913 bzero(sc, sizeof(*sc)); 914 sc->dev = dev; 915 subdev = (pci_get_subdevice(dev) << 16) | pci_get_subvendor(dev); 916 sc->type = ds_finddev(pci_get_devid(dev), subdev); 917 sc->rev = pci_get_revid(dev); 918 919 data = pci_read_config(dev, PCIR_COMMAND, 2); 920 data |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN); 921 pci_write_config(dev, PCIR_COMMAND, data, 2); 922 data = pci_read_config(dev, PCIR_COMMAND, 2); 923 924 sc->regid = PCIR_MAPS; 925 sc->reg = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->regid, 926 0, ~0, 1, RF_ACTIVE); 927 if (!sc->reg) { 928 device_printf(dev, "unable to map register space\n"); 929 goto bad; 930 } 931 932 sc->st = rman_get_bustag(sc->reg); 933 sc->sh = rman_get_bushandle(sc->reg); 934 935 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, 936 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 937 /*highaddr*/BUS_SPACE_MAXADDR, 938 /*filter*/NULL, /*filterarg*/NULL, 939 /*maxsize*/65536, /*nsegments*/1, /*maxsegz*/0x3ffff, 940 /*flags*/0, &sc->parent_dmat) != 0) { 941 device_printf(dev, "unable to create dma tag\n"); 942 goto bad; 943 } 944 945 sc->regbase = NULL; 946 if (ds_init(sc) == -1) { 947 device_printf(dev, "unable to initialize the card\n"); 948 goto bad; 949 } 950 951 codec = AC97_CREATE(dev, sc, ds_ac97); 952 if (codec == NULL) 953 goto bad; 954 mixer_init(dev, ac97_getmixerclass(), codec); 955 956 sc->irqid = 0; 957 sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irqid, 958 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); 959 if (!sc->irq || 960 bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, ds_intr, sc, &sc->ih)) { 961 device_printf(dev, "unable to map interrupt\n"); 962 goto bad; 963 } 964 965 snprintf(status, SND_STATUSLEN, "at memory 0x%lx irq %ld", 966 rman_get_start(sc->reg), rman_get_start(sc->irq)); 967 968 if (pcm_register(dev, sc, DS1_CHANS, 2)) 969 goto bad; 970 for (i = 0; i < DS1_CHANS; i++) 971 pcm_addchan(dev, PCMDIR_PLAY, &ds1pchan_class, sc); 972 for (i = 0; i < 2; i++) 973 pcm_addchan(dev, PCMDIR_REC, &ds1rchan_class, sc); 974 pcm_setstatus(dev, status); 975 976 return 0; 977 978bad: 979 if (codec) 980 ac97_destroy(codec); 981 if (sc->reg) 982 bus_release_resource(dev, SYS_RES_MEMORY, sc->regid, sc->reg); 983 if (sc->ih) 984 bus_teardown_intr(dev, sc->irq, sc->ih); 985 if (sc->irq) 986 bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq); 987 if (sc->parent_dmat) 988 bus_dma_tag_destroy(sc->parent_dmat); 989 free(sc, M_DEVBUF); 990 return ENXIO; 991} 992 993static int 994ds_pci_resume(device_t dev) 995{ 996 struct sc_info *sc; 997 998 sc = pcm_getdevinfo(dev); 999 1000 if (ds_init(sc) == -1) { 1001 device_printf(dev, "unable to reinitialize the card\n"); 1002 return ENXIO; 1003 } 1004 if (mixer_reinit(dev) == -1) { 1005 device_printf(dev, "unable to reinitialize the mixer\n"); 1006 return ENXIO; 1007 } 1008 return 0; 1009} 1010 1011static int 1012ds_pci_detach(device_t dev) 1013{ 1014 int r; 1015 struct sc_info *sc; 1016 1017 r = pcm_unregister(dev); 1018 if (r) 1019 return r; 1020 1021 sc = pcm_getdevinfo(dev); 1022 ds_uninit(sc); 1023 bus_release_resource(dev, SYS_RES_MEMORY, sc->regid, sc->reg); 1024 bus_teardown_intr(dev, sc->irq, sc->ih); 1025 bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq); 1026 bus_dma_tag_destroy(sc->parent_dmat); 1027 free(sc, M_DEVBUF); 1028 return 0; 1029} 1030 1031static device_method_t ds1_methods[] = { 1032 /* Device interface */ 1033 DEVMETHOD(device_probe, ds_pci_probe), 1034 DEVMETHOD(device_attach, ds_pci_attach), 1035 DEVMETHOD(device_detach, ds_pci_detach), 1036 DEVMETHOD(device_resume, ds_pci_resume), 1037 { 0, 0 } 1038}; 1039 1040static driver_t ds1_driver = { 1041 "pcm", 1042 ds1_methods, 1043 sizeof(snddev_info), 1044}; 1045 1046static devclass_t pcm_devclass; 1047 1048DRIVER_MODULE(snd_ds1, pci, ds1_driver, pcm_devclass, 0, 0); 1049MODULE_DEPEND(snd_ds1, snd_pcm, PCM_MINVER, PCM_PREFVER, PCM_MAXVER); 1050MODULE_VERSION(snd_ds1, 1); 1051