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