cs4281.c revision 127135
11541Srgrimes/* 222521Sdyson * Copyright (c) 2000 Orion Hodson <O.Hodson@cs.ucl.ac.uk> 31541Srgrimes * All rights reserved. 41541Srgrimes * 522521Sdyson * Redistribution and use in source and binary forms, with or without 622521Sdyson * modification, are permitted provided that the following conditions 722521Sdyson * are met: 81541Srgrimes * 1. Redistributions of source code must retain the above copyright 91541Srgrimes * notice, this list of conditions and the following disclaimer. 101541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111541Srgrimes * notice, this list of conditions and the following disclaimer in the 121541Srgrimes * documentation and/or other materials provided with the distribution. 131541Srgrimes * 141541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 151541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 161541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 171541Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 181541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 191541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 201541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 211541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHERIN CONTRACT, STRICT 221541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 231541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF 241541Srgrimes * SUCH DAMAGE. 251541Srgrimes * 261541Srgrimes * The order of pokes in the initiation sequence is based on Linux 271541Srgrimes * driver by Thomas Sailer, gw boynton (wesb@crystal.cirrus.com), tom 281541Srgrimes * woller (twoller@crystal.cirrus.com). Shingo Watanabe (nabe@nabechan.org) 291541Srgrimes * contributed towards power management. 301541Srgrimes */ 311541Srgrimes 321541Srgrimes#include <dev/sound/pcm/sound.h> 331541Srgrimes#include <dev/sound/pcm/ac97.h> 341541Srgrimes 351541Srgrimes#include <dev/pci/pcireg.h> 3623521Sbde#include <dev/pci/pcivar.h> 3723521Sbde 381541Srgrimes#include <dev/sound/pci/cs4281.h> 391541Srgrimes 401541SrgrimesSND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pci/cs4281.c 127135 2004-03-17 17:50:55Z njl $"); 411541Srgrimes 4212820Sphk#define CS4281_DEFAULT_BUFSZ 16384 4312820Sphk 441541Srgrimes/* Max fifo size for full duplex is 64 */ 451541Srgrimes#define CS4281_FIFO_SIZE 15 461541Srgrimes 471541Srgrimes/* DMA Engine Indices */ 481541Srgrimes#define CS4281_DMA_PLAY 0 491541Srgrimes#define CS4281_DMA_REC 1 501541Srgrimes 5113490Sdyson/* Misc */ 5213490Sdyson 531541Srgrimes#define inline __inline 541541Srgrimes 551541Srgrimes#ifndef DEB 561541Srgrimes#define DEB(x) /* x */ 571541Srgrimes#endif /* DEB */ 581541Srgrimes 591541Srgrimes/* ------------------------------------------------------------------------- */ 601541Srgrimes/* Structures */ 611541Srgrimes 6222521Sdysonstruct sc_info; 6322521Sdyson 646968Sphk/* channel registers */ 651541Srgrimesstruct sc_chinfo { 661541Srgrimes struct sc_info *parent; 671541Srgrimes 681541Srgrimes struct snd_dbuf *buffer; 691541Srgrimes struct pcm_channel *channel; 701541Srgrimes 711541Srgrimes u_int32_t spd, fmt, bps, blksz; 721541Srgrimes 731541Srgrimes int dma_setup, dma_active, dma_chan; 741541Srgrimes}; 751541Srgrimes 761541Srgrimes/* device private data */ 7722521Sdysonstruct sc_info { 7823521Sbde device_t dev; 7912820Sphk u_int32_t type; 8023521Sbde 8123521Sbde bus_space_tag_t st; 8212820Sphk bus_space_handle_t sh; 8322521Sdyson bus_dma_tag_t parent_dmat; 841541Srgrimes 8523521Sbde struct resource *reg, *irq, *mem; 8623521Sbde int regtype, regid, irqid, memid; 8723521Sbde void *ih; 886968Sphk 896968Sphk int power; 906968Sphk unsigned long bufsz; 916968Sphk struct sc_chinfo pch; 926968Sphk struct sc_chinfo rch; 936968Sphk}; 946968Sphk 956968Sphk/* -------------------------------------------------------------------- */ 966968Sphk/* prototypes */ 9722521Sdyson 9822521Sdyson/* ADC/DAC control */ 9922521Sdysonstatic u_int32_t adcdac_go(struct sc_chinfo *ch, u_int32_t go); 10022521Sdysonstatic void adcdac_prog(struct sc_chinfo *ch); 1016968Sphk 1026968Sphk/* power management and interrupt control */ 1036968Sphkstatic void cs4281_intr(void *); 1046968Sphkstatic int cs4281_power(struct sc_info *, int); 10522521Sdysonstatic int cs4281_init(struct sc_info *); 10622521Sdyson 1076968Sphk/* talk to the card */ 10822521Sdysonstatic u_int32_t cs4281_rd(struct sc_info *, int); 10922521Sdysonstatic void cs4281_wr(struct sc_info *, int, u_int32_t); 11022521Sdyson 11122521Sdyson/* misc */ 1126968Sphkstatic u_int8_t cs4281_rate_to_rv(u_int32_t); 11322521Sdysonstatic u_int32_t cs4281_format_to_dmr(u_int32_t); 1146968Sphkstatic u_int32_t cs4281_format_to_bps(u_int32_t); 1156968Sphk 11622521Sdyson/* -------------------------------------------------------------------- */ 11722521Sdyson/* formats (do not add formats without editing cs_fmt_tab) */ 11822521Sdyson 1196968Sphkstatic u_int32_t cs4281_fmts[] = { 1201541Srgrimes AFMT_U8, 12123521Sbde AFMT_U8 | AFMT_STEREO, 1226968Sphk AFMT_S8, 12323521Sbde AFMT_S8 | AFMT_STEREO, 1246968Sphk AFMT_S16_LE, 1251541Srgrimes AFMT_S16_LE | AFMT_STEREO, 1261541Srgrimes AFMT_U16_LE, 1276968Sphk AFMT_U16_LE | AFMT_STEREO, 12822521Sdyson AFMT_S16_BE, 12922521Sdyson AFMT_S16_BE | AFMT_STEREO, 13022521Sdyson AFMT_U16_BE, 13122521Sdyson AFMT_U16_BE | AFMT_STEREO, 13222521Sdyson 0 1331541Srgrimes}; 1346968Sphk 1351541Srgrimesstatic struct pcmchan_caps cs4281_caps = {6024, 48000, cs4281_fmts, 0}; 1361541Srgrimes 1371541Srgrimes/* -------------------------------------------------------------------- */ 1381541Srgrimes/* Hardware */ 1391541Srgrimes 1401541Srgrimesstatic inline u_int32_t 14122521Sdysoncs4281_rd(struct sc_info *sc, int regno) 1426928Sphk{ 1431541Srgrimes return bus_space_read_4(sc->st, sc->sh, regno); 1446928Sphk} 1456928Sphk 1461541Srgrimesstatic inline void 1476928Sphkcs4281_wr(struct sc_info *sc, int regno, u_int32_t data) 1481541Srgrimes{ 1491541Srgrimes bus_space_write_4(sc->st, sc->sh, regno, data); 1501541Srgrimes DELAY(100); 1511541Srgrimes} 1521541Srgrimes 1536968Sphkstatic inline void 15422521Sdysoncs4281_clr4(struct sc_info *sc, int regno, u_int32_t mask) 1556928Sphk{ 1566928Sphk u_int32_t r; 1576952Sphk r = cs4281_rd(sc, regno); 1586952Sphk cs4281_wr(sc, regno, r & ~mask); 15922521Sdyson} 1607013Sphk 1616968Sphkstatic inline void 1626968Sphkcs4281_set4(struct sc_info *sc, int regno, u_int32_t mask) 1636928Sphk{ 1646968Sphk u_int32_t v; 1656968Sphk v = cs4281_rd(sc, regno); 1666968Sphk cs4281_wr(sc, regno, v | mask); 1676968Sphk} 16822521Sdyson 1691541Srgrimesstatic int 1706968Sphkcs4281_waitset(struct sc_info *sc, int regno, u_int32_t mask, int tries) 17122521Sdyson{ 17222521Sdyson u_int32_t v; 17322521Sdyson 17422521Sdyson while(tries > 0) { 17522521Sdyson DELAY(100); 17622521Sdyson v = cs4281_rd(sc, regno); 1776968Sphk if ((v & mask) == mask) break; 1786968Sphk tries --; 1796968Sphk } 1806928Sphk return tries; 1811541Srgrimes} 1826968Sphk 1836968Sphkstatic int 18423521Sbdecs4281_waitclr(struct sc_info *sc, int regno, u_int32_t mask, int tries) 1856968Sphk{ 1866968Sphk u_int32_t v; 18722521Sdyson 1881541Srgrimes while(tries > 0) { 1896968Sphk DELAY(100); 1901541Srgrimes v = ~ cs4281_rd(sc, regno); 19113490Sdyson if (v & mask) break; 19213490Sdyson tries --; 1931541Srgrimes } 1941541Srgrimes return tries; 1951541Srgrimes} 1966968Sphk 1976968Sphk/* ------------------------------------------------------------------------- */ 1987013Sphk/* Register value mapping functions */ 1996968Sphk 2006968Sphkstatic u_int32_t cs4281_rates[] = {48000, 44100, 22050, 16000, 11025, 8000}; 2016968Sphk#define CS4281_NUM_RATES sizeof(cs4281_rates)/sizeof(cs4281_rates[0]) 2026968Sphk 20322521Sdysonstatic u_int8_t 20422521Sdysoncs4281_rate_to_rv(u_int32_t rate) 20522521Sdyson{ 20622521Sdyson u_int32_t v; 2076968Sphk 2086968Sphk for (v = 0; v < CS4281_NUM_RATES; v++) { 20922521Sdyson if (rate == cs4281_rates[v]) return v; 2106968Sphk } 2111541Srgrimes 2121541Srgrimes v = 1536000 / rate; 2131541Srgrimes if (v > 255 || v < 32) v = 5; /* default to 8k */ 2146968Sphk return v; 2151541Srgrimes} 2161549Srgrimes 2171541Srgrimesstatic u_int32_t 2181541Srgrimescs4281_rv_to_rate(u_int8_t rv) 2191541Srgrimes{ 2201541Srgrimes u_int32_t r; 2211541Srgrimes 2226928Sphk if (rv < CS4281_NUM_RATES) return cs4281_rates[rv]; 2236928Sphk r = 1536000 / rv; 2241541Srgrimes return r; 2251541Srgrimes} 2261541Srgrimes 2276968Sphkstatic inline u_int32_t 2286968Sphkcs4281_format_to_dmr(u_int32_t format) 2296968Sphk{ 2306968Sphk u_int32_t dmr = 0; 2316968Sphk if (AFMT_8BIT & format) dmr |= CS4281PCI_DMR_SIZE8; 2326968Sphk if (!(AFMT_STEREO & format)) dmr |= CS4281PCI_DMR_MONO; 23322521Sdyson if (AFMT_BIGENDIAN & format) dmr |= CS4281PCI_DMR_BEND; 23422521Sdyson if (!(AFMT_SIGNED & format)) dmr |= CS4281PCI_DMR_USIGN; 23522521Sdyson return dmr; 23622521Sdyson} 23722521Sdyson 23822521Sdysonstatic inline u_int32_t 23922521Sdysoncs4281_format_to_bps(u_int32_t format) 24022521Sdyson{ 2416968Sphk return ((AFMT_8BIT & format) ? 1 : 2) * ((AFMT_STEREO & format) ? 2 : 1); 2421541Srgrimes} 2431541Srgrimes 2441541Srgrimes/* -------------------------------------------------------------------- */ 2451541Srgrimes/* ac97 codec */ 2466928Sphk 2476968Sphkstatic u_int32_t 2486928Sphkcs4281_rdcd(kobj_t obj, void *devinfo, int regno) 2496928Sphk{ 2506928Sphk struct sc_info *sc = (struct sc_info *)devinfo; 2516928Sphk int codecno; 2526928Sphk 2536968Sphk codecno = regno >> 8; 2546968Sphk regno &= 0xff; 2553308Sphk 2566968Sphk /* Remove old state */ 25723521Sbde cs4281_rd(sc, CS4281PCI_ACSDA); 25822521Sdyson 25922521Sdyson /* Fill in AC97 register value request form */ 26022521Sdyson cs4281_wr(sc, CS4281PCI_ACCAD, regno); 26122521Sdyson cs4281_wr(sc, CS4281PCI_ACCDA, 0); 26222521Sdyson cs4281_wr(sc, CS4281PCI_ACCTL, CS4281PCI_ACCTL_ESYN | 26322521Sdyson CS4281PCI_ACCTL_VFRM | CS4281PCI_ACCTL_DCV | 2641541Srgrimes CS4281PCI_ACCTL_CRW); 26522521Sdyson 26622521Sdyson /* Wait for read to complete */ 26722521Sdyson if (cs4281_waitclr(sc, CS4281PCI_ACCTL, CS4281PCI_ACCTL_DCV, 250) == 0) { 26822521Sdyson device_printf(sc->dev, "cs4281_rdcd: DCV did not go\n"); 26922521Sdyson return 0xffffffff; 27022521Sdyson } 2711541Srgrimes 2721541Srgrimes /* Wait for valid status */ 2731541Srgrimes if (cs4281_waitset(sc, CS4281PCI_ACSTS, CS4281PCI_ACSTS_VSTS, 250) == 0) { 2741541Srgrimes device_printf(sc->dev,"cs4281_rdcd: VSTS did not come\n"); 2756928Sphk return 0xffffffff; 27622521Sdyson } 2776928Sphk 2781541Srgrimes return cs4281_rd(sc, CS4281PCI_ACSDA); 2791541Srgrimes} 2801541Srgrimes 2811541Srgrimesstatic void 2821541Srgrimescs4281_wrcd(kobj_t obj, void *devinfo, int regno, u_int32_t data) 2831549Srgrimes{ 2841541Srgrimes struct sc_info *sc = (struct sc_info *)devinfo; 2851541Srgrimes int codecno; 28623521Sbde 2876928Sphk codecno = regno >> 8; 2887611Sdg regno &= 0xff; 2891541Srgrimes 2901541Srgrimes cs4281_wr(sc, CS4281PCI_ACCAD, regno); 2911541Srgrimes cs4281_wr(sc, CS4281PCI_ACCDA, data); 29222521Sdyson cs4281_wr(sc, CS4281PCI_ACCTL, CS4281PCI_ACCTL_ESYN | 29323521Sbde CS4281PCI_ACCTL_VFRM | CS4281PCI_ACCTL_DCV); 29422521Sdyson 29522521Sdyson if (cs4281_waitclr(sc, CS4281PCI_ACCTL, CS4281PCI_ACCTL_DCV, 250) == 0) { 29622521Sdyson device_printf(sc->dev,"cs4281_wrcd: DCV did not go\n"); 29722521Sdyson } 2981541Srgrimes} 2991549Srgrimes 3001541Srgrimesstatic kobj_method_t cs4281_ac97_methods[] = { 3011541Srgrimes KOBJMETHOD(ac97_read, cs4281_rdcd), 3021541Srgrimes KOBJMETHOD(ac97_write, cs4281_wrcd), 30322521Sdyson { 0, 0 } 3046928Sphk}; 30512968SphkAC97_DECLARE(cs4281_ac97); 3061541Srgrimes 3071541Srgrimes/* ------------------------------------------------------------------------- */ 3081541Srgrimes/* shared rec/play channel interface */ 3091541Srgrimes 3107831Sdgstatic void * 31122521Sdysoncs4281chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) 31222521Sdyson{ 3131541Srgrimes struct sc_info *sc = devinfo; 3141541Srgrimes struct sc_chinfo *ch = (dir == PCMDIR_PLAY) ? &sc->pch : &sc->rch; 3151541Srgrimes 3161541Srgrimes ch->buffer = b; 3171541Srgrimes if (sndbuf_alloc(ch->buffer, sc->parent_dmat, sc->bufsz) != 0) { 3186968Sphk return NULL; 3191541Srgrimes } 3206968Sphk ch->parent = sc; 32112968Sphk ch->channel = c; 3221541Srgrimes 3231549Srgrimes ch->fmt = AFMT_U8; 3241541Srgrimes ch->spd = DSP_DEFAULT_SPEED; 3251541Srgrimes ch->bps = 1; 3261541Srgrimes ch->blksz = sndbuf_getsize(ch->buffer); 3276968Sphk 32822521Sdyson ch->dma_chan = (dir == PCMDIR_PLAY) ? CS4281_DMA_PLAY : CS4281_DMA_REC; 3291541Srgrimes ch->dma_setup = 0; 3306968Sphk 3317831Sdg adcdac_go(ch, 0); 33222521Sdyson adcdac_prog(ch); 33322521Sdyson 3346968Sphk return ch; 33522521Sdyson} 3366968Sphk 3376968Sphkstatic int 3386968Sphkcs4281chan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) 3391541Srgrimes{ 3401541Srgrimes struct sc_chinfo *ch = data; 3411541Srgrimes struct sc_info *sc = ch->parent; 342 u_int32_t go; 343 344 go = adcdac_go(ch, 0); 345 346 /* 2 interrupts are possible and used in buffer (half-empty,empty), 347 * hence factor of 2. */ 348 ch->blksz = MIN(blocksize, sc->bufsz / 2); 349 sndbuf_resize(ch->buffer, 2, ch->blksz); 350 ch->dma_setup = 0; 351 adcdac_prog(ch); 352 adcdac_go(ch, go); 353 354 DEB(printf("cs4281chan_setblocksize: blksz %d Setting %d\n", blocksize, ch->blksz)); 355 356 return ch->blksz; 357} 358 359static int 360cs4281chan_setspeed(kobj_t obj, void *data, u_int32_t speed) 361{ 362 struct sc_chinfo *ch = data; 363 struct sc_info *sc = ch->parent; 364 u_int32_t go, v, r; 365 366 go = adcdac_go(ch, 0); /* pause */ 367 r = (ch->dma_chan == CS4281_DMA_PLAY) ? CS4281PCI_DACSR : CS4281PCI_ADCSR; 368 v = cs4281_rate_to_rv(speed); 369 cs4281_wr(sc, r, v); 370 adcdac_go(ch, go); /* unpause */ 371 372 ch->spd = cs4281_rv_to_rate(v); 373 return ch->spd; 374} 375 376static int 377cs4281chan_setformat(kobj_t obj, void *data, u_int32_t format) 378{ 379 struct sc_chinfo *ch = data; 380 struct sc_info *sc = ch->parent; 381 u_int32_t v, go; 382 383 go = adcdac_go(ch, 0); /* pause */ 384 385 if (ch->dma_chan == CS4281_DMA_PLAY) 386 v = CS4281PCI_DMR_TR_PLAY; 387 else 388 v = CS4281PCI_DMR_TR_REC; 389 v |= CS4281PCI_DMR_DMA | CS4281PCI_DMR_AUTO; 390 v |= cs4281_format_to_dmr(format); 391 cs4281_wr(sc, CS4281PCI_DMR(ch->dma_chan), v); 392 393 adcdac_go(ch, go); /* unpause */ 394 395 ch->fmt = format; 396 ch->bps = cs4281_format_to_bps(format); 397 ch->dma_setup = 0; 398 399 return 0; 400} 401 402static int 403cs4281chan_getptr(kobj_t obj, void *data) 404{ 405 struct sc_chinfo *ch = data; 406 struct sc_info *sc = ch->parent; 407 u_int32_t dba, dca, ptr; 408 int sz; 409 410 sz = sndbuf_getsize(ch->buffer); 411 dba = cs4281_rd(sc, CS4281PCI_DBA(ch->dma_chan)); 412 dca = cs4281_rd(sc, CS4281PCI_DCA(ch->dma_chan)); 413 ptr = (dca - dba + sz) % sz; 414 415 return ptr; 416} 417 418static int 419cs4281chan_trigger(kobj_t obj, void *data, int go) 420{ 421 struct sc_chinfo *ch = data; 422 423 switch(go) { 424 case PCMTRIG_START: 425 adcdac_prog(ch); 426 adcdac_go(ch, 1); 427 break; 428 case PCMTRIG_ABORT: 429 adcdac_go(ch, 0); 430 break; 431 default: 432 break; 433 } 434 435 /* return 0 if ok */ 436 return 0; 437} 438 439static struct pcmchan_caps * 440cs4281chan_getcaps(kobj_t obj, void *data) 441{ 442 return &cs4281_caps; 443} 444 445static kobj_method_t cs4281chan_methods[] = { 446 KOBJMETHOD(channel_init, cs4281chan_init), 447 KOBJMETHOD(channel_setformat, cs4281chan_setformat), 448 KOBJMETHOD(channel_setspeed, cs4281chan_setspeed), 449 KOBJMETHOD(channel_setblocksize, cs4281chan_setblocksize), 450 KOBJMETHOD(channel_trigger, cs4281chan_trigger), 451 KOBJMETHOD(channel_getptr, cs4281chan_getptr), 452 KOBJMETHOD(channel_getcaps, cs4281chan_getcaps), 453 { 0, 0 } 454}; 455CHANNEL_DECLARE(cs4281chan); 456 457/* -------------------------------------------------------------------- */ 458/* ADC/DAC control */ 459 460/* adcdac_go enables/disable DMA channel, returns non-zero if DMA was 461 * active before call */ 462 463static u_int32_t 464adcdac_go(struct sc_chinfo *ch, u_int32_t go) 465{ 466 struct sc_info *sc = ch->parent; 467 u_int32_t going; 468 469 going = !(cs4281_rd(sc, CS4281PCI_DCR(ch->dma_chan)) & CS4281PCI_DCR_MSK); 470 471 if (go) 472 cs4281_clr4(sc, CS4281PCI_DCR(ch->dma_chan), CS4281PCI_DCR_MSK); 473 else 474 cs4281_set4(sc, CS4281PCI_DCR(ch->dma_chan), CS4281PCI_DCR_MSK); 475 476 cs4281_wr(sc, CS4281PCI_HICR, CS4281PCI_HICR_EOI); 477 478 return going; 479} 480 481static void 482adcdac_prog(struct sc_chinfo *ch) 483{ 484 struct sc_info *sc = ch->parent; 485 u_int32_t go; 486 487 if (!ch->dma_setup) { 488 go = adcdac_go(ch, 0); 489 cs4281_wr(sc, CS4281PCI_DBA(ch->dma_chan), 490 sndbuf_getbufaddr(ch->buffer)); 491 cs4281_wr(sc, CS4281PCI_DBC(ch->dma_chan), 492 sndbuf_getsize(ch->buffer) / ch->bps - 1); 493 ch->dma_setup = 1; 494 adcdac_go(ch, go); 495 } 496} 497 498/* -------------------------------------------------------------------- */ 499/* The interrupt handler */ 500 501static void 502cs4281_intr(void *p) 503{ 504 struct sc_info *sc = (struct sc_info *)p; 505 u_int32_t hisr; 506 507 hisr = cs4281_rd(sc, CS4281PCI_HISR); 508 509 if (hisr == 0) return; 510 511 if (hisr & CS4281PCI_HISR_DMA(CS4281_DMA_PLAY)) { 512 chn_intr(sc->pch.channel); 513 cs4281_rd(sc, CS4281PCI_HDSR(CS4281_DMA_PLAY)); /* Clear interrupt */ 514 } 515 516 if (hisr & CS4281PCI_HISR_DMA(CS4281_DMA_REC)) { 517 chn_intr(sc->rch.channel); 518 cs4281_rd(sc, CS4281PCI_HDSR(CS4281_DMA_REC)); /* Clear interrupt */ 519 } 520 521 /* Signal End-of-Interrupt */ 522 cs4281_wr(sc, CS4281PCI_HICR, CS4281PCI_HICR_EOI); 523} 524 525/* -------------------------------------------------------------------- */ 526/* power management related */ 527 528static int 529cs4281_power(struct sc_info *sc, int state) 530{ 531 532 switch (state) { 533 case 0: 534 /* Permit r/w access to all BA0 registers */ 535 cs4281_wr(sc, CS4281PCI_CWPR, CS4281PCI_CWPR_MAGIC); 536 /* Power on */ 537 cs4281_clr4(sc, CS4281PCI_EPPMC, CS4281PCI_EPPMC_FPDN); 538 break; 539 case 3: 540 /* Power off card and codec */ 541 cs4281_set4(sc, CS4281PCI_EPPMC, CS4281PCI_EPPMC_FPDN); 542 cs4281_clr4(sc, CS4281PCI_SPMC, CS4281PCI_SPMC_RSTN); 543 break; 544 } 545 546 DEB(printf("cs4281_power %d -> %d\n", sc->power, state)); 547 sc->power = state; 548 549 return 0; 550} 551 552static int 553cs4281_init(struct sc_info *sc) 554{ 555 u_int32_t i, v; 556 557 /* (0) Blast clock register and serial port */ 558 cs4281_wr(sc, CS4281PCI_CLKCR1, 0); 559 cs4281_wr(sc, CS4281PCI_SERMC, 0); 560 561 /* (1) Make ESYN 0 to turn sync pulse on AC97 link */ 562 cs4281_wr(sc, CS4281PCI_ACCTL, 0); 563 DELAY(50); 564 565 /* (2) Effect Reset */ 566 cs4281_wr(sc, CS4281PCI_SPMC, 0); 567 DELAY(100); 568 cs4281_wr(sc, CS4281PCI_SPMC, CS4281PCI_SPMC_RSTN); 569 /* Wait 50ms for ABITCLK to become stable */ 570 DELAY(50000); 571 572 /* (3) Enable Sound System Clocks */ 573 cs4281_wr(sc, CS4281PCI_CLKCR1, CS4281PCI_CLKCR1_DLLP); 574 DELAY(50000); /* Wait for PLL to stabilize */ 575 cs4281_wr(sc, CS4281PCI_CLKCR1, 576 CS4281PCI_CLKCR1_DLLP | CS4281PCI_CLKCR1_SWCE); 577 578 /* (4) Power Up - this combination is essential. */ 579 cs4281_set4(sc, CS4281PCI_SSPM, 580 CS4281PCI_SSPM_ACLEN | CS4281PCI_SSPM_PSRCEN | 581 CS4281PCI_SSPM_CSRCEN | CS4281PCI_SSPM_MIXEN); 582 583 /* (5) Wait for clock stabilization */ 584 if (cs4281_waitset(sc, 585 CS4281PCI_CLKCR1, 586 CS4281PCI_CLKCR1_DLLRDY, 587 250) == 0) { 588 device_printf(sc->dev, "Clock stabilization failed\n"); 589 return -1; 590 } 591 592 /* (6) Enable ASYNC generation. */ 593 cs4281_wr(sc, CS4281PCI_ACCTL,CS4281PCI_ACCTL_ESYN); 594 595 /* Wait to allow AC97 to start generating clock bit */ 596 DELAY(50000); 597 598 /* Set AC97 timing */ 599 cs4281_wr(sc, CS4281PCI_SERMC, CS4281PCI_SERMC_PTC_AC97); 600 601 /* (7) Wait for AC97 ready signal */ 602 if (cs4281_waitset(sc, CS4281PCI_ACSTS, CS4281PCI_ACSTS_CRDY, 250) == 0) { 603 device_printf(sc->dev, "codec did not avail\n"); 604 return -1; 605 } 606 607 /* (8) Assert valid frame signal to begin sending commands to 608 * AC97 codec */ 609 cs4281_wr(sc, 610 CS4281PCI_ACCTL, 611 CS4281PCI_ACCTL_VFRM | CS4281PCI_ACCTL_ESYN); 612 613 /* (9) Wait for codec calibration */ 614 for(i = 0 ; i < 1000; i++) { 615 DELAY(10000); 616 v = cs4281_rdcd(0, sc, AC97_REG_POWER); 617 if ((v & 0x0f) == 0x0f) { 618 break; 619 } 620 } 621 if (i == 1000) { 622 device_printf(sc->dev, "codec failed to calibrate\n"); 623 return -1; 624 } 625 626 /* (10) Set AC97 timing */ 627 cs4281_wr(sc, CS4281PCI_SERMC, CS4281PCI_SERMC_PTC_AC97); 628 629 /* (11) Wait for valid data to arrive */ 630 if (cs4281_waitset(sc, 631 CS4281PCI_ACISV, 632 CS4281PCI_ACISV_ISV(3) | CS4281PCI_ACISV_ISV(4), 633 10000) == 0) { 634 device_printf(sc->dev, "cs4281 never got valid data\n"); 635 return -1; 636 } 637 638 /* (12) Start digital data transfer of audio data to codec */ 639 cs4281_wr(sc, 640 CS4281PCI_ACOSV, 641 CS4281PCI_ACOSV_SLV(3) | CS4281PCI_ACOSV_SLV(4)); 642 643 /* Set Master and headphone to max */ 644 cs4281_wrcd(0, sc, AC97_MIX_AUXOUT, 0); 645 cs4281_wrcd(0, sc, AC97_MIX_MASTER, 0); 646 647 /* Power on the DAC */ 648 v = cs4281_rdcd(0, sc, AC97_REG_POWER) & 0xfdff; 649 cs4281_wrcd(0, sc, AC97_REG_POWER, v); 650 651 /* Wait until DAC state ready */ 652 for(i = 0; i < 320; i++) { 653 DELAY(100); 654 v = cs4281_rdcd(0, sc, AC97_REG_POWER); 655 if (v & 0x02) break; 656 } 657 658 /* Power on the ADC */ 659 v = cs4281_rdcd(0, sc, AC97_REG_POWER) & 0xfeff; 660 cs4281_wrcd(0, sc, AC97_REG_POWER, v); 661 662 /* Wait until ADC state ready */ 663 for(i = 0; i < 320; i++) { 664 DELAY(100); 665 v = cs4281_rdcd(0, sc, AC97_REG_POWER); 666 if (v & 0x01) break; 667 } 668 669 /* FIFO configuration (driver is DMA orientated, implicit FIFO) */ 670 /* Play FIFO */ 671 672 v = CS4281PCI_FCR_RS(CS4281PCI_RPCM_PLAY_SLOT) | 673 CS4281PCI_FCR_LS(CS4281PCI_LPCM_PLAY_SLOT) | 674 CS4281PCI_FCR_SZ(CS4281_FIFO_SIZE)| 675 CS4281PCI_FCR_OF(0); 676 cs4281_wr(sc, CS4281PCI_FCR(CS4281_DMA_PLAY), v); 677 678 cs4281_wr(sc, CS4281PCI_FCR(CS4281_DMA_PLAY), v | CS4281PCI_FCR_FEN); 679 680 /* Record FIFO */ 681 v = CS4281PCI_FCR_RS(CS4281PCI_RPCM_REC_SLOT) | 682 CS4281PCI_FCR_LS(CS4281PCI_LPCM_REC_SLOT) | 683 CS4281PCI_FCR_SZ(CS4281_FIFO_SIZE)| 684 CS4281PCI_FCR_OF(CS4281_FIFO_SIZE + 1); 685 cs4281_wr(sc, CS4281PCI_FCR(CS4281_DMA_REC), v | CS4281PCI_FCR_PSH); 686 cs4281_wr(sc, CS4281PCI_FCR(CS4281_DMA_REC), v | CS4281PCI_FCR_FEN); 687 688 /* Match AC97 slots to FIFOs */ 689 v = CS4281PCI_SRCSA_PLSS(CS4281PCI_LPCM_PLAY_SLOT) | 690 CS4281PCI_SRCSA_PRSS(CS4281PCI_RPCM_PLAY_SLOT) | 691 CS4281PCI_SRCSA_CLSS(CS4281PCI_LPCM_REC_SLOT) | 692 CS4281PCI_SRCSA_CRSS(CS4281PCI_RPCM_REC_SLOT); 693 cs4281_wr(sc, CS4281PCI_SRCSA, v); 694 695 /* Set Auto-Initialize and set directions */ 696 cs4281_wr(sc, 697 CS4281PCI_DMR(CS4281_DMA_PLAY), 698 CS4281PCI_DMR_DMA | 699 CS4281PCI_DMR_AUTO | 700 CS4281PCI_DMR_TR_PLAY); 701 cs4281_wr(sc, 702 CS4281PCI_DMR(CS4281_DMA_REC), 703 CS4281PCI_DMR_DMA | 704 CS4281PCI_DMR_AUTO | 705 CS4281PCI_DMR_TR_REC); 706 707 /* Enable half and empty buffer interrupts keeping DMA paused */ 708 cs4281_wr(sc, 709 CS4281PCI_DCR(CS4281_DMA_PLAY), 710 CS4281PCI_DCR_TCIE | CS4281PCI_DCR_HTCIE | CS4281PCI_DCR_MSK); 711 cs4281_wr(sc, 712 CS4281PCI_DCR(CS4281_DMA_REC), 713 CS4281PCI_DCR_TCIE | CS4281PCI_DCR_HTCIE | CS4281PCI_DCR_MSK); 714 715 /* Enable Interrupts */ 716 cs4281_clr4(sc, 717 CS4281PCI_HIMR, 718 CS4281PCI_HIMR_DMAI | 719 CS4281PCI_HIMR_DMA(CS4281_DMA_PLAY) | 720 CS4281PCI_HIMR_DMA(CS4281_DMA_REC)); 721 722 /* Set playback volume */ 723 cs4281_wr(sc, CS4281PCI_PPLVC, 7); 724 cs4281_wr(sc, CS4281PCI_PPRVC, 7); 725 726 return 0; 727} 728 729/* -------------------------------------------------------------------- */ 730/* Probe and attach the card */ 731 732static int 733cs4281_pci_probe(device_t dev) 734{ 735 char *s = NULL; 736 737 switch (pci_get_devid(dev)) { 738 case CS4281_PCI_ID: 739 s = "Crystal Semiconductor CS4281"; 740 break; 741 } 742 743 if (s) 744 device_set_desc(dev, s); 745 return s ? 0 : ENXIO; 746} 747 748static int 749cs4281_pci_attach(device_t dev) 750{ 751 struct sc_info *sc; 752 struct ac97_info *codec = NULL; 753 u_int32_t data; 754 char status[SND_STATUSLEN]; 755 756 if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) { 757 device_printf(dev, "cannot allocate softc\n"); 758 return ENXIO; 759 } 760 761 sc->dev = dev; 762 sc->type = pci_get_devid(dev); 763 764 data = pci_read_config(dev, PCIR_COMMAND, 2); 765 data |= (PCIM_CMD_PORTEN | PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN); 766 pci_write_config(dev, PCIR_COMMAND, data, 2); 767 768#if __FreeBSD_version > 500000 769 if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) { 770 /* Reset the power state. */ 771 device_printf(dev, "chip is in D%d power mode " 772 "-- setting to D0\n", pci_get_powerstate(dev)); 773 774 pci_set_powerstate(dev, PCI_POWERSTATE_D0); 775 } 776#else 777 data = pci_read_config(dev, CS4281PCI_PMCS_OFFSET, 4); 778 if (data & CS4281PCI_PMCS_PS_MASK) { 779 /* Reset the power state. */ 780 device_printf(dev, "chip is in D%d power mode " 781 "-- setting to D0\n", 782 data & CS4281PCI_PMCS_PS_MASK); 783 pci_write_config(dev, CS4281PCI_PMCS_OFFSET, 784 data & ~CS4281PCI_PMCS_PS_MASK, 4); 785 } 786#endif 787 788 sc->regid = PCIR_BAR(0); 789 sc->regtype = SYS_RES_MEMORY; 790 sc->reg = bus_alloc_resource(dev, sc->regtype, &sc->regid, 791 0, ~0, CS4281PCI_BA0_SIZE, RF_ACTIVE); 792 if (!sc->reg) { 793 sc->regtype = SYS_RES_IOPORT; 794 sc->reg = bus_alloc_resource(dev, sc->regtype, &sc->regid, 795 0, ~0, CS4281PCI_BA0_SIZE, RF_ACTIVE); 796 if (!sc->reg) { 797 device_printf(dev, "unable to allocate register space\n"); 798 goto bad; 799 } 800 } 801 sc->st = rman_get_bustag(sc->reg); 802 sc->sh = rman_get_bushandle(sc->reg); 803 804 sc->memid = PCIR_BAR(1); 805 sc->mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->memid, 0, 806 ~0, CS4281PCI_BA1_SIZE, RF_ACTIVE); 807 if (sc->mem == NULL) { 808 device_printf(dev, "unable to allocate fifo space\n"); 809 goto bad; 810 } 811 812 sc->irqid = 0; 813 sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqid, 814 RF_ACTIVE | RF_SHAREABLE); 815 if (!sc->irq) { 816 device_printf(dev, "unable to allocate interrupt\n"); 817 goto bad; 818 } 819 820 if (snd_setup_intr(dev, sc->irq, 0, cs4281_intr, sc, &sc->ih)) { 821 device_printf(dev, "unable to setup interrupt\n"); 822 goto bad; 823 } 824 825 sc->bufsz = pcm_getbuffersize(dev, 4096, CS4281_DEFAULT_BUFSZ, 65536); 826 827 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, 828 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 829 /*highaddr*/BUS_SPACE_MAXADDR, 830 /*filter*/NULL, /*filterarg*/NULL, 831 /*maxsize*/sc->bufsz, /*nsegments*/1, 832 /*maxsegz*/0x3ffff, 833 /*flags*/0, /*lockfunc*/busdma_lock_mutex, 834 /*lockarg*/&Giant, &sc->parent_dmat) != 0) { 835 device_printf(dev, "unable to create dma tag\n"); 836 goto bad; 837 } 838 839 /* power up */ 840 cs4281_power(sc, 0); 841 842 /* init chip */ 843 if (cs4281_init(sc) == -1) { 844 device_printf(dev, "unable to initialize the card\n"); 845 goto bad; 846 } 847 848 /* create/init mixer */ 849 codec = AC97_CREATE(dev, sc, cs4281_ac97); 850 if (codec == NULL) 851 goto bad; 852 853 mixer_init(dev, ac97_getmixerclass(), codec); 854 855 if (pcm_register(dev, sc, 1, 1)) 856 goto bad; 857 858 pcm_addchan(dev, PCMDIR_PLAY, &cs4281chan_class, sc); 859 pcm_addchan(dev, PCMDIR_REC, &cs4281chan_class, sc); 860 861 snprintf(status, SND_STATUSLEN, "at %s 0x%lx irq %ld %s", 862 (sc->regtype == SYS_RES_IOPORT)? "io" : "memory", 863 rman_get_start(sc->reg), rman_get_start(sc->irq),PCM_KLDSTRING(snd_cs4281)); 864 pcm_setstatus(dev, status); 865 866 return 0; 867 868 bad: 869 if (codec) 870 ac97_destroy(codec); 871 if (sc->reg) 872 bus_release_resource(dev, sc->regtype, sc->regid, sc->reg); 873 if (sc->mem) 874 bus_release_resource(dev, SYS_RES_MEMORY, sc->memid, sc->mem); 875 if (sc->ih) 876 bus_teardown_intr(dev, sc->irq, sc->ih); 877 if (sc->irq) 878 bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq); 879 if (sc->parent_dmat) 880 bus_dma_tag_destroy(sc->parent_dmat); 881 free(sc, M_DEVBUF); 882 883 return ENXIO; 884} 885 886static int 887cs4281_pci_detach(device_t dev) 888{ 889 int r; 890 struct sc_info *sc; 891 892 r = pcm_unregister(dev); 893 if (r) 894 return r; 895 896 sc = pcm_getdevinfo(dev); 897 898 /* power off */ 899 cs4281_power(sc, 3); 900 901 bus_release_resource(dev, sc->regtype, sc->regid, sc->reg); 902 bus_release_resource(dev, SYS_RES_MEMORY, sc->memid, sc->mem); 903 bus_teardown_intr(dev, sc->irq, sc->ih); 904 bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq); 905 bus_dma_tag_destroy(sc->parent_dmat); 906 free(sc, M_DEVBUF); 907 908 return 0; 909} 910 911static int 912cs4281_pci_suspend(device_t dev) 913{ 914 struct sc_info *sc; 915 916 sc = pcm_getdevinfo(dev); 917 918 sc->rch.dma_active = adcdac_go(&sc->rch, 0); 919 sc->pch.dma_active = adcdac_go(&sc->pch, 0); 920 921 cs4281_power(sc, 3); 922 923 return 0; 924} 925 926static int 927cs4281_pci_resume(device_t dev) 928{ 929 struct sc_info *sc; 930 931 sc = pcm_getdevinfo(dev); 932 933 /* power up */ 934 cs4281_power(sc, 0); 935 936 /* initialize chip */ 937 if (cs4281_init(sc) == -1) { 938 device_printf(dev, "unable to reinitialize the card\n"); 939 return ENXIO; 940 } 941 942 /* restore mixer state */ 943 if (mixer_reinit(dev) == -1) { 944 device_printf(dev, "unable to reinitialize the mixer\n"); 945 return ENXIO; 946 } 947 948 /* restore chip state */ 949 cs4281chan_setspeed(NULL, &sc->rch, sc->rch.spd); 950 cs4281chan_setblocksize(NULL, &sc->rch, sc->rch.blksz); 951 cs4281chan_setformat(NULL, &sc->rch, sc->rch.fmt); 952 adcdac_go(&sc->rch, sc->rch.dma_active); 953 954 cs4281chan_setspeed(NULL, &sc->pch, sc->pch.spd); 955 cs4281chan_setblocksize(NULL, &sc->pch, sc->pch.blksz); 956 cs4281chan_setformat(NULL, &sc->pch, sc->pch.fmt); 957 adcdac_go(&sc->pch, sc->pch.dma_active); 958 959 return 0; 960} 961 962static device_method_t cs4281_methods[] = { 963 /* Device interface */ 964 DEVMETHOD(device_probe, cs4281_pci_probe), 965 DEVMETHOD(device_attach, cs4281_pci_attach), 966 DEVMETHOD(device_detach, cs4281_pci_detach), 967 DEVMETHOD(device_suspend, cs4281_pci_suspend), 968 DEVMETHOD(device_resume, cs4281_pci_resume), 969 { 0, 0 } 970}; 971 972static driver_t cs4281_driver = { 973 "pcm", 974 cs4281_methods, 975 PCM_SOFTC_SIZE, 976}; 977 978DRIVER_MODULE(snd_cs4281, pci, cs4281_driver, pcm_devclass, 0, 0); 979MODULE_DEPEND(snd_cs4281, snd_pcm, PCM_MINVER, PCM_PREFVER, PCM_MAXVER); 980MODULE_VERSION(snd_cs4281, 1); 981