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