ich.c revision 82180
1/* 2 * Copyright (c) 2000 Katsurajima Naoto <raven@katsurajima.seya.yokohama.jp> 3 * Copyright (c) 2001 Cameron Grant <cg@freebsd.org> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHERIN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28#include <dev/sound/pcm/sound.h> 29#include <dev/sound/pcm/ac97.h> 30#include <dev/sound/pci/ich.h> 31 32#include <pci/pcireg.h> 33#include <pci/pcivar.h> 34 35SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pci/ich.c 82180 2001-08-23 11:30:52Z cg $"); 36 37/* -------------------------------------------------------------------- */ 38 39#define ICH_TIMEOUT 1000 /* semaphore timeout polling count */ 40#define ICH_DTBL_LENGTH 32 41#define ICH_DEFAULT_BUFSZ 16384 42 43/* buffer descriptor */ 44struct ich_desc { 45 volatile u_int32_t buffer; 46 volatile u_int32_t length; 47}; 48 49struct sc_info; 50 51/* channel registers */ 52struct sc_chinfo { 53 u_int32_t num, run; 54 u_int32_t blksz, blkcnt; 55 u_int32_t regbase, spdreg; 56 57 struct snd_dbuf *buffer; 58 struct pcm_channel *channel; 59 struct sc_info *parent; 60 61 struct ich_desc *dtbl; 62}; 63 64/* device private data */ 65struct sc_info { 66 device_t dev; 67 int hasvra, hasvrm; 68 int chnum; 69 70 struct resource *nambar, *nabmbar, *irq; 71 int nambarid, nabmbarid, irqid; 72 bus_space_tag_t nambart, nabmbart; 73 bus_space_handle_t nambarh, nabmbarh; 74 bus_dma_tag_t dmat; 75 bus_dmamap_t dtmap; 76 void *ih; 77 78 struct ac97_info *codec; 79 struct sc_chinfo ch[3]; 80 struct ich_desc *dtbl; 81}; 82 83/* -------------------------------------------------------------------- */ 84 85static u_int32_t ich_fmt[] = { 86 AFMT_STEREO | AFMT_S16_LE, 87 0 88}; 89static struct pcmchan_caps ich_vrcaps = {8000, 48000, ich_fmt, 0}; 90static struct pcmchan_caps ich_caps = {48000, 48000, ich_fmt, 0}; 91 92/* -------------------------------------------------------------------- */ 93/* Hardware */ 94static u_int32_t 95ich_rd(struct sc_info *sc, int regno, int size) 96{ 97 switch (size) { 98 case 1: 99 return bus_space_read_1(sc->nabmbart, sc->nabmbarh, regno); 100 case 2: 101 return bus_space_read_2(sc->nabmbart, sc->nabmbarh, regno); 102 case 4: 103 return bus_space_read_4(sc->nabmbart, sc->nabmbarh, regno); 104 default: 105 return 0xffffffff; 106 } 107} 108 109static void 110ich_wr(struct sc_info *sc, int regno, u_int32_t data, int size) 111{ 112 switch (size) { 113 case 1: 114 bus_space_write_1(sc->nabmbart, sc->nabmbarh, regno, data); 115 break; 116 case 2: 117 bus_space_write_2(sc->nabmbart, sc->nabmbarh, regno, data); 118 break; 119 case 4: 120 bus_space_write_4(sc->nabmbart, sc->nabmbarh, regno, data); 121 break; 122 } 123} 124 125/* ac97 codec */ 126static int 127ich_waitcd(void *devinfo) 128{ 129 int i; 130 u_int32_t data; 131 struct sc_info *sc = (struct sc_info *)devinfo; 132 133 for (i = 0; i < ICH_TIMEOUT; i++) { 134 data = ich_rd(sc, ICH_REG_ACC_SEMA, 1); 135 if ((data & 0x01) == 0) 136 return 0; 137 } 138 device_printf(sc->dev, "CODEC semaphore timeout\n"); 139 return ETIMEDOUT; 140} 141 142static int 143ich_rdcd(kobj_t obj, void *devinfo, int regno) 144{ 145 struct sc_info *sc = (struct sc_info *)devinfo; 146 147 regno &= 0xff; 148 ich_waitcd(sc); 149 150 return bus_space_read_2(sc->nambart, sc->nambarh, regno); 151} 152 153static int 154ich_wrcd(kobj_t obj, void *devinfo, int regno, u_int16_t data) 155{ 156 struct sc_info *sc = (struct sc_info *)devinfo; 157 158 regno &= 0xff; 159 ich_waitcd(sc); 160 bus_space_write_2(sc->nambart, sc->nambarh, regno, data); 161 162 return 0; 163} 164 165static kobj_method_t ich_ac97_methods[] = { 166 KOBJMETHOD(ac97_read, ich_rdcd), 167 KOBJMETHOD(ac97_write, ich_wrcd), 168 { 0, 0 } 169}; 170AC97_DECLARE(ich_ac97); 171 172/* -------------------------------------------------------------------- */ 173/* common routines */ 174 175static void 176ich_filldtbl(struct sc_chinfo *ch) 177{ 178 u_int32_t base; 179 int i, bs, gap; 180 181 base = vtophys(sndbuf_getbuf(ch->buffer)); 182 ch->blkcnt = sndbuf_getsize(ch->buffer) / ch->blksz; 183 if (ch->blkcnt != 2 && ch->blkcnt != 4 && ch->blkcnt != 8 && ch->blkcnt != 16 && ch->blkcnt != 32) { 184 ch->blkcnt = 2; 185 ch->blksz = sndbuf_getsize(ch->buffer) / ch->blkcnt; 186 } 187 188 bs = sndbuf_getsize(ch->buffer) / ICH_DTBL_LENGTH; 189 gap = ICH_DTBL_LENGTH / ch->blkcnt; 190 for (i = 0; i < ICH_DTBL_LENGTH; i++) { 191 ch->dtbl[i].buffer = base + (i * bs); 192 ch->dtbl[i].length = bs / 2; 193 if (i % gap == gap - 1) 194 ch->dtbl[i].length |= ICH_BDC_IOC; 195 } 196#ifdef DALEK 197 for (i = 0; i < ICH_DTBL_LENGTH; i++) { 198 ch->dtbl[i].buffer = base; 199 ch->dtbl[i].length = ch->blksz / 2; 200 if (pos % ch->blksz == 0) 201 ch->dtbl[i].length |= ICH_BDC_IOC; 202 } 203#endif 204} 205 206static int 207ich_resetchan(struct sc_info *sc, int num) 208{ 209 int i, cr, regbase; 210 211 if (num == 0) 212 regbase = ICH_REG_PO_BASE; 213 else if (num == 1) 214 regbase = ICH_REG_PI_BASE; 215 else if (num == 2) 216 regbase = ICH_REG_MC_BASE; 217 else 218 return ENXIO; 219 220 ich_wr(sc, regbase + ICH_REG_X_CR, 0, 1); 221 DELAY(100); 222 ich_wr(sc, regbase + ICH_REG_X_CR, ICH_X_CR_RR, 1); 223 for (i = 0; i < ICH_TIMEOUT; i++) { 224 cr = ich_rd(sc, regbase + ICH_REG_X_CR, 1); 225 if (cr == 0) 226 return 0; 227 } 228 229 device_printf(sc->dev, "cannot reset channel %d\n", num); 230 return ENXIO; 231} 232 233/* -------------------------------------------------------------------- */ 234/* channel interface */ 235 236static void * 237ichchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) 238{ 239 struct sc_info *sc = devinfo; 240 struct sc_chinfo *ch; 241 int num; 242 243 num = sc->chnum++; 244 ch = &sc->ch[num]; 245 ch->num = num; 246 ch->buffer = b; 247 ch->channel = c; 248 ch->parent = sc; 249 ch->run = 0; 250 ch->dtbl = sc->dtbl + (ch->num * ICH_DTBL_LENGTH); 251 ch->blkcnt = 2; 252 ch->blksz = ICH_DEFAULT_BUFSZ / ch->blkcnt; 253 254 switch(ch->num) { 255 case 0: /* play */ 256 KASSERT(dir == PCMDIR_PLAY, ("wrong direction")); 257 ch->regbase = ICH_REG_PO_BASE; 258 ch->spdreg = sc->hasvra? AC97_REGEXT_FDACRATE : 0; 259 break; 260 261 case 1: /* mic */ 262 KASSERT(dir == PCMDIR_REC, ("wrong direction")); 263 ch->regbase = ICH_REG_MC_BASE; 264 ch->spdreg = sc->hasvrm? AC97_REGEXT_MADCRATE : 0; 265 break; 266 267 case 2: /* record */ 268 KASSERT(dir == PCMDIR_REC, ("wrong direction")); 269 ch->regbase = ICH_REG_PI_BASE; 270 ch->spdreg = sc->hasvra? AC97_REGEXT_LADCRATE : 0; 271 break; 272 273 default: 274 return NULL; 275 } 276 277 if (sndbuf_alloc(ch->buffer, sc->dmat, ICH_DEFAULT_BUFSZ)) 278 return NULL; 279 280 ich_wr(sc, ch->regbase + ICH_REG_X_BDBAR, (u_int32_t)vtophys(ch->dtbl), 4); 281 282 return ch; 283} 284 285static int 286ichchan_setformat(kobj_t obj, void *data, u_int32_t format) 287{ 288 return 0; 289} 290 291static int 292ichchan_setspeed(kobj_t obj, void *data, u_int32_t speed) 293{ 294 struct sc_chinfo *ch = data; 295 struct sc_info *sc = ch->parent; 296 297 if (ch->spdreg) 298 return ac97_setrate(sc->codec, ch->spdreg, speed); 299 else 300 return 48000; 301} 302 303static int 304ichchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) 305{ 306 struct sc_chinfo *ch = data; 307 struct sc_info *sc = ch->parent; 308 309 ch->blksz = blocksize; 310 ich_filldtbl(ch); 311 ich_wr(sc, ch->regbase + ICH_REG_X_LVI, ICH_DTBL_LENGTH - 1, 1); 312 313 return ch->blksz; 314} 315 316static int 317ichchan_trigger(kobj_t obj, void *data, int go) 318{ 319 struct sc_chinfo *ch = data; 320 struct sc_info *sc = ch->parent; 321 322 switch (go) { 323 case PCMTRIG_START: 324 ch->run = 1; 325 ich_wr(sc, ch->regbase + ICH_REG_X_BDBAR, (u_int32_t)vtophys(ch->dtbl), 4); 326 ich_wr(sc, ch->regbase + ICH_REG_X_CR, ICH_X_CR_RPBM | ICH_X_CR_LVBIE | ICH_X_CR_IOCE | ICH_X_CR_FEIE, 1); 327 break; 328 329 case PCMTRIG_ABORT: 330 ich_resetchan(sc, ch->num); 331 ch->run = 0; 332 break; 333 } 334 return 0; 335} 336 337static int 338ichchan_getptr(kobj_t obj, void *data) 339{ 340 struct sc_chinfo *ch = data; 341 struct sc_info *sc = ch->parent; 342 u_int32_t bs, ci, ofs, pos; 343 344 ofs = 0; 345 ci = 1234; 346 while (ci != ich_rd(sc, ch->regbase + ICH_REG_X_CIV, 1)) { 347 ci = ich_rd(sc, ch->regbase + ICH_REG_X_CIV, 1); 348 ofs = ich_rd(sc, ch->regbase + ICH_REG_X_PICB, 2) * 2; 349 } 350 351 bs = sndbuf_getsize(ch->buffer) / ICH_DTBL_LENGTH; 352 ofs = bs - ofs; 353 pos = ci * bs; 354 pos += ofs; 355 356 return pos; 357} 358 359static struct pcmchan_caps * 360ichchan_getcaps(kobj_t obj, void *data) 361{ 362 struct sc_chinfo *ch = data; 363 364 return ch->spdreg? &ich_vrcaps : &ich_caps; 365} 366 367static kobj_method_t ichchan_methods[] = { 368 KOBJMETHOD(channel_init, ichchan_init), 369 KOBJMETHOD(channel_setformat, ichchan_setformat), 370 KOBJMETHOD(channel_setspeed, ichchan_setspeed), 371 KOBJMETHOD(channel_setblocksize, ichchan_setblocksize), 372 KOBJMETHOD(channel_trigger, ichchan_trigger), 373 KOBJMETHOD(channel_getptr, ichchan_getptr), 374 KOBJMETHOD(channel_getcaps, ichchan_getcaps), 375 { 0, 0 } 376}; 377CHANNEL_DECLARE(ichchan); 378 379/* -------------------------------------------------------------------- */ 380/* The interrupt handler */ 381 382static void 383ich_intr(void *p) 384{ 385 struct sc_info *sc = (struct sc_info *)p; 386 struct sc_chinfo *ch; 387 u_int32_t st, lvi; 388 int i; 389 390 for (i = 0; i < 3; i++) { 391 ch = &sc->ch[i]; 392 /* check channel status */ 393 st = ich_rd(sc, ch->regbase + ICH_REG_X_SR, 2); 394 st &= ICH_X_SR_FIFOE | ICH_X_SR_BCIS | ICH_X_SR_LVBCI; 395 if (st != 0) { 396 /* clear status bit */ 397 ich_wr(sc, ch->regbase + ICH_REG_X_SR, st, 2); 398 if (st & (ICH_X_SR_BCIS/* | ICH_X_SR_LVBCI*/)) { 399 /* block complete - update buffer */ 400 if (ch->run) 401 chn_intr(ch->channel); 402 lvi = ich_rd(sc, ch->regbase + ICH_REG_X_LVI, 1); 403 lvi += ICH_DTBL_LENGTH / ch->blkcnt; 404 lvi %= ICH_DTBL_LENGTH; 405 ich_wr(sc, ch->regbase + ICH_REG_X_LVI, lvi, 1); 406 } 407 } 408 } 409} 410 411/* -------------------------------------------------------------------- */ 412/* Probe and attach the card */ 413 414static void 415ich_setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error) 416{ 417 return; 418} 419 420static int 421ich_init(struct sc_info *sc) 422{ 423 u_int32_t stat; 424 int sz; 425 426 ich_wr(sc, ICH_REG_GLOB_CNT, ICH_GLOB_CTL_COLD, 4); 427 DELAY(600000); 428 stat = ich_rd(sc, ICH_REG_GLOB_STA, 4); 429 430 if ((stat & ICH_GLOB_STA_PCR) == 0) 431 return ENXIO; 432 433 ich_wr(sc, ICH_REG_GLOB_CNT, ICH_GLOB_CTL_COLD | ICH_GLOB_CTL_PRES, 4); 434 435 if (ich_resetchan(sc, 0) || ich_resetchan(sc, 0)) 436 return ENXIO; 437 438 if (bus_dmamem_alloc(sc->dmat, (void **)&sc->dtbl, BUS_DMA_NOWAIT, &sc->dtmap)) 439 return ENOSPC; 440 441 sz = sizeof(struct ich_desc) * ICH_DTBL_LENGTH * 3; 442 if (bus_dmamap_load(sc->dmat, sc->dtmap, sc->dtbl, sz, ich_setmap, NULL, 0)) { 443 bus_dmamem_free(sc->dmat, (void **)&sc->dtbl, sc->dtmap); 444 return ENOSPC; 445 } 446 447 return 0; 448} 449 450static int 451ich_pci_probe(device_t dev) 452{ 453 switch(pci_get_devid(dev)) { 454 case 0x71958086: 455 device_set_desc(dev, "Intel 443MX"); 456 return 0; 457 458 case 0x24158086: 459 device_set_desc(dev, "Intel 82801AA (ICH)"); 460 return 0; 461 462 case 0x24258086: 463 device_set_desc(dev, "Intel 82901AB (ICH)"); 464 return 0; 465 466 case 0x24458086: 467 device_set_desc(dev, "Intel 82801BA (ICH2)"); 468 return 0; 469 470 default: 471 return ENXIO; 472 } 473} 474 475static int 476ich_pci_attach(device_t dev) 477{ 478 u_int32_t data; 479 struct sc_info *sc; 480 char status[SND_STATUSLEN]; 481 482 if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT)) == NULL) { 483 device_printf(dev, "cannot allocate softc\n"); 484 return ENXIO; 485 } 486 487 bzero(sc, sizeof(*sc)); 488 sc->dev = dev; 489 490 data = pci_read_config(dev, PCIR_COMMAND, 2); 491 data |= (PCIM_CMD_PORTEN | PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN); 492 pci_write_config(dev, PCIR_COMMAND, data, 2); 493 data = pci_read_config(dev, PCIR_COMMAND, 2); 494 495 sc->nambarid = PCIR_NAMBAR; 496 sc->nabmbarid = PCIR_NABMBAR; 497 sc->nambar = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->nambarid, 0, ~0, 1, RF_ACTIVE); 498 sc->nabmbar = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->nabmbarid, 0, ~0, 1, RF_ACTIVE); 499 500 if (!sc->nambar || !sc->nabmbar) { 501 device_printf(dev, "unable to map IO port space\n"); 502 goto bad; 503 } 504 505 sc->nambart = rman_get_bustag(sc->nambar); 506 sc->nambarh = rman_get_bushandle(sc->nambar); 507 sc->nabmbart = rman_get_bustag(sc->nabmbar); 508 sc->nabmbarh = rman_get_bushandle(sc->nabmbar); 509 510 if (bus_dma_tag_create(NULL, 4, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, 511 NULL, NULL, ICH_DEFAULT_BUFSZ, 1, 0x3ffff, 0, &sc->dmat) != 0) { 512 device_printf(dev, "unable to create dma tag\n"); 513 goto bad; 514 } 515 516 if (ich_init(sc)) { 517 device_printf(dev, "unable to initialize the card\n"); 518 goto bad; 519 } 520 521 sc->codec = AC97_CREATE(dev, sc, ich_ac97); 522 if (sc->codec == NULL) 523 goto bad; 524 mixer_init(dev, ac97_getmixerclass(), sc->codec); 525 526 /* check and set VRA function */ 527 if (ac97_setextmode(sc->codec, AC97_EXTCAP_VRA) == 0) 528 sc->hasvra = 1; 529 if (ac97_setextmode(sc->codec, AC97_EXTCAP_VRM) == 0) 530 sc->hasvrm = 1; 531 532 sc->irqid = 0; 533 sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irqid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); 534 if (!sc->irq || snd_setup_intr(dev, sc->irq, INTR_MPSAFE, ich_intr, sc, &sc->ih)) { 535 device_printf(dev, "unable to map interrupt\n"); 536 goto bad; 537 } 538 539 if (pcm_register(dev, sc, 1, 2)) 540 goto bad; 541 542 pcm_addchan(dev, PCMDIR_PLAY, &ichchan_class, sc); 543 pcm_addchan(dev, PCMDIR_REC, &ichchan_class, sc); 544 pcm_addchan(dev, PCMDIR_REC, &ichchan_class, sc); 545 546 snprintf(status, SND_STATUSLEN, "at io 0x%lx, 0x%lx irq %ld", 547 rman_get_start(sc->nambar), rman_get_start(sc->nabmbar), rman_get_start(sc->irq)); 548 549 pcm_setstatus(dev, status); 550 551 return 0; 552 553bad: 554 if (sc->codec) 555 ac97_destroy(sc->codec); 556 if (sc->nambar) 557 bus_release_resource(dev, SYS_RES_IOPORT, 558 sc->nambarid, sc->nambar); 559 if (sc->nabmbar) 560 bus_release_resource(dev, SYS_RES_IOPORT, 561 sc->nabmbarid, sc->nabmbar); 562 if (sc->ih) 563 bus_teardown_intr(dev, sc->irq, sc->ih); 564 if (sc->irq) 565 bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq); 566 free(sc, M_DEVBUF); 567 return ENXIO; 568} 569 570static int 571ich_pci_detach(device_t dev) 572{ 573 struct sc_info *sc; 574 int r; 575 576 r = pcm_unregister(dev); 577 if (r) 578 return r; 579 sc = pcm_getdevinfo(dev); 580 581 bus_teardown_intr(dev, sc->irq, sc->ih); 582 bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq); 583 bus_release_resource(dev, SYS_RES_IOPORT, sc->nambarid, sc->nambar); 584 bus_release_resource(dev, SYS_RES_IOPORT, sc->nabmbarid, sc->nabmbar); 585 bus_dma_tag_destroy(sc->dmat); 586 free(sc, M_DEVBUF); 587 return 0; 588} 589 590static int 591ich_pci_resume(device_t dev) 592{ 593 struct sc_info *sc; 594 595 sc = pcm_getdevinfo(dev); 596 597 /* Reinit audio device */ 598 if (ich_init(sc) == -1) { 599 device_printf(dev, "unable to reinitialize the card\n"); 600 return ENXIO; 601 } 602 /* Reinit mixer */ 603 if (mixer_reinit(dev) == -1) { 604 device_printf(dev, "unable to reinitialize the mixer\n"); 605 return ENXIO; 606 } 607 return 0; 608} 609 610static device_method_t ich_methods[] = { 611 /* Device interface */ 612 DEVMETHOD(device_probe, ich_pci_probe), 613 DEVMETHOD(device_attach, ich_pci_attach), 614 DEVMETHOD(device_detach, ich_pci_detach), 615 DEVMETHOD(device_resume, ich_pci_resume), 616 { 0, 0 } 617}; 618 619static driver_t ich_driver = { 620 "pcm", 621 ich_methods, 622 PCM_SOFTC_SIZE, 623}; 624 625DRIVER_MODULE(snd_ich, pci, ich_driver, pcm_devclass, 0, 0); 626MODULE_DEPEND(snd_ich, snd_pcm, PCM_MINVER, PCM_PREFVER, PCM_MAXVER); 627MODULE_VERSION(snd_ich, 1); 628