1 /*- 2 * Copyright (c) 1999 Cameron Grant <cg@freebsd.org> 3 * All rights reserved. 4 * 5 * Derived from the public domain Linux driver 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 AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHERIN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 * $FreeBSD: src/sys/dev/sound/pci/neomagic.c,v 1.34.2.1 2005/12/30 19:55:53 netchild Exp $ 29 */ 30 31 #include <dev/sound/pcm/sound.h> 32 #include <dev/sound/pcm/ac97.h> 33 #include <dev/sound/pci/neomagic.h> 34 #include <dev/sound/pci/neomagic-coeff.h> 35 36 #include <bus/pci/pcireg.h> 37 #include <bus/pci/pcivar.h> 38 39 SND_DECLARE_FILE("$DragonFly: src/sys/dev/sound/pci/neomagic.c,v 1.7 2007/01/04 21:47:02 corecode Exp $"); 40 41 /* -------------------------------------------------------------------- */ 42 43 #define NM_BUFFSIZE 16384 44 45 #define NM256AV_PCI_ID 0x800510c8 46 #define NM256ZX_PCI_ID 0x800610c8 47 48 struct sc_info; 49 50 /* channel registers */ 51 struct sc_chinfo { 52 int active, spd, dir, fmt; 53 u_int32_t blksize, wmark; 54 struct snd_dbuf *buffer; 55 struct pcm_channel *channel; 56 struct sc_info *parent; 57 }; 58 59 /* device private data */ 60 struct sc_info { 61 device_t dev; 62 u_int32_t type; 63 64 struct resource *reg, *irq, *buf; 65 int regid, irqid, bufid; 66 void *ih; 67 68 u_int32_t ac97_base, ac97_status, ac97_busy; 69 u_int32_t buftop, pbuf, rbuf, cbuf, acbuf; 70 u_int32_t playint, recint, misc1int, misc2int; 71 u_int32_t irsz, badintr; 72 73 struct sc_chinfo pch, rch; 74 }; 75 76 /* -------------------------------------------------------------------- */ 77 78 /* 79 * prototypes 80 */ 81 82 /* stuff */ 83 static int nm_loadcoeff(struct sc_info *sc, int dir, int num); 84 static int nm_setch(struct sc_chinfo *ch); 85 static int nm_init(struct sc_info *); 86 static void nm_intr(void *); 87 88 /* talk to the card */ 89 static u_int32_t nm_rd(struct sc_info *, int, int); 90 static void nm_wr(struct sc_info *, int, u_int32_t, int); 91 static u_int32_t nm_rdbuf(struct sc_info *, int, int); 92 static void nm_wrbuf(struct sc_info *, int, u_int32_t, int); 93 94 static u_int32_t badcards[] = { 95 0x0007103c, 96 0x008f1028, 97 0x00dd1014, 98 0x8005110a, 99 }; 100 #define NUM_BADCARDS (sizeof(badcards) / sizeof(u_int32_t)) 101 102 /* The actual rates supported by the card. */ 103 static int samplerates[9] = { 104 8000, 105 11025, 106 16000, 107 22050, 108 24000, 109 32000, 110 44100, 111 48000, 112 99999999 113 }; 114 115 /* -------------------------------------------------------------------- */ 116 117 static u_int32_t nm_fmt[] = { 118 AFMT_U8, 119 AFMT_STEREO | AFMT_U8, 120 AFMT_S16_LE, 121 AFMT_STEREO | AFMT_S16_LE, 122 0 123 }; 124 static struct pcmchan_caps nm_caps = {4000, 48000, nm_fmt, 0}; 125 126 /* -------------------------------------------------------------------- */ 127 128 /* Hardware */ 129 static u_int32_t 130 nm_rd(struct sc_info *sc, int regno, int size) 131 { 132 bus_space_tag_t st = rman_get_bustag(sc->reg); 133 bus_space_handle_t sh = rman_get_bushandle(sc->reg); 134 135 switch (size) { 136 case 1: 137 return bus_space_read_1(st, sh, regno); 138 case 2: 139 return bus_space_read_2(st, sh, regno); 140 case 4: 141 return bus_space_read_4(st, sh, regno); 142 default: 143 return 0xffffffff; 144 } 145 } 146 147 static void 148 nm_wr(struct sc_info *sc, int regno, u_int32_t data, int size) 149 { 150 bus_space_tag_t st = rman_get_bustag(sc->reg); 151 bus_space_handle_t sh = rman_get_bushandle(sc->reg); 152 153 switch (size) { 154 case 1: 155 bus_space_write_1(st, sh, regno, data); 156 break; 157 case 2: 158 bus_space_write_2(st, sh, regno, data); 159 break; 160 case 4: 161 bus_space_write_4(st, sh, regno, data); 162 break; 163 } 164 } 165 166 static u_int32_t 167 nm_rdbuf(struct sc_info *sc, int regno, int size) 168 { 169 bus_space_tag_t st = rman_get_bustag(sc->buf); 170 bus_space_handle_t sh = rman_get_bushandle(sc->buf); 171 172 switch (size) { 173 case 1: 174 return bus_space_read_1(st, sh, regno); 175 case 2: 176 return bus_space_read_2(st, sh, regno); 177 case 4: 178 return bus_space_read_4(st, sh, regno); 179 default: 180 return 0xffffffff; 181 } 182 } 183 184 static void 185 nm_wrbuf(struct sc_info *sc, int regno, u_int32_t data, int size) 186 { 187 bus_space_tag_t st = rman_get_bustag(sc->buf); 188 bus_space_handle_t sh = rman_get_bushandle(sc->buf); 189 190 switch (size) { 191 case 1: 192 bus_space_write_1(st, sh, regno, data); 193 break; 194 case 2: 195 bus_space_write_2(st, sh, regno, data); 196 break; 197 case 4: 198 bus_space_write_4(st, sh, regno, data); 199 break; 200 } 201 } 202 203 /* -------------------------------------------------------------------- */ 204 /* ac97 codec */ 205 static int 206 nm_waitcd(struct sc_info *sc) 207 { 208 int cnt = 10; 209 int fail = 1; 210 211 while (cnt-- > 0) { 212 if (nm_rd(sc, sc->ac97_status, 2) & sc->ac97_busy) { 213 DELAY(100); 214 } else { 215 fail = 0; 216 break; 217 } 218 } 219 return (fail); 220 } 221 222 static u_int32_t 223 nm_initcd(kobj_t obj, void *devinfo) 224 { 225 struct sc_info *sc = (struct sc_info *)devinfo; 226 227 nm_wr(sc, 0x6c0, 0x01, 1); 228 #if 0 229 /* 230 * The following code-line may cause a hang for some chipsets, see 231 * PR 56617. 232 * In case of a bugreport without this line have a look at the PR and 233 * conditionize the code-line based upon the specific version of 234 * the chip. 235 */ 236 nm_wr(sc, 0x6cc, 0x87, 1); 237 #endif 238 nm_wr(sc, 0x6cc, 0x80, 1); 239 nm_wr(sc, 0x6cc, 0x00, 1); 240 return 1; 241 } 242 243 static int 244 nm_rdcd(kobj_t obj, void *devinfo, int regno) 245 { 246 struct sc_info *sc = (struct sc_info *)devinfo; 247 u_int32_t x; 248 249 if (!nm_waitcd(sc)) { 250 x = nm_rd(sc, sc->ac97_base + regno, 2); 251 DELAY(1000); 252 return x; 253 } else { 254 device_printf(sc->dev, "ac97 codec not ready\n"); 255 return -1; 256 } 257 } 258 259 static int 260 nm_wrcd(kobj_t obj, void *devinfo, int regno, u_int32_t data) 261 { 262 struct sc_info *sc = (struct sc_info *)devinfo; 263 int cnt = 3; 264 265 if (!nm_waitcd(sc)) { 266 while (cnt-- > 0) { 267 nm_wr(sc, sc->ac97_base + regno, data, 2); 268 if (!nm_waitcd(sc)) { 269 DELAY(1000); 270 return 0; 271 } 272 } 273 } 274 device_printf(sc->dev, "ac97 codec not ready\n"); 275 return -1; 276 } 277 278 static kobj_method_t nm_ac97_methods[] = { 279 KOBJMETHOD(ac97_init, nm_initcd), 280 KOBJMETHOD(ac97_read, nm_rdcd), 281 KOBJMETHOD(ac97_write, nm_wrcd), 282 { 0, 0 } 283 }; 284 AC97_DECLARE(nm_ac97); 285 286 /* -------------------------------------------------------------------- */ 287 288 static void 289 nm_ackint(struct sc_info *sc, u_int32_t num) 290 { 291 if (sc->type == NM256AV_PCI_ID) { 292 nm_wr(sc, NM_INT_REG, num << 1, 2); 293 } else if (sc->type == NM256ZX_PCI_ID) { 294 nm_wr(sc, NM_INT_REG, num, 4); 295 } 296 } 297 298 static int 299 nm_loadcoeff(struct sc_info *sc, int dir, int num) 300 { 301 int ofs, sz, i; 302 u_int32_t addr; 303 304 addr = (dir == PCMDIR_PLAY)? 0x01c : 0x21c; 305 if (dir == PCMDIR_REC) 306 num += 8; 307 sz = coefficientSizes[num]; 308 ofs = 0; 309 while (num-- > 0) 310 ofs+= coefficientSizes[num]; 311 for (i = 0; i < sz; i++) 312 nm_wrbuf(sc, sc->cbuf + i, coefficients[ofs + i], 1); 313 nm_wr(sc, addr, sc->cbuf, 4); 314 if (dir == PCMDIR_PLAY) 315 sz--; 316 nm_wr(sc, addr + 4, sc->cbuf + sz, 4); 317 return 0; 318 } 319 320 static int 321 nm_setch(struct sc_chinfo *ch) 322 { 323 struct sc_info *sc = ch->parent; 324 u_int32_t base; 325 u_int8_t x; 326 327 for (x = 0; x < 8; x++) 328 if (ch->spd < (samplerates[x] + samplerates[x + 1]) / 2) 329 break; 330 331 if (x == 8) return 1; 332 333 ch->spd = samplerates[x]; 334 nm_loadcoeff(sc, ch->dir, x); 335 336 x <<= 4; 337 x &= NM_RATE_MASK; 338 if (ch->fmt & AFMT_16BIT) x |= NM_RATE_BITS_16; 339 if (ch->fmt & AFMT_STEREO) x |= NM_RATE_STEREO; 340 341 base = (ch->dir == PCMDIR_PLAY)? NM_PLAYBACK_REG_OFFSET : NM_RECORD_REG_OFFSET; 342 nm_wr(sc, base + NM_RATE_REG_OFFSET, x, 1); 343 return 0; 344 } 345 346 /* channel interface */ 347 static void * 348 nmchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) 349 { 350 struct sc_info *sc = devinfo; 351 struct sc_chinfo *ch; 352 u_int32_t chnbuf; 353 354 chnbuf = (dir == PCMDIR_PLAY)? sc->pbuf : sc->rbuf; 355 ch = (dir == PCMDIR_PLAY)? &sc->pch : &sc->rch; 356 ch->active = 0; 357 ch->blksize = 0; 358 ch->wmark = 0; 359 ch->buffer = b; 360 sndbuf_setup(ch->buffer, (u_int8_t *)rman_get_virtual(sc->buf) + chnbuf, NM_BUFFSIZE); 361 if (bootverbose) 362 device_printf(sc->dev, "%s buf %p\n", (dir == PCMDIR_PLAY)? 363 "play" : "rec", sndbuf_getbuf(ch->buffer)); 364 ch->parent = sc; 365 ch->channel = c; 366 ch->dir = dir; 367 return ch; 368 } 369 370 static int 371 nmchan_free(kobj_t obj, void *data) 372 { 373 return 0; 374 } 375 376 static int 377 nmchan_setformat(kobj_t obj, void *data, u_int32_t format) 378 { 379 struct sc_chinfo *ch = data; 380 381 ch->fmt = format; 382 return nm_setch(ch); 383 } 384 385 static int 386 nmchan_setspeed(kobj_t obj, void *data, u_int32_t speed) 387 { 388 struct sc_chinfo *ch = data; 389 390 ch->spd = speed; 391 return nm_setch(ch)? 0 : ch->spd; 392 } 393 394 static int 395 nmchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) 396 { 397 struct sc_chinfo *ch = data; 398 399 ch->blksize = blocksize; 400 401 return blocksize; 402 } 403 404 static int 405 nmchan_trigger(kobj_t obj, void *data, int go) 406 { 407 struct sc_chinfo *ch = data; 408 struct sc_info *sc = ch->parent; 409 int ssz; 410 411 if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) 412 return 0; 413 414 ssz = (ch->fmt & AFMT_16BIT)? 2 : 1; 415 if (ch->fmt & AFMT_STEREO) 416 ssz <<= 1; 417 418 if (ch->dir == PCMDIR_PLAY) { 419 if (go == PCMTRIG_START) { 420 ch->active = 1; 421 ch->wmark = ch->blksize; 422 nm_wr(sc, NM_PBUFFER_START, sc->pbuf, 4); 423 nm_wr(sc, NM_PBUFFER_END, sc->pbuf + NM_BUFFSIZE - ssz, 4); 424 nm_wr(sc, NM_PBUFFER_CURRP, sc->pbuf, 4); 425 nm_wr(sc, NM_PBUFFER_WMARK, sc->pbuf + ch->wmark, 4); 426 nm_wr(sc, NM_PLAYBACK_ENABLE_REG, NM_PLAYBACK_FREERUN | 427 NM_PLAYBACK_ENABLE_FLAG, 1); 428 nm_wr(sc, NM_AUDIO_MUTE_REG, 0, 2); 429 } else { 430 ch->active = 0; 431 nm_wr(sc, NM_PLAYBACK_ENABLE_REG, 0, 1); 432 nm_wr(sc, NM_AUDIO_MUTE_REG, NM_AUDIO_MUTE_BOTH, 2); 433 } 434 } else { 435 if (go == PCMTRIG_START) { 436 ch->active = 1; 437 ch->wmark = ch->blksize; 438 nm_wr(sc, NM_RECORD_ENABLE_REG, NM_RECORD_FREERUN | 439 NM_RECORD_ENABLE_FLAG, 1); 440 nm_wr(sc, NM_RBUFFER_START, sc->rbuf, 4); 441 nm_wr(sc, NM_RBUFFER_END, sc->rbuf + NM_BUFFSIZE, 4); 442 nm_wr(sc, NM_RBUFFER_CURRP, sc->rbuf, 4); 443 nm_wr(sc, NM_RBUFFER_WMARK, sc->rbuf + ch->wmark, 4); 444 } else { 445 ch->active = 0; 446 nm_wr(sc, NM_RECORD_ENABLE_REG, 0, 1); 447 } 448 } 449 return 0; 450 } 451 452 static int 453 nmchan_getptr(kobj_t obj, void *data) 454 { 455 struct sc_chinfo *ch = data; 456 struct sc_info *sc = ch->parent; 457 458 if (ch->dir == PCMDIR_PLAY) 459 return nm_rd(sc, NM_PBUFFER_CURRP, 4) - sc->pbuf; 460 else 461 return nm_rd(sc, NM_RBUFFER_CURRP, 4) - sc->rbuf; 462 } 463 464 static struct pcmchan_caps * 465 nmchan_getcaps(kobj_t obj, void *data) 466 { 467 return &nm_caps; 468 } 469 470 static kobj_method_t nmchan_methods[] = { 471 KOBJMETHOD(channel_init, nmchan_init), 472 KOBJMETHOD(channel_free, nmchan_free), 473 KOBJMETHOD(channel_setformat, nmchan_setformat), 474 KOBJMETHOD(channel_setspeed, nmchan_setspeed), 475 KOBJMETHOD(channel_setblocksize, nmchan_setblocksize), 476 KOBJMETHOD(channel_trigger, nmchan_trigger), 477 KOBJMETHOD(channel_getptr, nmchan_getptr), 478 KOBJMETHOD(channel_getcaps, nmchan_getcaps), 479 { 0, 0 } 480 }; 481 CHANNEL_DECLARE(nmchan); 482 483 /* The interrupt handler */ 484 static void 485 nm_intr(void *p) 486 { 487 struct sc_info *sc = (struct sc_info *)p; 488 int status, x; 489 490 status = nm_rd(sc, NM_INT_REG, sc->irsz); 491 if (status == 0) 492 return; 493 494 if (status & sc->playint) { 495 status &= ~sc->playint; 496 sc->pch.wmark += sc->pch.blksize; 497 sc->pch.wmark %= NM_BUFFSIZE; 498 nm_wr(sc, NM_PBUFFER_WMARK, sc->pbuf + sc->pch.wmark, 4); 499 500 nm_ackint(sc, sc->playint); 501 chn_intr(sc->pch.channel); 502 } 503 if (status & sc->recint) { 504 status &= ~sc->recint; 505 sc->rch.wmark += sc->rch.blksize; 506 sc->rch.wmark %= NM_BUFFSIZE; 507 nm_wr(sc, NM_RBUFFER_WMARK, sc->rbuf + sc->rch.wmark, 4); 508 509 nm_ackint(sc, sc->recint); 510 chn_intr(sc->rch.channel); 511 } 512 if (status & sc->misc1int) { 513 status &= ~sc->misc1int; 514 nm_ackint(sc, sc->misc1int); 515 x = nm_rd(sc, 0x400, 1); 516 nm_wr(sc, 0x400, x | 2, 1); 517 device_printf(sc->dev, "misc int 1\n"); 518 } 519 if (status & sc->misc2int) { 520 status &= ~sc->misc2int; 521 nm_ackint(sc, sc->misc2int); 522 x = nm_rd(sc, 0x400, 1); 523 nm_wr(sc, 0x400, x & ~2, 1); 524 device_printf(sc->dev, "misc int 2\n"); 525 } 526 if (status) { 527 nm_ackint(sc, status); 528 device_printf(sc->dev, "unknown int\n"); 529 } 530 } 531 532 /* -------------------------------------------------------------------- */ 533 534 /* 535 * Probe and attach the card 536 */ 537 538 static int 539 nm_init(struct sc_info *sc) 540 { 541 u_int32_t ofs, i; 542 543 if (sc->type == NM256AV_PCI_ID) { 544 sc->ac97_base = NM_MIXER_OFFSET; 545 sc->ac97_status = NM_MIXER_STATUS_OFFSET; 546 sc->ac97_busy = NM_MIXER_READY_MASK; 547 548 sc->buftop = 2560 * 1024; 549 550 sc->irsz = 2; 551 sc->playint = NM_PLAYBACK_INT; 552 sc->recint = NM_RECORD_INT; 553 sc->misc1int = NM_MISC_INT_1; 554 sc->misc2int = NM_MISC_INT_2; 555 } else if (sc->type == NM256ZX_PCI_ID) { 556 sc->ac97_base = NM_MIXER_OFFSET; 557 sc->ac97_status = NM2_MIXER_STATUS_OFFSET; 558 sc->ac97_busy = NM2_MIXER_READY_MASK; 559 560 sc->buftop = (nm_rd(sc, 0xa0b, 2)? 6144 : 4096) * 1024; 561 562 sc->irsz = 4; 563 sc->playint = NM2_PLAYBACK_INT; 564 sc->recint = NM2_RECORD_INT; 565 sc->misc1int = NM2_MISC_INT_1; 566 sc->misc2int = NM2_MISC_INT_2; 567 } else return -1; 568 sc->badintr = 0; 569 ofs = sc->buftop - 0x0400; 570 sc->buftop -= 0x1400; 571 572 if (bootverbose) 573 device_printf(sc->dev, "buftop is 0x%08x\n", sc->buftop); 574 if ((nm_rdbuf(sc, ofs, 4) & NM_SIG_MASK) == NM_SIGNATURE) { 575 i = nm_rdbuf(sc, ofs + 4, 4); 576 if (i != 0 && i != 0xffffffff) { 577 if (bootverbose) 578 device_printf(sc->dev, "buftop is changed to 0x%08x\n", i); 579 sc->buftop = i; 580 } 581 } 582 583 sc->cbuf = sc->buftop - NM_MAX_COEFFICIENT; 584 sc->rbuf = sc->cbuf - NM_BUFFSIZE; 585 sc->pbuf = sc->rbuf - NM_BUFFSIZE; 586 sc->acbuf = sc->pbuf - (NM_TOTAL_COEFF_COUNT * 4); 587 588 nm_wr(sc, 0, 0x11, 1); 589 nm_wr(sc, NM_RECORD_ENABLE_REG, 0, 1); 590 nm_wr(sc, 0x214, 0, 2); 591 592 return 0; 593 } 594 595 static int 596 nm_pci_probe(device_t dev) 597 { 598 struct sc_info *sc = NULL; 599 char *s = NULL; 600 u_int32_t subdev, i, data; 601 602 subdev = (pci_get_subdevice(dev) << 16) | pci_get_subvendor(dev); 603 switch (pci_get_devid(dev)) { 604 case NM256AV_PCI_ID: 605 i = 0; 606 while ((i < NUM_BADCARDS) && (badcards[i] != subdev)) 607 i++; 608 609 /* Try to catch other non-ac97 cards */ 610 611 if (i == NUM_BADCARDS) { 612 sc = kmalloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO); 613 data = pci_read_config(dev, PCIR_COMMAND, 2); 614 pci_write_config(dev, PCIR_COMMAND, data | 615 PCIM_CMD_PORTEN | PCIM_CMD_MEMEN | 616 PCIM_CMD_BUSMASTEREN, 2); 617 618 sc->regid = PCIR_BAR(1); 619 sc->reg = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 620 &sc->regid, 621 RF_ACTIVE); 622 623 if (!sc->reg) { 624 device_printf(dev, "unable to map register space\n"); 625 pci_write_config(dev, PCIR_COMMAND, data, 2); 626 kfree(sc, M_DEVBUF); 627 return ENXIO; 628 } 629 630 /* 631 * My Panasonic CF-M2EV needs resetting device 632 * before checking mixer is present or not. 633 * t.ichinoseki@nifty.com. 634 */ 635 nm_wr(sc, 0, 0x11, 1); /* reset device */ 636 if ((nm_rd(sc, NM_MIXER_PRESENCE, 2) & 637 NM_PRESENCE_MASK) != NM_PRESENCE_VALUE) { 638 i = 0; /* non-ac97 card, but not listed */ 639 DEB(device_printf(dev, "subdev = 0x%x - badcard?\n", 640 subdev)); 641 } 642 pci_write_config(dev, PCIR_COMMAND, data, 2); 643 bus_release_resource(dev, SYS_RES_MEMORY, sc->regid, 644 sc->reg); 645 kfree(sc, M_DEVBUF); 646 } 647 648 if (i == NUM_BADCARDS) 649 s = "NeoMagic 256AV"; 650 DEB(else) 651 DEB(device_printf(dev, "this is a non-ac97 NM256AV, not attaching\n")); 652 653 break; 654 655 case NM256ZX_PCI_ID: 656 s = "NeoMagic 256ZX"; 657 break; 658 } 659 660 if (s) device_set_desc(dev, s); 661 return s? 0 : ENXIO; 662 } 663 664 static int 665 nm_pci_attach(device_t dev) 666 { 667 u_int32_t data; 668 struct sc_info *sc; 669 struct ac97_info *codec = NULL; 670 char status[SND_STATUSLEN]; 671 672 sc = kmalloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO); 673 sc->dev = dev; 674 sc->type = pci_get_devid(dev); 675 676 data = pci_read_config(dev, PCIR_COMMAND, 2); 677 data |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN); 678 pci_write_config(dev, PCIR_COMMAND, data, 2); 679 data = pci_read_config(dev, PCIR_COMMAND, 2); 680 681 sc->bufid = PCIR_BAR(0); 682 sc->buf = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->bufid, 683 RF_ACTIVE); 684 sc->regid = PCIR_BAR(1); 685 sc->reg = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->regid, 686 RF_ACTIVE); 687 688 if (!sc->buf || !sc->reg) { 689 device_printf(dev, "unable to map register space\n"); 690 goto bad; 691 } 692 693 if (nm_init(sc) == -1) { 694 device_printf(dev, "unable to initialize the card\n"); 695 goto bad; 696 } 697 698 codec = AC97_CREATE(dev, sc, nm_ac97); 699 if (codec == NULL) goto bad; 700 if (mixer_init(dev, ac97_getmixerclass(), codec) == -1) goto bad; 701 702 sc->irqid = 0; 703 sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqid, 704 RF_ACTIVE | RF_SHAREABLE); 705 if (!sc->irq || snd_setup_intr(dev, sc->irq, 0, nm_intr, sc, &sc->ih)) { 706 device_printf(dev, "unable to map interrupt\n"); 707 goto bad; 708 } 709 710 ksnprintf(status, SND_STATUSLEN, "at memory 0x%lx, 0x%lx irq %ld %s", 711 rman_get_start(sc->buf), rman_get_start(sc->reg), 712 rman_get_start(sc->irq),PCM_KLDSTRING(snd_neomagic)); 713 714 if (pcm_register(dev, sc, 1, 1)) goto bad; 715 pcm_addchan(dev, PCMDIR_REC, &nmchan_class, sc); 716 pcm_addchan(dev, PCMDIR_PLAY, &nmchan_class, sc); 717 pcm_setstatus(dev, status); 718 719 return 0; 720 721 bad: 722 if (codec) ac97_destroy(codec); 723 if (sc->buf) bus_release_resource(dev, SYS_RES_MEMORY, sc->bufid, sc->buf); 724 if (sc->reg) bus_release_resource(dev, SYS_RES_MEMORY, sc->regid, sc->reg); 725 if (sc->ih) bus_teardown_intr(dev, sc->irq, sc->ih); 726 if (sc->irq) bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq); 727 kfree(sc, M_DEVBUF); 728 return ENXIO; 729 } 730 731 static int 732 nm_pci_detach(device_t dev) 733 { 734 int r; 735 struct sc_info *sc; 736 737 r = pcm_unregister(dev); 738 if (r) 739 return r; 740 741 sc = pcm_getdevinfo(dev); 742 bus_release_resource(dev, SYS_RES_MEMORY, sc->bufid, sc->buf); 743 bus_release_resource(dev, SYS_RES_MEMORY, sc->regid, sc->reg); 744 bus_teardown_intr(dev, sc->irq, sc->ih); 745 bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq); 746 kfree(sc, M_DEVBUF); 747 748 return 0; 749 } 750 751 static int 752 nm_pci_suspend(device_t dev) 753 { 754 struct sc_info *sc; 755 756 sc = pcm_getdevinfo(dev); 757 758 /* stop playing */ 759 if (sc->pch.active) { 760 nm_wr(sc, NM_PLAYBACK_ENABLE_REG, 0, 1); 761 nm_wr(sc, NM_AUDIO_MUTE_REG, NM_AUDIO_MUTE_BOTH, 2); 762 } 763 /* stop recording */ 764 if (sc->rch.active) { 765 nm_wr(sc, NM_RECORD_ENABLE_REG, 0, 1); 766 } 767 return 0; 768 } 769 770 static int 771 nm_pci_resume(device_t dev) 772 { 773 struct sc_info *sc; 774 775 sc = pcm_getdevinfo(dev); 776 777 /* 778 * Reinit audio device. 779 * Don't call nm_init(). It would change buftop if X ran or 780 * is running. This makes playing and recording buffer address 781 * shift but these buffers of channel layer are not changed. 782 * As a result of this inconsistency, periodic noise will be 783 * generated while playing. 784 */ 785 nm_wr(sc, 0, 0x11, 1); 786 nm_wr(sc, 0x214, 0, 2); 787 788 /* Reinit mixer */ 789 if (mixer_reinit(dev) == -1) { 790 device_printf(dev, "unable to reinitialize the mixer\n"); 791 return ENXIO; 792 } 793 /* restart playing */ 794 if (sc->pch.active) { 795 nm_wr(sc, NM_PLAYBACK_ENABLE_REG, NM_PLAYBACK_FREERUN | 796 NM_PLAYBACK_ENABLE_FLAG, 1); 797 nm_wr(sc, NM_AUDIO_MUTE_REG, 0, 2); 798 } 799 /* restart recording */ 800 if (sc->rch.active) { 801 nm_wr(sc, NM_RECORD_ENABLE_REG, NM_RECORD_FREERUN | 802 NM_RECORD_ENABLE_FLAG, 1); 803 } 804 return 0; 805 } 806 807 static device_method_t nm_methods[] = { 808 /* Device interface */ 809 DEVMETHOD(device_probe, nm_pci_probe), 810 DEVMETHOD(device_attach, nm_pci_attach), 811 DEVMETHOD(device_detach, nm_pci_detach), 812 DEVMETHOD(device_suspend, nm_pci_suspend), 813 DEVMETHOD(device_resume, nm_pci_resume), 814 { 0, 0 } 815 }; 816 817 static driver_t nm_driver = { 818 "pcm", 819 nm_methods, 820 PCM_SOFTC_SIZE, 821 }; 822 823 DRIVER_MODULE(snd_neomagic, pci, nm_driver, pcm_devclass, NULL, NULL); 824 MODULE_DEPEND(snd_neomagic, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER); 825 MODULE_VERSION(snd_neomagic, 1); 826