root/dev/pci/neo.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nm_rd
  2. nm_wr
  3. nm_rdbuf
  4. nm_wrbuf
  5. nm_waitcd
  6. nm_ackint
  7. nm_loadcoeff
  8. nmchan_getptr
  9. neo_intr
  10. nm_init
  11. neo_attach
  12. neo_power
  13. neo_match
  14. neo_read_codec
  15. neo_write_codec
  16. neo_attach_codec
  17. neo_reset_codec
  18. neo_flags_codec
  19. neo_open
  20. neo_close
  21. neo_query_encoding
  22. neo_set_params
  23. neo_round_blocksize
  24. neo_trigger_output
  25. neo_trigger_input
  26. neo_halt_output
  27. neo_halt_input
  28. neo_getdev
  29. neo_mixer_set_port
  30. neo_mixer_get_port
  31. neo_query_devinfo
  32. neo_malloc
  33. neo_free
  34. neo_round_buffersize
  35. neo_get_props

    1 /*      $OpenBSD: neo.c,v 1.19 2005/08/09 04:10:13 mickey Exp $       */
    2 
    3 /*
    4  * Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk>
    5  * All rights reserved.
    6  *
    7  * Derived from the public domain Linux driver
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   28  * SUCH DAMAGE.
   29  *
   30  * $FreeBSD: src/sys/dev/sound/pci/neomagic.c,v 1.8 2000/03/20 15:30:50 cg Exp $
   31  */
   32 
   33 
   34 
   35 #include <sys/param.h>
   36 #include <sys/systm.h>
   37 #include <sys/kernel.h>
   38 #include <sys/malloc.h>
   39 #include <sys/device.h>
   40 
   41 #include <dev/pci/pcidevs.h>
   42 #include <dev/pci/pcivar.h>
   43 
   44 #include <sys/audioio.h>
   45 #include <dev/audio_if.h>
   46 #include <dev/mulaw.h>
   47 #include <dev/auconv.h>
   48 #include <dev/ic/ac97.h>
   49 
   50 #include <dev/pci/neoreg.h>
   51 
   52 /* -------------------------------------------------------------------- */
   53 /*
   54  * As of 04/13/00, public documentation on the Neomagic 256 is not available.
   55  * These comments were gleaned by looking at the driver carefully.
   56  *
   57  * The Neomagic 256 AV/ZX chips provide both video and audio capabilities
   58  * on one chip. About 2-6 megabytes of memory are associated with
   59  * the chip. Most of this goes to video frame buffers, but some is used for
   60  * audio buffering.
   61  *
   62  * Unlike most PCI audio chips, the Neomagic chip does not rely on DMA.
   63  * Instead, the chip allows you to carve two ring buffers out of its
   64  * memory. How you carve this and how much you can carve seems to be
   65  * voodoo. The algorithm is in nm_init.
   66  *
   67  * Most Neomagic audio chips use the AC-97 codec interface. However, there
   68  * seem to be a select few chips 256AV chips that do not support AC-97.
   69  * This driver does not support them but there are rumors that it
   70  * might work with wss isa drivers. This might require some playing around
   71  * with your BIOS.
   72  *
   73  * The Neomagic 256 AV/ZX have 2 PCI I/O region descriptors. Both of
   74  * them describe a memory region. The frame buffer is the first region
   75  * and the register set is the second region.
   76  *
   77  * The register manipulation logic is taken from the Linux driver,
   78  * which is in the public domain.
   79  *
   80  * The Neomagic is even nice enough to map the AC-97 codec registers into
   81  * the register space to allow direct manipulation. Watch out, accessing
   82  * AC-97 registers on the Neomagic requires great delicateness, otherwise
   83  * the thing will hang the PCI bus, rendering your system frozen.
   84  *
   85  * For one, it seems the Neomagic status register that reports AC-97
   86  * readiness should NOT be polled more often than once each 1ms.
   87  *
   88  * Also, writes to the AC-97 register space may take over 40us to
   89  * complete.
   90  *
   91  * Unlike many sound engines, the Neomagic does not support (as fas as
   92  * we know :) ) the notion of interrupting every n bytes transferred,
   93  * unlike many DMA engines.  Instead, it allows you to specify one
   94  * location in each ring buffer (called the watermark). When the chip
   95  * passes that location while playing, it signals an interrupt.
   96  *
   97  * The ring buffer size is currently 16k. That is about 100ms of audio
   98  * at 44.1khz/stero/16 bit. However, to keep the buffer full, interrupts
   99  * are generated more often than that, so 20-40 interrupts per second
  100  * should not be unexpected. Increasing BUFFSIZE should help minimize
  101  * the glitches due to drivers that spend too much time looping at high
  102  * privelege levels as well as the impact of badly written audio
  103  * interface clients.
  104  *
  105  * TO-DO list:
  106  *    neo_malloc/neo_free are still seriously broken.
  107  *
  108  *    Figure out interaction with video stuff (look at Xfree86 driver?)
  109  *
  110  *    Power management (neoactivate)
  111  *
  112  *    Fix detection of Neo devices that don't work this driver (see neo_attach)
  113  *
  114  *    Figure out how to shrink that huge table neo-coeff.h
  115  */
  116 
  117 #define NM_BUFFSIZE     16384
  118 
  119 #define NM256AV_PCI_ID  0x800510c8
  120 #define NM256ZX_PCI_ID  0x800610c8
  121 
  122 /* device private data */
  123 struct neo_softc {
  124         struct          device dev;
  125 
  126         bus_space_tag_t bufiot;
  127         bus_space_handle_t  bufioh;
  128 
  129         bus_space_tag_t regiot;
  130         bus_space_handle_t  regioh;
  131 
  132         u_int32_t       type;
  133         void            *ih;
  134 
  135         void    (*pintr)(void *);       /* dma completion intr handler */
  136         void    *parg;          /* arg for intr() */
  137 
  138         void    (*rintr)(void *);       /* dma completion intr handler */
  139         void    *rarg;          /* arg for intr() */
  140 
  141         u_int32_t       ac97_base, ac97_status, ac97_busy;
  142         u_int32_t       buftop, pbuf, rbuf, cbuf, acbuf;
  143         u_int32_t       playint, recint, misc1int, misc2int;
  144         u_int32_t       irsz, badintr;
  145 
  146         u_int32_t       pbufsize;
  147         u_int32_t       rbufsize;
  148 
  149         u_int32_t       pblksize;
  150         u_int32_t       rblksize;
  151 
  152         u_int32_t       pwmark;
  153         u_int32_t       rwmark;
  154 
  155         struct ac97_codec_if *codec_if;
  156         struct ac97_host_if host_if;
  157 
  158         void *powerhook;
  159 };
  160 
  161 static struct neo_firmware *nf;
  162 
  163 /* -------------------------------------------------------------------- */
  164 
  165 /*
  166  * prototypes
  167  */
  168 
  169 static int       nm_waitcd(struct neo_softc *sc);
  170 static int       nm_loadcoeff(struct neo_softc *sc, int dir, int num);
  171 static int       nm_init(struct neo_softc *);
  172 
  173 int    nmchan_getptr(struct neo_softc *, int);
  174 /* talk to the card */
  175 static u_int32_t nm_rd(struct neo_softc *, int, int);
  176 static void      nm_wr(struct neo_softc *, int, u_int32_t, int);
  177 static u_int32_t nm_rdbuf(struct neo_softc *, int, int);
  178 static void      nm_wrbuf(struct neo_softc *, int, u_int32_t, int);
  179 
  180 int     neo_match(struct device *, void *, void *);
  181 void    neo_attach(struct device *, struct device *, void *);
  182 int     neo_intr(void *);
  183 
  184 int     neo_open(void *, int);
  185 void    neo_close(void *);
  186 int     neo_query_encoding(void *, struct audio_encoding *);
  187 int     neo_set_params(void *, int, int, struct audio_params *, struct audio_params *);
  188 int     neo_round_blocksize(void *, int);
  189 int     neo_trigger_output(void *, void *, void *, int, void (*)(void *),
  190             void *, struct audio_params *);
  191 int     neo_trigger_input(void *, void *, void *, int, void (*)(void *),
  192             void *, struct audio_params *);
  193 int     neo_halt_output(void *);
  194 int     neo_halt_input(void *);
  195 int     neo_getdev(void *, struct audio_device *);
  196 int     neo_mixer_set_port(void *, mixer_ctrl_t *);
  197 int     neo_mixer_get_port(void *, mixer_ctrl_t *);
  198 int     neo_attach_codec(void *sc, struct ac97_codec_if *);
  199 int     neo_read_codec(void *sc, u_int8_t a, u_int16_t *d);
  200 int     neo_write_codec(void *sc, u_int8_t a, u_int16_t d);
  201 void    neo_reset_codec(void *sc);
  202 enum ac97_host_flags neo_flags_codec(void *sc);
  203 int     neo_query_devinfo(void *, mixer_devinfo_t *);
  204 void   *neo_malloc(void *, int, size_t, int, int);
  205 void    neo_free(void *, void *, int);
  206 size_t  neo_round_buffersize(void *, int, size_t);
  207 int     neo_get_props(void *);
  208 void    neo_set_mixer(struct neo_softc *sc, int a, int d);
  209 void    neo_power(int why, void *arg);
  210 
  211 
  212 struct cfdriver neo_cd = {
  213         NULL, "neo", DV_DULL
  214 };
  215 
  216 
  217 struct cfattach neo_ca = {
  218         sizeof(struct neo_softc), neo_match, neo_attach
  219 };
  220 
  221 
  222 struct audio_device neo_device = {
  223         "NeoMagic 256",
  224         "",
  225         "neo"
  226 };
  227 
  228 #if 0
  229 static u_int32_t badcards[] = {
  230         0x0007103c,
  231         0x008f1028,
  232 };
  233 #endif
  234 
  235 #define NUM_BADCARDS (sizeof(badcards) / sizeof(u_int32_t))
  236 
  237 /* The actual rates supported by the card. */
  238 static int samplerates[9] = {
  239         8000,
  240         11025,
  241         16000,
  242         22050,
  243         24000,
  244         32000,
  245         44100,
  246         48000,
  247         99999999
  248 };
  249 
  250 /* -------------------------------------------------------------------- */
  251 
  252 struct audio_hw_if neo_hw_if = {
  253         neo_open,
  254         neo_close,
  255         NULL,
  256         neo_query_encoding,
  257         neo_set_params,
  258 #if 1
  259         neo_round_blocksize,
  260 #else
  261         NULL,
  262 #endif
  263         NULL,
  264         NULL,
  265         NULL,
  266         NULL,
  267         NULL,
  268         neo_halt_output,
  269         neo_halt_input,
  270         NULL,
  271         neo_getdev,
  272         NULL,
  273         neo_mixer_set_port,
  274         neo_mixer_get_port,
  275         neo_query_devinfo,
  276         neo_malloc,
  277         neo_free,
  278         neo_round_buffersize,
  279         0,                              /* neo_mappage, */
  280         neo_get_props,
  281         neo_trigger_output,
  282         neo_trigger_input,
  283 
  284 };
  285 
  286 /* -------------------------------------------------------------------- */
  287 
  288 /* Hardware */
  289 static u_int32_t
  290 nm_rd(struct neo_softc *sc, int regno, int size)
  291 {
  292         bus_space_tag_t st = sc->regiot;
  293         bus_space_handle_t sh = sc->regioh;
  294 
  295         switch (size) {
  296         case 1:
  297                 return bus_space_read_1(st, sh, regno);
  298         case 2:
  299                 return bus_space_read_2(st, sh, regno);
  300         case 4:
  301                 return bus_space_read_4(st, sh, regno);
  302         default:
  303                 return (0xffffffff);
  304         }
  305 }
  306 
  307 static void
  308 nm_wr(struct neo_softc *sc, int regno, u_int32_t data, int size)
  309 {
  310         bus_space_tag_t st = sc->regiot;
  311         bus_space_handle_t sh = sc->regioh;
  312 
  313         switch (size) {
  314         case 1:
  315                 bus_space_write_1(st, sh, regno, data);
  316                 break;
  317         case 2:
  318                 bus_space_write_2(st, sh, regno, data);
  319                 break;
  320         case 4:
  321                 bus_space_write_4(st, sh, regno, data);
  322                 break;
  323         }
  324 }
  325 
  326 static u_int32_t
  327 nm_rdbuf(struct neo_softc *sc, int regno, int size)
  328 {
  329         bus_space_tag_t st = sc->bufiot;
  330         bus_space_handle_t sh = sc->bufioh;
  331 
  332         switch (size) {
  333         case 1:
  334                 return bus_space_read_1(st, sh, regno);
  335         case 2:
  336                 return bus_space_read_2(st, sh, regno);
  337         case 4:
  338                 return bus_space_read_4(st, sh, regno);
  339         default:
  340                 return (0xffffffff);
  341         }
  342 }
  343 
  344 static void
  345 nm_wrbuf(struct neo_softc *sc, int regno, u_int32_t data, int size)
  346 {
  347         bus_space_tag_t st = sc->bufiot;
  348         bus_space_handle_t sh = sc->bufioh;
  349 
  350         switch (size) {
  351         case 1:
  352                 bus_space_write_1(st, sh, regno, data);
  353                 break;
  354         case 2:
  355                 bus_space_write_2(st, sh, regno, data);
  356                 break;
  357         case 4:
  358                 bus_space_write_4(st, sh, regno, data);
  359                 break;
  360         }
  361 }
  362 
  363 /* ac97 codec */
  364 static int
  365 nm_waitcd(struct neo_softc *sc)
  366 {
  367         int cnt = 10;
  368         int fail = 1;
  369 
  370         while (cnt-- > 0) {
  371                 if (nm_rd(sc, sc->ac97_status, 2) & sc->ac97_busy)
  372                         DELAY(100);
  373                 else {
  374                         fail = 0;
  375                         break;
  376                 }
  377         }
  378         return (fail);
  379 }
  380 
  381 
  382 static void
  383 nm_ackint(struct neo_softc *sc, u_int32_t num)
  384 {
  385         if (sc->type == NM256AV_PCI_ID)
  386                 nm_wr(sc, NM_INT_REG, num << 1, 2);
  387         else if (sc->type == NM256ZX_PCI_ID)
  388                 nm_wr(sc, NM_INT_REG, num, 4);
  389 }
  390 
  391 static int
  392 nm_loadcoeff(struct neo_softc *sc, int dir, int num)
  393 {
  394         int ofs, sz, i;
  395         u_int32_t addr;
  396 
  397         if (nf == NULL) {
  398                 size_t buflen;
  399                 u_char *buf;
  400                 int error;
  401 
  402                 error = loadfirmware("neo-coefficients", &buf, &buflen);
  403                 if (error)
  404                         return (error);
  405                 nf = (struct neo_firmware *)buf;
  406         }
  407 
  408         addr = (dir == AUMODE_PLAY)? 0x01c : 0x21c;
  409         if (dir == AUMODE_RECORD)
  410                 num += 8;
  411         sz = nf->coefficientSizes[num];
  412         ofs = 0;
  413         while (num-- > 0)
  414                 ofs+= nf->coefficientSizes[num];
  415         for (i = 0; i < sz; i++)
  416                 nm_wrbuf(sc, sc->cbuf + i, nf->coefficients[ofs + i], 1);
  417         nm_wr(sc, addr, sc->cbuf, 4);
  418         if (dir == AUMODE_PLAY)
  419                 sz--;
  420         nm_wr(sc, addr + 4, sc->cbuf + sz, 4);
  421         return (0);
  422 }
  423 
  424 int
  425 nmchan_getptr(sc, mode)
  426         struct neo_softc *sc;
  427         int mode;
  428 {
  429         if (mode == AUMODE_PLAY)
  430                 return (nm_rd(sc, NM_PBUFFER_CURRP, 4) - sc->pbuf);
  431         else
  432                 return (nm_rd(sc, NM_RBUFFER_CURRP, 4) - sc->rbuf);
  433 }
  434 
  435 
  436 /* The interrupt handler */
  437 int
  438 neo_intr(void *p)
  439 {
  440         struct neo_softc *sc = (struct neo_softc *)p;
  441         int status, x;
  442         int rv = 0;
  443 
  444         status = nm_rd(sc, NM_INT_REG, sc->irsz);
  445 
  446         if (status & sc->playint) {
  447                 status &= ~sc->playint;
  448 
  449                 sc->pwmark += sc->pblksize;
  450                 sc->pwmark %= sc->pbufsize;
  451 
  452                 nm_wr(sc, NM_PBUFFER_WMARK, sc->pbuf + sc->pwmark, 4);
  453 
  454                 nm_ackint(sc, sc->playint);
  455 
  456                 if (sc->pintr)
  457                         (*sc->pintr)(sc->parg);
  458 
  459                 rv = 1;
  460         }
  461         if (status & sc->recint) {
  462                 status &= ~sc->recint;
  463 
  464                 sc->rwmark += sc->rblksize;
  465                 sc->rwmark %= sc->rbufsize;
  466 
  467                 nm_ackint(sc, sc->recint);
  468                 if (sc->rintr)
  469                         (*sc->rintr)(sc->rarg);
  470 
  471                 rv = 1;
  472         }
  473         if (status & sc->misc1int) {
  474                 status &= ~sc->misc1int;
  475                 nm_ackint(sc, sc->misc1int);
  476                 x = nm_rd(sc, 0x400, 1);
  477                 nm_wr(sc, 0x400, x | 2, 1);
  478                 printf("%s: misc int 1\n", sc->dev.dv_xname);
  479                 rv = 1;
  480         }
  481         if (status & sc->misc2int) {
  482                 status &= ~sc->misc2int;
  483                 nm_ackint(sc, sc->misc2int);
  484                 x = nm_rd(sc, 0x400, 1);
  485                 nm_wr(sc, 0x400, x & ~2, 1);
  486                 printf("%s: misc int 2\n", sc->dev.dv_xname);
  487                 rv = 1;
  488         }
  489         if (status) {
  490                 status &= ~sc->misc2int;
  491                 nm_ackint(sc, sc->misc2int);
  492                 printf("%s: unknown int\n", sc->dev.dv_xname);
  493                 rv = 1;
  494         }
  495 
  496         return (rv);
  497 }
  498 
  499 /* -------------------------------------------------------------------- */
  500 
  501 /*
  502  * Probe and attach the card
  503  */
  504 
  505 static int
  506 nm_init(struct neo_softc *sc)
  507 {
  508         u_int32_t ofs, i;
  509 
  510         if (sc->type == NM256AV_PCI_ID) {
  511                 sc->ac97_base = NM_MIXER_OFFSET;
  512                 sc->ac97_status = NM_MIXER_STATUS_OFFSET;
  513                 sc->ac97_busy = NM_MIXER_READY_MASK;
  514 
  515                 sc->buftop = 2560 * 1024;
  516 
  517                 sc->irsz = 2;
  518                 sc->playint = NM_PLAYBACK_INT;
  519                 sc->recint = NM_RECORD_INT;
  520                 sc->misc1int = NM_MISC_INT_1;
  521                 sc->misc2int = NM_MISC_INT_2;
  522         } else if (sc->type == NM256ZX_PCI_ID) {
  523                 sc->ac97_base = NM_MIXER_OFFSET;
  524                 sc->ac97_status = NM2_MIXER_STATUS_OFFSET;
  525                 sc->ac97_busy = NM2_MIXER_READY_MASK;
  526 
  527                 sc->buftop = (nm_rd(sc, 0xa0b, 2)? 6144 : 4096) * 1024;
  528 
  529                 sc->irsz = 4;
  530                 sc->playint = NM2_PLAYBACK_INT;
  531                 sc->recint = NM2_RECORD_INT;
  532                 sc->misc1int = NM2_MISC_INT_1;
  533                 sc->misc2int = NM2_MISC_INT_2;
  534         } else return -1;
  535         sc->badintr = 0;
  536         ofs = sc->buftop - 0x0400;
  537         sc->buftop -= 0x1400;
  538 
  539         if ((nm_rdbuf(sc, ofs, 4) & NM_SIG_MASK) == NM_SIGNATURE) {
  540                 i = nm_rdbuf(sc, ofs + 4, 4);
  541                 if (i != 0 && i != 0xffffffff)
  542                         sc->buftop = i;
  543         }
  544 
  545         sc->cbuf = sc->buftop - NM_MAX_COEFFICIENT;
  546         sc->rbuf = sc->cbuf - NM_BUFFSIZE;
  547         sc->pbuf = sc->rbuf - NM_BUFFSIZE;
  548         sc->acbuf = sc->pbuf - (NM_TOTAL_COEFF_COUNT * 4);
  549 
  550         nm_wr(sc, 0, 0x11, 1);
  551         nm_wr(sc, NM_RECORD_ENABLE_REG, 0, 1);
  552         nm_wr(sc, 0x214, 0, 2);
  553 
  554         return 0;
  555 }
  556 
  557 
  558 void
  559 neo_attach(parent, self, aux)
  560         struct device *parent;
  561         struct device *self;
  562         void *aux;
  563 {
  564         struct neo_softc *sc = (struct neo_softc *)self;
  565         struct pci_attach_args *pa = (struct pci_attach_args *)aux;
  566         pci_chipset_tag_t pc = pa->pa_pc;
  567         char const *intrstr;
  568         pci_intr_handle_t ih;
  569         int error;
  570 
  571         sc->type = pa->pa_id;
  572 
  573         /* Map I/O register */
  574         if (pci_mapreg_map(pa, PCI_MAPS, PCI_MAPREG_TYPE_MEM, 0,
  575                            &sc->bufiot, &sc->bufioh, NULL, NULL, 0)) {
  576                 printf("\n%s: can't map i/o space\n", sc->dev.dv_xname);
  577                 return;
  578         }
  579 
  580 
  581         if (pci_mapreg_map(pa, PCI_MAPS + 4, PCI_MAPREG_TYPE_MEM, 0,
  582                            &sc->regiot, &sc->regioh, NULL, NULL, 0)) {
  583                 printf("\n%s: can't map i/o space\n", sc->dev.dv_xname);
  584                 return;
  585         }
  586 
  587         /* Map and establish the interrupt. */
  588         if (pci_intr_map(pa, &ih)) {
  589                 printf("\n%s: couldn't map interrupt\n", sc->dev.dv_xname);
  590                 return;
  591         }
  592         intrstr = pci_intr_string(pc, ih);
  593         sc->ih = pci_intr_establish(pc, ih, IPL_AUDIO, neo_intr, sc,
  594                                        sc->dev.dv_xname);
  595 
  596         if (sc->ih == NULL) {
  597                 printf("\n%s: couldn't establish interrupt",
  598                        sc->dev.dv_xname);
  599                 if (intrstr != NULL)
  600                         printf(" at %s", intrstr);
  601                 printf("\n");
  602                 return;
  603         }
  604         printf(": %s\n", intrstr);
  605 
  606         if ((error = nm_init(sc)) != 0)
  607                 return;
  608 
  609         sc->host_if.arg = sc;
  610 
  611         sc->host_if.attach = neo_attach_codec;
  612         sc->host_if.read   = neo_read_codec;
  613         sc->host_if.write  = neo_write_codec;
  614         sc->host_if.reset  = neo_reset_codec;
  615         sc->host_if.flags  = neo_flags_codec;
  616 
  617         if ((error = ac97_attach(&sc->host_if)) != 0)
  618                 return;
  619 
  620         sc->powerhook = powerhook_establish(neo_power, sc);
  621 
  622         audio_attach_mi(&neo_hw_if, sc, &sc->dev);
  623 
  624         return;
  625 }
  626 
  627 void
  628 neo_power(int why, void *addr)
  629 {
  630         struct neo_softc *sc = (struct neo_softc *)addr;
  631 
  632         if (why == PWR_RESUME) {
  633                 nm_init(sc);
  634                 (sc->codec_if->vtbl->restore_ports)(sc->codec_if);
  635         }
  636 }
  637 
  638 
  639 
  640 int
  641 neo_match(parent, match, aux)
  642         struct device *parent;
  643         void *match;
  644         void *aux;
  645 {
  646         struct pci_attach_args *pa = (struct pci_attach_args *) aux;
  647 #if 0
  648         u_int32_t subdev, badcard;
  649 #endif
  650 
  651         if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_NEOMAGIC)
  652                 return (0);
  653 
  654 #if 0
  655         subdev = (pci_get_subdevice(dev) << 16) | pci_get_subvendor(dev);
  656 #endif
  657         switch (PCI_PRODUCT(pa->pa_id)) {
  658         case PCI_PRODUCT_NEOMAGIC_NM256AV:
  659 #if 0
  660                 i = 0;
  661                 while ((i < NUM_BADCARDS) && (badcards[i] != subdev))
  662                         i++;
  663                 if (i == NUM_BADCARDS)
  664                         s = "NeoMagic 256AV";
  665                 DEB(else)
  666                         DEB(device_printf(dev, "this is a non-ac97 NM256AV, not attaching\n"));
  667                 return (1);
  668 #endif
  669         case PCI_PRODUCT_NEOMAGIC_NM256ZX:
  670                 return (1);
  671         }
  672 
  673         return (0);
  674 }
  675 
  676 int
  677 neo_read_codec(sc_, a, d)
  678         void *sc_;
  679         u_int8_t a;
  680         u_int16_t *d;
  681 {
  682         struct neo_softc *sc = sc_;
  683 
  684         if (!nm_waitcd(sc)) {
  685                 *d = nm_rd(sc, sc->ac97_base + a, 2);
  686                 DELAY(1000);
  687                 return 0;
  688         }
  689 
  690         return (ENXIO);
  691 }
  692 
  693 
  694 int
  695 neo_write_codec(sc_, a, d)
  696         void *sc_;
  697         u_int8_t a;
  698         u_int16_t d;
  699 {
  700         struct neo_softc *sc = sc_;
  701         int cnt = 3;
  702 
  703         if (!nm_waitcd(sc)) {
  704                 while (cnt-- > 0) {
  705                         nm_wr(sc, sc->ac97_base + a, d, 2);
  706                         if (!nm_waitcd(sc)) {
  707                                 DELAY(1000);
  708                                 return (0);
  709                         }
  710                 }
  711         }
  712 
  713         return (ENXIO);
  714 }
  715 
  716 
  717 int
  718 neo_attach_codec(sc_, codec_if)
  719         void *sc_;
  720         struct ac97_codec_if  *codec_if;
  721 {
  722         struct neo_softc *sc = sc_;
  723 
  724         sc->codec_if = codec_if;
  725         return (0);
  726 }
  727 
  728 void
  729 neo_reset_codec(sc)
  730         void *sc;
  731 {
  732         nm_wr(sc, 0x6c0, 0x01, 1);
  733         nm_wr(sc, 0x6cc, 0x87, 1);
  734         nm_wr(sc, 0x6cc, 0x80, 1);
  735         nm_wr(sc, 0x6cc, 0x00, 1);
  736 
  737         return;
  738 }
  739 
  740 
  741 enum ac97_host_flags
  742 neo_flags_codec(sc)
  743         void *sc;
  744 {
  745         return (AC97_HOST_DONT_READANY);
  746 }
  747 
  748 int
  749 neo_open(addr, flags)
  750         void *addr;
  751         int flags;
  752 {
  753         return (0);
  754 }
  755 
  756 /*
  757  * Close function is called at splaudio().
  758  */
  759 void
  760 neo_close(addr)
  761         void *addr;
  762 {
  763         struct neo_softc *sc = addr;
  764 
  765         neo_halt_output(sc);
  766         neo_halt_input(sc);
  767 
  768         sc->pintr = 0;
  769         sc->rintr = 0;
  770 }
  771 
  772 int
  773 neo_query_encoding(addr, fp)
  774         void *addr;
  775         struct audio_encoding *fp;
  776 {
  777         switch (fp->index) {
  778         case 0:
  779                 strlcpy(fp->name, AudioEulinear, sizeof fp->name);
  780                 fp->encoding = AUDIO_ENCODING_ULINEAR;
  781                 fp->precision = 8;
  782                 fp->flags = 0;
  783                 return (0);
  784         case 1:
  785                 strlcpy(fp->name, AudioEmulaw, sizeof fp->name);
  786                 fp->encoding = AUDIO_ENCODING_ULAW;
  787                 fp->precision = 8;
  788                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  789                 return (0);
  790         case 2:
  791                 strlcpy(fp->name, AudioEalaw, sizeof fp->name);
  792                 fp->encoding = AUDIO_ENCODING_ALAW;
  793                 fp->precision = 8;
  794                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  795                 return (0);
  796         case 3:
  797                 strlcpy(fp->name, AudioEslinear, sizeof fp->name);
  798                 fp->encoding = AUDIO_ENCODING_SLINEAR;
  799                 fp->precision = 8;
  800                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  801                 return (0);
  802         case 4:
  803                 strlcpy(fp->name, AudioEslinear_le, sizeof fp->name);
  804                 fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
  805                 fp->precision = 16;
  806                 fp->flags = 0;
  807                 return (0);
  808         case 5:
  809                 strlcpy(fp->name, AudioEulinear_le, sizeof fp->name);
  810                 fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
  811                 fp->precision = 16;
  812                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  813                 return (0);
  814         case 6:
  815                 strlcpy(fp->name, AudioEslinear_be, sizeof fp->name);
  816                 fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
  817                 fp->precision = 16;
  818                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  819                 return (0);
  820         case 7:
  821                 strlcpy(fp->name, AudioEulinear_be, sizeof fp->name);
  822                 fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
  823                 fp->precision = 16;
  824                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  825                 return (0);
  826         default:
  827                 return (EINVAL);
  828         }
  829 }
  830 
  831 /* Todo: don't commit settings to card until we've verified all parameters */
  832 int
  833 neo_set_params(addr, setmode, usemode, play, rec)
  834         void *addr;
  835         int setmode, usemode;
  836         struct audio_params *play, *rec;
  837 {
  838         struct neo_softc *sc = addr;
  839         u_int32_t base;
  840         u_int8_t x;
  841         int mode;
  842         struct audio_params *p;
  843 
  844         for (mode = AUMODE_RECORD; mode != -1;
  845              mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
  846                 if ((setmode & mode) == 0)
  847                         continue;
  848 
  849                 p = mode == AUMODE_PLAY ? play : rec;
  850 
  851                 if (p == NULL) continue;
  852 
  853                 for (x = 0; x < 8; x++)
  854                         if (p->sample_rate < (samplerates[x] + samplerates[x + 1]) / 2)
  855                                 break;
  856 
  857                 if (x == 8) return (EINVAL);
  858 
  859                 p->sample_rate = samplerates[x];
  860                 nm_loadcoeff(sc, mode, x);
  861 
  862                 x <<= 4;
  863                 x &= NM_RATE_MASK;
  864                 if (p->precision == 16) x |= NM_RATE_BITS_16;
  865                 if (p->channels == 2) x |= NM_RATE_STEREO;
  866 
  867                 base = (mode == AUMODE_PLAY) ?
  868                     NM_PLAYBACK_REG_OFFSET : NM_RECORD_REG_OFFSET;
  869                 nm_wr(sc, base + NM_RATE_REG_OFFSET, x, 1);
  870 
  871                 p->factor = 1;
  872                 p->sw_code = 0;
  873                 switch (p->encoding) {
  874                 case AUDIO_ENCODING_SLINEAR_BE:
  875                         if (p->precision == 16)
  876                                 p->sw_code = swap_bytes;
  877                         else
  878                                 p->sw_code = change_sign8;
  879                         break;
  880                 case AUDIO_ENCODING_SLINEAR_LE:
  881                         if (p->precision != 16)
  882                                 p->sw_code = change_sign8;
  883                         break;
  884                 case AUDIO_ENCODING_ULINEAR_BE:
  885                         if (p->precision == 16) {
  886                                 if (mode == AUMODE_PLAY)
  887                                         p->sw_code = swap_bytes_change_sign16;
  888                                 else
  889                                         p->sw_code = change_sign16_swap_bytes;
  890                         }
  891                         break;
  892                 case AUDIO_ENCODING_ULINEAR_LE:
  893                         if (p->precision == 16)
  894                                 p->sw_code = change_sign16;
  895                         break;
  896                 case AUDIO_ENCODING_ULAW:
  897                         if (mode == AUMODE_PLAY) {
  898                                 p->factor = 2;
  899                                 p->sw_code = mulaw_to_slinear16;
  900                         } else
  901                                 p->sw_code = ulinear8_to_mulaw;
  902                         break;
  903                 case AUDIO_ENCODING_ALAW:
  904                         if (mode == AUMODE_PLAY) {
  905                                 p->factor = 2;
  906                                 p->sw_code = alaw_to_slinear16;
  907                         } else
  908                                 p->sw_code = ulinear8_to_alaw;
  909                         break;
  910                 default:
  911                         return (EINVAL);
  912                 }
  913         }
  914 
  915 
  916         return (0);
  917 }
  918 
  919 int
  920 neo_round_blocksize(addr, blk)
  921         void *addr;
  922         int blk;
  923 {
  924         return (NM_BUFFSIZE / 2);
  925 }
  926 
  927 int
  928 neo_trigger_output(addr, start, end, blksize, intr, arg, param)
  929         void *addr;
  930         void *start, *end;
  931         int blksize;
  932         void (*intr)(void *);
  933         void *arg;
  934         struct audio_params *param;
  935 {
  936         struct neo_softc *sc = addr;
  937         int ssz;
  938 
  939         sc->pintr = intr;
  940         sc->parg = arg;
  941 
  942         ssz = (param->precision * param->factor == 16)? 2 : 1;
  943         if (param->channels == 2)
  944                 ssz <<= 1;
  945 
  946         sc->pbufsize = ((char *)end - (char *)start);
  947         sc->pblksize = blksize;
  948         sc->pwmark = blksize;
  949 
  950         nm_wr(sc, NM_PBUFFER_START, sc->pbuf, 4);
  951         nm_wr(sc, NM_PBUFFER_END, sc->pbuf + sc->pbufsize - ssz, 4);
  952         nm_wr(sc, NM_PBUFFER_CURRP, sc->pbuf, 4);
  953         nm_wr(sc, NM_PBUFFER_WMARK, sc->pbuf + sc->pwmark, 4);
  954         nm_wr(sc, NM_PLAYBACK_ENABLE_REG, NM_PLAYBACK_FREERUN |
  955             NM_PLAYBACK_ENABLE_FLAG, 1);
  956         nm_wr(sc, NM_AUDIO_MUTE_REG, 0, 2);
  957 
  958         return (0);
  959 }
  960 
  961 
  962 
  963 int
  964 neo_trigger_input(addr, start, end, blksize, intr, arg, param)
  965         void *addr;
  966         void *start, *end;
  967         int blksize;
  968         void (*intr)(void *);
  969         void *arg;
  970         struct audio_params *param;
  971 {
  972         struct neo_softc *sc = addr;
  973         int ssz;
  974 
  975         sc->rintr = intr;
  976         sc->rarg = arg;
  977 
  978         ssz = (param->precision * param->factor == 16)? 2 : 1;
  979         if (param->channels == 2)
  980                 ssz <<= 1;
  981 
  982         sc->rbufsize = ((char *)end - (char *)start);
  983         sc->rblksize = blksize;
  984         sc->rwmark = blksize;
  985 
  986         nm_wr(sc, NM_RBUFFER_START, sc->rbuf, 4);
  987         nm_wr(sc, NM_RBUFFER_END, sc->rbuf + sc->rbufsize, 4);
  988         nm_wr(sc, NM_RBUFFER_CURRP, sc->rbuf, 4);
  989         nm_wr(sc, NM_RBUFFER_WMARK, sc->rbuf + sc->rwmark, 4);
  990         nm_wr(sc, NM_RECORD_ENABLE_REG, NM_RECORD_FREERUN |
  991             NM_RECORD_ENABLE_FLAG, 1);
  992 
  993         return (0);
  994 }
  995 
  996 int
  997 neo_halt_output(addr)
  998         void *addr;
  999 {
 1000         struct neo_softc *sc = (struct neo_softc *)addr;
 1001 
 1002         nm_wr(sc, NM_PLAYBACK_ENABLE_REG, 0, 1);
 1003         nm_wr(sc, NM_AUDIO_MUTE_REG, NM_AUDIO_MUTE_BOTH, 2);
 1004 
 1005         sc->pintr = 0;
 1006 
 1007         return (0);
 1008 }
 1009 
 1010 int
 1011 neo_halt_input(addr)
 1012         void *addr;
 1013 {
 1014         struct neo_softc *sc = (struct neo_softc *)addr;
 1015 
 1016         nm_wr(sc, NM_RECORD_ENABLE_REG, 0, 1);
 1017 
 1018         sc->rintr = 0;
 1019 
 1020         return (0);
 1021 }
 1022 
 1023 int
 1024 neo_getdev(addr, retp)
 1025         void *addr;
 1026         struct audio_device *retp;
 1027 {
 1028         *retp = neo_device;
 1029         return (0);
 1030 }
 1031 
 1032 int
 1033 neo_mixer_set_port(addr, cp)
 1034         void *addr;
 1035         mixer_ctrl_t *cp;
 1036 {
 1037         struct neo_softc *sc = addr;
 1038 
 1039         return ((sc->codec_if->vtbl->mixer_set_port)(sc->codec_if, cp));
 1040 }
 1041 
 1042 int
 1043 neo_mixer_get_port(addr, cp)
 1044         void *addr;
 1045         mixer_ctrl_t *cp;
 1046 {
 1047         struct neo_softc *sc = addr;
 1048 
 1049         return ((sc->codec_if->vtbl->mixer_get_port)(sc->codec_if, cp));
 1050 }
 1051 
 1052 int
 1053 neo_query_devinfo(addr, dip)
 1054         void *addr;
 1055         mixer_devinfo_t *dip;
 1056 {
 1057         struct neo_softc *sc = addr;
 1058 
 1059         return ((sc->codec_if->vtbl->query_devinfo)(sc->codec_if, dip));
 1060 }
 1061 
 1062 void *
 1063 neo_malloc(addr, direction, size, pool, flags)
 1064         void *addr;
 1065         int  direction;
 1066         size_t size;
 1067         int pool, flags;
 1068 {
 1069         struct neo_softc *sc = addr;
 1070         void *rv = 0;
 1071 
 1072         switch (direction) {
 1073         case AUMODE_PLAY:
 1074                 rv = (char *)sc->bufioh + sc->pbuf;
 1075                 break;
 1076         case AUMODE_RECORD:
 1077                 rv = (char *)sc->bufioh + sc->rbuf;
 1078                 break;
 1079         default:
 1080                 break;
 1081         }
 1082 
 1083         return (rv);
 1084 }
 1085 
 1086 void
 1087 neo_free(addr, ptr, pool)
 1088         void *addr;
 1089         void *ptr;
 1090         int pool;
 1091 {
 1092         return;
 1093 }
 1094 
 1095 size_t
 1096 neo_round_buffersize(addr, direction, size)
 1097         void *addr;
 1098         int direction;
 1099         size_t size;
 1100 {
 1101         return (NM_BUFFSIZE);
 1102 }
 1103 
 1104 
 1105 int
 1106 neo_get_props(addr)
 1107         void *addr;
 1108 {
 1109 
 1110         return (AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX);
 1111 }

/* [<][>][^][v][top][bottom][index][help] */