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