root/dev/pci/auich.c

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

DEFINITIONS

This source file includes following definitions.
  1. auich_match
  2. auich_attach
  3. auich_read_codec
  4. auich_write_codec
  5. auich_attach_codec
  6. auich_reset_codec
  7. auich_flags_codec
  8. auich_open
  9. auich_close
  10. auich_query_encoding
  11. auich_set_params
  12. auich_round_blocksize
  13. auich_halt_output
  14. auich_halt_input
  15. auich_getdev
  16. auich_set_port
  17. auich_get_port
  18. auich_query_devinfo
  19. auich_allocm
  20. auich_freem
  21. auich_round_buffersize
  22. auich_mappage
  23. auich_get_props
  24. auich_intr
  25. auich_trigger_output
  26. auich_trigger_input
  27. auich_powerhook
  28. auich_calibrate

    1 /*      $OpenBSD: auich.c,v 1.64 2007/08/02 07:43:41 jakemsr Exp $      */
    2 
    3 /*
    4  * Copyright (c) 2000,2001 Michael Shalayeff
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   19  * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
   20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   22  * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   24  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
   25  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   26  * THE POSSIBILITY OF SUCH DAMAGE.
   27  */
   28 
   29 /* #define      AUICH_DEBUG */
   30 /*
   31  * AC'97 audio found on Intel 810/815/820/440MX chipsets.
   32  *      http://developer.intel.com/design/chipsets/datashts/290655.htm
   33  *      http://developer.intel.com/design/chipsets/manuals/298028.htm
   34  *      http://www.intel.com/design/chipsets/datashts/290716.htm
   35  *      http://www.intel.com/design/chipsets/datashts/290744.htm
   36  */
   37 
   38 #include <sys/param.h>
   39 #include <sys/systm.h>
   40 #include <sys/kernel.h>
   41 #include <sys/malloc.h>
   42 #include <sys/device.h>
   43 
   44 #include <dev/pci/pcidevs.h>
   45 #include <dev/pci/pcivar.h>
   46 
   47 #include <sys/audioio.h>
   48 #include <dev/audio_if.h>
   49 #include <dev/mulaw.h>
   50 #include <dev/auconv.h>
   51 
   52 #include <machine/bus.h>
   53 
   54 #include <dev/ic/ac97.h>
   55 
   56 /* 12.1.10 NAMBAR - native audio mixer base address register */
   57 #define AUICH_NAMBAR    0x10
   58 /* 12.1.11 NABMBAR - native audio bus mastering base address register */
   59 #define AUICH_NABMBAR   0x14
   60 #define AUICH_CFG       0x41
   61 #define AUICH_CFG_IOSE  0x01
   62 /* ICH4/ICH5/ICH6/ICH7 native audio mixer BAR */
   63 #define AUICH_MMBAR     0x18
   64 /* ICH4/ICH5/ICH6/ICH7 native bus mastering BAR */
   65 #define AUICH_MBBAR     0x1c
   66 #define AUICH_S2CR      0x10000000      /* tertiary codec ready */
   67 
   68 /* table 12-3. native audio bus master control registers */
   69 #define AUICH_BDBAR     0x00    /* 8-byte aligned address */
   70 #define AUICH_CIV               0x04    /* 5 bits current index value */
   71 #define AUICH_LVI               0x05    /* 5 bits last valid index value */
   72 #define         AUICH_LVI_MASK  0x1f
   73 #define AUICH_STS               0x06    /* 16 bits status */
   74 #define         AUICH_FIFOE     0x10    /* fifo error */
   75 #define         AUICH_BCIS      0x08    /* r- buf cmplt int sts; wr ack */
   76 #define         AUICH_LVBCI     0x04    /* r- last valid bci, wr ack */
   77 #define         AUICH_CELV      0x02    /* current equals last valid */
   78 #define         AUICH_DCH               0x01    /* dma halted */
   79 #define         AUICH_ISTS_BITS "\020\01dch\02celv\03lvbci\04bcis\05fifoe"
   80 #define AUICH_PICB      0x08    /* 16 bits */
   81 #define AUICH_PIV               0x0a    /* 5 bits prefetched index value */
   82 #define AUICH_CTRL      0x0b    /* control */
   83 #define         AUICH_IOCE      0x10    /* int on completion enable */
   84 #define         AUICH_FEIE      0x08    /* fifo error int enable */
   85 #define         AUICH_LVBIE     0x04    /* last valid buf int enable */
   86 #define         AUICH_RR                0x02    /* 1 - reset regs */
   87 #define         AUICH_RPBM      0x01    /* 1 - run, 0 - pause */
   88 
   89 #define AUICH_PCMI      0x00
   90 #define AUICH_PCMO      0x10
   91 #define AUICH_MICI      0x20
   92 
   93 #define AUICH_GCTRL     0x2c
   94 #define         AUICH_SSM_78    0x40000000      /* S/PDIF slots 7 and 8 */
   95 #define         AUICH_SSM_69    0x80000000      /* S/PDIF slots 6 and 9 */
   96 #define         AUICH_SSM_1011  0xc0000000      /* S/PDIF slots 10 and 11 */
   97 #define         AUICH_POM16     0x000000        /* PCM out precision 16bit */
   98 #define         AUICH_POM20     0x400000        /* PCM out precision 20bit */
   99 #define         AUICH_PCM246_MASK 0x300000
  100 #define         AUICH_PCM2      0x000000        /* 2ch output */
  101 #define         AUICH_PCM4      0x100000        /* 4ch output */
  102 #define         AUICH_PCM6      0x200000        /* 6ch output */
  103 #define         AUICH_S2RIE     0x40    /* int when tertiary codec resume */
  104 #define         AUICH_SRIE      0x20    /* int when 2ndary codec resume */
  105 #define         AUICH_PRIE      0x10    /* int when primary codec resume */
  106 #define         AUICH_ACLSO     0x08    /* aclink shut off */
  107 #define         AUICH_WRESET    0x04    /* warm reset */
  108 #define         AUICH_CRESET    0x02    /* cold reset */
  109 #define         AUICH_GIE               0x01    /* gpi int enable */
  110 #define AUICH_GSTS      0x30
  111 #define         AUICH_MD3               0x20000 /* pwr-dn semaphore for modem */
  112 #define         AUICH_AD3               0x10000 /* pwr-dn semaphore for audio */
  113 #define         AUICH_RCS               0x08000 /* read completion status */
  114 #define         AUICH_B3S12     0x04000 /* bit 3 of slot 12 */
  115 #define         AUICH_B2S12     0x02000 /* bit 2 of slot 12 */
  116 #define         AUICH_B1S12     0x01000 /* bit 1 of slot 12 */
  117 #define         AUICH_SRI               0x00800 /* secondary resume int */
  118 #define         AUICH_PRI               0x00400 /* primary resume int */
  119 #define         AUICH_SCR               0x00200 /* secondary codec ready */
  120 #define         AUICH_PCR               0x00100 /* primary codec ready */
  121 #define         AUICH_MINT      0x00080 /* mic in int */
  122 #define         AUICH_POINT     0x00040 /* pcm out int */
  123 #define         AUICH_PIINT     0x00020 /* pcm in int */
  124 #define         AUICH_MOINT     0x00004 /* modem out int */
  125 #define         AUICH_MIINT     0x00002 /* modem in int */
  126 #define         AUICH_GSCI      0x00001 /* gpi status change */
  127 #define         AUICH_GSTS_BITS "\020\01gsci\02miict\03moint\06piint\07point\010mint\011pcr\012scr\013pri\014sri\015b1s12\016b2s12\017b3s12\020rcs\021ad3\022md3"
  128 #define AUICH_CAS               0x34    /* 1/8 bit */
  129 #define AUICH_SEMATIMO          1000    /* us */
  130 #define AUICH_RESETIMO          500000  /* us */
  131 
  132 #define ICH_SIS_NV_CTL  0x4c    /* some SiS/NVIDIA register.  From Linux */
  133 #define         ICH_SIS_CTL_UNMUTE      0x01    /* un-mute the output */
  134 
  135 /*
  136  * according to the dev/audiovar.h AU_RING_SIZE is 2^16, what fits
  137  * in our limits perfectly, i.e. setting it to higher value
  138  * in your kernel config would improve perfomance, still 2^21 is the max
  139  */
  140 #define AUICH_DMALIST_MAX       32
  141 #define AUICH_DMASEG_MAX        (65536*2)       /* 64k samples, 2x16 bit samples */
  142 struct auich_dmalist {
  143         u_int32_t       base;
  144         u_int32_t       len;
  145 #define AUICH_DMAF_IOC  0x80000000      /* 1-int on complete */
  146 #define AUICH_DMAF_BUP  0x40000000      /* 0-retrans last, 1-transmit 0 */
  147 };
  148 
  149 #define AUICH_FIXED_RATE 48000
  150 
  151 struct auich_dma {
  152         bus_dmamap_t map;
  153         caddr_t addr;
  154         bus_dma_segment_t segs[AUICH_DMALIST_MAX];
  155         int nsegs;
  156         size_t size;
  157         struct auich_dma *next;
  158 };
  159 
  160 struct auich_softc {
  161         struct device sc_dev;
  162         void *sc_ih;
  163 
  164         audio_device_t sc_audev;
  165 
  166         bus_space_tag_t iot;
  167         bus_space_tag_t iot_mix;
  168         bus_space_handle_t mix_ioh;
  169         bus_space_handle_t aud_ioh;
  170         bus_dma_tag_t dmat;
  171 
  172         struct ac97_codec_if *codec_if;
  173         struct ac97_host_if host_if;
  174 
  175         /* dma scatter-gather buffer lists, aligned to 8 bytes */
  176         struct auich_dmalist *dmalist_pcmo, *dmap_pcmo;
  177         struct auich_dmalist *dmalist_pcmi, *dmap_pcmi;
  178         struct auich_dmalist *dmalist_mici, *dmap_mici;
  179 
  180         bus_dmamap_t dmalist_map;
  181         bus_dma_segment_t dmalist_seg[2];
  182         caddr_t dmalist_kva;
  183         bus_addr_t dmalist_pcmo_pa;
  184         bus_addr_t dmalist_pcmi_pa;
  185         bus_addr_t dmalist_mici_pa;
  186 
  187         /* i/o buffer pointers */
  188         u_int32_t pcmo_start, pcmo_p, pcmo_end;
  189         int pcmo_blksize, pcmo_fifoe;
  190         u_int32_t pcmi_start, pcmi_p, pcmi_end;
  191         int pcmi_blksize, pcmi_fifoe;
  192         u_int32_t mici_start, mici_p, mici_end;
  193         int mici_blksize, mici_fifoe;
  194         struct auich_dma *sc_dmas;
  195 
  196         void (*sc_pintr)(void *);
  197         void *sc_parg;
  198 
  199         void (*sc_rintr)(void *);
  200         void *sc_rarg;
  201 
  202         void *powerhook;
  203         int suspend;
  204         u_int16_t ext_ctrl;
  205         int sc_sample_size;
  206         int sc_sts_reg;
  207         int sc_ignore_codecready;
  208         int flags;
  209         int sc_ac97rate;
  210 };
  211 
  212 #ifdef AUICH_DEBUG
  213 #define DPRINTF(l,x)    do { if (auich_debug & (l)) printf x; } while(0)
  214 int auich_debug = 0xfffe;
  215 #define AUICH_DEBUG_CODECIO     0x0001
  216 #define AUICH_DEBUG_DMA         0x0002
  217 #define AUICH_DEBUG_PARAM       0x0004
  218 #else
  219 #define DPRINTF(x,y)    /* nothing */
  220 #endif
  221 
  222 struct cfdriver auich_cd = {
  223         NULL, "auich", DV_DULL
  224 };
  225 
  226 int  auich_match(struct device *, void *, void *);
  227 void auich_attach(struct device *, struct device *, void *);
  228 int  auich_intr(void *);
  229 
  230 struct cfattach auich_ca = {
  231         sizeof(struct auich_softc), auich_match, auich_attach
  232 };
  233 
  234 static const struct auich_devtype {
  235         int     vendor;
  236         int     product;
  237         int     options;
  238         char    name[8];
  239 } auich_devices[] = {
  240         { PCI_VENDOR_INTEL,     PCI_PRODUCT_INTEL_6300ESB_ACA,  0, "ESB" },
  241         { PCI_VENDOR_INTEL,     PCI_PRODUCT_INTEL_6321ESB_ACA,  0, "ESB2" },
  242         { PCI_VENDOR_INTEL,     PCI_PRODUCT_INTEL_82801AA_ACA,  0, "ICH" },
  243         { PCI_VENDOR_INTEL,     PCI_PRODUCT_INTEL_82801AB_ACA,  0, "ICH0" },
  244         { PCI_VENDOR_INTEL,     PCI_PRODUCT_INTEL_82801BA_ACA,  0, "ICH2" },
  245         { PCI_VENDOR_INTEL,     PCI_PRODUCT_INTEL_82801CA_ACA,  0, "ICH3" },
  246         { PCI_VENDOR_INTEL,     PCI_PRODUCT_INTEL_82801DB_ACA,  0, "ICH4" },
  247         { PCI_VENDOR_INTEL,     PCI_PRODUCT_INTEL_82801EB_ACA,  0, "ICH5" },
  248         { PCI_VENDOR_INTEL,     PCI_PRODUCT_INTEL_82801FB_ACA,  0, "ICH6" },
  249         { PCI_VENDOR_INTEL,     PCI_PRODUCT_INTEL_82801GB_ACA,  0, "ICH7" },
  250         { PCI_VENDOR_INTEL,     PCI_PRODUCT_INTEL_82440MX_ACA,  0, "440MX" },
  251         { PCI_VENDOR_SIS,       PCI_PRODUCT_SIS_7012_ACA,       0, "SiS7012" },
  252         { PCI_VENDOR_NVIDIA,    PCI_PRODUCT_NVIDIA_NFORCE_ACA,  0, "nForce" },
  253         { PCI_VENDOR_NVIDIA,    PCI_PRODUCT_NVIDIA_NFORCE2_ACA, 0, "nForce2" },
  254         { PCI_VENDOR_NVIDIA,    PCI_PRODUCT_NVIDIA_NFORCE2_400_ACA,
  255             0, "nForce2" },
  256         { PCI_VENDOR_NVIDIA,    PCI_PRODUCT_NVIDIA_NFORCE3_ACA, 0, "nForce3" },
  257         { PCI_VENDOR_NVIDIA,    PCI_PRODUCT_NVIDIA_NFORCE3_250_ACA,
  258             0, "nForce3" },
  259         { PCI_VENDOR_NVIDIA,    PCI_PRODUCT_NVIDIA_NFORCE4_AC,  0, "nForce4" },
  260         { PCI_VENDOR_NVIDIA,    PCI_PRODUCT_NVIDIA_MCP04_AC97,  0, "MCP04" },
  261         { PCI_VENDOR_NVIDIA,    PCI_PRODUCT_NVIDIA_MCP51_ACA,   0, "MCP51" },
  262         { PCI_VENDOR_AMD,       PCI_PRODUCT_AMD_PBC768_ACA,     0, "AMD768" },
  263         { PCI_VENDOR_AMD,       PCI_PRODUCT_AMD_8111_ACA,       0, "AMD8111" },
  264 };
  265 
  266 int auich_open(void *, int);
  267 void auich_close(void *);
  268 int auich_query_encoding(void *, struct audio_encoding *);
  269 int auich_set_params(void *, int, int, struct audio_params *,
  270     struct audio_params *);
  271 int auich_round_blocksize(void *, int);
  272 int auich_halt_output(void *);
  273 int auich_halt_input(void *);
  274 int auich_getdev(void *, struct audio_device *);
  275 int auich_set_port(void *, mixer_ctrl_t *);
  276 int auich_get_port(void *, mixer_ctrl_t *);
  277 int auich_query_devinfo(void *, mixer_devinfo_t *);
  278 void *auich_allocm(void *, int, size_t, int, int);
  279 void auich_freem(void *, void *, int);
  280 size_t auich_round_buffersize(void *, int, size_t);
  281 paddr_t auich_mappage(void *, void *, off_t, int);
  282 int auich_get_props(void *);
  283 int auich_trigger_output(void *, void *, void *, int, void (*)(void *),
  284     void *, struct audio_params *);
  285 int auich_trigger_input(void *, void *, void *, int, void (*)(void *),
  286     void *, struct audio_params *);
  287 
  288 void auich_powerhook(int, void *);
  289 
  290 struct audio_hw_if auich_hw_if = {
  291         auich_open,
  292         auich_close,
  293         NULL,                   /* drain */
  294         auich_query_encoding,
  295         auich_set_params,
  296         auich_round_blocksize,
  297         NULL,                   /* commit_setting */
  298         NULL,                   /* init_output */
  299         NULL,                   /* init_input */
  300         NULL,                   /* start_output */
  301         NULL,                   /* start_input */
  302         auich_halt_output,
  303         auich_halt_input,
  304         NULL,                   /* speaker_ctl */
  305         auich_getdev,
  306         NULL,                   /* getfd */
  307         auich_set_port,
  308         auich_get_port,
  309         auich_query_devinfo,
  310         auich_allocm,
  311         auich_freem,
  312         auich_round_buffersize,
  313         auich_mappage,
  314         auich_get_props,
  315         auich_trigger_output,
  316         auich_trigger_input
  317 };
  318 
  319 int  auich_attach_codec(void *, struct ac97_codec_if *);
  320 int  auich_read_codec(void *, u_int8_t, u_int16_t *);
  321 int  auich_write_codec(void *, u_int8_t, u_int16_t);
  322 void auich_reset_codec(void *);
  323 enum ac97_host_flags auich_flags_codec(void *);
  324 unsigned int auich_calibrate(struct auich_softc *);
  325 
  326 int
  327 auich_match(parent, match, aux)
  328         struct device *parent;
  329         void *match;
  330         void *aux;
  331 {
  332         struct pci_attach_args *pa = aux;
  333         int i;
  334 
  335         for (i = sizeof(auich_devices)/sizeof(auich_devices[0]); i--;)
  336                 if (PCI_VENDOR(pa->pa_id) == auich_devices[i].vendor &&
  337                     PCI_PRODUCT(pa->pa_id) == auich_devices[i].product)
  338                         return 1;
  339 
  340         return 0;
  341 }
  342 
  343 void
  344 auich_attach(parent, self, aux)
  345         struct device *parent, *self;
  346         void *aux;
  347 {
  348         struct auich_softc *sc = (struct auich_softc *)self;
  349         struct pci_attach_args *pa = aux;
  350         pci_intr_handle_t ih;
  351         bus_size_t mix_size, aud_size;
  352         pcireg_t csr;
  353         const char *intrstr;
  354         u_int32_t status;
  355         bus_size_t dmasz;
  356         int i, segs;
  357 
  358         if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL &&
  359             (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801DB_ACA ||
  360             PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801EB_ACA ||
  361             PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801FB_ACA ||
  362             PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801GB_ACA)) {
  363                 /*
  364                  * Use native mode for ICH4/ICH5/ICH6/ICH7
  365                  */
  366                 if (pci_mapreg_map(pa, AUICH_MMBAR, PCI_MAPREG_TYPE_MEM, 0,
  367                     &sc->iot_mix, &sc->mix_ioh, NULL, &mix_size, 0)) {
  368                         csr = pci_conf_read(pa->pa_pc, pa->pa_tag, AUICH_CFG);
  369                         pci_conf_write(pa->pa_pc, pa->pa_tag, AUICH_CFG,
  370                             csr | AUICH_CFG_IOSE);
  371                         if (pci_mapreg_map(pa, AUICH_NAMBAR, PCI_MAPREG_TYPE_IO,
  372                             0, &sc->iot_mix, &sc->mix_ioh, NULL, &mix_size, 0)) {
  373                                 printf(": can't map codec mem/io space\n");
  374                                 return;
  375                         }
  376                 }
  377 
  378                 if (pci_mapreg_map(pa, AUICH_MBBAR, PCI_MAPREG_TYPE_MEM, 0,
  379                     &sc->iot, &sc->aud_ioh, NULL, &aud_size, 0)) {
  380                         csr = pci_conf_read(pa->pa_pc, pa->pa_tag, AUICH_CFG);
  381                         pci_conf_write(pa->pa_pc, pa->pa_tag, AUICH_CFG,
  382                             csr | AUICH_CFG_IOSE);
  383                         if (pci_mapreg_map(pa, AUICH_NABMBAR,
  384                             PCI_MAPREG_TYPE_IO, 0, &sc->iot,
  385                             &sc->aud_ioh, NULL, &aud_size, 0)) {
  386                                 printf(": can't map device mem/io space\n");
  387                                 bus_space_unmap(sc->iot_mix, sc->mix_ioh, mix_size);
  388                                 return;
  389                         }
  390                 }
  391         } else {
  392                 if (pci_mapreg_map(pa, AUICH_NAMBAR, PCI_MAPREG_TYPE_IO,
  393                     0, &sc->iot_mix, &sc->mix_ioh, NULL, &mix_size, 0)) {
  394                         printf(": can't map codec i/o space\n");
  395                         return;
  396                 }
  397 
  398                 if (pci_mapreg_map(pa, AUICH_NABMBAR, PCI_MAPREG_TYPE_IO,
  399                     0, &sc->iot, &sc->aud_ioh, NULL, &aud_size, 0)) {
  400                         printf(": can't map device i/o space\n");
  401                         bus_space_unmap(sc->iot_mix, sc->mix_ioh, mix_size);
  402                         return;
  403                 }
  404         }
  405         sc->dmat = pa->pa_dmat;
  406 
  407         /* allocate dma memory */
  408         dmasz = AUICH_DMALIST_MAX * 3 * sizeof(struct auich_dma);
  409         segs = 1;
  410         if (bus_dmamem_alloc(sc->dmat, dmasz, PAGE_SIZE, 0, sc->dmalist_seg,
  411             segs, &segs, BUS_DMA_NOWAIT)) {
  412                 printf(": failed to alloc dmalist\n");
  413                 return;
  414         }
  415         if (bus_dmamem_map(sc->dmat, sc->dmalist_seg, segs, dmasz,
  416             &sc->dmalist_kva, BUS_DMA_NOWAIT)) {
  417                 printf(": failed to map dmalist\n");
  418                 bus_dmamem_free(sc->dmat, sc->dmalist_seg, segs);
  419                 return;
  420         }
  421         if (bus_dmamap_create(sc->dmat, dmasz, segs, dmasz, 0, BUS_DMA_NOWAIT,
  422             &sc->dmalist_map)) {
  423                 printf(": failed to create dmalist map\n");
  424                 bus_dmamem_unmap(sc->dmat, sc->dmalist_kva, dmasz);
  425                 bus_dmamem_free(sc->dmat, sc->dmalist_seg, segs);
  426                 return;
  427         }
  428         if (bus_dmamap_load_raw(sc->dmat, sc->dmalist_map, sc->dmalist_seg,
  429             segs, dmasz, BUS_DMA_NOWAIT)) {
  430                 printf(": failed to load dmalist map: %d segs %lu size\n",
  431                     segs, (u_long)dmasz);
  432                 bus_dmamap_destroy(sc->dmat, sc->dmalist_map);
  433                 bus_dmamem_unmap(sc->dmat, sc->dmalist_kva, dmasz);
  434                 bus_dmamem_free(sc->dmat, sc->dmalist_seg, segs);
  435                 return;
  436         }
  437 
  438         if (pci_intr_map(pa, &ih)) {
  439                 bus_space_unmap(sc->iot, sc->aud_ioh, aud_size);
  440                 bus_space_unmap(sc->iot_mix, sc->mix_ioh, mix_size);
  441                 return;
  442         }
  443         intrstr = pci_intr_string(pa->pa_pc, ih);
  444         sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_AUDIO, auich_intr,
  445                                        sc, sc->sc_dev.dv_xname);
  446         if (!sc->sc_ih) {
  447                 printf(": can't establish interrupt");
  448                 if (intrstr)
  449                         printf(" at %s", intrstr);
  450                 printf("\n");
  451                 bus_space_unmap(sc->iot, sc->aud_ioh, aud_size);
  452                 bus_space_unmap(sc->iot_mix, sc->mix_ioh, mix_size);
  453                 return;
  454         }
  455 
  456         for (i = sizeof(auich_devices)/sizeof(auich_devices[0]); i--;)
  457                 if (PCI_PRODUCT(pa->pa_id) == auich_devices[i].product)
  458                         break;
  459 
  460         snprintf(sc->sc_audev.name, sizeof sc->sc_audev.name, "%s AC97",
  461                  auich_devices[i].name);
  462         snprintf(sc->sc_audev.version, sizeof sc->sc_audev.version, "0x%02x",
  463                  PCI_REVISION(pa->pa_class));
  464         strlcpy(sc->sc_audev.config, sc->sc_dev.dv_xname,
  465                 sizeof sc->sc_audev.config);
  466 
  467         printf(": %s, %s\n", intrstr, sc->sc_audev.name);
  468 
  469         /* SiS 7012 needs special handling */
  470         if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_SIS &&
  471             PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SIS_7012_ACA) {
  472                 sc->sc_sts_reg = AUICH_PICB;
  473                 sc->sc_sample_size = 1;
  474                 /* un-mute output */
  475                 bus_space_write_4(sc->iot, sc->aud_ioh, ICH_SIS_NV_CTL,
  476                     bus_space_read_4(sc->iot, sc->aud_ioh, ICH_SIS_NV_CTL) |
  477                     ICH_SIS_CTL_UNMUTE);
  478         } else {
  479                 sc->sc_sts_reg = AUICH_STS;
  480                 sc->sc_sample_size = 2;
  481         }
  482 
  483         sc->dmalist_pcmo = (struct auich_dmalist *)(sc->dmalist_kva +
  484             (0 * sizeof(struct auich_dmalist) + AUICH_DMALIST_MAX));
  485         sc->dmalist_pcmo_pa = sc->dmalist_map->dm_segs[0].ds_addr +
  486             (0 * sizeof(struct auich_dmalist) + AUICH_DMALIST_MAX);
  487 
  488         sc->dmalist_pcmi = (struct auich_dmalist *)(sc->dmalist_kva +
  489             (1 * sizeof(struct auich_dmalist) + AUICH_DMALIST_MAX));
  490         sc->dmalist_pcmi_pa = sc->dmalist_map->dm_segs[0].ds_addr +
  491             (1 * sizeof(struct auich_dmalist) + AUICH_DMALIST_MAX);
  492 
  493         sc->dmalist_mici = (struct auich_dmalist *)(sc->dmalist_kva +
  494             (2 * sizeof(struct auich_dmalist) + AUICH_DMALIST_MAX));
  495         sc->dmalist_mici_pa = sc->dmalist_map->dm_segs[0].ds_addr +
  496             (2 * sizeof(struct auich_dmalist) + AUICH_DMALIST_MAX);
  497 
  498         DPRINTF(AUICH_DEBUG_DMA, ("auich_attach: lists %p %p %p\n",
  499             sc->dmalist_pcmo, sc->dmalist_pcmi, sc->dmalist_mici));
  500 
  501         /* Reset codec and AC'97 */
  502         auich_reset_codec(sc);
  503         status = bus_space_read_4(sc->iot, sc->aud_ioh, AUICH_GSTS);
  504         if (!(status & AUICH_PCR)) {    /* reset failure */
  505                 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL &&
  506                     (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801DB_ACA ||
  507                      PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801EB_ACA ||
  508                      PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801FB_ACA ||
  509                      PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801GB_ACA)) {
  510                         /* MSI 845G Max never return AUICH_PCR */
  511                         sc->sc_ignore_codecready = 1;
  512                 } else {
  513                         printf("%s: reset failed!\n", sc->sc_dev.dv_xname);
  514                         return;
  515                 }
  516         }
  517 
  518         sc->host_if.arg = sc;
  519         sc->host_if.attach = auich_attach_codec;
  520         sc->host_if.read = auich_read_codec;
  521         sc->host_if.write = auich_write_codec;
  522         sc->host_if.reset = auich_reset_codec;
  523         sc->host_if.flags = auich_flags_codec;
  524         if (sc->sc_dev.dv_cfdata->cf_flags & 0x0001)
  525                 sc->flags = AC97_HOST_SWAPPED_CHANNELS;
  526 
  527         if (ac97_attach(&sc->host_if) != 0) {
  528                 pci_intr_disestablish(pa->pa_pc, sc->sc_ih);
  529                 bus_space_unmap(sc->iot, sc->aud_ioh, aud_size);
  530                 bus_space_unmap(sc->iot_mix, sc->mix_ioh, mix_size);
  531                 return;
  532         }
  533 
  534         audio_attach_mi(&auich_hw_if, sc, &sc->sc_dev);
  535 
  536         /* Watch for power changes */
  537         sc->suspend = PWR_RESUME;
  538         sc->powerhook = powerhook_establish(auich_powerhook, sc);
  539 
  540         sc->sc_ac97rate = -1;
  541 }
  542 
  543 int
  544 auich_read_codec(v, reg, val)
  545         void *v;
  546         u_int8_t reg;
  547         u_int16_t *val;
  548 {
  549         struct auich_softc *sc = v;
  550         int i;
  551 
  552         /* wait for an access semaphore */
  553         for (i = AUICH_SEMATIMO; i-- &&
  554             bus_space_read_1(sc->iot, sc->aud_ioh, AUICH_CAS) & 1; DELAY(1));
  555 
  556         if (!sc->sc_ignore_codecready && i < 0) {
  557                 DPRINTF(AUICH_DEBUG_CODECIO,
  558                     ("%s: read_codec timeout\n", sc->sc_dev.dv_xname));
  559                 return (-1);
  560         }
  561 
  562         *val = bus_space_read_2(sc->iot_mix, sc->mix_ioh, reg);
  563         DPRINTF(AUICH_DEBUG_CODECIO, ("%s: read_codec(%x, %x)\n",
  564             sc->sc_dev.dv_xname, reg, *val));
  565         return (0);
  566 }
  567 
  568 int
  569 auich_write_codec(v, reg, val)
  570         void *v;
  571         u_int8_t reg;
  572         u_int16_t val;
  573 {
  574         struct auich_softc *sc = v;
  575         int i;
  576 
  577         /* wait for an access semaphore */
  578         for (i = AUICH_SEMATIMO; i-- &&
  579             bus_space_read_1(sc->iot, sc->aud_ioh, AUICH_CAS) & 1; DELAY(1));
  580 
  581         if (sc->sc_ignore_codecready || i >= 0) {
  582                 DPRINTF(AUICH_DEBUG_CODECIO, ("%s: write_codec(%x, %x)\n",
  583                     sc->sc_dev.dv_xname, reg, val));
  584                 bus_space_write_2(sc->iot_mix, sc->mix_ioh, reg, val);
  585                 return (0);
  586         } else {
  587                 DPRINTF(AUICH_DEBUG_CODECIO,
  588                     ("%s: write_codec timeout\n", sc->sc_dev.dv_xname));
  589                 return (-1);
  590         }
  591 }
  592 
  593 int
  594 auich_attach_codec(v, cif)
  595         void *v;
  596         struct ac97_codec_if *cif;
  597 {
  598         struct auich_softc *sc = v;
  599 
  600         sc->codec_if = cif;
  601         return 0;
  602 }
  603 
  604 void
  605 auich_reset_codec(v)
  606         void *v;
  607 {
  608         struct auich_softc *sc = v;
  609         u_int32_t control;
  610         int i;
  611 
  612         control = bus_space_read_4(sc->iot, sc->aud_ioh, AUICH_GCTRL);
  613         control &= ~(AUICH_ACLSO | AUICH_PCM246_MASK);
  614         control |= (control & AUICH_CRESET) ? AUICH_WRESET : AUICH_CRESET;
  615         bus_space_write_4(sc->iot, sc->aud_ioh, AUICH_GCTRL, control);
  616 
  617         for (i = AUICH_RESETIMO; i-- &&
  618             !(bus_space_read_4(sc->iot, sc->aud_ioh, AUICH_GSTS) & AUICH_PCR);
  619             DELAY(1));
  620 
  621         if (i < 0)
  622                 DPRINTF(AUICH_DEBUG_CODECIO,
  623                     ("%s: reset_codec timeout\n", sc->sc_dev.dv_xname));
  624 }
  625 
  626 enum ac97_host_flags
  627 auich_flags_codec(void *v)
  628 {
  629         struct auich_softc *sc = v;
  630 
  631         return (sc->flags);
  632 }
  633 
  634 int
  635 auich_open(v, flags)
  636         void *v;
  637         int flags;
  638 {
  639         struct auich_softc *sc = v;
  640 
  641         if (sc->sc_ac97rate == -1)
  642                 sc->sc_ac97rate = auich_calibrate(sc);
  643         return 0;
  644 }
  645 
  646 void
  647 auich_close(v)
  648         void *v;
  649 {
  650 }
  651 
  652 int
  653 auich_query_encoding(v, aep)
  654         void *v;
  655         struct audio_encoding *aep;
  656 {
  657         switch (aep->index) {
  658         case 0:
  659                 strlcpy(aep->name, AudioEulinear, sizeof aep->name);
  660                 aep->encoding = AUDIO_ENCODING_ULINEAR;
  661                 aep->precision = 8;
  662                 aep->flags = 0;
  663                 return (0);
  664         case 1:
  665                 strlcpy(aep->name, AudioEmulaw, sizeof aep->name);
  666                 aep->encoding = AUDIO_ENCODING_ULAW;
  667                 aep->precision = 8;
  668                 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
  669                 return (0);
  670         case 2:
  671                 strlcpy(aep->name, AudioEalaw, sizeof aep->name);
  672                 aep->encoding = AUDIO_ENCODING_ALAW;
  673                 aep->precision = 8;
  674                 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
  675                 return (0);
  676         case 3:
  677                 strlcpy(aep->name, AudioEslinear, sizeof aep->name);
  678                 aep->encoding = AUDIO_ENCODING_SLINEAR;
  679                 aep->precision = 8;
  680                 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
  681                 return (0);
  682         case 4:
  683                 strlcpy(aep->name, AudioEslinear_le, sizeof aep->name);
  684                 aep->encoding = AUDIO_ENCODING_SLINEAR_LE;
  685                 aep->precision = 16;
  686                 aep->flags = 0;
  687                 return (0);
  688         case 5:
  689                 strlcpy(aep->name, AudioEulinear_le, sizeof aep->name);
  690                 aep->encoding = AUDIO_ENCODING_ULINEAR_LE;
  691                 aep->precision = 16;
  692                 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
  693                 return (0);
  694         case 6:
  695                 strlcpy(aep->name, AudioEslinear_be, sizeof aep->name);
  696                 aep->encoding = AUDIO_ENCODING_SLINEAR_BE;
  697                 aep->precision = 16;
  698                 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
  699                 return (0);
  700         case 7:
  701                 strlcpy(aep->name, AudioEulinear_be, sizeof aep->name);
  702                 aep->encoding = AUDIO_ENCODING_ULINEAR_BE;
  703                 aep->precision = 16;
  704                 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
  705                 return (0);
  706         default:
  707                 return (EINVAL);
  708         }
  709 }
  710 
  711 int
  712 auich_set_params(v, setmode, usemode, play, rec)
  713         void *v;
  714         int setmode, usemode;
  715         struct audio_params *play, *rec;
  716 {
  717         struct auich_softc *sc = v;
  718         int error;
  719         u_int orate;
  720         u_int adj_rate;
  721 
  722         if (setmode & AUMODE_PLAY) {
  723                 play->factor = 1;
  724                 play->sw_code = NULL;
  725                 switch(play->encoding) {
  726                 case AUDIO_ENCODING_ULAW:
  727                         switch (play->channels) {
  728                         case 1:
  729                                 play->factor = 4;
  730                                 play->sw_code = mulaw_to_slinear16_mts;
  731                                 break;
  732                         case 2:
  733                                 play->factor = 2;
  734                                 play->sw_code = mulaw_to_slinear16;
  735                                 break;
  736                         default:
  737                                 return (EINVAL);
  738                         }
  739                         break;
  740                 case AUDIO_ENCODING_SLINEAR_LE:
  741                         switch (play->precision) {
  742                         case 8:
  743                                 switch (play->channels) {
  744                                 case 1:
  745                                         play->factor = 4;
  746                                         play->sw_code = linear8_to_linear16_mts;
  747                                         break;
  748                                 case 2:
  749                                         play->factor = 2;
  750                                         play->sw_code = linear8_to_linear16;
  751                                         break;
  752                                 default:
  753                                         return (EINVAL);
  754                                 }
  755                                 break;
  756                         case 16:
  757                                 switch (play->channels) {
  758                                 case 1:
  759                                         play->factor = 2;
  760                                         play->sw_code = noswap_bytes_mts;
  761                                         break;
  762                                 case 2:
  763                                         break;
  764                                 default:
  765                                         return (EINVAL);
  766                                 }
  767                                 break;
  768                         default:
  769                                 return (EINVAL);
  770                         }
  771                         break;
  772                 case AUDIO_ENCODING_ULINEAR_LE:
  773                         switch (play->precision) {
  774                         case 8:
  775                                 switch (play->channels) {
  776                                 case 1:
  777                                         play->factor = 4;
  778                                         play->sw_code = ulinear8_to_linear16_mts;
  779                                         break;
  780                                 case 2:
  781                                         play->factor = 2;
  782                                         play->sw_code = ulinear8_to_linear16;
  783                                         break;
  784                                 default:
  785                                         return (EINVAL);
  786                                 }
  787                                 break;
  788                         case 16:
  789                                 switch (play->channels) {
  790                                 case 1:
  791                                         play->factor = 2;
  792                                         play->sw_code = change_sign16_mts;
  793                                         break;
  794                                 case 2:
  795                                         play->sw_code = change_sign16;
  796                                         break;
  797                                 default:
  798                                         return (EINVAL);
  799                                 }
  800                                 break;
  801                         default:
  802                                 return (EINVAL);
  803                         }
  804                         break;
  805                 case AUDIO_ENCODING_ALAW:
  806                         switch (play->channels) {
  807                         case 1:
  808                                 play->factor = 4;
  809                                 play->sw_code = alaw_to_slinear16_mts;
  810                                 break;
  811                         case 2:
  812                                 play->factor = 2;
  813                                 play->sw_code = alaw_to_slinear16;
  814                                 break;
  815                         default:
  816                                 return (EINVAL);
  817                         }
  818                         break;
  819                 case AUDIO_ENCODING_SLINEAR_BE:
  820                         switch (play->precision) {
  821                         case 8:
  822                                 switch (play->channels) {
  823                                 case 1:
  824                                         play->factor = 4;
  825                                         play->sw_code = linear8_to_linear16_mts;
  826                                         break;
  827                                 case 2:
  828                                         play->factor = 2;
  829                                         play->sw_code = linear8_to_linear16;
  830                                         break;
  831                                 default:
  832                                         return (EINVAL);
  833                                 }
  834                                 break;
  835                         case 16:
  836                                 switch (play->channels) {
  837                                 case 1:
  838                                         play->factor = 2;
  839                                         play->sw_code = swap_bytes_mts;
  840                                         break;
  841                                 case 2:
  842                                         play->sw_code = swap_bytes;
  843                                         break;
  844                                 default:
  845                                         return (EINVAL);
  846                                 }
  847                                 break;
  848                         default:
  849                                 return (EINVAL);
  850                         }
  851                         break;
  852                 case AUDIO_ENCODING_ULINEAR_BE:
  853                         switch (play->precision) {
  854                         case 8:
  855                                 switch (play->channels) {
  856                                 case 1:
  857                                         play->factor = 4;
  858                                         play->sw_code = ulinear8_to_linear16_mts;
  859                                         break;
  860                                 case 2:
  861                                         play->factor = 2;
  862                                         play->sw_code = ulinear8_to_linear16;
  863                                         break;
  864                                 default:
  865                                         return (EINVAL);
  866                                 }
  867                                 break;
  868                         case 16:
  869                                 switch (play->channels) {
  870                                 case 1:
  871                                         play->factor = 2;
  872                                         play->sw_code = change_sign16_swap_bytes_mts;
  873                                         break;
  874                                 case 2:
  875                                         play->sw_code = change_sign16_swap_bytes;
  876                                         break;
  877                                 default:
  878                                         return (EINVAL);
  879                                 }
  880                                 break;
  881                         default:
  882                                 return (EINVAL);
  883                         }
  884                         break;
  885                 default:
  886                         return (EINVAL);
  887                 }
  888 
  889                 orate = adj_rate = play->sample_rate;
  890                 if (sc->sc_ac97rate != 0)
  891                         adj_rate = orate * AUICH_FIXED_RATE / sc->sc_ac97rate;
  892                 play->sample_rate = adj_rate;
  893                 error = ac97_set_rate(sc->codec_if, play, AUMODE_PLAY);
  894                 if (play->sample_rate == adj_rate)
  895                         play->sample_rate = orate;
  896                 if (error)
  897                         return (error);
  898         }
  899 
  900         if (setmode & AUMODE_RECORD) {
  901                 rec->factor = 1;
  902                 rec->sw_code = 0;
  903                 switch(rec->encoding) {
  904                 case AUDIO_ENCODING_ULAW:
  905                         rec->sw_code = slinear16_to_mulaw_le;
  906                         rec->factor = 2;
  907                         break;
  908                 case AUDIO_ENCODING_ALAW:
  909                         rec->sw_code = slinear16_to_alaw_le;
  910                         rec->factor = 2;
  911                         break;
  912                 case AUDIO_ENCODING_SLINEAR_LE:
  913                         switch (rec->precision) {
  914                         case 8:
  915                                 rec->sw_code = linear16_to_linear8_le;
  916                                 rec->factor = 2;
  917                                 break;
  918                         case 16:
  919                                 break;
  920                         default:
  921                                 return (EINVAL);
  922                         }
  923                         break;
  924                 case AUDIO_ENCODING_ULINEAR_LE:
  925                         switch (rec->precision) {
  926                         case 8:
  927                                 rec->sw_code = linear16_to_ulinear8_le;
  928                                 rec->factor = 2;
  929                                 break;
  930                         case 16:
  931                                 rec->sw_code = change_sign16_le;
  932                                 break;
  933                         default:
  934                                 return (EINVAL);
  935                         }
  936                         break;
  937                 case AUDIO_ENCODING_SLINEAR_BE:
  938                         switch (rec->precision) {
  939                         case 8:
  940                                 rec->sw_code = linear16_to_linear8_le;
  941                                 rec->factor = 2;
  942                                 break;
  943                         case 16:
  944                                 rec->sw_code = swap_bytes;
  945                                 break;
  946                         default:
  947                                 return (EINVAL);
  948                         }
  949                         break;
  950                 case AUDIO_ENCODING_ULINEAR_BE:
  951                         switch (rec->precision) {
  952                         case 8:
  953                                 rec->sw_code = linear16_to_ulinear8_le;
  954                                 rec->factor = 2;
  955                                 break;
  956                         case 16:
  957                                 rec->sw_code = change_sign16_swap_bytes_le;
  958                                 break;
  959                         default:
  960                                 return (EINVAL);
  961                         }
  962                         break;
  963                 default:
  964                         return (EINVAL);
  965                 }
  966 
  967                 orate = rec->sample_rate;
  968                 if (sc->sc_ac97rate != 0)
  969                         rec->sample_rate = orate * AUICH_FIXED_RATE /
  970                             sc->sc_ac97rate;
  971                 error = ac97_set_rate(sc->codec_if, rec, AUMODE_RECORD);
  972                 rec->sample_rate = orate;
  973                 if (error)
  974                         return (error);
  975         }
  976 
  977         return (0);
  978 }
  979 
  980 int
  981 auich_round_blocksize(v, blk)
  982         void *v;
  983         int blk;
  984 {
  985         return (blk + 0x3f) & ~0x3f;
  986 }
  987 
  988 int
  989 auich_halt_output(v)
  990         void *v;
  991 {
  992         struct auich_softc *sc = v;
  993 
  994         DPRINTF(AUICH_DEBUG_DMA, ("%s: halt_output\n", sc->sc_dev.dv_xname));
  995 
  996         bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_PCMO + AUICH_CTRL, AUICH_RR);
  997 
  998         return 0;
  999 }
 1000 
 1001 int
 1002 auich_halt_input(v)
 1003         void *v;
 1004 {
 1005         struct auich_softc *sc = v;
 1006 
 1007         DPRINTF(AUICH_DEBUG_DMA,
 1008             ("%s: halt_input\n", sc->sc_dev.dv_xname));
 1009 
 1010         /* XXX halt both unless known otherwise */
 1011 
 1012         bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_CTRL, AUICH_RR);
 1013         bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_MICI + AUICH_CTRL, AUICH_RR);
 1014 
 1015         return 0;
 1016 }
 1017 
 1018 int
 1019 auich_getdev(v, adp)
 1020         void *v;
 1021         struct audio_device *adp;
 1022 {
 1023         struct auich_softc *sc = v;
 1024         *adp = sc->sc_audev;
 1025         return 0;
 1026 }
 1027 
 1028 int
 1029 auich_set_port(v, cp)
 1030         void *v;
 1031         mixer_ctrl_t *cp;
 1032 {
 1033         struct auich_softc *sc = v;
 1034         return sc->codec_if->vtbl->mixer_set_port(sc->codec_if, cp);
 1035 }
 1036 
 1037 int
 1038 auich_get_port(v, cp)
 1039         void *v;
 1040         mixer_ctrl_t *cp;
 1041 {
 1042         struct auich_softc *sc = v;
 1043         return sc->codec_if->vtbl->mixer_get_port(sc->codec_if, cp);
 1044 }
 1045 
 1046 int
 1047 auich_query_devinfo(v, dp)
 1048         void *v;
 1049         mixer_devinfo_t *dp;
 1050 {
 1051         struct auich_softc *sc = v;
 1052         return sc->codec_if->vtbl->query_devinfo(sc->codec_if, dp);
 1053 }
 1054 
 1055 void *
 1056 auich_allocm(v, direction, size, pool, flags)
 1057         void *v;
 1058         int direction;
 1059         size_t size;
 1060         int pool, flags;
 1061 {
 1062         struct auich_softc *sc = v;
 1063         struct auich_dma *p;
 1064         int error;
 1065 
 1066         if (size > AUICH_DMALIST_MAX * AUICH_DMASEG_MAX)
 1067                 return NULL;
 1068 
 1069         p = malloc(sizeof(*p), pool, flags);
 1070         if (!p)
 1071                 return NULL;
 1072         bzero(p, sizeof(*p));
 1073 
 1074         p->size = size;
 1075         if ((error = bus_dmamem_alloc(sc->dmat, p->size, NBPG, 0, p->segs,
 1076             1, &p->nsegs, BUS_DMA_NOWAIT)) != 0) {
 1077                 printf("%s: unable to allocate dma, error = %d\n",
 1078                     sc->sc_dev.dv_xname, error);
 1079                 free(p, pool);
 1080                 return NULL;
 1081         }
 1082 
 1083         if ((error = bus_dmamem_map(sc->dmat, p->segs, p->nsegs, p->size,
 1084             &p->addr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
 1085                 printf("%s: unable to map dma, error = %d\n",
 1086                     sc->sc_dev.dv_xname, error);
 1087                 bus_dmamem_free(sc->dmat, p->segs, p->nsegs);
 1088                 free(p, pool);
 1089                 return NULL;
 1090         }
 1091 
 1092         if ((error = bus_dmamap_create(sc->dmat, p->size, 1,
 1093             p->size, 0, BUS_DMA_NOWAIT, &p->map)) != 0) {
 1094                 printf("%s: unable to create dma map, error = %d\n",
 1095                     sc->sc_dev.dv_xname, error);
 1096                 bus_dmamem_unmap(sc->dmat, p->addr, size);
 1097                 bus_dmamem_free(sc->dmat, p->segs, p->nsegs);
 1098                 free(p, pool);
 1099                 return NULL;
 1100         }
 1101 
 1102         if ((error = bus_dmamap_load(sc->dmat, p->map, p->addr, p->size,
 1103             NULL, BUS_DMA_NOWAIT)) != 0) {
 1104                 printf("%s: unable to load dma map, error = %d\n",
 1105                     sc->sc_dev.dv_xname, error);
 1106                 bus_dmamap_destroy(sc->dmat, p->map);
 1107                 bus_dmamem_unmap(sc->dmat, p->addr, size);
 1108                 bus_dmamem_free(sc->dmat, p->segs, p->nsegs);
 1109                 free(p, pool);
 1110                 return NULL;
 1111         }
 1112 
 1113         p->next = sc->sc_dmas;
 1114         sc->sc_dmas = p;
 1115 
 1116         return p->addr;
 1117 }
 1118 
 1119 void
 1120 auich_freem(v, ptr, pool)
 1121         void *v;
 1122         void *ptr;
 1123         int pool;
 1124 {
 1125         struct auich_softc *sc = v;
 1126         struct auich_dma *p;
 1127 
 1128         for (p = sc->sc_dmas; p->addr != ptr; p = p->next)
 1129                 if (p->next == NULL) {
 1130                         printf("auich_freem: trying to free not allocated memory");
 1131                         return;
 1132                 }
 1133 
 1134         bus_dmamap_unload(sc->dmat, p->map);
 1135         bus_dmamap_destroy(sc->dmat, p->map);
 1136         bus_dmamem_unmap(sc->dmat, p->addr, p->size);
 1137         bus_dmamem_free(sc->dmat, p->segs, p->nsegs);
 1138         free(p, pool);
 1139 }
 1140 
 1141 size_t
 1142 auich_round_buffersize(v, direction, size)
 1143         void *v;
 1144         int direction;
 1145         size_t size;
 1146 {
 1147         if (size > AUICH_DMALIST_MAX * AUICH_DMASEG_MAX)
 1148                 size = AUICH_DMALIST_MAX * AUICH_DMASEG_MAX;
 1149 
 1150         return size;
 1151 }
 1152 
 1153 paddr_t
 1154 auich_mappage(v, mem, off, prot)
 1155         void *v;
 1156         void *mem;
 1157         off_t off;
 1158         int prot;
 1159 {
 1160         struct auich_softc *sc = v;
 1161         struct auich_dma *p;
 1162 
 1163         if (off < 0)
 1164                 return -1;
 1165 
 1166         for (p = sc->sc_dmas; p && p->addr != mem; p = p->next);
 1167         if (!p)
 1168                 return -1;
 1169 
 1170         return bus_dmamem_mmap(sc->dmat, p->segs, p->nsegs,
 1171             off, prot, BUS_DMA_WAITOK);
 1172 }
 1173 
 1174 int
 1175 auich_get_props(v)
 1176         void *v;
 1177 {
 1178         return AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX;
 1179 }
 1180 
 1181 int
 1182 auich_intr(v)
 1183         void *v;
 1184 {
 1185         struct auich_softc *sc = v;
 1186         int ret = 0, sts, gsts, i;
 1187 
 1188         gsts = bus_space_read_2(sc->iot, sc->aud_ioh, AUICH_GSTS);
 1189         DPRINTF(AUICH_DEBUG_DMA, ("auich_intr: gsts=%b\n", gsts, AUICH_GSTS_BITS));
 1190 
 1191         if (gsts & AUICH_POINT) {
 1192                 sts = bus_space_read_2(sc->iot, sc->aud_ioh,
 1193                     AUICH_PCMO + sc->sc_sts_reg);
 1194                 DPRINTF(AUICH_DEBUG_DMA,
 1195                     ("auich_intr: osts=%b\n", sts, AUICH_ISTS_BITS));
 1196 
 1197 #ifdef AUICH_DEBUG
 1198                 if (sts & AUICH_FIFOE) {
 1199                         printf("%s: fifo underrun # %u\n",
 1200                             sc->sc_dev.dv_xname, ++sc->pcmo_fifoe);
 1201                 }
 1202 #endif
 1203                 i = bus_space_read_1(sc->iot, sc->aud_ioh, AUICH_PCMO + AUICH_CIV);
 1204                 if (sts & (AUICH_LVBCI | AUICH_CELV)) {
 1205                         struct auich_dmalist *q, *qe;
 1206 
 1207                         q = sc->dmap_pcmo;
 1208                         qe = &sc->dmalist_pcmo[i];
 1209 
 1210                         while (q != qe) {
 1211 
 1212                                 q->base = sc->pcmo_p;
 1213                                 q->len = (sc->pcmo_blksize /
 1214                                     sc->sc_sample_size) | AUICH_DMAF_IOC;
 1215                                 DPRINTF(AUICH_DEBUG_DMA,
 1216                                     ("auich_intr: %p, %p = %x @ %p\n",
 1217                                     qe, q, sc->pcmo_blksize /
 1218                                     sc->sc_sample_size, sc->pcmo_p));
 1219 
 1220                                 sc->pcmo_p += sc->pcmo_blksize;
 1221                                 if (sc->pcmo_p >= sc->pcmo_end)
 1222                                         sc->pcmo_p = sc->pcmo_start;
 1223 
 1224                                 if (++q == &sc->dmalist_pcmo[AUICH_DMALIST_MAX])
 1225                                         q = sc->dmalist_pcmo;
 1226                         }
 1227 
 1228                         sc->dmap_pcmo = q;
 1229                         bus_space_write_1(sc->iot, sc->aud_ioh,
 1230                             AUICH_PCMO + AUICH_LVI,
 1231                             (sc->dmap_pcmo - sc->dmalist_pcmo - 1) &
 1232                             AUICH_LVI_MASK);
 1233                 }
 1234 
 1235                 if (sts & AUICH_BCIS && sc->sc_pintr)
 1236                         sc->sc_pintr(sc->sc_parg);
 1237 
 1238                 /* int ack */
 1239                 bus_space_write_2(sc->iot, sc->aud_ioh,
 1240                     AUICH_PCMO + sc->sc_sts_reg, sts &
 1241                     (AUICH_LVBCI | AUICH_CELV | AUICH_BCIS | AUICH_FIFOE));
 1242                 bus_space_write_2(sc->iot, sc->aud_ioh, AUICH_GSTS, AUICH_POINT);
 1243                 ret++;
 1244         }
 1245 
 1246         if (gsts & AUICH_PIINT) {
 1247                 sts = bus_space_read_2(sc->iot, sc->aud_ioh,
 1248                     AUICH_PCMI + sc->sc_sts_reg);
 1249                 DPRINTF(AUICH_DEBUG_DMA,
 1250                     ("auich_intr: ists=%b\n", sts, AUICH_ISTS_BITS));
 1251 
 1252 #ifdef AUICH_DEBUG
 1253                 if (sts & AUICH_FIFOE) {
 1254                         printf("%s: in fifo overrun # %u\n",
 1255                             sc->sc_dev.dv_xname, ++sc->pcmi_fifoe);
 1256                 }
 1257 #endif
 1258                 i = bus_space_read_1(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_CIV);
 1259                 if (sts & (AUICH_LVBCI | AUICH_CELV)) {
 1260                         struct auich_dmalist *q, *qe;
 1261 
 1262                         q = sc->dmap_pcmi;
 1263                         qe = &sc->dmalist_pcmi[i];
 1264 
 1265                         while (q != qe) {
 1266 
 1267                                 q->base = sc->pcmi_p;
 1268                                 q->len = (sc->pcmi_blksize /
 1269                                     sc->sc_sample_size) | AUICH_DMAF_IOC;
 1270                                 DPRINTF(AUICH_DEBUG_DMA,
 1271                                     ("auich_intr: %p, %p = %x @ %p\n",
 1272                                     qe, q, sc->pcmi_blksize /
 1273                                     sc->sc_sample_size, sc->pcmi_p));
 1274 
 1275                                 sc->pcmi_p += sc->pcmi_blksize;
 1276                                 if (sc->pcmi_p >= sc->pcmi_end)
 1277                                         sc->pcmi_p = sc->pcmi_start;
 1278 
 1279                                 if (++q == &sc->dmalist_pcmi[AUICH_DMALIST_MAX])
 1280                                         q = sc->dmalist_pcmi;
 1281                         }
 1282 
 1283                         sc->dmap_pcmi = q;
 1284                         bus_space_write_1(sc->iot, sc->aud_ioh,
 1285                             AUICH_PCMI + AUICH_LVI,
 1286                             (sc->dmap_pcmi - sc->dmalist_pcmi - 1) &
 1287                             AUICH_LVI_MASK);
 1288                 }
 1289 
 1290                 if (sts & AUICH_BCIS && sc->sc_rintr)
 1291                         sc->sc_rintr(sc->sc_rarg);
 1292 
 1293                 /* int ack */
 1294                 bus_space_write_2(sc->iot, sc->aud_ioh,
 1295                     AUICH_PCMI + sc->sc_sts_reg, sts &
 1296                     (AUICH_LVBCI | AUICH_CELV | AUICH_BCIS | AUICH_FIFOE));
 1297                 bus_space_write_2(sc->iot, sc->aud_ioh, AUICH_GSTS, AUICH_PIINT);
 1298                 ret++;
 1299         }
 1300 
 1301         if (gsts & AUICH_MIINT) {
 1302                 sts = bus_space_read_2(sc->iot, sc->aud_ioh,
 1303                     AUICH_MICI + sc->sc_sts_reg);
 1304                 DPRINTF(AUICH_DEBUG_DMA,
 1305                     ("auich_intr: ists=%b\n", sts, AUICH_ISTS_BITS));
 1306 #ifdef AUICH_DEBUG
 1307                 if (sts & AUICH_FIFOE)
 1308                         printf("%s: mic fifo overrun\n", sc->sc_dev.dv_xname);
 1309 #endif
 1310 
 1311                 /* TODO mic input dma */
 1312 
 1313                 bus_space_write_2(sc->iot, sc->aud_ioh, AUICH_GSTS, AUICH_MIINT);
 1314         }
 1315 
 1316         return ret;
 1317 }
 1318 
 1319 int
 1320 auich_trigger_output(v, start, end, blksize, intr, arg, param)
 1321         void *v;
 1322         void *start, *end;
 1323         int blksize;
 1324         void (*intr)(void *);
 1325         void *arg;
 1326         struct audio_params *param;
 1327 {
 1328         struct auich_softc *sc = v;
 1329         struct auich_dmalist *q;
 1330         struct auich_dma *p;
 1331 
 1332         DPRINTF(AUICH_DEBUG_DMA,
 1333             ("auich_trigger_output(%x, %x, %d, %p, %p, %p)\n",
 1334             start, end, blksize, intr, arg, param));
 1335 
 1336         for (p = sc->sc_dmas; p && p->addr != start; p = p->next);
 1337         if (!p)
 1338                 return -1;
 1339 
 1340         sc->sc_pintr = intr;
 1341         sc->sc_parg = arg;
 1342 
 1343         /*
 1344          * The logic behind this is:
 1345          * setup one buffer to play, then LVI dump out the rest
 1346          * to the scatter-gather chain.
 1347          */
 1348         sc->pcmo_start = p->segs->ds_addr;
 1349         sc->pcmo_p = sc->pcmo_start + blksize;
 1350         sc->pcmo_end = sc->pcmo_start + ((char *)end - (char *)start);
 1351         sc->pcmo_blksize = blksize;
 1352 
 1353         q = sc->dmap_pcmo = sc->dmalist_pcmo;
 1354         q->base = sc->pcmo_start;
 1355         q->len = (blksize / sc->sc_sample_size) | AUICH_DMAF_IOC;
 1356         if (++q == &sc->dmalist_pcmo[AUICH_DMALIST_MAX])
 1357                 q = sc->dmalist_pcmo;
 1358         sc->dmap_pcmo = q;
 1359 
 1360         bus_space_write_4(sc->iot, sc->aud_ioh, AUICH_PCMO + AUICH_BDBAR,
 1361             sc->dmalist_pcmo_pa);
 1362         bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_PCMO + AUICH_CTRL,
 1363             AUICH_IOCE | AUICH_FEIE | AUICH_LVBIE | AUICH_RPBM);
 1364         bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_PCMO + AUICH_LVI,
 1365             (sc->dmap_pcmo - 1 - sc->dmalist_pcmo) & AUICH_LVI_MASK);
 1366 
 1367         return 0;
 1368 }
 1369 
 1370 int
 1371 auich_trigger_input(v, start, end, blksize, intr, arg, param)
 1372         void *v;
 1373         void *start, *end;
 1374         int blksize;
 1375         void (*intr)(void *);
 1376         void *arg;
 1377         struct audio_params *param;
 1378 {
 1379         struct auich_softc *sc = v;
 1380         struct auich_dmalist *q;
 1381         struct auich_dma *p;
 1382 
 1383         DPRINTF(AUICH_DEBUG_DMA,
 1384             ("auich_trigger_input(%x, %x, %d, %p, %p, %p)\n",
 1385             start, end, blksize, intr, arg, param));
 1386 
 1387         for (p = sc->sc_dmas; p && p->addr != start; p = p->next);
 1388         if (!p)
 1389                 return -1;
 1390 
 1391         sc->sc_rintr = intr;
 1392         sc->sc_rarg = arg;
 1393 
 1394         /*
 1395          * The logic behind this is:
 1396          * setup one buffer to play, then LVI dump out the rest
 1397          * to the scatter-gather chain.
 1398          */
 1399         sc->pcmi_start = p->segs->ds_addr;
 1400         sc->pcmi_p = sc->pcmi_start + blksize;
 1401         sc->pcmi_end = sc->pcmi_start + ((char *)end - (char *)start);
 1402         sc->pcmi_blksize = blksize;
 1403 
 1404         q = sc->dmap_pcmi = sc->dmalist_pcmi;
 1405         q->base = sc->pcmi_start;
 1406         q->len = (blksize / sc->sc_sample_size) | AUICH_DMAF_IOC;
 1407         if (++q == &sc->dmalist_pcmi[AUICH_DMALIST_MAX])
 1408                 q = sc->dmalist_pcmi;
 1409         sc->dmap_pcmi = q;
 1410 
 1411         bus_space_write_4(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_BDBAR,
 1412             sc->dmalist_pcmi_pa);
 1413         bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_CTRL,
 1414             AUICH_IOCE | AUICH_FEIE | AUICH_LVBIE | AUICH_RPBM);
 1415         bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_LVI,
 1416             (sc->dmap_pcmi - 1 - sc->dmalist_pcmi) & AUICH_LVI_MASK);
 1417 
 1418         return 0;
 1419 }
 1420 
 1421 void
 1422 auich_powerhook(why, self)
 1423         int why;
 1424         void *self;
 1425 {
 1426         struct auich_softc *sc = (struct auich_softc *)self;
 1427 
 1428         if (why != PWR_RESUME) {
 1429                 /* Power down */
 1430                 DPRINTF(1, ("auich: power down\n"));
 1431                 sc->suspend = why;
 1432                 auich_read_codec(sc, AC97_REG_EXT_AUDIO_CTRL, &sc->ext_ctrl);
 1433 
 1434         } else {
 1435                 /* Wake up */
 1436                 DPRINTF(1, ("auich: power resume\n"));
 1437                 if (sc->suspend == PWR_RESUME) {
 1438                         printf("%s: resume without suspend?\n",
 1439                             sc->sc_dev.dv_xname);
 1440                         sc->suspend = why;
 1441                         return;
 1442                 }
 1443                 sc->suspend = why;
 1444                 auich_reset_codec(sc);
 1445                 DELAY(1000);
 1446                 (sc->codec_if->vtbl->restore_ports)(sc->codec_if);
 1447                 auich_write_codec(sc, AC97_REG_EXT_AUDIO_CTRL, sc->ext_ctrl);
 1448         }
 1449 }
 1450 
 1451 
 1452 
 1453 /* -------------------------------------------------------------------- */
 1454 /* Calibrate card (some boards are overclocked and need scaling) */
 1455 
 1456 unsigned int
 1457 auich_calibrate(struct auich_softc *sc)
 1458 {
 1459         struct timeval t1, t2;
 1460         u_int8_t ociv, nciv;
 1461         u_int32_t wait_us, actual_48k_rate, bytes, ac97rate;
 1462         void *temp_buffer;
 1463         struct auich_dma *p;
 1464         int i;
 1465 
 1466         ac97rate = AUICH_FIXED_RATE;
 1467         /*
 1468          * Grab audio from input for fixed interval and compare how
 1469          * much we actually get with what we expect.  Interval needs
 1470          * to be sufficiently short that no interrupts are
 1471          * generated.
 1472          */
 1473 
 1474         /* Setup a buffer */
 1475         bytes = 16000;
 1476         temp_buffer = auich_allocm(sc, AUMODE_RECORD, bytes, M_DEVBUF,
 1477             M_NOWAIT);
 1478         if (temp_buffer == NULL)
 1479                 return (ac97rate);
 1480         for (p = sc->sc_dmas; p && p->addr != temp_buffer; p = p->next)
 1481                 ;
 1482         if (p == NULL) {
 1483                 printf("auich_calibrate: bad address %p\n", temp_buffer);
 1484                 return (ac97rate);
 1485         }
 1486 
 1487         for (i = 0; i < AUICH_DMALIST_MAX; i++) {
 1488                 sc->dmalist_pcmi[i].base = p->map->dm_segs[0].ds_addr;
 1489                 sc->dmalist_pcmi[i].len = bytes / sc->sc_sample_size;
 1490         }
 1491 
 1492         /*
 1493          * our data format is stereo, 16 bit so each sample is 4 bytes.
 1494          * assuming we get 48000 samples per second, we get 192000 bytes/sec.
 1495          * we're going to start recording with interrupts disabled and measure
 1496          * the time taken for one block to complete.  we know the block size,
 1497          * we know the time in microseconds, we calculate the sample rate:
 1498          *
 1499          * actual_rate [bps] = bytes / (time [s] * 4)
 1500          * actual_rate [bps] = (bytes * 1000000) / (time [us] * 4)
 1501          * actual_rate [Hz] = (bytes * 250000) / time [us]
 1502          */
 1503 
 1504         /* prepare */
 1505         ociv = bus_space_read_1(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_CIV);
 1506         nciv = ociv;
 1507         bus_space_write_4(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_BDBAR,
 1508             sc->dmalist_pcmi_pa);
 1509         bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_LVI,
 1510                           (0 - 1) & AUICH_LVI_MASK);
 1511 
 1512         /* start */
 1513         microuptime(&t1);
 1514         bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_CTRL,
 1515             AUICH_RPBM);
 1516 
 1517         /* wait */
 1518         while (nciv == ociv) {
 1519                 microuptime(&t2);
 1520                 if (t2.tv_sec - t1.tv_sec > 1)
 1521                         break;
 1522                 nciv = bus_space_read_1(sc->iot, sc->aud_ioh,
 1523                                         AUICH_PCMI + AUICH_CIV);
 1524         }
 1525         microuptime(&t2);
 1526 
 1527         /* reset */
 1528         bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_CTRL, AUICH_RR);
 1529         bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_MICI + AUICH_CTRL, AUICH_RR);
 1530         DELAY(100);
 1531 
 1532         /* turn time delta into us */
 1533         wait_us = ((t2.tv_sec - t1.tv_sec) * 1000000) + t2.tv_usec - t1.tv_usec;
 1534 
 1535 #if 0
 1536         auich_freem(sc, temp_buffer, M_DEVBUF);
 1537 #endif
 1538 
 1539         if (nciv == ociv) {
 1540                 printf("%s: ac97 link rate calibration timed out after %d us\n",
 1541                        sc->sc_dev.dv_xname, wait_us);
 1542                 return (ac97rate);
 1543         }
 1544 
 1545         actual_48k_rate = (bytes * 250000) / wait_us;
 1546 
 1547         if (actual_48k_rate <= 48500)
 1548                 ac97rate = AUICH_FIXED_RATE;
 1549         else
 1550                 ac97rate = actual_48k_rate;
 1551 
 1552         printf("%s: measured ac97 link rate at %d Hz",
 1553                sc->sc_dev.dv_xname, actual_48k_rate);
 1554         if (ac97rate != actual_48k_rate)
 1555                 printf(", will use %d Hz", ac97rate);
 1556         printf("\n");
 1557 
 1558         return (ac97rate);
 1559 }

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