The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/pci/neo.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 1a6e4ad08ede1fdaea028e1dd7d94939


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.