1 /* 2 * Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk> 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$ 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 <pci/pcireg.h> 37 #include <pci/pcivar.h> 38 39 /* -------------------------------------------------------------------- */ 40 41 #define NM_BUFFSIZE 16384 42 43 #define NM256AV_PCI_ID 0x800510c8 44 #define NM256ZX_PCI_ID 0x800610c8 45 46 struct sc_info; 47 48 /* channel registers */ 49 struct sc_chinfo { 50 int spd, dir, fmt; 51 snd_dbuf *buffer; 52 pcm_channel *channel; 53 struct sc_info *parent; 54 }; 55 56 /* device private data */ 57 struct sc_info { 58 device_t dev; 59 u_int32_t type; 60 61 struct resource *reg, *irq, *buf; 62 int regid, irqid, bufid; 63 void *ih; 64 65 u_int32_t ac97_base, ac97_status, ac97_busy; 66 u_int32_t buftop, pbuf, rbuf, cbuf, acbuf; 67 u_int32_t playint, recint, misc1int, misc2int; 68 u_int32_t irsz, badintr; 69 70 struct sc_chinfo pch, rch; 71 }; 72 73 /* -------------------------------------------------------------------- */ 74 75 /* 76 * prototypes 77 */ 78 79 /* channel interface */ 80 static void *nmchan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir); 81 static int nmchan_setdir(void *data, int dir); 82 static int nmchan_setformat(void *data, u_int32_t format); 83 static int nmchan_setspeed(void *data, u_int32_t speed); 84 static int nmchan_setblocksize(void *data, u_int32_t blocksize); 85 static int nmchan_trigger(void *data, int go); 86 static int nmchan_getptr(void *data); 87 static pcmchan_caps *nmchan_getcaps(void *data); 88 89 static int nm_waitcd(struct sc_info *sc); 90 /* talk to the codec - called from ac97.c */ 91 static u_int32_t nm_rdcd(void *, int); 92 static void nm_wrcd(void *, int, u_int32_t); 93 94 /* stuff */ 95 static int nm_loadcoeff(struct sc_info *sc, int dir, int num); 96 static int nm_setch(struct sc_chinfo *ch); 97 static int nm_init(struct sc_info *); 98 static void nm_intr(void *); 99 100 /* talk to the card */ 101 static u_int32_t nm_rd(struct sc_info *, int, int); 102 static void nm_wr(struct sc_info *, int, u_int32_t, int); 103 static u_int32_t nm_rdbuf(struct sc_info *, int, int); 104 static void nm_wrbuf(struct sc_info *, int, u_int32_t, int); 105 106 static u_int32_t badcards[] = { 107 0x0007103c, 108 0x008f1028, 109 }; 110 #define NUM_BADCARDS (sizeof(badcards) / sizeof(u_int32_t)) 111 112 /* The actual rates supported by the card. */ 113 static int samplerates[9] = { 114 8000, 115 11025, 116 16000, 117 22050, 118 24000, 119 32000, 120 44100, 121 48000, 122 99999999 123 }; 124 125 /* -------------------------------------------------------------------- */ 126 127 static pcmchan_caps nm_caps = { 128 4000, 48000, 129 AFMT_STEREO | AFMT_U8 | AFMT_S16_LE, 130 AFMT_STEREO | AFMT_S16_LE 131 }; 132 133 static pcm_channel nm_chantemplate = { 134 nmchan_init, 135 nmchan_setdir, 136 nmchan_setformat, 137 nmchan_setspeed, 138 nmchan_setblocksize, 139 nmchan_trigger, 140 nmchan_getptr, 141 nmchan_getcaps, 142 }; 143 144 /* -------------------------------------------------------------------- */ 145 146 /* Hardware */ 147 static u_int32_t 148 nm_rd(struct sc_info *sc, int regno, 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 return bus_space_read_1(st, sh, regno); 156 case 2: 157 return bus_space_read_2(st, sh, regno); 158 case 4: 159 return bus_space_read_4(st, sh, regno); 160 default: 161 return 0xffffffff; 162 } 163 } 164 165 static void 166 nm_wr(struct sc_info *sc, int regno, u_int32_t data, int size) 167 { 168 bus_space_tag_t st = rman_get_bustag(sc->reg); 169 bus_space_handle_t sh = rman_get_bushandle(sc->reg); 170 171 switch (size) { 172 case 1: 173 bus_space_write_1(st, sh, regno, data); 174 break; 175 case 2: 176 bus_space_write_2(st, sh, regno, data); 177 break; 178 case 4: 179 bus_space_write_4(st, sh, regno, data); 180 break; 181 } 182 } 183 184 static u_int32_t 185 nm_rdbuf(struct sc_info *sc, int regno, 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 return bus_space_read_1(st, sh, regno); 193 case 2: 194 return bus_space_read_2(st, sh, regno); 195 case 4: 196 return bus_space_read_4(st, sh, regno); 197 default: 198 return 0xffffffff; 199 } 200 } 201 202 static void 203 nm_wrbuf(struct sc_info *sc, int regno, u_int32_t data, int size) 204 { 205 bus_space_tag_t st = rman_get_bustag(sc->buf); 206 bus_space_handle_t sh = rman_get_bushandle(sc->buf); 207 208 switch (size) { 209 case 1: 210 bus_space_write_1(st, sh, regno, data); 211 break; 212 case 2: 213 bus_space_write_2(st, sh, regno, data); 214 break; 215 case 4: 216 bus_space_write_4(st, sh, regno, data); 217 break; 218 } 219 } 220 221 /* ac97 codec */ 222 static int 223 nm_waitcd(struct sc_info *sc) 224 { 225 int cnt = 10; 226 227 while (cnt-- > 0) { 228 if (nm_rd(sc, sc->ac97_status, 2) & sc->ac97_busy) 229 DELAY(100); 230 else 231 break; 232 } 233 return (nm_rd(sc, sc->ac97_status, 2) & sc->ac97_busy); 234 } 235 236 static u_int32_t 237 nm_initcd(void *devinfo) 238 { 239 struct sc_info *sc = (struct sc_info *)devinfo; 240 241 nm_wr(sc, 0x6c0, 0x01, 1); 242 nm_wr(sc, 0x6cc, 0x87, 1); 243 nm_wr(sc, 0x6cc, 0x80, 1); 244 nm_wr(sc, 0x6cc, 0x00, 1); 245 return 0; 246 } 247 248 static u_int32_t 249 nm_rdcd(void *devinfo, int regno) 250 { 251 struct sc_info *sc = (struct sc_info *)devinfo; 252 u_int32_t x; 253 254 if (!nm_waitcd(sc)) { 255 x = nm_rd(sc, sc->ac97_base + regno, 2); 256 DELAY(1000); 257 return x; 258 } else { 259 device_printf(sc->dev, "ac97 codec not ready\n"); 260 return 0xffffffff; 261 } 262 } 263 264 static void 265 nm_wrcd(void *devinfo, int regno, u_int32_t data) 266 { 267 struct sc_info *sc = (struct sc_info *)devinfo; 268 int cnt = 3; 269 270 if (!nm_waitcd(sc)) { 271 while (cnt-- > 0) { 272 nm_wr(sc, sc->ac97_base + regno, data, 2); 273 if (!nm_waitcd(sc)) { 274 DELAY(1000); 275 return; 276 } 277 } 278 } 279 device_printf(sc->dev, "ac97 codec not ready\n"); 280 } 281 282 static void 283 nm_ackint(struct sc_info *sc, u_int32_t num) 284 { 285 if (sc->type == NM256AV_PCI_ID) { 286 nm_wr(sc, NM_INT_REG, num << 1, 2); 287 } else if (sc->type == NM256ZX_PCI_ID) { 288 nm_wr(sc, NM_INT_REG, num, 4); 289 } 290 } 291 292 static int 293 nm_loadcoeff(struct sc_info *sc, int dir, int num) 294 { 295 int ofs, sz, i; 296 u_int32_t addr; 297 298 addr = (dir == PCMDIR_PLAY)? 0x01c : 0x21c; 299 if (dir == PCMDIR_REC) 300 num += 8; 301 sz = coefficientSizes[num]; 302 ofs = 0; 303 while (num-- > 0) 304 ofs+= coefficientSizes[num]; 305 for (i = 0; i < sz; i++) 306 nm_wrbuf(sc, sc->cbuf + i, coefficients[ofs + i], 1); 307 nm_wr(sc, addr, sc->cbuf, 4); 308 if (dir == PCMDIR_PLAY) 309 sz--; 310 nm_wr(sc, addr + 4, sc->cbuf + sz, 4); 311 return 0; 312 } 313 314 static int 315 nm_setch(struct sc_chinfo *ch) 316 { 317 struct sc_info *sc = ch->parent; 318 u_int32_t base; 319 u_int8_t x; 320 321 for (x = 0; x < 8; x++) 322 if (ch->spd < (samplerates[x] + samplerates[x + 1]) / 2) 323 break; 324 325 if (x == 8) return 1; 326 327 ch->spd = samplerates[x]; 328 nm_loadcoeff(sc, ch->dir, x); 329 330 x <<= 4; 331 x &= NM_RATE_MASK; 332 if (ch->fmt & AFMT_16BIT) x |= NM_RATE_BITS_16; 333 if (ch->fmt & AFMT_STEREO) x |= NM_RATE_STEREO; 334 335 base = (ch->dir == PCMDIR_PLAY)? NM_PLAYBACK_REG_OFFSET : NM_RECORD_REG_OFFSET; 336 nm_wr(sc, base + NM_RATE_REG_OFFSET, x, 1); 337 return 0; 338 } 339 340 /* channel interface */ 341 static void * 342 nmchan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) 343 { 344 struct sc_info *sc = devinfo; 345 struct sc_chinfo *ch; 346 u_int32_t chnbuf; 347 348 chnbuf = (dir == PCMDIR_PLAY)? sc->pbuf : sc->rbuf; 349 ch = (dir == PCMDIR_PLAY)? &sc->pch : &sc->rch; 350 ch->buffer = b; 351 ch->buffer->bufsize = NM_BUFFSIZE; 352 ch->buffer->buf = (u_int8_t *)(rman_get_bushandle(sc->buf) + chnbuf); 353 if (bootverbose) 354 device_printf(sc->dev, "%s buf %p\n", (dir == PCMDIR_PLAY)? 355 "play" : "rec", ch->buffer->buf); 356 ch->parent = sc; 357 ch->channel = c; 358 ch->dir = dir; 359 return ch; 360 } 361 362 static int 363 nmchan_setdir(void *data, int dir) 364 { 365 return 0; 366 } 367 368 static int 369 nmchan_setformat(void *data, u_int32_t format) 370 { 371 struct sc_chinfo *ch = data; 372 373 ch->fmt = format; 374 return nm_setch(ch); 375 } 376 377 static int 378 nmchan_setspeed(void *data, u_int32_t speed) 379 { 380 struct sc_chinfo *ch = data; 381 382 ch->spd = speed; 383 return nm_setch(ch)? 0 : ch->spd; 384 } 385 386 static int 387 nmchan_setblocksize(void *data, u_int32_t blocksize) 388 { 389 return blocksize; 390 } 391 392 static int 393 nmchan_trigger(void *data, int go) 394 { 395 struct sc_chinfo *ch = data; 396 struct sc_info *sc = ch->parent; 397 int ssz; 398 399 if (go == PCMTRIG_EMLDMAWR) return 0; 400 401 ssz = (ch->fmt & AFMT_16BIT)? 2 : 1; 402 if (ch->fmt & AFMT_STEREO) 403 ssz <<= 1; 404 405 if (ch->dir == PCMDIR_PLAY) { 406 if (go == PCMTRIG_START) { 407 nm_wr(sc, NM_PBUFFER_START, sc->pbuf, 4); 408 nm_wr(sc, NM_PBUFFER_END, sc->pbuf + NM_BUFFSIZE - ssz, 4); 409 nm_wr(sc, NM_PBUFFER_CURRP, sc->pbuf, 4); 410 nm_wr(sc, NM_PBUFFER_WMARK, sc->pbuf + NM_BUFFSIZE / 2, 4); 411 nm_wr(sc, NM_PLAYBACK_ENABLE_REG, NM_PLAYBACK_FREERUN | 412 NM_PLAYBACK_ENABLE_FLAG, 1); 413 nm_wr(sc, NM_AUDIO_MUTE_REG, 0, 2); 414 } else { 415 nm_wr(sc, NM_PLAYBACK_ENABLE_REG, 0, 1); 416 nm_wr(sc, NM_AUDIO_MUTE_REG, NM_AUDIO_MUTE_BOTH, 2); 417 } 418 } else { 419 if (go == PCMTRIG_START) { 420 nm_wr(sc, NM_RECORD_ENABLE_REG, NM_RECORD_FREERUN | 421 NM_RECORD_ENABLE_FLAG, 1); 422 nm_wr(sc, NM_RBUFFER_START, sc->rbuf, 4); 423 nm_wr(sc, NM_RBUFFER_END, sc->rbuf + NM_BUFFSIZE, 4); 424 nm_wr(sc, NM_RBUFFER_CURRP, sc->rbuf, 4); 425 nm_wr(sc, NM_RBUFFER_WMARK, sc->rbuf + NM_BUFFSIZE / 2, 4); 426 } else { 427 nm_wr(sc, NM_RECORD_ENABLE_REG, 0, 1); 428 } 429 } 430 return 0; 431 } 432 433 static int 434 nmchan_getptr(void *data) 435 { 436 struct sc_chinfo *ch = data; 437 struct sc_info *sc = ch->parent; 438 439 if (ch->dir == PCMDIR_PLAY) 440 return nm_rd(sc, NM_PBUFFER_CURRP, 4) - sc->pbuf; 441 else 442 return nm_rd(sc, NM_RBUFFER_CURRP, 4) - sc->rbuf; 443 } 444 445 static pcmchan_caps * 446 nmchan_getcaps(void *data) 447 { 448 return &nm_caps; 449 } 450 451 /* The interrupt handler */ 452 static void 453 nm_intr(void *p) 454 { 455 struct sc_info *sc = (struct sc_info *)p; 456 int status, x, active; 457 458 active = (sc->pch.channel->buffer.dl || sc->rch.channel->buffer.dl); 459 status = nm_rd(sc, NM_INT_REG, sc->irsz); 460 if (status == 0 && active) { 461 if (sc->badintr++ > 1000) { 462 device_printf(sc->dev, "1000 bad intrs\n"); 463 sc->badintr = 0; 464 } 465 return; 466 } 467 sc->badintr = 0; 468 469 if (status & sc->playint) { 470 status &= ~sc->playint; 471 nm_ackint(sc, sc->playint); 472 chn_intr(sc->pch.channel); 473 } 474 if (status & sc->recint) { 475 status &= ~sc->recint; 476 nm_ackint(sc, sc->recint); 477 chn_intr(sc->rch.channel); 478 } 479 if (status & sc->misc1int) { 480 status &= ~sc->misc1int; 481 nm_ackint(sc, sc->misc1int); 482 x = nm_rd(sc, 0x400, 1); 483 nm_wr(sc, 0x400, x | 2, 1); 484 device_printf(sc->dev, "misc int 1\n"); 485 } 486 if (status & sc->misc2int) { 487 status &= ~sc->misc2int; 488 nm_ackint(sc, sc->misc2int); 489 x = nm_rd(sc, 0x400, 1); 490 nm_wr(sc, 0x400, x & ~2, 1); 491 device_printf(sc->dev, "misc int 2\n"); 492 } 493 if (status) { 494 status &= ~sc->misc2int; 495 nm_ackint(sc, sc->misc2int); 496 device_printf(sc->dev, "unknown int\n"); 497 } 498 } 499 500 /* -------------------------------------------------------------------- */ 501 502 /* 503 * Probe and attach the card 504 */ 505 506 static int 507 nm_init(struct sc_info *sc) 508 { 509 u_int32_t ofs, i; 510 511 if (sc->type == NM256AV_PCI_ID) { 512 sc->ac97_base = NM_MIXER_OFFSET; 513 sc->ac97_status = NM_MIXER_STATUS_OFFSET; 514 sc->ac97_busy = NM_MIXER_READY_MASK; 515 516 sc->buftop = 2560 * 1024; 517 518 sc->irsz = 2; 519 sc->playint = NM_PLAYBACK_INT; 520 sc->recint = NM_RECORD_INT; 521 sc->misc1int = NM_MISC_INT_1; 522 sc->misc2int = NM_MISC_INT_2; 523 } else if (sc->type == NM256ZX_PCI_ID) { 524 sc->ac97_base = NM_MIXER_OFFSET; 525 sc->ac97_status = NM2_MIXER_STATUS_OFFSET; 526 sc->ac97_busy = NM2_MIXER_READY_MASK; 527 528 sc->buftop = (nm_rd(sc, 0xa0b, 2)? 6144 : 4096) * 1024; 529 530 sc->irsz = 4; 531 sc->playint = NM2_PLAYBACK_INT; 532 sc->recint = NM2_RECORD_INT; 533 sc->misc1int = NM2_MISC_INT_1; 534 sc->misc2int = NM2_MISC_INT_2; 535 } else return -1; 536 sc->badintr = 0; 537 ofs = sc->buftop - 0x0400; 538 sc->buftop -= 0x1400; 539 540 if ((nm_rdbuf(sc, ofs, 4) & NM_SIG_MASK) == NM_SIGNATURE) { 541 i = nm_rdbuf(sc, ofs + 4, 4); 542 if (i != 0 && i != 0xffffffff) 543 sc->buftop = i; 544 } 545 546 sc->cbuf = sc->buftop - NM_MAX_COEFFICIENT; 547 sc->rbuf = sc->cbuf - NM_BUFFSIZE; 548 sc->pbuf = sc->rbuf - NM_BUFFSIZE; 549 sc->acbuf = sc->pbuf - (NM_TOTAL_COEFF_COUNT * 4); 550 551 nm_wr(sc, 0, 0x11, 1); 552 nm_wr(sc, NM_RECORD_ENABLE_REG, 0, 1); 553 nm_wr(sc, 0x214, 0, 2); 554 555 return 0; 556 } 557 558 static int 559 nm_pci_probe(device_t dev) 560 { 561 char *s = NULL; 562 u_int32_t subdev, i; 563 564 subdev = (pci_get_subdevice(dev) << 16) | pci_get_subvendor(dev); 565 switch (pci_get_devid(dev)) { 566 case NM256AV_PCI_ID: 567 i = 0; 568 while ((i < NUM_BADCARDS) && (badcards[i] != subdev)) 569 i++; 570 if (i == NUM_BADCARDS) 571 s = "NeoMagic 256AV"; 572 DEB(else) 573 DEB(device_printf(dev, "this is a non-ac97 NM256AV, not attaching\n")); 574 break; 575 576 case NM256ZX_PCI_ID: 577 s = "NeoMagic 256ZX"; 578 break; 579 } 580 581 if (s) device_set_desc(dev, s); 582 return s? 0 : ENXIO; 583 } 584 585 static int 586 nm_pci_attach(device_t dev) 587 { 588 snddev_info *d; 589 u_int32_t data; 590 struct sc_info *sc; 591 struct ac97_info *codec; 592 char status[SND_STATUSLEN]; 593 594 d = device_get_softc(dev); 595 if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT)) == NULL) { 596 device_printf(dev, "cannot allocate softc\n"); 597 return ENXIO; 598 } 599 600 bzero(sc, sizeof(*sc)); 601 sc->dev = dev; 602 sc->type = pci_get_devid(dev); 603 604 data = pci_read_config(dev, PCIR_COMMAND, 2); 605 data |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN); 606 pci_write_config(dev, PCIR_COMMAND, data, 2); 607 data = pci_read_config(dev, PCIR_COMMAND, 2); 608 609 sc->bufid = PCIR_MAPS; 610 sc->buf = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->bufid, 611 0, ~0, 1, RF_ACTIVE); 612 sc->regid = PCIR_MAPS + 4; 613 sc->reg = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->regid, 614 0, ~0, 1, RF_ACTIVE); 615 616 if (!sc->buf || !sc->reg) { 617 device_printf(dev, "unable to map register space\n"); 618 goto bad; 619 } 620 621 if (nm_init(sc) == -1) { 622 device_printf(dev, "unable to initialize the card\n"); 623 goto bad; 624 } 625 626 codec = ac97_create(dev, sc, nm_initcd, nm_rdcd, nm_wrcd); 627 if (codec == NULL) goto bad; 628 if (mixer_init(d, &ac97_mixer, codec) == -1) goto bad; 629 630 sc->irqid = 0; 631 sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irqid, 632 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); 633 if (!sc->irq || 634 bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, nm_intr, sc, &sc->ih)) { 635 device_printf(dev, "unable to map interrupt\n"); 636 goto bad; 637 } 638 639 snprintf(status, SND_STATUSLEN, "at memory 0x%lx, 0x%lx irq %ld", 640 rman_get_start(sc->buf), rman_get_start(sc->reg), 641 rman_get_start(sc->irq)); 642 643 if (pcm_register(dev, sc, 1, 1)) goto bad; 644 pcm_addchan(dev, PCMDIR_REC, &nm_chantemplate, sc); 645 pcm_addchan(dev, PCMDIR_PLAY, &nm_chantemplate, sc); 646 pcm_setstatus(dev, status); 647 648 return 0; 649 650 bad: 651 if (sc->buf) bus_release_resource(dev, SYS_RES_MEMORY, sc->bufid, sc->buf); 652 if (sc->reg) bus_release_resource(dev, SYS_RES_MEMORY, sc->regid, sc->reg); 653 if (sc->ih) bus_teardown_intr(dev, sc->irq, sc->ih); 654 if (sc->irq) bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq); 655 free(sc, M_DEVBUF); 656 return ENXIO; 657 } 658 659 static int 660 nm_pci_resume(device_t dev) 661 { 662 snddev_info *d; 663 struct sc_info *sc; 664 665 d = device_get_softc(dev); 666 sc = pcm_getdevinfo(dev); 667 668 /* Reinit audio device */ 669 if (nm_init(sc) == -1) { 670 device_printf(dev, "unable to reinitialize the card\n"); 671 return ENXIO; 672 } 673 /* Reinit mixer */ 674 if (mixer_reinit(d) == -1) { 675 device_printf(dev, "unable to reinitialize the mixer\n"); 676 return ENXIO; 677 } 678 return 0; 679 } 680 681 static device_method_t nm_methods[] = { 682 /* Device interface */ 683 DEVMETHOD(device_probe, nm_pci_probe), 684 DEVMETHOD(device_attach, nm_pci_attach), 685 DEVMETHOD(device_resume, nm_pci_resume), 686 { 0, 0 } 687 }; 688 689 static driver_t nm_driver = { 690 "pcm", 691 nm_methods, 692 sizeof(snddev_info), 693 }; 694 695 static devclass_t pcm_devclass; 696 697 DRIVER_MODULE(nm, pci, nm_driver, pcm_devclass, 0, 0); 698