ich.c revision 79091
1/* 2 * Copyright (c) 2000 Katsurajima Naoto <raven@katsurajima.seya.yokohama.jp> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHERIN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD: head/sys/dev/sound/pci/ich.c 79091 2001-07-02 15:29:38Z green $ 27 */ 28 29#include <dev/sound/pcm/sound.h> 30#include <dev/sound/pcm/ac97.h> 31 32#include <pci/pcireg.h> 33#include <pci/pcivar.h> 34 35 36/* -------------------------------------------------------------------- */ 37 38#define ICH_RECPRIMARY 0 39 40#define ICH_TIMEOUT 1000 /* semaphore timeout polling count */ 41 42#define PCIR_NAMBAR 0x10 43#define PCIR_NABMBAR 0x14 44 45/* Native Audio Bus Master Control Registers */ 46#define ICH_REG_PI_BDBAR 0x00 47#define ICH_REG_PI_CIV 0x04 48#define ICH_REG_PI_LVI 0x05 49#define ICH_REG_PI_SR 0x06 50#define ICH_REG_PI_PICB 0x08 51#define ICH_REG_PI_PIV 0x0a 52#define ICH_REG_PI_CR 0x0b 53#define ICH_REG_PO_BDBAR 0x10 54#define ICH_REG_PO_CIV 0x14 55#define ICH_REG_PO_LVI 0x15 56#define ICH_REG_PO_SR 0x16 57#define ICH_REG_PO_PICB 0x18 58#define ICH_REG_PO_PIV 0x1a 59#define ICH_REG_PO_CR 0x1b 60#define ICH_REG_MC_BDBAR 0x20 61#define ICH_REG_MC_CIV 0x24 62#define ICH_REG_MC_LVI 0x25 63#define ICH_REG_MC_SR 0x26 64#define ICH_REG_MC_PICB 0x28 65#define ICH_REG_MC_PIV 0x2a 66#define ICH_REG_MC_CR 0x2b 67#define ICH_REG_GLOB_CNT 0x2c 68#define ICH_REG_GLOB_STA 0x30 69#define ICH_REG_ACC_SEMA 0x34 70/* Status Register Values */ 71#define ICH_X_SR_DCH 0x0001 72#define ICH_X_SR_CELV 0x0002 73#define ICH_X_SR_LVBCI 0x0004 74#define ICH_X_SR_BCIS 0x0008 75#define ICH_X_SR_FIFOE 0x0010 76/* Control Register Values */ 77#define ICH_X_CR_RPBM 0x01 78#define ICH_X_CR_RR 0x02 79#define ICH_X_CR_LVBIE 0x04 80#define ICH_X_CR_FEIE 0x08 81#define ICH_X_CR_IOCE 0x10 82/* Global Control Register Values */ 83#define ICH_GLOB_CTL_GIE 0x00000001 84#define ICH_GLOB_CTL_COLD 0x00000002 /* negate */ 85#define ICH_GLOB_CTL_WARM 0x00000004 86#define ICH_GLOB_CTL_SHUT 0x00000008 87#define ICH_GLOB_CTL_PRES 0x00000010 88#define ICH_GLOB_CTL_SRES 0x00000020 89/* Global Status Register Values */ 90#define ICH_GLOB_STA_GSCI 0x00000001 91#define ICH_GLOB_STA_MIINT 0x00000002 92#define ICH_GLOB_STA_MOINT 0x00000004 93#define ICH_GLOB_STA_PIINT 0x00000020 94#define ICH_GLOB_STA_POINT 0x00000040 95#define ICH_GLOB_STA_MINT 0x00000080 96#define ICH_GLOB_STA_PCR 0x00000100 97#define ICH_GLOB_STA_SCR 0x00000200 98#define ICH_GLOB_STA_PRES 0x00000400 99#define ICH_GLOB_STA_SRES 0x00000800 100#define ICH_GLOB_STA_SLOT12 0x00007000 101#define ICH_GLOB_STA_RCODEC 0x00008000 102#define ICH_GLOB_STA_AD3 0x00010000 103#define ICH_GLOB_STA_MD3 0x00020000 104#define ICH_GLOB_STA_IMASK (ICH_GLOB_STA_MIINT | ICH_GLOB_STA_MOINT | ICH_GLOB_STA_PIINT | ICH_GLOB_STA_POINT | ICH_GLOB_STA_MINT | ICH_GLOB_STA_PRES | ICH_GLOB_STA_SRES) 105 106/* AC'97 power/ready functions */ 107#define AC97_POWER_PINPOWER 0x0100 108#define AC97_POWER_PINREADY 0x0001 109#define AC97_POWER_POUTPOWER 0x0200 110#define AC97_POWER_POUTREADY 0x0002 111 112/* play/record buffer */ 113#define ICH_FIFOINDEX 32 114#define ICH_BDC_IOC 0x80000000 115#define ICH_BDC_BUP 0x40000000 116#define ICH_DEFAULT_BLOCKSZ 2048 117/* buffer descriptor */ 118struct ich_desc { 119 volatile u_int32_t buffer; 120 volatile u_int32_t length; 121}; 122 123struct sc_info; 124 125/* channel registers */ 126struct sc_chinfo { 127 int run, spd, dir, fmt; 128 struct snd_dbuf *buffer; 129 struct pcm_channel *channel; 130 struct sc_info *parent; 131 struct ich_desc *index; 132 bus_dmamap_t imap; 133 u_int32_t lvi; 134}; 135 136/* device private data */ 137struct sc_info { 138 device_t dev; 139 u_int32_t type, rev; 140 u_int32_t cd2id, ctrlbase; 141 142 struct resource *nambar, *nabmbar; 143 int nambarid, nabmbarid; 144 bus_space_tag_t nambart, nabmbart; 145 bus_space_handle_t nambarh, nabmbarh; 146 bus_dma_tag_t dmat; 147 struct resource *irq; 148 int irqid; 149 void *ih; 150 151 struct ac97_info *codec; 152 struct sc_chinfo *pi, *po; 153}; 154 155struct { 156 u_int32_t dev, subdev; 157 char *name; 158} ich_devs[] = { 159 {0x71958086, 0, "Intel 443MX"}, 160 {0x24138086, 0, "Intel 82801AA (ICH)"}, 161 {0x24158086, 0, "Intel 82801AA (ICH)"}, 162 {0x24258086, 0, "Intel 82901AB (ICH)"}, 163 {0x24458086, 0, "Intel 82801BA (ICH2)"}, 164 {0, 0, NULL} 165}; 166 167/* variable rate audio */ 168static u_int32_t ich_rate[] = { 169 48000, 44100, 22050, 16000, 11025, 8000, 0 170}; 171 172/* -------------------------------------------------------------------- */ 173 174/* 175 * prototypes 176 */ 177 178/* channel interface */ 179static void *ichpchan_init(kobj_t, void *, struct snd_dbuf *, struct pcm_channel *, int); 180static int ichpchan_setformat(kobj_t, void *, u_int32_t); 181static int ichpchan_setspeed(kobj_t, void *, u_int32_t); 182static int ichpchan_setblocksize(kobj_t, void *, u_int32_t); 183static int ichpchan_trigger(kobj_t, void *, int); 184static int ichpchan_getptr(kobj_t, void *); 185static struct pcmchan_caps *ichpchan_getcaps(kobj_t, void *); 186 187static void *ichrchan_init(kobj_t, void *, struct snd_dbuf *, struct pcm_channel *, int); 188static int ichrchan_setformat(kobj_t, void *, u_int32_t); 189static int ichrchan_setspeed(kobj_t, void *, u_int32_t); 190static int ichrchan_setblocksize(kobj_t, void *, u_int32_t); 191static int ichrchan_trigger(kobj_t, void *, int); 192static int ichrchan_getptr(kobj_t, void *); 193static struct pcmchan_caps *ichrchan_getcaps(kobj_t, void *); 194 195/* stuff */ 196static int ich_init(struct sc_info *); 197static void ich_intr(void *); 198 199/* -------------------------------------------------------------------- */ 200 201static u_int32_t ich_recfmt[] = { 202 AFMT_STEREO | AFMT_S16_LE, 203 0 204}; 205static struct pcmchan_caps ich_reccaps = {8000, 48000, ich_recfmt, 0}; 206 207static u_int32_t ich_playfmt[] = { 208 AFMT_STEREO | AFMT_S16_LE, 209 0 210}; 211static struct pcmchan_caps ich_playcaps = {8000, 48000, ich_playfmt, 0}; 212 213/* -------------------------------------------------------------------- */ 214/* Hardware */ 215static u_int32_t 216ich_rd(struct sc_info *sc, int regno, int size) 217{ 218 switch (size) { 219 case 1: 220 return bus_space_read_1(sc->nambart, sc->nambarh, regno); 221 case 2: 222 return bus_space_read_2(sc->nambart, sc->nambarh, regno); 223 case 4: 224 return bus_space_read_4(sc->nambart, sc->nambarh, regno); 225 default: 226 return 0xffffffff; 227 } 228} 229 230static void 231ich_wr(struct sc_info *sc, int regno, u_int32_t data, int size) 232{ 233 switch (size) { 234 case 1: 235 bus_space_write_1(sc->nambart, sc->nambarh, regno, data); 236 break; 237 case 2: 238 bus_space_write_2(sc->nambart, sc->nambarh, regno, data); 239 break; 240 case 4: 241 bus_space_write_4(sc->nambart, sc->nambarh, regno, data); 242 break; 243 } 244} 245 246/* ac97 codec */ 247static int 248ich_waitcd(void *devinfo) 249{ 250 int i; 251 u_int32_t data; 252 struct sc_info *sc = (struct sc_info *)devinfo; 253 for (i = 0;i < ICH_TIMEOUT;i++) { 254 data = bus_space_read_1(sc->nabmbart, sc->nabmbarh, 255 ICH_REG_ACC_SEMA); 256 if ((data & 0x01) == 0) 257 return 0; 258 } 259 device_printf(sc->dev, "CODEC semaphore timeout\n"); 260 return ETIMEDOUT; 261} 262 263static int 264ich_rdcd(kobj_t obj, void *devinfo, int regno) 265{ 266 struct sc_info *sc = (struct sc_info *)devinfo; 267 regno &= 0xff; 268 ich_waitcd(sc); 269 return ich_rd(sc, regno, 2); 270} 271 272static int 273ich_wrcd(kobj_t obj, void *devinfo, int regno, u_int32_t data) 274{ 275 struct sc_info *sc = (struct sc_info *)devinfo; 276 regno &= 0xff; 277 ich_waitcd(sc); 278 ich_wr(sc, regno, data, 2); 279 return 0; 280} 281 282static kobj_method_t ich_ac97_methods[] = { 283 KOBJMETHOD(ac97_read, ich_rdcd), 284 KOBJMETHOD(ac97_write, ich_wrcd), 285 { 0, 0 } 286}; 287AC97_DECLARE(ich_ac97); 288 289/* -------------------------------------------------------------------- */ 290 291/* channel common routines */ 292static void 293ichchan_setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error) 294{ 295 struct sc_chinfo *ch = arg; 296 297 if (bootverbose) { 298 device_printf(ch->parent->dev, "setmap(0x%lx, 0x%lx)\n", (unsigned long)segs->ds_addr, (unsigned long)segs->ds_len); 299 } 300} 301 302static int 303ichchan_initbuf(struct sc_chinfo *ch) 304{ 305 struct sc_info *sc = ch->parent; 306 int i; 307 308 if (sndbuf_alloc(ch->buffer, sc->dmat, ICH_DEFAULT_BLOCKSZ * ICH_FIFOINDEX)) { 309 return ENOSPC; 310 } 311 if (bus_dmamem_alloc(sc->dmat,(void **)&ch->index, BUS_DMA_NOWAIT, &ch->imap)) { 312 sndbuf_free(ch->buffer); 313 return ENOSPC; 314 } 315 if (bus_dmamap_load(sc->dmat, ch->imap, ch->index, 316 sizeof(struct ich_desc) * ICH_FIFOINDEX, ichchan_setmap, ch, 0)) { 317 bus_dmamem_free(sc->dmat, (void **)&ch->index, ch->imap); 318 sndbuf_free(ch->buffer); 319 return ENOSPC; 320 } 321 for (i = 0;i < ICH_FIFOINDEX;i++) { 322 ch->index[i].buffer = vtophys(sndbuf_getbuf(ch->buffer)) + 323 ICH_DEFAULT_BLOCKSZ * i; 324 if (ch->dir == PCMDIR_PLAY) 325 ch->index[i].length = 0; 326 else 327 ch->index[i].length = ICH_BDC_IOC + 328 ICH_DEFAULT_BLOCKSZ / 2; 329 } 330 return 0; 331} 332 333static void 334ichchan_free(struct sc_chinfo *ch) 335{ 336 struct sc_info *sc = ch->parent; 337 338 bus_dmamap_unload(sc->dmat, ch->imap); 339 bus_dmamem_free(sc->dmat, (void **)&ch->index, ch->imap); 340 sndbuf_free(ch->buffer); 341} 342 343/* play channel interface */ 344static int 345ichpchan_power(kobj_t obj, struct sc_info *sc, int sw) 346{ 347 u_int32_t cr; 348 int i; 349 350 cr = ich_rdcd(obj, sc, AC97_REG_POWER); 351 if (sw) { /* power on */ 352 cr &= ~AC97_POWER_POUTPOWER; 353 ich_wrcd(obj, sc, AC97_REG_POWER, cr); 354 for (i = 0;i < ICH_TIMEOUT;i++) { 355 cr = ich_rdcd(obj, sc, AC97_REG_POWER); 356 if ((cr & AC97_POWER_POUTREADY) != 0) 357 break; 358 } 359 } 360 else { /* power off */ 361 cr |= AC97_POWER_POUTPOWER; 362 ich_wrcd(obj, sc, AC97_REG_POWER, cr); 363 for (i = 0;i < ICH_TIMEOUT;i++) { 364 cr = ich_rdcd(obj, sc, AC97_REG_POWER); 365 if ((cr & AC97_POWER_POUTREADY) == 0) 366 break; 367 } 368 } 369 if (i == ICH_TIMEOUT) 370 return -1; 371 return 0; 372} 373 374static u_int32_t 375ichpchan_getminspeed(kobj_t obj, void *data) 376{ 377 struct sc_chinfo *ch = data; 378 u_int32_t extcap; 379 u_int32_t minspeed = 48000; /* before AC'97 R2.0 */ 380 int i = 0; 381 382 extcap = ac97_getextmode(ch->parent->codec); 383 if (extcap & AC97_EXTCAP_VRA) { 384 for (i = 0;ich_rate[i] != 0;i++) { 385 if (ac97_setrate(ch->parent->codec, AC97_REGEXT_FDACRATE, ich_rate[i]) == ich_rate[i]) 386 minspeed = ich_rate[i]; 387 } 388 } 389 return minspeed; 390} 391 392static void * 393ichpchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) 394{ 395 struct sc_info *sc = devinfo; 396 struct sc_chinfo *ch; 397 u_int32_t cr; 398 int i; 399 400 bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_CR, 0); 401 bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_CR, 402 ICH_X_CR_RR); 403 for (i = 0;i < ICH_TIMEOUT;i++) { 404 cr = bus_space_read_1(sc->nabmbart, sc->nabmbarh, 405 ICH_REG_PO_CR); 406 if (cr == 0) 407 break; 408 } 409 if (i == ICH_TIMEOUT) { 410 device_printf(sc->dev, "cannot reset play codec\n"); 411 return NULL; 412 } 413 if (ichpchan_power(obj, sc, 1) == -1) { 414 device_printf(sc->dev, "play DAC not ready\n"); 415 return NULL; 416 } 417 ichpchan_power(obj, sc, 0); 418 if ((ch = malloc(sizeof(*ch), M_DEVBUF, M_NOWAIT)) == NULL) { 419 device_printf(sc->dev, "cannot allocate channel info area\n"); 420 return NULL; 421 } 422 ch->buffer = b; 423 ch->channel = c; 424 ch->parent = sc; 425 ch->dir = PCMDIR_PLAY; 426 ch->run = 0; 427 ch->lvi = 0; 428 if (ichchan_initbuf(ch)) { 429 device_printf(sc->dev, "cannot allocate channel buffer\n"); 430 free(ch, M_DEVBUF); 431 return NULL; 432 } 433 bus_space_write_4(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_BDBAR, 434 (u_int32_t)vtophys(ch->index)); 435 sc->po = ch; 436 if (bootverbose) { 437 device_printf(sc->dev,"Play codec support rate(Hz): "); 438 for (i = 0;ich_rate[i] != 0;i++) { 439 if (ichpchan_setspeed(obj, ch, ich_rate[i]) == ich_rate[i]) { 440 printf("%d ", ich_rate[i]); 441 } 442 } 443 printf("\n"); 444 } 445 ich_playcaps.minspeed = ichpchan_getminspeed(obj, ch); 446 return ch; 447} 448 449static int 450ichpchan_free(kobj_t obj, void *data) 451{ 452 struct sc_chinfo *ch = data; 453 ichchan_free(ch); 454 return ichpchan_power(obj, ch->parent, 0); 455} 456 457static int 458ichpchan_setformat(kobj_t obj, void *data, u_int32_t format) 459{ 460 struct sc_chinfo *ch = data; 461 462 ch->fmt = format; 463 return 0; 464} 465 466static int 467ichpchan_setspeed(kobj_t obj, void *data, u_int32_t speed) 468{ 469 struct sc_chinfo *ch = data; 470 u_int32_t extcap; 471 472 extcap = ac97_getextmode(ch->parent->codec); 473 if (extcap & AC97_EXTCAP_VRA) { 474 ch->spd = (u_int32_t)ac97_setrate(ch->parent->codec, AC97_REGEXT_FDACRATE, speed); 475 } 476 else { 477 ch->spd = 48000; /* before AC'97 R2.0 */ 478 } 479#if(0) 480 device_printf(ch->parent->dev, "ichpchan_setspeed():ch->spd = %d\n", ch->spd); 481#endif 482 return ch->spd; 483} 484 485static int 486ichpchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) 487{ 488 return blocksize; 489} 490 491/* update index */ 492static void 493ichpchan_update(struct sc_chinfo *ch) 494{ 495 struct sc_info *sc = ch->parent; 496 u_int32_t lvi; 497 int fp; 498 int last; 499 int i; 500 501 fp = sndbuf_getfreeptr(ch->buffer); 502 last = fp - 1; 503 if (last < 0) 504 last = ICH_DEFAULT_BLOCKSZ * ICH_FIFOINDEX - 1; 505 lvi = last / ICH_DEFAULT_BLOCKSZ; 506 if (lvi >= ch->lvi) { 507 for (i = ch->lvi;i < lvi;i++) 508 ch->index[i].length = 509 ICH_BDC_IOC + ICH_DEFAULT_BLOCKSZ / 2; 510 ch->index[i].length = ICH_BDC_IOC + ICH_BDC_BUP 511 + (last % ICH_DEFAULT_BLOCKSZ + 1) / 2; 512 } 513 else { 514 for (i = ch->lvi;i < ICH_FIFOINDEX;i++) 515 ch->index[i].length = 516 ICH_BDC_IOC + ICH_DEFAULT_BLOCKSZ / 2; 517 for (i = 0;i < lvi;i++) 518 ch->index[i].length = 519 ICH_BDC_IOC + ICH_DEFAULT_BLOCKSZ / 2; 520 ch->index[i].length = ICH_BDC_IOC + ICH_BDC_BUP 521 + (last % ICH_DEFAULT_BLOCKSZ + 1) / 2; 522 } 523 bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_LVI, lvi); 524 ch->lvi = lvi; 525#if(0) 526 device_printf(ch->parent->dev, "ichpchan_update():fp = %d, lvi = %d\n", fp, lvi); 527#endif 528 return; 529} 530static void 531ichpchan_fillblank(struct sc_chinfo *ch) 532{ 533 struct sc_info *sc = ch->parent; 534 535 ch->lvi++; 536 if (ch->lvi == ICH_FIFOINDEX) 537 ch->lvi = 0; 538 ch->index[ch->lvi].length = ICH_BDC_BUP + ICH_DEFAULT_BLOCKSZ / 2; 539 bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_LVI, ch->lvi); 540 return; 541} 542/* semantic note: must start at beginning of buffer */ 543static int 544ichpchan_trigger(kobj_t obj, void *data, int go) 545{ 546 struct sc_chinfo *ch = data; 547 struct sc_info *sc = ch->parent; 548 u_int32_t cr; 549 int i; 550 551#if(0) 552 device_printf(ch->parent->dev, "ichpchan_trigger(0x%08x, %d)\n", data, go); 553#endif 554 switch (go) { 555 case PCMTRIG_START: 556#if(0) 557 device_printf(ch->parent->dev, "ichpchan_trigger():PCMTRIG_START\n"); 558#endif 559 ch->run = 1; 560 ichpchan_power(obj, sc, 1); 561 bus_space_write_4(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_BDBAR, 562 (u_int32_t)vtophys(ch->index)); 563 ch->lvi = ICH_FIFOINDEX - 1; 564 ichpchan_update(ch); 565 bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_CR, 566 ICH_X_CR_RPBM | ICH_X_CR_LVBIE | ICH_X_CR_IOCE | 567 ICH_X_CR_FEIE); 568 break; 569 case PCMTRIG_STOP: 570#if(0) 571 device_printf(ch->parent->dev, "ichpchan_trigger():PCMTRIG_STOP\n"); 572#endif 573 cr = bus_space_read_1(sc->nabmbart, sc->nabmbarh, 574 ICH_REG_PO_CR); 575 bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_CR, 576 cr & ~ICH_X_CR_RPBM); 577 ichpchan_power(obj, sc, 0); 578 ch->run = 0; 579 break; 580 case PCMTRIG_ABORT: 581#if(0) 582 device_printf(ch->parent->dev, "ichpchan_trigger():PCMTRIG_ABORT\n"); 583#endif 584 bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_CR, 585 0); 586 bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_CR, 587 ICH_X_CR_RR); 588 for (i = 0;i < ICH_TIMEOUT;i++) { 589 cr = bus_space_read_1(sc->nabmbart, sc->nabmbarh, 590 ICH_REG_PO_CR); 591 if (cr == 0) 592 break; 593 } 594 ichpchan_power(obj, sc, 0); 595 ch->run = 0; 596 ch->lvi = 0; 597 break; 598 default: 599 break; 600 } 601 return 0; 602} 603 604static int 605ichpchan_getptr(kobj_t obj, void *data) 606{ 607 struct sc_chinfo *ch = data; 608 struct sc_info *sc = ch->parent; 609 u_int32_t ci; 610 611#if(0) 612 device_printf(ch->parent->dev, "ichpchan_getptr(0x%08x)\n", data); 613#endif 614 ci = bus_space_read_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_CIV); 615#if(0) 616 device_printf(ch->parent->dev, "ichpchan_getptr():ICH_REG_PO_CIV = %d\n", ci); 617#endif 618 return ICH_DEFAULT_BLOCKSZ * ci; 619} 620 621static struct pcmchan_caps * 622ichpchan_getcaps(kobj_t obj, void *data) 623{ 624 return &ich_playcaps; 625} 626 627static kobj_method_t ichpchan_methods[] = { 628 KOBJMETHOD(channel_init, ichpchan_init), 629 KOBJMETHOD(channel_free, ichpchan_free), 630 KOBJMETHOD(channel_setformat, ichpchan_setformat), 631 KOBJMETHOD(channel_setspeed, ichpchan_setspeed), 632 KOBJMETHOD(channel_setblocksize, ichpchan_setblocksize), 633 KOBJMETHOD(channel_trigger, ichpchan_trigger), 634 KOBJMETHOD(channel_getptr, ichpchan_getptr), 635 KOBJMETHOD(channel_getcaps, ichpchan_getcaps), 636 { 0, 0 } 637}; 638CHANNEL_DECLARE(ichpchan); 639 640/* -------------------------------------------------------------------- */ 641/* record channel interface */ 642static int 643ichrchan_power(kobj_t obj, struct sc_info *sc, int sw) 644{ 645 u_int32_t cr; 646 int i; 647 648 cr = ich_rdcd(obj, sc, AC97_REG_POWER); 649 if (sw) { /* power on */ 650 cr &= ~AC97_POWER_PINPOWER; 651 ich_wrcd(obj, sc, AC97_REG_POWER, cr); 652 for (i = 0;i < ICH_TIMEOUT;i++) { 653 cr = ich_rdcd(obj, sc, AC97_REG_POWER); 654 if ((cr & AC97_POWER_PINREADY) != 0) 655 break; 656 } 657 } 658 else { /* power off */ 659 cr |= AC97_POWER_PINPOWER; 660 ich_wrcd(obj, sc, AC97_REG_POWER, cr); 661 for (i = 0;i < ICH_TIMEOUT;i++) { 662 cr = ich_rdcd(obj, sc, AC97_REG_POWER); 663 if ((cr & AC97_POWER_PINREADY) == 0) 664 break; 665 } 666 } 667 if (i == ICH_TIMEOUT) 668 return -1; 669 return 0; 670} 671 672static u_int32_t 673ichrchan_getminspeed(kobj_t obj, void *data) 674{ 675 struct sc_chinfo *ch = data; 676 u_int32_t extcap; 677 u_int32_t minspeed = 48000; /* before AC'97 R2.0 */ 678 int i = 0; 679 680 extcap = ac97_getextmode(ch->parent->codec); 681 if (extcap & AC97_EXTCAP_VRM) { 682 for (i = 0;ich_rate[i] != 0;i++) { 683 if (ac97_setrate(ch->parent->codec, AC97_REGEXT_LADCRATE, ich_rate[i]) == ich_rate[i]) 684 minspeed = ich_rate[i]; 685 } 686 } 687 return minspeed; 688} 689 690static void * 691ichrchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) 692{ 693 struct sc_info *sc = devinfo; 694 struct sc_chinfo *ch; 695 u_int32_t cr; 696 int i; 697 698 /* reset codec */ 699 bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_CR, 0); 700 bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_CR, 701 ICH_X_CR_RR); 702 for (i = 0;i < ICH_TIMEOUT;i++) { 703 cr = bus_space_read_1(sc->nabmbart, sc->nabmbarh, 704 ICH_REG_PI_CR); 705 if (cr == 0) 706 break; 707 } 708 if (i == ICH_TIMEOUT) { 709 device_printf(sc->dev, "cannot reset record codec\n"); 710 return NULL; 711 } 712 if (ichrchan_power(obj, sc, 1) == -1) { 713 device_printf(sc->dev, "record ADC not ready\n"); 714 return NULL; 715 } 716 ichrchan_power(obj, sc, 0); 717 if ((ch = malloc(sizeof(*ch), M_DEVBUF, M_NOWAIT)) == NULL) { 718 device_printf(sc->dev, "cannot allocate channel info area\n"); 719 return NULL; 720 } 721 ch->buffer = b; 722 ch->channel = c; 723 ch->parent = sc; 724 ch->dir = PCMDIR_REC; 725 ch->run = 0; 726 ch->lvi = 0; 727 if (ichchan_initbuf(ch)) { 728 device_printf(sc->dev, "cannot allocate channel buffer\n"); 729 free(ch, M_DEVBUF); 730 return NULL; 731 } 732 bus_space_write_4(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_BDBAR, 733 (u_int32_t)vtophys(ch->index)); 734 sc->pi = ch; 735 if (bootverbose) { 736 device_printf(sc->dev,"Record codec support rate(Hz): "); 737 for (i = 0;ich_rate[i] != 0;i++) { 738 if (ichrchan_setspeed(obj, ch, ich_rate[i]) == ich_rate[i]) { 739 printf("%d ", ich_rate[i]); 740 } 741 } 742 printf("\n"); 743 } 744 ich_reccaps.minspeed = ichrchan_getminspeed(obj, ch); 745 return ch; 746} 747 748static int 749ichrchan_free(kobj_t obj, void *data) 750{ 751 struct sc_chinfo *ch = data; 752 ichchan_free(ch); 753 return ichrchan_power(obj, ch->parent, 0); 754} 755 756static int 757ichrchan_setformat(kobj_t obj, void *data, u_int32_t format) 758{ 759 struct sc_chinfo *ch = data; 760 761 ch->fmt = format; 762 763 return 0; 764} 765 766static int 767ichrchan_setspeed(kobj_t obj, void *data, u_int32_t speed) 768{ 769 struct sc_chinfo *ch = data; 770 u_int32_t extcap; 771 772 extcap = ac97_getextmode(ch->parent->codec); 773 if (extcap & AC97_EXTCAP_VRM) { 774 ch->spd = (u_int32_t)ac97_setrate(ch->parent->codec, AC97_REGEXT_LADCRATE, speed); 775 } 776 else { 777 ch->spd = 48000; /* before AC'97 R2.0 */ 778 } 779 780 return ch->spd; 781} 782 783static int 784ichrchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) 785{ 786 return blocksize; 787} 788 789/* semantic note: must start at beginning of buffer */ 790static int 791ichrchan_trigger(kobj_t obj, void *data, int go) 792{ 793 struct sc_chinfo *ch = data; 794 struct sc_info *sc = ch->parent; 795 u_int32_t cr; 796 int i; 797 798 switch (go) { 799 case PCMTRIG_START: 800 ch->run = 1; 801 ichrchan_power(obj, sc, 1); 802 bus_space_write_4(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_BDBAR, 803 (u_int32_t)vtophys(ch->index)); 804 ch->lvi = ICH_FIFOINDEX - 1; 805 bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_LVI, 806 ch->lvi); 807 bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_CR, 808 ICH_X_CR_RPBM | ICH_X_CR_LVBIE | ICH_X_CR_IOCE | 809 ICH_X_CR_FEIE); 810 break; 811 case PCMTRIG_STOP: 812 cr = bus_space_read_1(sc->nabmbart, sc->nabmbarh, 813 ICH_REG_PI_CR); 814 bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_CR, 815 cr & ~ICH_X_CR_RPBM); 816 ichrchan_power(obj, sc, 0); 817 ch->run = 0; 818 break; 819 case PCMTRIG_ABORT: 820 bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_CR, 821 0); 822 bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_CR, 823 ICH_X_CR_RR); 824 for (i = 0;i < ICH_TIMEOUT;i++) { 825 cr = bus_space_read_1(sc->nabmbart, sc->nabmbarh, 826 ICH_REG_PI_CR); 827 if (cr == 0) 828 break; 829 } 830 ichrchan_power(obj, sc, 0); 831 ch->run = 0; 832 ch->lvi = 0; 833 break; 834 default: 835 break; 836 } 837 return 0; 838} 839 840static int 841ichrchan_getptr(kobj_t obj, void *data) 842{ 843 struct sc_chinfo *ch = data; 844 struct sc_info *sc = ch->parent; 845 u_int32_t ci; 846 847 ci = bus_space_read_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_CIV); 848 return ci * ICH_DEFAULT_BLOCKSZ; 849} 850 851static struct pcmchan_caps * 852ichrchan_getcaps(kobj_t obj, void *data) 853{ 854 return &ich_reccaps; 855} 856 857static kobj_method_t ichrchan_methods[] = { 858 KOBJMETHOD(channel_init, ichrchan_init), 859 KOBJMETHOD(channel_free, ichrchan_free), 860 KOBJMETHOD(channel_setformat, ichrchan_setformat), 861 KOBJMETHOD(channel_setspeed, ichrchan_setspeed), 862 KOBJMETHOD(channel_setblocksize, ichrchan_setblocksize), 863 KOBJMETHOD(channel_trigger, ichrchan_trigger), 864 KOBJMETHOD(channel_getptr, ichrchan_getptr), 865 KOBJMETHOD(channel_getcaps, ichrchan_getcaps), 866 { 0, 0 } 867}; 868CHANNEL_DECLARE(ichrchan); 869 870/* -------------------------------------------------------------------- */ 871/* The interrupt handler */ 872static void 873ich_intr(void *p) 874{ 875 struct sc_info *sc = (struct sc_info *)p; 876 struct sc_chinfo *ch; 877 u_int32_t cp; 878 u_int32_t sg; 879 u_int32_t st; 880 u_int32_t lvi = 0; 881 882#if(0) 883 device_printf(sc->dev, "ich_intr(0x%08x)\n", p); 884#endif 885 /* check interface status */ 886 sg = bus_space_read_4(sc->nabmbart, sc->nabmbarh, ICH_REG_GLOB_STA); 887#if(0) 888 device_printf(sc->dev, "ich_intr():REG_GLOB_STA = 0x%08x\n", sg); 889#endif 890 if (sg & ICH_GLOB_STA_POINT) { 891 /* PCM Out INTerrupt */ 892 /* mask interrupt */ 893 cp = bus_space_read_1(sc->nabmbart, sc->nabmbarh, 894 ICH_REG_PO_CR); 895 cp &= ~(ICH_X_CR_LVBIE | ICH_X_CR_IOCE | ICH_X_CR_FEIE); 896 bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_CR, 897 cp); 898 /* check channel status */ 899 ch = sc->po; 900 st = bus_space_read_2(sc->nabmbart, sc->nabmbarh, 901 ICH_REG_PO_SR); 902#if(0) 903 device_printf(sc->dev, "ich_intr():REG_PO_SR = 0x%02x\n", st); 904#endif 905 if (st & (ICH_X_SR_BCIS | ICH_X_SR_LVBCI)) { 906 /* play buffer block complete */ 907 if (st & ICH_X_SR_LVBCI) 908 lvi = ch->lvi; 909 /* update buffer */ 910 chn_intr(ch->channel); 911 ichpchan_update(ch); 912 if (st & ICH_X_SR_LVBCI) { 913 /* re-check underflow status */ 914 if (lvi == ch->lvi) { 915 /* ch->buffer->underflow = 1; */ 916 ichpchan_fillblank(ch); 917 } 918 } 919 } 920 /* clear status bit */ 921 bus_space_write_2(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_SR, 922 st & (ICH_X_SR_FIFOE | ICH_X_SR_BCIS | ICH_X_SR_LVBCI)); 923 /* set interrupt */ 924 cp |= (ICH_X_CR_LVBIE | ICH_X_CR_IOCE | ICH_X_CR_FEIE); 925 bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_CR, 926 cp); 927 } 928 if (sg & ICH_GLOB_STA_PIINT) { 929 /* PCM In INTerrupt */ 930 /* mask interrupt */ 931 cp = bus_space_read_1(sc->nabmbart, sc->nabmbarh, 932 ICH_REG_PI_CR); 933 cp &= ~(ICH_X_CR_LVBIE | ICH_X_CR_IOCE | ICH_X_CR_FEIE); 934 bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_CR, 935 cp); 936 /* check channel status */ 937 ch = sc->pi; 938 st = bus_space_read_2(sc->nabmbart, sc->nabmbarh, 939 ICH_REG_PI_SR); 940#if(0) 941 device_printf(sc->dev, "ich_intr():REG_PI_SR = 0x%02x\n", st); 942#endif 943 if (st & (ICH_X_SR_BCIS | ICH_X_SR_LVBCI)) { 944 /* record buffer block filled */ 945 if (st & ICH_X_SR_LVBCI) 946 lvi = ch->lvi; 947 /* update space */ 948 chn_intr(ch->channel); 949 ch->lvi = sndbuf_getreadyptr(ch->buffer) / ICH_DEFAULT_BLOCKSZ - 1; 950 if (ch->lvi < 0) 951 ch->lvi = ICH_FIFOINDEX - 1; 952 bus_space_write_1(sc->nabmbart, sc->nabmbarh, 953 ICH_REG_PI_LVI, ch->lvi); 954 if (st & ICH_X_SR_LVBCI) { 955 /* re-check underflow status */ 956 if (lvi == ch->lvi) { 957 ch->lvi++; 958 if (ch->lvi == ICH_FIFOINDEX) 959 ch->lvi = 0; 960 bus_space_write_1(sc->nabmbart, 961 sc->nabmbarh, ICH_REG_PI_LVI, 962 ch->lvi); 963 } 964 } 965 } 966 /* clear status bit */ 967 bus_space_write_2(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_SR, 968 st & (ICH_X_SR_FIFOE | ICH_X_SR_BCIS | ICH_X_SR_LVBCI)); 969 /* set interrupt */ 970 cp |= (ICH_X_CR_LVBIE | ICH_X_CR_IOCE | ICH_X_CR_FEIE); 971 bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_CR, 972 cp); 973 } 974} 975 976/* -------------------------------------------------------------------- */ 977 978/* 979 * Probe and attach the card 980 */ 981 982static int 983ich_init(struct sc_info *sc) 984{ 985 u_int32_t stat; 986 u_int32_t save; 987 988 bus_space_write_4(sc->nabmbart, sc->nabmbarh, 989 ICH_REG_GLOB_CNT, ICH_GLOB_CTL_COLD); 990 DELAY(600000); 991 stat = bus_space_read_4(sc->nabmbart, sc->nabmbarh, ICH_REG_GLOB_STA); 992 if ((stat & ICH_GLOB_STA_PCR) == 0) 993 return -1; 994 bus_space_write_4(sc->nabmbart, sc->nabmbarh, 995 ICH_REG_GLOB_CNT, ICH_GLOB_CTL_COLD | ICH_GLOB_CTL_PRES); 996 save = bus_space_read_2(sc->nambart, sc->nambarh, AC97_MIX_MASTER); 997 bus_space_write_2(sc->nambart, sc->nambarh, AC97_MIX_MASTER, 998 AC97_MUTE); 999 if (ich_waitcd(sc) == ETIMEDOUT) 1000 return -1; 1001 DELAY(600); /* it is need for some system */ 1002 stat = bus_space_read_2(sc->nambart, sc->nambarh, AC97_MIX_MASTER); 1003 if (stat != AC97_MUTE) 1004 return -1; 1005 bus_space_write_2(sc->nambart, sc->nambarh, AC97_MIX_MASTER, save); 1006 return 0; 1007} 1008 1009static int 1010ich_finddev(u_int32_t dev, u_int32_t subdev) 1011{ 1012 int i; 1013 1014 for (i = 0; ich_devs[i].dev; i++) { 1015 if (ich_devs[i].dev == dev && 1016 (ich_devs[i].subdev == subdev || ich_devs[i].subdev == 0)) 1017 return i; 1018 } 1019 return -1; 1020} 1021 1022static int 1023ich_pci_probe(device_t dev) 1024{ 1025 int i; 1026 u_int32_t subdev; 1027 1028 subdev = (pci_get_subdevice(dev) << 16) | pci_get_subvendor(dev); 1029 i = ich_finddev(pci_get_devid(dev), subdev); 1030 if (i >= 0) { 1031 device_set_desc(dev, ich_devs[i].name); 1032 return 0; 1033 } else 1034 return ENXIO; 1035} 1036 1037static int 1038ich_pci_attach(device_t dev) 1039{ 1040 u_int32_t data; 1041 u_int32_t subdev; 1042 struct sc_info *sc; 1043 char status[SND_STATUSLEN]; 1044 1045 if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT)) == NULL) { 1046 device_printf(dev, "cannot allocate softc\n"); 1047 return ENXIO; 1048 } 1049 1050 bzero(sc, sizeof(*sc)); 1051 sc->dev = dev; 1052 subdev = (pci_get_subdevice(dev) << 16) | pci_get_subvendor(dev); 1053 sc->type = ich_finddev(pci_get_devid(dev), subdev); 1054 sc->rev = pci_get_revid(dev); 1055 1056 data = pci_read_config(dev, PCIR_COMMAND, 2); 1057 data |= (PCIM_CMD_PORTEN | PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN); 1058 pci_write_config(dev, PCIR_COMMAND, data, 2); 1059 data = pci_read_config(dev, PCIR_COMMAND, 2); 1060 1061 sc->nambarid = PCIR_NAMBAR; 1062 sc->nabmbarid = PCIR_NABMBAR; 1063 sc->nambar = bus_alloc_resource(dev, SYS_RES_IOPORT, 1064 &sc->nambarid, 0, ~0, 256, RF_ACTIVE); 1065 sc->nabmbar = bus_alloc_resource(dev, SYS_RES_IOPORT, 1066 &sc->nabmbarid, 0, ~0, 64, RF_ACTIVE); 1067 if (!sc->nambar || !sc->nabmbar) { 1068 device_printf(dev, "unable to map IO port space\n"); 1069 goto bad; 1070 } 1071 sc->nambart = rman_get_bustag(sc->nambar); 1072 sc->nambarh = rman_get_bushandle(sc->nambar); 1073 sc->nabmbart = rman_get_bustag(sc->nabmbar); 1074 sc->nabmbarh = rman_get_bushandle(sc->nabmbar); 1075 1076 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/4, /*boundary*/0, 1077 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 1078 /*highaddr*/BUS_SPACE_MAXADDR, 1079 /*filter*/NULL, /*filterarg*/NULL, 1080 /*maxsize*/65536, /*nsegments*/1, /*maxsegsz*/0x3ffff, 1081 /*flags*/0, &sc->dmat) != 0) { 1082 device_printf(dev, "unable to create dma tag\n"); 1083 goto bad; 1084 } 1085 1086 if (ich_init(sc) == -1) { 1087 device_printf(dev, "unable to initialize the card\n"); 1088 goto bad; 1089 } 1090 1091 sc->codec = AC97_CREATE(dev, sc, ich_ac97); 1092 if (sc->codec == NULL) 1093 goto bad; 1094 mixer_init(dev, ac97_getmixerclass(), sc->codec); 1095 /* check and set VRA function */ 1096 if (ac97_setextmode(sc->codec, AC97_EXTCAP_VRA) == 0) { 1097 if (bootverbose) { 1098 device_printf(sc->dev, "set VRA function\n"); 1099 } 1100 } 1101 if (ac97_setextmode(sc->codec, AC97_EXTCAP_VRM) == 0) { 1102 if (bootverbose) { 1103 device_printf(sc->dev, "set VRM function\n"); 1104 } 1105 } 1106 1107 sc->irqid = 0; 1108 sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irqid, 1109 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); 1110 if (!sc->irq || 1111 bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, ich_intr, sc, &sc->ih)) { 1112 device_printf(dev, "unable to map interrupt\n"); 1113 goto bad; 1114 } 1115 1116 snprintf(status, SND_STATUSLEN, 1117 "at io 0x%lx-0x%lx, 0x%lx-0x%lx irq %ld", 1118 rman_get_start(sc->nambar), rman_get_end(sc->nambar), 1119 rman_get_start(sc->nabmbar), rman_get_end(sc->nabmbar), 1120 rman_get_start(sc->irq)); 1121 1122 if (pcm_register(dev, sc, 1, 1)) 1123 goto bad; 1124 pcm_addchan(dev, PCMDIR_PLAY, &ichpchan_class, sc); 1125 pcm_addchan(dev, PCMDIR_REC, &ichrchan_class, sc); 1126 pcm_setstatus(dev, status); 1127 1128 return 0; 1129 1130bad: 1131 if (sc->codec) 1132 ac97_destroy(sc->codec); 1133 if (sc->nambar) 1134 bus_release_resource(dev, SYS_RES_IOPORT, 1135 sc->nambarid, sc->nambar); 1136 if (sc->nabmbar) 1137 bus_release_resource(dev, SYS_RES_IOPORT, 1138 sc->nabmbarid, sc->nabmbar); 1139 if (sc->ih) 1140 bus_teardown_intr(dev, sc->irq, sc->ih); 1141 if (sc->irq) 1142 bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq); 1143 free(sc, M_DEVBUF); 1144 return ENXIO; 1145} 1146 1147static int 1148ich_pci_detach(device_t dev) 1149{ 1150 struct sc_info *sc; 1151 int r; 1152 1153 r = pcm_unregister(dev); 1154 if (r) 1155 return r; 1156 sc = pcm_getdevinfo(dev); 1157 1158 bus_release_resource(dev, SYS_RES_IOPORT, sc->nambarid, sc->nambar); 1159 bus_release_resource(dev, SYS_RES_IOPORT, sc->nabmbarid, sc->nabmbar); 1160 bus_dma_tag_destroy(sc->dmat); 1161 bus_teardown_intr(dev, sc->irq, sc->ih); 1162 bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq); 1163 free(sc, M_DEVBUF); 1164 return 0; 1165} 1166 1167static int 1168ich_pci_resume(device_t dev) 1169{ 1170 struct sc_info *sc; 1171 1172 sc = pcm_getdevinfo(dev); 1173 1174 /* Reinit audio device */ 1175 if (ich_init(sc) == -1) { 1176 device_printf(dev, "unable to reinitialize the card\n"); 1177 return ENXIO; 1178 } 1179 /* Reinit mixer */ 1180 if (mixer_reinit(dev) == -1) { 1181 device_printf(dev, "unable to reinitialize the mixer\n"); 1182 return ENXIO; 1183 } 1184 return 0; 1185} 1186 1187static device_method_t ich_methods[] = { 1188 /* Device interface */ 1189 DEVMETHOD(device_probe, ich_pci_probe), 1190 DEVMETHOD(device_attach, ich_pci_attach), 1191 DEVMETHOD(device_detach, ich_pci_detach), 1192 DEVMETHOD(device_resume, ich_pci_resume), 1193 { 0, 0 } 1194}; 1195 1196static driver_t ich_driver = { 1197 "pcm", 1198 ich_methods, 1199 sizeof(struct snddev_info), 1200}; 1201 1202DRIVER_MODULE(snd_ich, pci, ich_driver, pcm_devclass, 0, 0); 1203MODULE_DEPEND(snd_ich, snd_pcm, PCM_MINVER, PCM_PREFVER, PCM_MAXVER); 1204MODULE_VERSION(snd_ich, 1); 1205