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