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_virtual(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 || go == PCMTRIG_EMLDMARD) 400 return 0; 401 402 ssz = (ch->fmt & AFMT_16BIT)? 2 : 1; 403 if (ch->fmt & AFMT_STEREO) 404 ssz <<= 1; 405 406 if (ch->dir == PCMDIR_PLAY) { 407 if (go == PCMTRIG_START) { 408 nm_wr(sc, NM_PBUFFER_START, sc->pbuf, 4); 409 nm_wr(sc, NM_PBUFFER_END, sc->pbuf + NM_BUFFSIZE - ssz, 4); 410 nm_wr(sc, NM_PBUFFER_CURRP, sc->pbuf, 4); 411 nm_wr(sc, NM_PBUFFER_WMARK, sc->pbuf + NM_BUFFSIZE / 2, 4); 412 nm_wr(sc, NM_PLAYBACK_ENABLE_REG, NM_PLAYBACK_FREERUN | 413 NM_PLAYBACK_ENABLE_FLAG, 1); 414 nm_wr(sc, NM_AUDIO_MUTE_REG, 0, 2); 415 } else { 416 nm_wr(sc, NM_PLAYBACK_ENABLE_REG, 0, 1); 417 nm_wr(sc, NM_AUDIO_MUTE_REG, NM_AUDIO_MUTE_BOTH, 2); 418 } 419 } else { 420 if (go == PCMTRIG_START) { 421 nm_wr(sc, NM_RECORD_ENABLE_REG, NM_RECORD_FREERUN | 422 NM_RECORD_ENABLE_FLAG, 1); 423 nm_wr(sc, NM_RBUFFER_START, sc->rbuf, 4); 424 nm_wr(sc, NM_RBUFFER_END, sc->rbuf + NM_BUFFSIZE, 4); 425 nm_wr(sc, NM_RBUFFER_CURRP, sc->rbuf, 4); 426 nm_wr(sc, NM_RBUFFER_WMARK, sc->rbuf + NM_BUFFSIZE / 2, 4); 427 } else { 428 nm_wr(sc, NM_RECORD_ENABLE_REG, 0, 1); 429 } 430 } 431 return 0; 432 } 433 434 static int 435 nmchan_getptr(void *data) 436 { 437 struct sc_chinfo *ch = data; 438 struct sc_info *sc = ch->parent; 439 440 if (ch->dir == PCMDIR_PLAY) 441 return nm_rd(sc, NM_PBUFFER_CURRP, 4) - sc->pbuf; 442 else 443 return nm_rd(sc, NM_RBUFFER_CURRP, 4) - sc->rbuf; 444 } 445 446 static pcmchan_caps * 447 nmchan_getcaps(void *data) 448 { 449 return &nm_caps; 450 } 451 452 /* The interrupt handler */ 453 static void 454 nm_intr(void *p) 455 { 456 struct sc_info *sc = (struct sc_info *)p; 457 int status, x, active; 458 459 active = (sc->pch.channel->buffer.dl || sc->rch.channel->buffer.dl); 460 status = nm_rd(sc, NM_INT_REG, sc->irsz); 461 if (status == 0 && active) { 462 if (sc->badintr++ > 1000) { 463 device_printf(sc->dev, "1000 bad intrs\n"); 464 sc->badintr = 0; 465 } 466 return; 467 } 468 sc->badintr = 0; 469 470 if (status & sc->playint) { 471 status &= ~sc->playint; 472 nm_ackint(sc, sc->playint); 473 chn_intr(sc->pch.channel); 474 } 475 if (status & sc->recint) { 476 status &= ~sc->recint; 477 nm_ackint(sc, sc->recint); 478 chn_intr(sc->rch.channel); 479 } 480 if (status & sc->misc1int) { 481 status &= ~sc->misc1int; 482 nm_ackint(sc, sc->misc1int); 483 x = nm_rd(sc, 0x400, 1); 484 nm_wr(sc, 0x400, x | 2, 1); 485 device_printf(sc->dev, "misc int 1\n"); 486 } 487 if (status & sc->misc2int) { 488 status &= ~sc->misc2int; 489 nm_ackint(sc, sc->misc2int); 490 x = nm_rd(sc, 0x400, 1); 491 nm_wr(sc, 0x400, x & ~2, 1); 492 device_printf(sc->dev, "misc int 2\n"); 493 } 494 if (status) { 495 status &= ~sc->misc2int; 496 nm_ackint(sc, sc->misc2int); 497 device_printf(sc->dev, "unknown int\n"); 498 } 499 } 500 501 /* -------------------------------------------------------------------- */ 502 503 /* 504 * Probe and attach the card 505 */ 506 507 static int 508 nm_init(struct sc_info *sc) 509 { 510 u_int32_t ofs, i; 511 512 if (sc->type == NM256AV_PCI_ID) { 513 sc->ac97_base = NM_MIXER_OFFSET; 514 sc->ac97_status = NM_MIXER_STATUS_OFFSET; 515 sc->ac97_busy = NM_MIXER_READY_MASK; 516 517 sc->buftop = 2560 * 1024; 518 519 sc->irsz = 2; 520 sc->playint = NM_PLAYBACK_INT; 521 sc->recint = NM_RECORD_INT; 522 sc->misc1int = NM_MISC_INT_1; 523 sc->misc2int = NM_MISC_INT_2; 524 } else if (sc->type == NM256ZX_PCI_ID) { 525 sc->ac97_base = NM_MIXER_OFFSET; 526 sc->ac97_status = NM2_MIXER_STATUS_OFFSET; 527 sc->ac97_busy = NM2_MIXER_READY_MASK; 528 529 sc->buftop = (nm_rd(sc, 0xa0b, 2)? 6144 : 4096) * 1024; 530 531 sc->irsz = 4; 532 sc->playint = NM2_PLAYBACK_INT; 533 sc->recint = NM2_RECORD_INT; 534 sc->misc1int = NM2_MISC_INT_1; 535 sc->misc2int = NM2_MISC_INT_2; 536 } else return -1; 537 sc->badintr = 0; 538 ofs = sc->buftop - 0x0400; 539 sc->buftop -= 0x1400; 540 541 if ((nm_rdbuf(sc, ofs, 4) & NM_SIG_MASK) == NM_SIGNATURE) { 542 i = nm_rdbuf(sc, ofs + 4, 4); 543 if (i != 0 && i != 0xffffffff) 544 sc->buftop = i; 545 } 546 547 sc->cbuf = sc->buftop - NM_MAX_COEFFICIENT; 548 sc->rbuf = sc->cbuf - NM_BUFFSIZE; 549 sc->pbuf = sc->rbuf - NM_BUFFSIZE; 550 sc->acbuf = sc->pbuf - (NM_TOTAL_COEFF_COUNT * 4); 551 552 nm_wr(sc, 0, 0x11, 1); 553 nm_wr(sc, NM_RECORD_ENABLE_REG, 0, 1); 554 nm_wr(sc, 0x214, 0, 2); 555 556 return 0; 557 } 558 559 static int 560 nm_pci_probe(device_t dev) 561 { 562 char *s = NULL; 563 u_int32_t subdev, i; 564 565 subdev = (pci_get_subdevice(dev) << 16) | pci_get_subvendor(dev); 566 switch (pci_get_devid(dev)) { 567 case NM256AV_PCI_ID: 568 i = 0; 569 while ((i < NUM_BADCARDS) && (badcards[i] != subdev)) 570 i++; 571 if (i == NUM_BADCARDS) 572 s = "NeoMagic 256AV"; 573 DEB(else) 574 DEB(device_printf(dev, "this is a non-ac97 NM256AV, not attaching\n")); 575 break; 576 577 case NM256ZX_PCI_ID: 578 s = "NeoMagic 256ZX"; 579 break; 580 } 581 582 if (s) device_set_desc(dev, s); 583 return s? 0 : ENXIO; 584 } 585 586 static int 587 nm_pci_attach(device_t dev) 588 { 589 snddev_info *d; 590 u_int32_t data; 591 struct sc_info *sc; 592 struct ac97_info *codec; 593 char status[SND_STATUSLEN]; 594 595 d = device_get_softc(dev); 596 if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT)) == NULL) { 597 device_printf(dev, "cannot allocate softc\n"); 598 return ENXIO; 599 } 600 601 bzero(sc, sizeof(*sc)); 602 sc->dev = dev; 603 sc->type = pci_get_devid(dev); 604 605 data = pci_read_config(dev, PCIR_COMMAND, 2); 606 data |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN); 607 pci_write_config(dev, PCIR_COMMAND, data, 2); 608 data = pci_read_config(dev, PCIR_COMMAND, 2); 609 610 sc->bufid = PCIR_MAPS; 611 sc->buf = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->bufid, 612 0, ~0, 1, RF_ACTIVE); 613 sc->regid = PCIR_MAPS + 4; 614 sc->reg = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->regid, 615 0, ~0, 1, RF_ACTIVE); 616 617 if (!sc->buf || !sc->reg) { 618 device_printf(dev, "unable to map register space\n"); 619 goto bad; 620 } 621 622 if (nm_init(sc) == -1) { 623 device_printf(dev, "unable to initialize the card\n"); 624 goto bad; 625 } 626 627 codec = ac97_create(dev, sc, nm_initcd, nm_rdcd, nm_wrcd); 628 if (codec == NULL) goto bad; 629 if (mixer_init(d, &ac97_mixer, codec) == -1) goto bad; 630 631 sc->irqid = 0; 632 sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irqid, 633 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); 634 if (!sc->irq || 635 bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, nm_intr, sc, &sc->ih)) { 636 device_printf(dev, "unable to map interrupt\n"); 637 goto bad; 638 } 639 640 snprintf(status, SND_STATUSLEN, "at memory 0x%lx, 0x%lx irq %ld", 641 rman_get_start(sc->buf), rman_get_start(sc->reg), 642 rman_get_start(sc->irq)); 643 644 if (pcm_register(dev, sc, 1, 1)) goto bad; 645 pcm_addchan(dev, PCMDIR_REC, &nm_chantemplate, sc); 646 pcm_addchan(dev, PCMDIR_PLAY, &nm_chantemplate, sc); 647 pcm_setstatus(dev, status); 648 649 return 0; 650 651 bad: 652 if (sc->buf) bus_release_resource(dev, SYS_RES_MEMORY, sc->bufid, sc->buf); 653 if (sc->reg) bus_release_resource(dev, SYS_RES_MEMORY, sc->regid, sc->reg); 654 if (sc->ih) bus_teardown_intr(dev, sc->irq, sc->ih); 655 if (sc->irq) bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq); 656 free(sc, M_DEVBUF); 657 return ENXIO; 658 } 659 660 static int 661 nm_pci_resume(device_t dev) 662 { 663 snddev_info *d; 664 struct sc_info *sc; 665 666 d = device_get_softc(dev); 667 sc = pcm_getdevinfo(dev); 668 669 /* Reinit audio device */ 670 if (nm_init(sc) == -1) { 671 device_printf(dev, "unable to reinitialize the card\n"); 672 return ENXIO; 673 } 674 /* Reinit mixer */ 675 if (mixer_reinit(d) == -1) { 676 device_printf(dev, "unable to reinitialize the mixer\n"); 677 return ENXIO; 678 } 679 return 0; 680 } 681 682 static device_method_t nm_methods[] = { 683 /* Device interface */ 684 DEVMETHOD(device_probe, nm_pci_probe), 685 DEVMETHOD(device_attach, nm_pci_attach), 686 DEVMETHOD(device_resume, nm_pci_resume), 687 { 0, 0 } 688 }; 689 690 static driver_t nm_driver = { 691 "pcm", 692 nm_methods, 693 sizeof(snddev_info), 694 }; 695 696 static devclass_t pcm_devclass; 697 698 DRIVER_MODULE(snd_neomagic, pci, nm_driver, pcm_devclass, 0, 0); 699 MODULE_DEPEND(snd_neomagic, snd_pcm, PCM_MINVER, PCM_PREFVER, PCM_MAXVER); 700 MODULE_VERSION(snd_neomagic, 1); 701