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/sound/pci/maestro3.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 /*-
    2  * Copyright (c) 2001 Scott Long <scottl@freebsd.org>
    3  * Copyright (c) 2001 Darrell Anderson <anderson@cs.duke.edu>
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  */
   27 
   28 /*
   29  * Maestro-3/Allegro FreeBSD pcm sound driver
   30  *
   31  * executive status summary:
   32  * (+) /dev/dsp multiple concurrent play channels.
   33  * (+) /dev/dsp config (speed, mono/stereo, 8/16 bit).
   34  * (+) /dev/mixer sets left/right volumes.
   35  * (+) /dev/dsp recording works.  Tested successfully with the cdrom channel
   36  * (+) apm suspend/resume works, and works properly!.
   37  * (-) hardware volme controls don't work =-(
   38  * (-) setblocksize() does nothing.
   39  *
   40  * The real credit goes to:
   41  *
   42  * Zach Brown for his Linux driver core and helpful technical comments.
   43  * <zab@zabbo.net>, http://www.zabbo.net/maestro3
   44  *
   45  * Cameron Grant created the pcm framework used here nearly verbatim.
   46  * <cg@freebsd.org>, http://people.freebsd.org/~cg/template.c
   47  *
   48  * Taku YAMAMOTO for his Maestro-1/2 FreeBSD driver and sanity reference.
   49  * <taku@cent.saitama-u.ac.jp>
   50  *
   51  * ESS docs explained a few magic registers and numbers.
   52  * http://virgo.caltech.edu/~dmoore/maestro3.pdf.gz
   53  */
   54 
   55 #include <dev/sound/pcm/sound.h>
   56 #include <dev/sound/pcm/ac97.h>
   57 
   58 #include <dev/pci/pcireg.h>
   59 #include <dev/pci/pcivar.h>
   60 
   61 #include <gnu/dev/sound/pci/maestro3_reg.h>
   62 #include <gnu/dev/sound/pci/maestro3_dsp.h>
   63 
   64 SND_DECLARE_FILE("$FreeBSD$");
   65 
   66 /* -------------------------------------------------------------------- */
   67 
   68 enum {CHANGE=0, CALL=1, INTR=2, BORING=3, NONE=-1};
   69 #ifndef M3_DEBUG_LEVEL
   70 #define M3_DEBUG_LEVEL NONE
   71 #endif
   72 #define M3_DEBUG(level, _msg) {if ((level) <= M3_DEBUG_LEVEL) {printf _msg;}}
   73 
   74 /* -------------------------------------------------------------------- */
   75 enum {
   76         ESS_ALLEGRO_1,
   77         ESS_MAESTRO3
   78 };
   79 
   80 static struct m3_card_type {
   81         u_int32_t pci_id; int which; int delay1; int delay2; char *name;
   82 } m3_card_types[] = {
   83         { 0x1988125d, ESS_ALLEGRO_1, 50, 800, "ESS Technology Allegro-1" },
   84         { 0x1998125d, ESS_MAESTRO3, 20, 500, "ESS Technology Maestro3" },
   85         { 0x199a125d, ESS_MAESTRO3, 20, 500, "ESS Technology Maestro3" },
   86         { 0, 0, 0, 0, NULL }
   87 };
   88 
   89 #define M3_BUFSIZE_MIN  1024
   90 #define M3_BUFSIZE_MAX  65536
   91 #define M3_BUFSIZE_DEFAULT 4096
   92 #define M3_PCHANS 4 /* create /dev/dsp0.[0-N] to use more than one */
   93 #define M3_RCHANS 1
   94 #define M3_MAXADDR ((1 << 27) - 1)
   95 
   96 struct sc_info;
   97 
   98 struct sc_pchinfo {
   99         u_int32_t       spd;
  100         u_int32_t       fmt;
  101         struct snd_dbuf *buffer;
  102         struct pcm_channel      *channel;
  103         struct sc_info  *parent;
  104         u_int32_t       bufsize;
  105         u_int32_t       dac_data;
  106         u_int32_t       dac_idx;
  107         u_int32_t       active;
  108 };
  109 
  110 struct sc_rchinfo {
  111         u_int32_t       spd;
  112         u_int32_t       fmt;
  113         struct snd_dbuf *buffer;
  114         struct pcm_channel      *channel;
  115         struct sc_info  *parent;
  116         u_int32_t       bufsize;
  117         u_int32_t       adc_data;
  118         u_int32_t       adc_idx;
  119         u_int32_t       active;
  120 };
  121 
  122 struct sc_info {
  123         device_t                dev;
  124         u_int32_t               type;
  125         int                     which;
  126         int                     delay1;
  127         int                     delay2;
  128 
  129         bus_space_tag_t         st;
  130         bus_space_handle_t       sh;
  131         bus_dma_tag_t           parent_dmat;
  132 
  133         struct resource         *reg;
  134         struct resource         *irq;
  135         int                     regtype;
  136         int                     regid;
  137         int                     irqid;
  138         void                    *ih;
  139 
  140         struct sc_pchinfo       pch[M3_PCHANS];
  141         struct sc_rchinfo       rch[M3_RCHANS];
  142         int                     pch_cnt;
  143         int                     rch_cnt;
  144         int                     pch_active_cnt;
  145         unsigned int            bufsz;
  146         u_int16_t               *savemem;
  147 
  148         struct mtx              *sc_lock;
  149 };
  150 
  151 #define M3_LOCK(_sc)            snd_mtxlock((_sc)->sc_lock)
  152 #define M3_UNLOCK(_sc)          snd_mtxunlock((_sc)->sc_lock)
  153 #define M3_LOCK_ASSERT(_sc)     snd_mtxassert((_sc)->sc_lock)
  154 
  155 /* -------------------------------------------------------------------- */
  156 
  157 /* play channel interface */
  158 static void *m3_pchan_init(kobj_t, void *, struct snd_dbuf *, struct pcm_channel *, int);
  159 static int m3_pchan_free(kobj_t, void *);
  160 static int m3_pchan_setformat(kobj_t, void *, u_int32_t);
  161 static int m3_pchan_setspeed(kobj_t, void *, u_int32_t);
  162 static int m3_pchan_setblocksize(kobj_t, void *, u_int32_t);
  163 static int m3_pchan_trigger(kobj_t, void *, int);
  164 static int m3_pchan_trigger_locked(kobj_t, void *, int);
  165 static int m3_pchan_getptr(kobj_t, void *);
  166 static struct pcmchan_caps *m3_pchan_getcaps(kobj_t, void *);
  167 
  168 /* record channel interface */
  169 static void *m3_rchan_init(kobj_t, void *, struct snd_dbuf *, struct pcm_channel *, int);
  170 static int m3_rchan_free(kobj_t, void *);
  171 static int m3_rchan_setformat(kobj_t, void *, u_int32_t);
  172 static int m3_rchan_setspeed(kobj_t, void *, u_int32_t);
  173 static int m3_rchan_setblocksize(kobj_t, void *, u_int32_t);
  174 static int m3_rchan_trigger(kobj_t, void *, int);
  175 static int m3_rchan_trigger_locked(kobj_t, void *, int);
  176 static int m3_rchan_getptr(kobj_t, void *);
  177 static struct pcmchan_caps *m3_rchan_getcaps(kobj_t, void *);
  178 
  179 /* talk to the codec - called from ac97.c */
  180 static int       m3_initcd(kobj_t, void *);
  181 static int       m3_rdcd(kobj_t, void *, int);
  182 static int       m3_wrcd(kobj_t, void *, int, u_int32_t);
  183 
  184 /* stuff */
  185 static void      m3_intr(void *);
  186 static int       m3_power(struct sc_info *, int);
  187 static int       m3_init(struct sc_info *);
  188 static int       m3_uninit(struct sc_info *);
  189 static u_int8_t  m3_assp_halt(struct sc_info *);
  190 static void      m3_config(struct sc_info *);
  191 static void      m3_amp_enable(struct sc_info *);
  192 static void      m3_enable_ints(struct sc_info *);
  193 static void      m3_codec_reset(struct sc_info *);
  194 
  195 /* -------------------------------------------------------------------- */
  196 /* Codec descriptor */
  197 static kobj_method_t m3_codec_methods[] = {
  198         KOBJMETHOD(ac97_init,   m3_initcd),
  199         KOBJMETHOD(ac97_read,   m3_rdcd),
  200         KOBJMETHOD(ac97_write,  m3_wrcd),
  201         { 0, 0 }
  202 };
  203 AC97_DECLARE(m3_codec);
  204 
  205 /* -------------------------------------------------------------------- */
  206 /* channel descriptors */
  207 
  208 static u_int32_t m3_playfmt[] = {
  209         AFMT_U8,
  210         AFMT_STEREO | AFMT_U8,
  211         AFMT_S16_LE,
  212         AFMT_STEREO | AFMT_S16_LE,
  213         0
  214 };
  215 static struct pcmchan_caps m3_playcaps = {8000, 48000, m3_playfmt, 0};
  216 
  217 static kobj_method_t m3_pch_methods[] = {
  218         KOBJMETHOD(channel_init,                m3_pchan_init),
  219         KOBJMETHOD(channel_setformat,           m3_pchan_setformat),
  220         KOBJMETHOD(channel_setspeed,            m3_pchan_setspeed),
  221         KOBJMETHOD(channel_setblocksize,        m3_pchan_setblocksize),
  222         KOBJMETHOD(channel_trigger,             m3_pchan_trigger),
  223         KOBJMETHOD(channel_getptr,              m3_pchan_getptr),
  224         KOBJMETHOD(channel_getcaps,             m3_pchan_getcaps),
  225         KOBJMETHOD(channel_free,                m3_pchan_free),
  226         { 0, 0 }
  227 };
  228 CHANNEL_DECLARE(m3_pch);
  229 
  230 static u_int32_t m3_recfmt[] = {
  231         AFMT_U8,
  232         AFMT_STEREO | AFMT_U8,
  233         AFMT_S16_LE,
  234         AFMT_STEREO | AFMT_S16_LE,
  235         0
  236 };
  237 static struct pcmchan_caps m3_reccaps = {8000, 48000, m3_recfmt, 0};
  238 
  239 static kobj_method_t m3_rch_methods[] = {
  240         KOBJMETHOD(channel_init,                m3_rchan_init),
  241         KOBJMETHOD(channel_setformat,           m3_rchan_setformat),
  242         KOBJMETHOD(channel_setspeed,            m3_rchan_setspeed),
  243         KOBJMETHOD(channel_setblocksize,        m3_rchan_setblocksize),
  244         KOBJMETHOD(channel_trigger,             m3_rchan_trigger),
  245         KOBJMETHOD(channel_getptr,              m3_rchan_getptr),
  246         KOBJMETHOD(channel_getcaps,             m3_rchan_getcaps),
  247         KOBJMETHOD(channel_free,                m3_rchan_free),
  248         { 0, 0 }
  249 };
  250 CHANNEL_DECLARE(m3_rch);
  251 
  252 /* -------------------------------------------------------------------- */
  253 /* some i/o convenience functions */
  254 
  255 #define m3_rd_1(sc, regno) bus_space_read_1(sc->st, sc->sh, regno)
  256 #define m3_rd_2(sc, regno) bus_space_read_2(sc->st, sc->sh, regno)
  257 #define m3_rd_4(sc, regno) bus_space_read_4(sc->st, sc->sh, regno)
  258 #define m3_wr_1(sc, regno, data) bus_space_write_1(sc->st, sc->sh, regno, data)
  259 #define m3_wr_2(sc, regno, data) bus_space_write_2(sc->st, sc->sh, regno, data)
  260 #define m3_wr_4(sc, regno, data) bus_space_write_4(sc->st, sc->sh, regno, data)
  261 #define m3_rd_assp_code(sc, index) \
  262         m3_rd_assp(sc, MEMTYPE_INTERNAL_CODE, index)
  263 #define m3_wr_assp_code(sc, index, data) \
  264         m3_wr_assp(sc, MEMTYPE_INTERNAL_CODE, index, data)
  265 #define m3_rd_assp_data(sc, index) \
  266         m3_rd_assp(sc, MEMTYPE_INTERNAL_DATA, index)
  267 #define m3_wr_assp_data(sc, index, data) \
  268         m3_wr_assp(sc, MEMTYPE_INTERNAL_DATA, index, data)
  269 
  270 static __inline u_int16_t
  271 m3_rd_assp(struct sc_info *sc, u_int16_t region, u_int16_t index)
  272 {
  273         m3_wr_2(sc, DSP_PORT_MEMORY_TYPE, region & MEMTYPE_MASK);
  274         m3_wr_2(sc, DSP_PORT_MEMORY_INDEX, index);
  275         return m3_rd_2(sc, DSP_PORT_MEMORY_DATA);
  276 }
  277 
  278 static __inline void
  279 m3_wr_assp(struct sc_info *sc, u_int16_t region, u_int16_t index,
  280            u_int16_t data)
  281 {
  282         m3_wr_2(sc, DSP_PORT_MEMORY_TYPE, region & MEMTYPE_MASK);
  283         m3_wr_2(sc, DSP_PORT_MEMORY_INDEX, index);
  284         m3_wr_2(sc, DSP_PORT_MEMORY_DATA, data);
  285 }
  286 
  287 static __inline int
  288 m3_wait(struct sc_info *sc)
  289 {
  290         int i;
  291 
  292         for (i=0 ; i<20 ; i++) {
  293                 if ((m3_rd_1(sc, CODEC_STATUS) & 1) == 0) {
  294                         return 0;
  295                 }
  296                 DELAY(2);
  297         }
  298         return -1;
  299 }
  300 
  301 /* -------------------------------------------------------------------- */
  302 /* ac97 codec */
  303 
  304 static int
  305 m3_initcd(kobj_t kobj, void *devinfo)
  306 {
  307         struct sc_info *sc = (struct sc_info *)devinfo;
  308         u_int32_t data;
  309 
  310         M3_DEBUG(CALL, ("m3_initcd\n"));
  311 
  312         /* init ac-link */
  313 
  314         data = m3_rd_1(sc, CODEC_COMMAND);
  315         return ((data & 0x1) ? 0 : 1);
  316 }
  317 
  318 static int
  319 m3_rdcd(kobj_t kobj, void *devinfo, int regno)
  320 {
  321         struct sc_info *sc = (struct sc_info *)devinfo;
  322         u_int32_t data;
  323 
  324         if (m3_wait(sc)) {
  325                 device_printf(sc->dev, "m3_rdcd timed out.\n");
  326                 return -1;
  327         }
  328         m3_wr_1(sc, CODEC_COMMAND, (regno & 0x7f) | 0x80);
  329         DELAY(50); /* ac97 cycle = 20.8 usec */
  330         if (m3_wait(sc)) {
  331                 device_printf(sc->dev, "m3_rdcd timed out.\n");
  332                 return -1;
  333         }
  334         data = m3_rd_2(sc, CODEC_DATA);
  335         return data;
  336 }
  337 
  338 static int
  339 m3_wrcd(kobj_t kobj, void *devinfo, int regno, u_int32_t data)
  340 {
  341         struct sc_info *sc = (struct sc_info *)devinfo;
  342         if (m3_wait(sc)) {
  343                 device_printf(sc->dev, "m3_wrcd timed out.\n");
  344                 return -1;;
  345         }
  346         m3_wr_2(sc, CODEC_DATA, data);
  347         m3_wr_1(sc, CODEC_COMMAND, regno & 0x7f);
  348         DELAY(50); /* ac97 cycle = 20.8 usec */
  349         return 0;
  350 }
  351 
  352 /* -------------------------------------------------------------------- */
  353 /* play channel interface */
  354 
  355 #define LO(x) (((x) & 0x0000ffff)      )
  356 #define HI(x) (((x) & 0xffff0000) >> 16)
  357 
  358 static void *
  359 m3_pchan_init(kobj_t kobj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
  360 {
  361         struct sc_info *sc = devinfo;
  362         struct sc_pchinfo *ch;
  363         u_int32_t bus_addr, i;
  364         int idx, data_bytes, dac_data;
  365         int dsp_in_size, dsp_out_size, dsp_in_buf, dsp_out_buf;
  366 
  367         M3_LOCK(sc);
  368         idx = sc->pch_cnt; /* dac instance number, no active reuse! */
  369         M3_DEBUG(CHANGE, ("m3_pchan_init(dac=%d)\n", idx));
  370 
  371         if (dir != PCMDIR_PLAY) {
  372                 M3_UNLOCK(sc);
  373                 device_printf(sc->dev, "m3_pchan_init not PCMDIR_PLAY\n");
  374                 return (NULL);
  375         }
  376 
  377         data_bytes = (((MINISRC_TMP_BUFFER_SIZE & ~1) +
  378                            (MINISRC_IN_BUFFER_SIZE & ~1) +
  379                            (MINISRC_OUT_BUFFER_SIZE & ~1) + 4) + 255) &~ 255;
  380         dac_data = 0x1100 + (data_bytes * idx);
  381 
  382         dsp_in_size = MINISRC_IN_BUFFER_SIZE - (0x20 * 2);
  383         dsp_out_size = MINISRC_OUT_BUFFER_SIZE - (0x20 * 2);
  384         dsp_in_buf = dac_data + (MINISRC_TMP_BUFFER_SIZE/2);
  385         dsp_out_buf = dsp_in_buf + (dsp_in_size/2) + 1;
  386 
  387         ch = &sc->pch[idx];
  388         ch->dac_idx = idx;
  389         ch->dac_data = dac_data;
  390         if (ch->dac_data + data_bytes/2 >= 0x1c00) {
  391                 M3_UNLOCK(sc);
  392                 device_printf(sc->dev, "m3_pchan_init: revb mem exhausted\n");
  393                 return (NULL);
  394         }
  395 
  396         ch->buffer = b;
  397         ch->parent = sc;
  398         ch->channel = c;
  399         ch->fmt = AFMT_U8;
  400         ch->spd = DSP_DEFAULT_SPEED;
  401         M3_UNLOCK(sc); /* XXX */
  402         if (sndbuf_alloc(ch->buffer, sc->parent_dmat, sc->bufsz) != 0) {
  403                 device_printf(sc->dev, "m3_pchan_init chn_allocbuf failed\n");
  404                 return (NULL);
  405         }
  406         M3_LOCK(sc);
  407         ch->bufsize = sndbuf_getsize(ch->buffer);
  408 
  409         /* host dma buffer pointers */
  410         bus_addr = sndbuf_getbufaddr(ch->buffer);
  411         if (bus_addr & 3) {
  412                 device_printf(sc->dev, "m3_pchan_init unaligned bus_addr\n");
  413                 bus_addr = (bus_addr + 4) & ~3;
  414         }
  415         m3_wr_assp_data(sc, ch->dac_data + CDATA_HOST_SRC_ADDRL, LO(bus_addr));
  416         m3_wr_assp_data(sc, ch->dac_data + CDATA_HOST_SRC_ADDRH, HI(bus_addr));
  417         m3_wr_assp_data(sc, ch->dac_data + CDATA_HOST_SRC_END_PLUS_1L,
  418                         LO(bus_addr + ch->bufsize));
  419         m3_wr_assp_data(sc, ch->dac_data + CDATA_HOST_SRC_END_PLUS_1H,
  420                         HI(bus_addr + ch->bufsize));
  421         m3_wr_assp_data(sc, ch->dac_data + CDATA_HOST_SRC_CURRENTL,
  422                         LO(bus_addr));
  423         m3_wr_assp_data(sc, ch->dac_data + CDATA_HOST_SRC_CURRENTH,
  424                         HI(bus_addr));
  425 
  426         /* dsp buffers */
  427         m3_wr_assp_data(sc, ch->dac_data + CDATA_IN_BUF_BEGIN, dsp_in_buf);
  428         m3_wr_assp_data(sc, ch->dac_data + CDATA_IN_BUF_END_PLUS_1,
  429                         dsp_in_buf + dsp_in_size/2);
  430         m3_wr_assp_data(sc, ch->dac_data + CDATA_IN_BUF_HEAD, dsp_in_buf);
  431         m3_wr_assp_data(sc, ch->dac_data + CDATA_IN_BUF_TAIL, dsp_in_buf);
  432         m3_wr_assp_data(sc, ch->dac_data + CDATA_OUT_BUF_BEGIN, dsp_out_buf);
  433         m3_wr_assp_data(sc, ch->dac_data + CDATA_OUT_BUF_END_PLUS_1,
  434                         dsp_out_buf + dsp_out_size/2);
  435         m3_wr_assp_data(sc, ch->dac_data + CDATA_OUT_BUF_HEAD, dsp_out_buf);
  436         m3_wr_assp_data(sc, ch->dac_data + CDATA_OUT_BUF_TAIL, dsp_out_buf);
  437 
  438         /* some per client initializers */
  439         m3_wr_assp_data(sc, ch->dac_data + SRC3_DIRECTION_OFFSET + 12,
  440                         ch->dac_data + 40 + 8);
  441         m3_wr_assp_data(sc, ch->dac_data + SRC3_DIRECTION_OFFSET + 19,
  442                         0x400 + MINISRC_COEF_LOC);
  443         /* enable or disable low pass filter? (0xff if rate> 45000) */
  444         m3_wr_assp_data(sc, ch->dac_data + SRC3_DIRECTION_OFFSET + 22, 0);
  445         /* tell it which way dma is going? */
  446         m3_wr_assp_data(sc, ch->dac_data + CDATA_DMA_CONTROL,
  447                         DMACONTROL_AUTOREPEAT + DMAC_PAGE3_SELECTOR +
  448                         DMAC_BLOCKF_SELECTOR);
  449 
  450         /* set an armload of static initializers */
  451         for(i = 0 ; i < (sizeof(pv) / sizeof(pv[0])) ; i++) {
  452                 m3_wr_assp_data(sc, ch->dac_data + pv[i].addr, pv[i].val);
  453         }
  454 
  455         /* put us in the packed task lists */
  456         m3_wr_assp_data(sc, KDATA_INSTANCE0_MINISRC +
  457                         (sc->pch_cnt + sc->rch_cnt),
  458                         ch->dac_data >> DP_SHIFT_COUNT);
  459         m3_wr_assp_data(sc, KDATA_DMA_XFER0 + (sc->pch_cnt + sc->rch_cnt),
  460                         ch->dac_data >> DP_SHIFT_COUNT);
  461         m3_wr_assp_data(sc, KDATA_MIXER_XFER0 + sc->pch_cnt,
  462                         ch->dac_data >> DP_SHIFT_COUNT);
  463 
  464         /* gotta start before stop */
  465         m3_pchan_trigger_locked(NULL, ch, PCMTRIG_START);
  466         /* silence noise on load */
  467         m3_pchan_trigger_locked(NULL, ch, PCMTRIG_STOP);
  468 
  469         sc->pch_cnt++;
  470         M3_UNLOCK(sc);
  471 
  472         return (ch);
  473 }
  474 
  475 static int
  476 m3_pchan_free(kobj_t kobj, void *chdata)
  477 {
  478         struct sc_pchinfo *ch = chdata;
  479         struct sc_info *sc = ch->parent;
  480 
  481         M3_LOCK(sc);
  482         M3_DEBUG(CHANGE, ("m3_pchan_free(dac=%d)\n", ch->dac_idx));
  483 
  484         /*
  485          * should remove this exact instance from the packed lists, but all
  486          * are released at once (and in a stopped state) so this is ok.
  487          */
  488         m3_wr_assp_data(sc, KDATA_INSTANCE0_MINISRC +
  489                         (sc->pch_cnt - 1) + sc->rch_cnt, 0);
  490         m3_wr_assp_data(sc, KDATA_DMA_XFER0 +
  491                         (sc->pch_cnt - 1) + sc->rch_cnt, 0);
  492         m3_wr_assp_data(sc, KDATA_MIXER_XFER0 + (sc->pch_cnt-1), 0);
  493         sc->pch_cnt--;
  494         M3_UNLOCK(sc);
  495 
  496         return (0);
  497 }
  498 
  499 static int
  500 m3_pchan_setformat(kobj_t kobj, void *chdata, u_int32_t format)
  501 {
  502         struct sc_pchinfo *ch = chdata;
  503         struct sc_info *sc = ch->parent;
  504         u_int32_t data;
  505 
  506         M3_LOCK(sc);
  507         M3_DEBUG(CHANGE,
  508                  ("m3_pchan_setformat(dac=%d, format=0x%x{%s-%s})\n",
  509                   ch->dac_idx, format,
  510                   format & (AFMT_U8|AFMT_S8) ? "8bit":"16bit",
  511                   format & AFMT_STEREO ? "STEREO":"MONO"));
  512 
  513         /* mono word */
  514         data = (format & AFMT_STEREO) ? 0 : 1;
  515         m3_wr_assp_data(sc, ch->dac_data + SRC3_MODE_OFFSET, data);
  516 
  517         /* 8bit word */
  518         data = ((format & AFMT_U8) || (format & AFMT_S8)) ? 1 : 0;
  519         m3_wr_assp_data(sc, ch->dac_data + SRC3_WORD_LENGTH_OFFSET, data);
  520 
  521         ch->fmt = format;
  522         M3_UNLOCK(sc);
  523 
  524         return (0);
  525 }
  526 
  527 static int
  528 m3_pchan_setspeed(kobj_t kobj, void *chdata, u_int32_t speed)
  529 {
  530         struct sc_pchinfo *ch = chdata;
  531         struct sc_info *sc = ch->parent;
  532         u_int32_t freq;
  533 
  534         M3_LOCK(sc);
  535         M3_DEBUG(CHANGE, ("m3_pchan_setspeed(dac=%d, speed=%d)\n",
  536                           ch->dac_idx, speed));
  537 
  538         if ((freq = ((speed << 15) + 24000) / 48000) != 0) {
  539                 freq--;
  540         }
  541 
  542         m3_wr_assp_data(sc, ch->dac_data + CDATA_FREQUENCY, freq);
  543         ch->spd = speed;
  544         M3_UNLOCK(sc);
  545 
  546         /* return closest possible speed */
  547         return (speed);
  548 }
  549 
  550 static int
  551 m3_pchan_setblocksize(kobj_t kobj, void *chdata, u_int32_t blocksize)
  552 {
  553         struct sc_pchinfo *ch = chdata;
  554 
  555         M3_DEBUG(CHANGE, ("m3_pchan_setblocksize(dac=%d, blocksize=%d)\n",
  556                           ch->dac_idx, blocksize));
  557 
  558         return blocksize;
  559 }
  560 
  561 static int
  562 m3_pchan_trigger(kobj_t kobj, void *chdata, int go)
  563 {
  564         struct sc_pchinfo *ch = chdata;
  565         struct sc_info *sc = ch->parent;
  566         int ret;
  567 
  568         M3_LOCK(sc);
  569         ret = m3_pchan_trigger_locked(kobj, chdata, go);
  570         M3_UNLOCK(sc);
  571 
  572         return (ret);
  573 }
  574 
  575 static int
  576 m3_pchan_trigger_locked(kobj_t kobj, void *chdata, int go)
  577 {
  578         struct sc_pchinfo *ch = chdata;
  579         struct sc_info *sc = ch->parent;
  580         u_int32_t data;
  581 
  582         M3_LOCK_ASSERT(sc);
  583         M3_DEBUG(go == PCMTRIG_START ? CHANGE :
  584                  go == PCMTRIG_STOP ? CHANGE :
  585                  go == PCMTRIG_ABORT ? CHANGE :
  586                  CALL,
  587                  ("m3_pchan_trigger(dac=%d, go=0x%x{%s})\n", ch->dac_idx, go,
  588                   go == PCMTRIG_START ? "PCMTRIG_START" :
  589                   go == PCMTRIG_STOP ? "PCMTRIG_STOP" :
  590                   go == PCMTRIG_ABORT ? "PCMTRIG_ABORT" : "ignore"));
  591 
  592         switch(go) {
  593         case PCMTRIG_START:
  594                 if (ch->active) {
  595                         return 0;
  596                 }
  597                 ch->active = 1;
  598                 sc->pch_active_cnt++;
  599 
  600                 /*[[inc_timer_users]]*/
  601                 m3_wr_assp_data(sc, KDATA_TIMER_COUNT_RELOAD, 240);
  602                 m3_wr_assp_data(sc, KDATA_TIMER_COUNT_CURRENT, 240);
  603                 data = m3_rd_2(sc, HOST_INT_CTRL);
  604                 m3_wr_2(sc, HOST_INT_CTRL, data | CLKRUN_GEN_ENABLE);
  605 
  606                 m3_wr_assp_data(sc, ch->dac_data + CDATA_INSTANCE_READY, 1);
  607                 m3_wr_assp_data(sc, KDATA_MIXER_TASK_NUMBER,
  608                                 sc->pch_active_cnt);
  609                 break;
  610 
  611         case PCMTRIG_STOP:
  612         case PCMTRIG_ABORT:
  613                 if (ch->active == 0) {
  614                         return 0;
  615                 }
  616                 ch->active = 0;
  617                 sc->pch_active_cnt--;
  618 
  619                 /* XXX should the channel be drained? */
  620                 /*[[dec_timer_users]]*/
  621                 m3_wr_assp_data(sc, KDATA_TIMER_COUNT_RELOAD, 0);
  622                 m3_wr_assp_data(sc, KDATA_TIMER_COUNT_CURRENT, 0);
  623                 data = m3_rd_2(sc, HOST_INT_CTRL);
  624                 m3_wr_2(sc, HOST_INT_CTRL, data & ~CLKRUN_GEN_ENABLE);
  625 
  626                 m3_wr_assp_data(sc, ch->dac_data + CDATA_INSTANCE_READY, 0);
  627                 m3_wr_assp_data(sc, KDATA_MIXER_TASK_NUMBER,
  628                                 sc->pch_active_cnt);
  629                 break;
  630 
  631         case PCMTRIG_EMLDMAWR:
  632                 /* got play irq, transfer next buffer - ignore if using dma */
  633         case PCMTRIG_EMLDMARD:
  634                 /* got rec irq, transfer next buffer - ignore if using dma */
  635         default:
  636                 break;
  637         }
  638         return 0;
  639 }
  640 
  641 static int
  642 m3_pchan_getptr(kobj_t kobj, void *chdata)
  643 {
  644         struct sc_pchinfo *ch = chdata;
  645         struct sc_info *sc = ch->parent;
  646         u_int32_t hi, lo, bus_base, bus_crnt;
  647 
  648         M3_LOCK(sc);
  649         bus_base = sndbuf_getbufaddr(ch->buffer);
  650         hi = m3_rd_assp_data(sc, ch->dac_data + CDATA_HOST_SRC_CURRENTH);
  651         lo = m3_rd_assp_data(sc, ch->dac_data + CDATA_HOST_SRC_CURRENTL);
  652         bus_crnt = lo | (hi << 16);
  653 
  654         M3_DEBUG(CALL, ("m3_pchan_getptr(dac=%d) result=%d\n",
  655                         ch->dac_idx, bus_crnt - bus_base));
  656         M3_UNLOCK(sc);
  657 
  658         return (bus_crnt - bus_base); /* current byte offset of channel */
  659 }
  660 
  661 static struct pcmchan_caps *
  662 m3_pchan_getcaps(kobj_t kobj, void *chdata)
  663 {
  664         struct sc_pchinfo *ch = chdata;
  665 
  666         M3_DEBUG(CALL, ("m3_pchan_getcaps(dac=%d)\n", ch->dac_idx));
  667 
  668         return &m3_playcaps;
  669 }
  670 
  671 /* -------------------------------------------------------------------- */
  672 /* rec channel interface */
  673 
  674 static void *
  675 m3_rchan_init(kobj_t kobj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
  676 {
  677         struct sc_info *sc = devinfo;
  678         struct sc_rchinfo *ch;
  679         u_int32_t bus_addr, i;
  680 
  681         int idx, data_bytes, adc_data;
  682         int dsp_in_size, dsp_out_size, dsp_in_buf, dsp_out_buf; 
  683 
  684         M3_LOCK(sc);
  685         idx = sc->rch_cnt; /* adc instance number, no active reuse! */
  686         M3_DEBUG(CHANGE, ("m3_rchan_init(adc=%d)\n", idx));
  687 
  688         if (dir != PCMDIR_REC) {
  689                 M3_UNLOCK(sc);
  690                 device_printf(sc->dev, "m3_pchan_init not PCMDIR_REC\n");
  691                 return (NULL);
  692         }
  693 
  694         data_bytes = (((MINISRC_TMP_BUFFER_SIZE & ~1) +
  695                            (MINISRC_IN_BUFFER_SIZE & ~1) +
  696                            (MINISRC_OUT_BUFFER_SIZE & ~1) + 4) + 255) &~ 255;
  697         adc_data = 0x1100 + (data_bytes * idx) + data_bytes/2;
  698         dsp_in_size = MINISRC_IN_BUFFER_SIZE + (0x10 * 2);
  699         dsp_out_size = MINISRC_OUT_BUFFER_SIZE - (0x10 * 2);
  700         dsp_in_buf = adc_data + (MINISRC_TMP_BUFFER_SIZE / 2);
  701         dsp_out_buf = dsp_in_buf + (dsp_in_size / 2) + 1;
  702 
  703         ch = &sc->rch[idx];
  704         ch->adc_idx = idx;
  705         ch->adc_data = adc_data;
  706         if (ch->adc_data + data_bytes/2 >= 0x1c00) {
  707                 M3_UNLOCK(sc);
  708                 device_printf(sc->dev, "m3_rchan_init: revb mem exhausted\n");
  709                 return (NULL);
  710         }
  711 
  712         ch->buffer = b;
  713         ch->parent = sc;
  714         ch->channel = c;
  715         ch->fmt = AFMT_U8;
  716         ch->spd = DSP_DEFAULT_SPEED;
  717         M3_UNLOCK(sc); /* XXX */
  718         if (sndbuf_alloc(ch->buffer, sc->parent_dmat, sc->bufsz) != 0) {
  719                 device_printf(sc->dev, "m3_rchan_init chn_allocbuf failed\n");
  720                 return (NULL);
  721         }
  722         M3_LOCK(sc);
  723         ch->bufsize = sndbuf_getsize(ch->buffer);
  724 
  725         /* host dma buffer pointers */
  726         bus_addr = sndbuf_getbufaddr(ch->buffer);
  727         if (bus_addr & 3) {
  728                 device_printf(sc->dev, "m3_rchan_init unaligned bus_addr\n");
  729                 bus_addr = (bus_addr + 4) & ~3;
  730         }
  731         m3_wr_assp_data(sc, ch->adc_data + CDATA_HOST_SRC_ADDRL, LO(bus_addr));
  732         m3_wr_assp_data(sc, ch->adc_data + CDATA_HOST_SRC_ADDRH, HI(bus_addr));
  733         m3_wr_assp_data(sc, ch->adc_data + CDATA_HOST_SRC_END_PLUS_1L,
  734                         LO(bus_addr + ch->bufsize));
  735         m3_wr_assp_data(sc, ch->adc_data + CDATA_HOST_SRC_END_PLUS_1H,
  736                         HI(bus_addr + ch->bufsize));
  737         m3_wr_assp_data(sc, ch->adc_data + CDATA_HOST_SRC_CURRENTL,
  738                         LO(bus_addr));
  739         m3_wr_assp_data(sc, ch->adc_data + CDATA_HOST_SRC_CURRENTH,
  740                         HI(bus_addr));
  741 
  742         /* dsp buffers */
  743         m3_wr_assp_data(sc, ch->adc_data + CDATA_IN_BUF_BEGIN, dsp_in_buf);
  744         m3_wr_assp_data(sc, ch->adc_data + CDATA_IN_BUF_END_PLUS_1,
  745                         dsp_in_buf + dsp_in_size/2);
  746         m3_wr_assp_data(sc, ch->adc_data + CDATA_IN_BUF_HEAD, dsp_in_buf);
  747         m3_wr_assp_data(sc, ch->adc_data + CDATA_IN_BUF_TAIL, dsp_in_buf);
  748         m3_wr_assp_data(sc, ch->adc_data + CDATA_OUT_BUF_BEGIN, dsp_out_buf);
  749         m3_wr_assp_data(sc, ch->adc_data + CDATA_OUT_BUF_END_PLUS_1,
  750                         dsp_out_buf + dsp_out_size/2);
  751         m3_wr_assp_data(sc, ch->adc_data + CDATA_OUT_BUF_HEAD, dsp_out_buf);
  752         m3_wr_assp_data(sc, ch->adc_data + CDATA_OUT_BUF_TAIL, dsp_out_buf);
  753 
  754         /* some per client initializers */
  755         m3_wr_assp_data(sc, ch->adc_data + SRC3_DIRECTION_OFFSET + 12,
  756                         ch->adc_data + 40 + 8);
  757         m3_wr_assp_data(sc, ch->adc_data + CDATA_DMA_CONTROL,
  758                         DMACONTROL_DIRECTION + DMACONTROL_AUTOREPEAT +
  759                         DMAC_PAGE3_SELECTOR + DMAC_BLOCKF_SELECTOR);
  760 
  761         /* set an armload of static initializers */
  762         for(i = 0 ; i < (sizeof(rv) / sizeof(rv[0])) ; i++) {
  763                 m3_wr_assp_data(sc, ch->adc_data + rv[i].addr, rv[i].val);
  764         }
  765 
  766         /* put us in the packed task lists */
  767         m3_wr_assp_data(sc, KDATA_INSTANCE0_MINISRC +
  768                         (sc->pch_cnt + sc->rch_cnt),
  769                         ch->adc_data >> DP_SHIFT_COUNT);
  770         m3_wr_assp_data(sc, KDATA_DMA_XFER0 + (sc->pch_cnt + sc->rch_cnt),
  771                         ch->adc_data >> DP_SHIFT_COUNT);
  772         m3_wr_assp_data(sc, KDATA_ADC1_XFER0 + sc->rch_cnt,
  773                         ch->adc_data >> DP_SHIFT_COUNT);
  774 
  775         /* gotta start before stop */
  776         m3_rchan_trigger_locked(NULL, ch, PCMTRIG_START);
  777         /* stop on init */
  778         m3_rchan_trigger_locked(NULL, ch, PCMTRIG_STOP);
  779 
  780         sc->rch_cnt++;
  781         M3_UNLOCK(sc);
  782 
  783         return (ch);
  784 }
  785 
  786 static int
  787 m3_rchan_free(kobj_t kobj, void *chdata)
  788 {
  789         struct sc_rchinfo *ch = chdata;
  790         struct sc_info *sc = ch->parent;
  791 
  792         M3_LOCK(sc);
  793         M3_DEBUG(CHANGE, ("m3_rchan_free(adc=%d)\n", ch->adc_idx));
  794 
  795         /*
  796          * should remove this exact instance from the packed lists, but all
  797          * are released at once (and in a stopped state) so this is ok.
  798          */
  799         m3_wr_assp_data(sc, KDATA_INSTANCE0_MINISRC +
  800                         (sc->rch_cnt - 1) + sc->pch_cnt, 0);
  801         m3_wr_assp_data(sc, KDATA_DMA_XFER0 +
  802                         (sc->rch_cnt - 1) + sc->pch_cnt, 0);
  803         m3_wr_assp_data(sc, KDATA_ADC1_XFER0 + (sc->rch_cnt - 1), 0);
  804         sc->rch_cnt--;
  805         M3_UNLOCK(sc);
  806 
  807         return (0);
  808 }
  809 
  810 static int
  811 m3_rchan_setformat(kobj_t kobj, void *chdata, u_int32_t format)
  812 {
  813         struct sc_rchinfo *ch = chdata;
  814         struct sc_info *sc = ch->parent;
  815         u_int32_t data;
  816 
  817         M3_LOCK(sc);
  818         M3_DEBUG(CHANGE,
  819                  ("m3_rchan_setformat(dac=%d, format=0x%x{%s-%s})\n",
  820                   ch->adc_idx, format,
  821                   format & (AFMT_U8|AFMT_S8) ? "8bit":"16bit",
  822                   format & AFMT_STEREO ? "STEREO":"MONO"));
  823 
  824         /* mono word */
  825         data = (format & AFMT_STEREO) ? 0 : 1;
  826         m3_wr_assp_data(sc, ch->adc_data + SRC3_MODE_OFFSET, data);
  827 
  828         /* 8bit word */
  829         data = ((format & AFMT_U8) || (format & AFMT_S8)) ? 1 : 0;
  830         m3_wr_assp_data(sc, ch->adc_data + SRC3_WORD_LENGTH_OFFSET, data);
  831         ch->fmt = format;
  832         M3_UNLOCK(sc);
  833 
  834         return (0);
  835 }
  836 
  837 static int
  838 m3_rchan_setspeed(kobj_t kobj, void *chdata, u_int32_t speed)
  839 {
  840         struct sc_rchinfo *ch = chdata;
  841         struct sc_info *sc = ch->parent;
  842         u_int32_t freq;
  843 
  844         M3_LOCK(sc);
  845         M3_DEBUG(CHANGE, ("m3_rchan_setspeed(adc=%d, speed=%d)\n",
  846                           ch->adc_idx, speed));
  847 
  848         if ((freq = ((speed << 15) + 24000) / 48000) != 0) {
  849                 freq--;
  850         }
  851 
  852         m3_wr_assp_data(sc, ch->adc_data + CDATA_FREQUENCY, freq);
  853         ch->spd = speed;
  854         M3_UNLOCK(sc);
  855 
  856         /* return closest possible speed */
  857         return (speed);
  858 }
  859 
  860 static int
  861 m3_rchan_setblocksize(kobj_t kobj, void *chdata, u_int32_t blocksize)
  862 {
  863         struct sc_rchinfo *ch = chdata;
  864 
  865         M3_DEBUG(CHANGE, ("m3_rchan_setblocksize(adc=%d, blocksize=%d)\n",
  866                           ch->adc_idx, blocksize));
  867 
  868         return blocksize;
  869 }
  870 
  871 static int
  872 m3_rchan_trigger(kobj_t kobj, void *chdata, int go)
  873 {
  874         struct sc_rchinfo *ch = chdata;
  875         struct sc_info *sc = ch->parent;
  876         int ret;
  877 
  878         M3_LOCK(sc);
  879         ret = m3_rchan_trigger_locked(kobj, chdata, go);
  880         M3_UNLOCK(sc);
  881 
  882         return (ret);
  883 }
  884 
  885 static int
  886 m3_rchan_trigger_locked(kobj_t kobj, void *chdata, int go)
  887 {
  888         struct sc_rchinfo *ch = chdata;
  889         struct sc_info *sc = ch->parent;
  890         u_int32_t data;
  891 
  892         M3_LOCK_ASSERT(sc);
  893         M3_DEBUG(go == PCMTRIG_START ? CHANGE :
  894                  go == PCMTRIG_STOP ? CHANGE :
  895                  go == PCMTRIG_ABORT ? CHANGE :
  896                  CALL,
  897                  ("m3_rchan_trigger(adc=%d, go=0x%x{%s})\n", ch->adc_idx, go,
  898                   go == PCMTRIG_START ? "PCMTRIG_START" :
  899                   go == PCMTRIG_STOP ? "PCMTRIG_STOP" :
  900                   go == PCMTRIG_ABORT ? "PCMTRIG_ABORT" : "ignore"));
  901 
  902         switch(go) {
  903         case PCMTRIG_START:
  904                 if (ch->active) {
  905                         return 0;
  906                 }
  907                 ch->active = 1;
  908 
  909                 /*[[inc_timer_users]]*/
  910                 m3_wr_assp_data(sc, KDATA_TIMER_COUNT_RELOAD, 240);
  911                 m3_wr_assp_data(sc, KDATA_TIMER_COUNT_CURRENT, 240);
  912                 data = m3_rd_2(sc, HOST_INT_CTRL);
  913                 m3_wr_2(sc, HOST_INT_CTRL, data | CLKRUN_GEN_ENABLE);
  914 
  915                 m3_wr_assp_data(sc, KDATA_ADC1_REQUEST, 1);
  916                 m3_wr_assp_data(sc, ch->adc_data + CDATA_INSTANCE_READY, 1);
  917                 break;
  918 
  919         case PCMTRIG_STOP:
  920         case PCMTRIG_ABORT:
  921                 if (ch->active == 0) {
  922                         return 0;
  923                 }
  924                 ch->active = 0;
  925 
  926                 /*[[dec_timer_users]]*/
  927                 m3_wr_assp_data(sc, KDATA_TIMER_COUNT_RELOAD, 0);
  928                 m3_wr_assp_data(sc, KDATA_TIMER_COUNT_CURRENT, 0);
  929                 data = m3_rd_2(sc, HOST_INT_CTRL);
  930                 m3_wr_2(sc, HOST_INT_CTRL, data & ~CLKRUN_GEN_ENABLE);
  931 
  932                 m3_wr_assp_data(sc, ch->adc_data + CDATA_INSTANCE_READY, 0);
  933                 m3_wr_assp_data(sc, KDATA_ADC1_REQUEST, 0);
  934                 break;
  935 
  936         case PCMTRIG_EMLDMAWR:
  937                 /* got play irq, transfer next buffer - ignore if using dma */
  938         case PCMTRIG_EMLDMARD:
  939                 /* got rec irq, transfer next buffer - ignore if using dma */
  940         default:
  941                 break;
  942         }
  943         return 0;
  944 }
  945 
  946 static int
  947 m3_rchan_getptr(kobj_t kobj, void *chdata)
  948 {
  949         struct sc_rchinfo *ch = chdata;
  950         struct sc_info *sc = ch->parent;
  951         u_int32_t hi, lo, bus_base, bus_crnt;
  952 
  953         M3_LOCK(sc);
  954         bus_base = sndbuf_getbufaddr(ch->buffer);
  955         hi = m3_rd_assp_data(sc, ch->adc_data + CDATA_HOST_SRC_CURRENTH);
  956         lo = m3_rd_assp_data(sc, ch->adc_data + CDATA_HOST_SRC_CURRENTL);
  957         bus_crnt = lo | (hi << 16);
  958 
  959         M3_DEBUG(CALL, ("m3_rchan_getptr(adc=%d) result=%d\n",
  960                         ch->adc_idx, bus_crnt - bus_base));
  961         M3_UNLOCK(sc);
  962 
  963         return (bus_crnt - bus_base); /* current byte offset of channel */
  964 }
  965 
  966 static struct pcmchan_caps *
  967 m3_rchan_getcaps(kobj_t kobj, void *chdata)
  968 {
  969         struct sc_rchinfo *ch = chdata;
  970 
  971         M3_DEBUG(CALL, ("m3_rchan_getcaps(adc=%d)\n", ch->adc_idx));
  972 
  973         return &m3_reccaps;
  974 }
  975 
  976 /* -------------------------------------------------------------------- */
  977 /* The interrupt handler */
  978 
  979 static void
  980 m3_intr(void *p)
  981 {
  982         struct sc_info *sc = (struct sc_info *)p;
  983         u_int32_t status, ctl, i;
  984 
  985         M3_DEBUG(INTR, ("m3_intr\n"));
  986 
  987         M3_LOCK(sc);
  988         status = m3_rd_1(sc, HOST_INT_STATUS);
  989         if (!status) {
  990                 M3_UNLOCK(sc);
  991                 return;
  992         }
  993 
  994         m3_wr_1(sc, HOST_INT_STATUS, 0xff); /* ack the int? */
  995 
  996         if (status & HV_INT_PENDING) {
  997                 u_int8_t event;
  998 
  999                 event = m3_rd_1(sc, HW_VOL_COUNTER_MASTER);
 1000                 switch (event) {
 1001                 case 0x99:
 1002                         mixer_hwvol_mute(sc->dev);
 1003                         break;
 1004                 case 0xaa:
 1005                         mixer_hwvol_step(sc->dev, 1, 1);
 1006                         break;
 1007                 case 0x66:
 1008                         mixer_hwvol_step(sc->dev, -1, -1);
 1009                         break;
 1010                 case 0x88:
 1011                         break;
 1012                 default:
 1013                         device_printf(sc->dev, "Unknown HWVOL event\n");
 1014                 }
 1015                 m3_wr_1(sc, HW_VOL_COUNTER_MASTER, 0x88);
 1016 
 1017         }
 1018 
 1019         if (status & ASSP_INT_PENDING) {
 1020                 ctl = m3_rd_1(sc, ASSP_CONTROL_B);
 1021                 if (!(ctl & STOP_ASSP_CLOCK)) {
 1022                         ctl = m3_rd_1(sc, ASSP_HOST_INT_STATUS);
 1023                         if (ctl & DSP2HOST_REQ_TIMER) {
 1024                                 m3_wr_1(sc, ASSP_HOST_INT_STATUS,
 1025                                         DSP2HOST_REQ_TIMER);
 1026                                 /*[[ess_update_ptr]]*/
 1027                         }
 1028                 }
 1029         }
 1030 
 1031         for (i=0 ; i<sc->pch_cnt ; i++) {
 1032                 if (sc->pch[i].active) {
 1033                         M3_UNLOCK(sc);
 1034                         chn_intr(sc->pch[i].channel);
 1035                         M3_LOCK(sc);
 1036                 }
 1037         }
 1038         for (i=0 ; i<sc->rch_cnt ; i++) {
 1039                 if (sc->rch[i].active) {
 1040                         M3_UNLOCK(sc);
 1041                         chn_intr(sc->rch[i].channel);
 1042                         M3_LOCK(sc);
 1043                 }
 1044         }
 1045 
 1046         M3_UNLOCK(sc);
 1047 }
 1048 
 1049 /* -------------------------------------------------------------------- */
 1050 /* stuff */
 1051 
 1052 static int
 1053 m3_power(struct sc_info *sc, int state)
 1054 {
 1055         u_int32_t data;
 1056 
 1057         M3_DEBUG(CHANGE, ("m3_power(%d)\n", state));
 1058         M3_LOCK_ASSERT(sc);
 1059 
 1060         data = pci_read_config(sc->dev, 0x34, 1);
 1061         if (pci_read_config(sc->dev, data, 1) == 1) {
 1062                 pci_write_config(sc->dev, data + 4, state, 1);
 1063         }
 1064 
 1065         return 0;
 1066 }
 1067 
 1068 static int
 1069 m3_init(struct sc_info *sc)
 1070 {
 1071         u_int32_t data, i, size;
 1072         u_int8_t reset_state;
 1073 
 1074         M3_LOCK_ASSERT(sc);
 1075         M3_DEBUG(CHANGE, ("m3_init\n"));
 1076 
 1077         /* diable legacy emulations. */
 1078         data = pci_read_config(sc->dev, PCI_LEGACY_AUDIO_CTRL, 2);
 1079         data |= DISABLE_LEGACY;
 1080         pci_write_config(sc->dev, PCI_LEGACY_AUDIO_CTRL, data, 2);
 1081 
 1082         m3_config(sc);
 1083 
 1084         reset_state = m3_assp_halt(sc);
 1085 
 1086         m3_codec_reset(sc);
 1087 
 1088         /* [m3_assp_init] */
 1089         /* zero kernel data */
 1090         size = REV_B_DATA_MEMORY_UNIT_LENGTH * NUM_UNITS_KERNEL_DATA;
 1091         for(i = 0 ; i < size / 2 ; i++) {
 1092                 m3_wr_assp_data(sc, KDATA_BASE_ADDR + i, 0);
 1093         }
 1094         /* zero mixer data? */
 1095         size = REV_B_DATA_MEMORY_UNIT_LENGTH * NUM_UNITS_KERNEL_DATA;
 1096         for(i = 0 ; i < size / 2 ; i++) {
 1097                 m3_wr_assp_data(sc, KDATA_BASE_ADDR2 + i, 0);
 1098         }
 1099         /* init dma pointer */
 1100         m3_wr_assp_data(sc, KDATA_CURRENT_DMA,
 1101                         KDATA_DMA_XFER0);
 1102         /* write kernel into code memory */
 1103         size = sizeof(assp_kernel_image);
 1104         for(i = 0 ; i < size / 2; i++) {
 1105                 m3_wr_assp_code(sc, REV_B_CODE_MEMORY_BEGIN + i,
 1106                                 assp_kernel_image[i]);
 1107         }
 1108         /*
 1109          * We only have this one client and we know that 0x400 is free in
 1110          * our kernel's mem map, so lets just drop it there.  It seems that
 1111          * the minisrc doesn't need vectors, so we won't bother with them..
 1112          */
 1113         size = sizeof(assp_minisrc_image);
 1114         for(i = 0 ; i < size / 2; i++) {
 1115                 m3_wr_assp_code(sc, 0x400 + i, assp_minisrc_image[i]);
 1116         }
 1117         /* write the coefficients for the low pass filter? */
 1118         size = sizeof(minisrc_lpf_image);
 1119         for(i = 0; i < size / 2 ; i++) {
 1120                 m3_wr_assp_code(sc,0x400 + MINISRC_COEF_LOC + i,
 1121                                 minisrc_lpf_image[i]);
 1122         }
 1123         m3_wr_assp_code(sc, 0x400 + MINISRC_COEF_LOC + size, 0x8000);
 1124         /* the minisrc is the only thing on our task list */
 1125         m3_wr_assp_data(sc, KDATA_TASK0, 0x400);
 1126         /* init the mixer number */
 1127         m3_wr_assp_data(sc, KDATA_MIXER_TASK_NUMBER, 0);
 1128         /* extreme kernel master volume */
 1129         m3_wr_assp_data(sc, KDATA_DAC_LEFT_VOLUME, ARB_VOLUME);
 1130         m3_wr_assp_data(sc, KDATA_DAC_RIGHT_VOLUME, ARB_VOLUME);
 1131 
 1132         m3_amp_enable(sc);
 1133 
 1134         /* [m3_assp_client_init] (only one client at index 0) */
 1135         for (i=0x1100 ; i<0x1c00 ; i++) {
 1136                 m3_wr_assp_data(sc, i, 0); /* zero entire dac/adc area */
 1137         }
 1138 
 1139         /* [m3_assp_continue] */
 1140         m3_wr_1(sc, DSP_PORT_CONTROL_REG_B, reset_state | REGB_ENABLE_RESET);
 1141 
 1142         return 0;
 1143 }
 1144 
 1145 static int
 1146 m3_uninit(struct sc_info *sc)
 1147 {
 1148         M3_DEBUG(CHANGE, ("m3_uninit\n"));
 1149         return 0;
 1150 }
 1151 
 1152 /* -------------------------------------------------------------------- */
 1153 /* Probe and attach the card */
 1154 
 1155 static int
 1156 m3_pci_probe(device_t dev)
 1157 {
 1158         struct m3_card_type *card;
 1159 
 1160         M3_DEBUG(CALL, ("m3_pci_probe(0x%x)\n", pci_get_devid(dev)));
 1161 
 1162         for (card = m3_card_types ; card->pci_id ; card++) {
 1163                 if (pci_get_devid(dev) == card->pci_id) {
 1164                         device_set_desc(dev, card->name);
 1165                         return 0;
 1166                 }
 1167         }
 1168         return ENXIO;
 1169 }
 1170 
 1171 static int
 1172 m3_pci_attach(device_t dev)
 1173 {
 1174         struct sc_info *sc;
 1175         struct ac97_info *codec = NULL;
 1176         u_int32_t data, i;
 1177         char status[SND_STATUSLEN];
 1178         struct m3_card_type *card;
 1179         int len;
 1180 
 1181         M3_DEBUG(CALL, ("m3_pci_attach\n"));
 1182 
 1183         if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) {
 1184                 device_printf(dev, "cannot allocate softc\n");
 1185                 return ENXIO;
 1186         }
 1187 
 1188         sc->dev = dev;
 1189         sc->type = pci_get_devid(dev);
 1190         sc->sc_lock = snd_mtxcreate(device_get_nameunit(dev),
 1191             "sound softc");
 1192         if (sc->sc_lock == NULL) {
 1193                 device_printf(dev, "cannot create mutex\n");
 1194                 free(sc, M_DEVBUF);
 1195                 return (ENXIO);
 1196         }
 1197         for (card = m3_card_types ; card->pci_id ; card++) {
 1198                 if (sc->type == card->pci_id) {
 1199                         sc->which = card->which;
 1200                         sc->delay1 = card->delay1;
 1201                         sc->delay2 = card->delay2;
 1202                         break;
 1203                 }
 1204         }
 1205 
 1206         data = pci_read_config(dev, PCIR_COMMAND, 2);
 1207         data |= (PCIM_CMD_PORTEN | PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN);
 1208         pci_write_config(dev, PCIR_COMMAND, data, 2);
 1209 
 1210         sc->regid = PCIR_BAR(0);
 1211         sc->regtype = SYS_RES_MEMORY;
 1212         sc->reg = bus_alloc_resource_any(dev, sc->regtype, &sc->regid,
 1213                                          RF_ACTIVE);
 1214         if (!sc->reg) {
 1215                 sc->regtype = SYS_RES_IOPORT;
 1216                 sc->reg = bus_alloc_resource_any(dev, sc->regtype, &sc->regid,
 1217                                                  RF_ACTIVE);
 1218         }
 1219         if (!sc->reg) {
 1220                 device_printf(dev, "unable to allocate register space\n");
 1221                 goto bad;
 1222         }
 1223         sc->st = rman_get_bustag(sc->reg);
 1224         sc->sh = rman_get_bushandle(sc->reg);
 1225 
 1226         sc->irqid = 0;
 1227         sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqid,
 1228                                          RF_ACTIVE | RF_SHAREABLE);
 1229         if (!sc->irq) {
 1230                 device_printf(dev, "unable to allocate interrupt\n");
 1231                 goto bad;
 1232         }
 1233 
 1234         if (snd_setup_intr(dev, sc->irq, INTR_MPSAFE, m3_intr, sc, &sc->ih)) {
 1235                 device_printf(dev, "unable to setup interrupt\n");
 1236                 goto bad;
 1237         }
 1238 
 1239         sc->bufsz = pcm_getbuffersize(dev, M3_BUFSIZE_MAX, M3_BUFSIZE_DEFAULT,
 1240             M3_BUFSIZE_MAX);
 1241 
 1242         if (bus_dma_tag_create(
 1243             NULL,               /* parent */
 1244             2, 0,               /* alignment, boundary */
 1245             M3_MAXADDR,         /* lowaddr */
 1246             BUS_SPACE_MAXADDR,  /* highaddr */
 1247             NULL, NULL,         /* filtfunc, filtfuncarg */
 1248             sc->bufsz,          /* maxsize */
 1249             1,                  /* nsegments */
 1250             0x3ffff,            /* maxsegz */
 1251             0,                  /* flags */
 1252             NULL,               /* lockfunc */
 1253             NULL,               /* lockfuncarg */
 1254             &sc->parent_dmat) != 0) {
 1255                 device_printf(dev, "unable to create dma tag\n");
 1256                 goto bad;
 1257         }
 1258 
 1259         M3_LOCK(sc);
 1260         m3_power(sc, 0); /* power up */
 1261         /* init chip */
 1262         i = m3_init(sc);
 1263         M3_UNLOCK(sc);
 1264         if (i == -1) {
 1265                 device_printf(dev, "unable to initialize the card\n");
 1266                 goto bad;
 1267         }
 1268 
 1269         /* create/init mixer */
 1270         codec = AC97_CREATE(dev, sc, m3_codec);
 1271         if (codec == NULL) {
 1272                 device_printf(dev, "ac97_create error\n");
 1273                 goto bad;
 1274         }
 1275         if (mixer_init(dev, ac97_getmixerclass(), codec)) {
 1276                 device_printf(dev, "mixer_init error\n");
 1277                 goto bad;
 1278         }
 1279 
 1280         m3_enable_ints(sc);
 1281 
 1282         if (pcm_register(dev, sc, M3_PCHANS, M3_RCHANS)) {
 1283                 device_printf(dev, "pcm_register error\n");
 1284                 goto bad;
 1285         }
 1286         for (i=0 ; i<M3_PCHANS ; i++) {
 1287                 if (pcm_addchan(dev, PCMDIR_PLAY, &m3_pch_class, sc)) {
 1288                         device_printf(dev, "pcm_addchan (play) error\n");
 1289                         goto bad;
 1290                 }
 1291         }
 1292         for (i=0 ; i<M3_RCHANS ; i++) {
 1293                 if (pcm_addchan(dev, PCMDIR_REC, &m3_rch_class, sc)) {
 1294                         device_printf(dev, "pcm_addchan (rec) error\n");
 1295                         goto bad;
 1296                 }
 1297         }
 1298         snprintf(status, SND_STATUSLEN, "at %s 0x%lx irq %ld %s",
 1299             (sc->regtype == SYS_RES_IOPORT)? "io" : "memory",
 1300             rman_get_start(sc->reg), rman_get_start(sc->irq),
 1301             PCM_KLDSTRING(snd_maestro3));
 1302         if (pcm_setstatus(dev, status)) {
 1303                 device_printf(dev, "attach: pcm_setstatus error\n");
 1304                 goto bad;
 1305         }
 1306 
 1307         mixer_hwvol_init(dev);
 1308 
 1309         /* Create the buffer for saving the card state during suspend */
 1310         len = sizeof(u_int16_t) * (REV_B_CODE_MEMORY_LENGTH +
 1311             REV_B_DATA_MEMORY_LENGTH);
 1312         sc->savemem = (u_int16_t*)malloc(len, M_DEVBUF, M_NOWAIT | M_ZERO);
 1313         if (sc->savemem == NULL) {
 1314                 device_printf(dev, "Failed to create suspend buffer\n");
 1315                 goto bad;
 1316         }
 1317 
 1318         return 0;
 1319 
 1320  bad:
 1321         if (codec)
 1322                 ac97_destroy(codec);
 1323         if (sc->ih)
 1324                 bus_teardown_intr(dev, sc->irq, sc->ih);
 1325         if (sc->irq)
 1326                 bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
 1327         if (sc->reg)
 1328                 bus_release_resource(dev, sc->regtype, sc->regid, sc->reg);
 1329         if (sc->parent_dmat)
 1330                 bus_dma_tag_destroy(sc->parent_dmat);
 1331         if (sc->sc_lock)
 1332                 snd_mtxfree(sc->sc_lock);
 1333         free(sc, M_DEVBUF);
 1334         return ENXIO;
 1335 }
 1336 
 1337 static int
 1338 m3_pci_detach(device_t dev)
 1339 {
 1340         struct sc_info *sc = pcm_getdevinfo(dev);
 1341         int r;
 1342 
 1343         M3_DEBUG(CALL, ("m3_pci_detach\n"));
 1344 
 1345         if ((r = pcm_unregister(dev)) != 0) {
 1346                 return r;
 1347         }
 1348 
 1349         M3_LOCK(sc);
 1350         m3_uninit(sc); /* shutdown chip */
 1351         m3_power(sc, 3); /* power off */
 1352         M3_UNLOCK(sc);
 1353 
 1354         bus_teardown_intr(dev, sc->irq, sc->ih);
 1355         bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
 1356         bus_release_resource(dev, sc->regtype, sc->regid, sc->reg);
 1357         bus_dma_tag_destroy(sc->parent_dmat);
 1358 
 1359         free(sc->savemem, M_DEVBUF);
 1360         snd_mtxfree(sc->sc_lock);
 1361         free(sc, M_DEVBUF);
 1362         return 0;
 1363 }
 1364 
 1365 static int
 1366 m3_pci_suspend(device_t dev)
 1367 {
 1368         struct sc_info *sc = pcm_getdevinfo(dev);
 1369         int i, index = 0;
 1370 
 1371         M3_DEBUG(CHANGE, ("m3_pci_suspend\n"));
 1372 
 1373         M3_LOCK(sc);
 1374         for (i=0 ; i<sc->pch_cnt ; i++) {
 1375                 if (sc->pch[i].active) {
 1376                         m3_pchan_trigger_locked(NULL, &sc->pch[i],
 1377                             PCMTRIG_STOP);
 1378                 }
 1379         }
 1380         for (i=0 ; i<sc->rch_cnt ; i++) {
 1381                 if (sc->rch[i].active) {
 1382                         m3_rchan_trigger_locked(NULL, &sc->rch[i],
 1383                             PCMTRIG_STOP);
 1384                 }
 1385         }
 1386         DELAY(10 * 1000); /* give things a chance to stop */
 1387 
 1388         /* Disable interrupts */
 1389         m3_wr_2(sc, HOST_INT_CTRL, 0);
 1390         m3_wr_1(sc, ASSP_CONTROL_C, 0);
 1391 
 1392         m3_assp_halt(sc);
 1393 
 1394         /* Save the state of the ASSP */
 1395         for (i = REV_B_CODE_MEMORY_BEGIN; i <= REV_B_CODE_MEMORY_END; i++)
 1396                 sc->savemem[index++] = m3_rd_assp_code(sc, i);
 1397         for (i = REV_B_DATA_MEMORY_BEGIN; i <= REV_B_DATA_MEMORY_END; i++)
 1398                 sc->savemem[index++] = m3_rd_assp_data(sc, i);
 1399 
 1400         /* Power down the card to D3 state */
 1401         m3_power(sc, 3);
 1402         M3_UNLOCK(sc);
 1403 
 1404         return 0;
 1405 }
 1406 
 1407 static int
 1408 m3_pci_resume(device_t dev)
 1409 {
 1410         struct sc_info *sc = pcm_getdevinfo(dev);
 1411         int i, index = 0;
 1412         u_int8_t reset_state;
 1413 
 1414         M3_DEBUG(CHANGE, ("m3_pci_resume\n"));
 1415 
 1416         M3_LOCK(sc);
 1417         /* Power the card back to D0 */
 1418         m3_power(sc, 0);
 1419 
 1420         m3_config(sc);
 1421 
 1422         reset_state = m3_assp_halt(sc);
 1423 
 1424         m3_codec_reset(sc);
 1425 
 1426         /* Restore the ASSP state */
 1427         for (i = REV_B_CODE_MEMORY_BEGIN; i <= REV_B_CODE_MEMORY_END; i++)
 1428                 m3_wr_assp_code(sc, i, sc->savemem[index++]);
 1429         for (i = REV_B_DATA_MEMORY_BEGIN; i <= REV_B_DATA_MEMORY_END; i++)
 1430                 m3_wr_assp_data(sc, i, sc->savemem[index++]);
 1431 
 1432         /* Restart the DMA engine */
 1433         m3_wr_assp_data(sc, KDATA_DMA_ACTIVE, 0);
 1434 
 1435         /* [m3_assp_continue] */
 1436         m3_wr_1(sc, DSP_PORT_CONTROL_REG_B, reset_state | REGB_ENABLE_RESET);
 1437 
 1438         m3_amp_enable(sc);
 1439 
 1440         m3_enable_ints(sc);
 1441 
 1442         M3_UNLOCK(sc); /* XXX */
 1443         if (mixer_reinit(dev) == -1) {
 1444                 device_printf(dev, "unable to reinitialize the mixer\n");
 1445                 return (ENXIO);
 1446         }
 1447         M3_LOCK(sc);
 1448 
 1449         /* Turn the channels back on */
 1450         for (i=0 ; i<sc->pch_cnt ; i++) {
 1451                 if (sc->pch[i].active) {
 1452                         m3_pchan_trigger_locked(NULL, &sc->pch[i],
 1453                             PCMTRIG_START);
 1454                 }
 1455         }
 1456         for (i=0 ; i<sc->rch_cnt ; i++) {
 1457                 if (sc->rch[i].active) {
 1458                         m3_rchan_trigger_locked(NULL, &sc->rch[i],
 1459                             PCMTRIG_START);
 1460                 }
 1461         }
 1462 
 1463         M3_UNLOCK(sc);
 1464         return 0;
 1465 }
 1466 
 1467 static int
 1468 m3_pci_shutdown(device_t dev)
 1469 {
 1470         struct sc_info *sc = pcm_getdevinfo(dev);
 1471 
 1472         M3_DEBUG(CALL, ("m3_pci_shutdown\n"));
 1473 
 1474         M3_LOCK(sc);
 1475         m3_power(sc, 3); /* power off */
 1476         M3_UNLOCK(sc);
 1477 
 1478         return 0;
 1479 }
 1480 
 1481 static u_int8_t
 1482 m3_assp_halt(struct sc_info *sc)
 1483 {
 1484         u_int8_t data, reset_state;
 1485 
 1486         M3_LOCK_ASSERT(sc);
 1487 
 1488         data = m3_rd_1(sc, DSP_PORT_CONTROL_REG_B);
 1489         reset_state = data & ~REGB_STOP_CLOCK; /* remember for continue */
 1490         DELAY(10 * 1000);
 1491         m3_wr_1(sc, DSP_PORT_CONTROL_REG_B, reset_state & ~REGB_ENABLE_RESET);
 1492         DELAY(10 * 1000); /* necessary? */
 1493 
 1494         return reset_state;
 1495 }
 1496 
 1497 static void
 1498 m3_config(struct sc_info *sc)
 1499 {
 1500         u_int32_t data, hv_cfg;
 1501         int hint;
 1502 
 1503         M3_LOCK_ASSERT(sc);
 1504 
 1505         M3_UNLOCK(sc);
 1506         /*
 1507          * The volume buttons can be wired up via two different sets of pins.
 1508          * This presents a problem since we can't tell which way it's
 1509          * configured.  Allow the user to set a hint in order to twiddle
 1510          * the proper bits.
 1511          */
 1512         if (resource_int_value(device_get_name(sc->dev),
 1513                                device_get_unit(sc->dev),
 1514                                "hwvol_config", &hint) == 0)
 1515                 hv_cfg = (hint > 0) ? HV_BUTTON_FROM_GD : 0;
 1516         else
 1517                 hv_cfg = HV_BUTTON_FROM_GD;
 1518         M3_LOCK(sc);
 1519 
 1520         data = pci_read_config(sc->dev, PCI_ALLEGRO_CONFIG, 4);
 1521         data &= ~HV_BUTTON_FROM_GD;
 1522         data |= REDUCED_DEBOUNCE | HV_CTRL_ENABLE | hv_cfg;
 1523         data |= PM_CTRL_ENABLE | CLK_DIV_BY_49 | USE_PCI_TIMING;
 1524         pci_write_config(sc->dev, PCI_ALLEGRO_CONFIG, data, 4);
 1525 
 1526         m3_wr_1(sc, ASSP_CONTROL_B, RESET_ASSP);
 1527         data = pci_read_config(sc->dev, PCI_ALLEGRO_CONFIG, 4);
 1528         data &= ~INT_CLK_SELECT;
 1529         if (sc->which == ESS_MAESTRO3) {
 1530                 data &= ~INT_CLK_MULT_ENABLE;
 1531                 data |= INT_CLK_SRC_NOT_PCI;
 1532         }
 1533         data &= ~(CLK_MULT_MODE_SELECT | CLK_MULT_MODE_SELECT_2);
 1534         pci_write_config(sc->dev, PCI_ALLEGRO_CONFIG, data, 4);
 1535 
 1536         if (sc->which == ESS_ALLEGRO_1) {
 1537                 data = pci_read_config(sc->dev, PCI_USER_CONFIG, 4);
 1538                 data |= IN_CLK_12MHZ_SELECT;
 1539                 pci_write_config(sc->dev, PCI_USER_CONFIG, data, 4);
 1540         }
 1541 
 1542         data = m3_rd_1(sc, ASSP_CONTROL_A);
 1543         data &= ~(DSP_CLK_36MHZ_SELECT | ASSP_CLK_49MHZ_SELECT);
 1544         data |= ASSP_CLK_49MHZ_SELECT; /*XXX assumes 49MHZ dsp XXX*/
 1545         data |= ASSP_0_WS_ENABLE;
 1546         m3_wr_1(sc, ASSP_CONTROL_A, data);
 1547 
 1548         m3_wr_1(sc, ASSP_CONTROL_B, RUN_ASSP);
 1549 }
 1550 
 1551 static void
 1552 m3_enable_ints(struct sc_info *sc)
 1553 {
 1554         u_int8_t data;
 1555 
 1556         m3_wr_2(sc, HOST_INT_CTRL, ASSP_INT_ENABLE | HV_INT_ENABLE);
 1557         data = m3_rd_1(sc, ASSP_CONTROL_C);
 1558         m3_wr_1(sc, ASSP_CONTROL_C, data | ASSP_HOST_INT_ENABLE);
 1559 }
 1560 
 1561 static void
 1562 m3_amp_enable(struct sc_info *sc)
 1563 {
 1564         u_int32_t gpo, polarity_port, polarity;
 1565         u_int16_t data;
 1566 
 1567         M3_LOCK_ASSERT(sc);
 1568 
 1569         switch (sc->which) {
 1570         case ESS_ALLEGRO_1:
 1571                 polarity_port = 0x1800;
 1572                 break;
 1573         case ESS_MAESTRO3:
 1574                 polarity_port = 0x1100;
 1575                 break;
 1576         default:
 1577                 panic("bad sc->which");
 1578         }
 1579         gpo = (polarity_port >> 8) & 0x0f;
 1580         polarity = polarity_port >> 12;
 1581         polarity = !polarity; /* enable */
 1582         polarity = polarity << gpo;
 1583         gpo = 1 << gpo;
 1584         m3_wr_2(sc, GPIO_MASK, ~gpo);
 1585         data = m3_rd_2(sc, GPIO_DIRECTION);
 1586         m3_wr_2(sc, GPIO_DIRECTION, data | gpo);
 1587         data = GPO_SECONDARY_AC97 | GPO_PRIMARY_AC97 | polarity;
 1588         m3_wr_2(sc, GPIO_DATA, data);
 1589         m3_wr_2(sc, GPIO_MASK, ~0);
 1590 }
 1591 
 1592 static void
 1593 m3_codec_reset(struct sc_info *sc)
 1594 {
 1595         u_int16_t data, dir;
 1596         int retry = 0;
 1597 
 1598         M3_LOCK_ASSERT(sc);
 1599         do {
 1600                 data = m3_rd_2(sc, GPIO_DIRECTION);
 1601                 dir = data | 0x10; /* assuming pci bus master? */
 1602 
 1603                 /* [[remote_codec_config]] */
 1604                 data = m3_rd_2(sc, RING_BUS_CTRL_B);
 1605                 m3_wr_2(sc, RING_BUS_CTRL_B, data & ~SECOND_CODEC_ID_MASK);
 1606                 data = m3_rd_2(sc, SDO_OUT_DEST_CTRL);
 1607                 m3_wr_2(sc, SDO_OUT_DEST_CTRL, data & ~COMMAND_ADDR_OUT);
 1608                 data = m3_rd_2(sc, SDO_IN_DEST_CTRL);
 1609                 m3_wr_2(sc, SDO_IN_DEST_CTRL, data & ~STATUS_ADDR_IN);
 1610 
 1611                 m3_wr_2(sc, RING_BUS_CTRL_A, IO_SRAM_ENABLE);
 1612                 DELAY(20);
 1613 
 1614                 m3_wr_2(sc, GPIO_DIRECTION, dir & ~GPO_PRIMARY_AC97);
 1615                 m3_wr_2(sc, GPIO_MASK, ~GPO_PRIMARY_AC97);
 1616                 m3_wr_2(sc, GPIO_DATA, 0);
 1617                 m3_wr_2(sc, GPIO_DIRECTION, dir | GPO_PRIMARY_AC97);
 1618                 DELAY(sc->delay1 * 1000); /*delay1 (ALLEGRO:50, MAESTRO3:20)*/
 1619                 m3_wr_2(sc, GPIO_DATA, GPO_PRIMARY_AC97);
 1620                 DELAY(5);
 1621                 m3_wr_2(sc, RING_BUS_CTRL_A, IO_SRAM_ENABLE |
 1622                     SERIAL_AC_LINK_ENABLE);
 1623                 m3_wr_2(sc, GPIO_MASK, ~0);
 1624                 DELAY(sc->delay2 * 1000); /*delay2 (ALLEGRO:800, MAESTRO3:500)*/
 1625 
 1626                 /* [[try read vendor]] */
 1627                 data = m3_rdcd(NULL, sc, 0x7c);
 1628                 if ((data == 0) || (data == 0xffff)) {
 1629                         retry++;
 1630                         if (retry > 3) {
 1631                                 device_printf(sc->dev, "Codec reset failed\n");
 1632                                 break;
 1633                         }
 1634                         device_printf(sc->dev, "Codec reset retry\n");
 1635                 } else retry = 0;
 1636         } while (retry);
 1637 }
 1638 
 1639 static device_method_t m3_methods[] = {
 1640         DEVMETHOD(device_probe,         m3_pci_probe),
 1641         DEVMETHOD(device_attach,        m3_pci_attach),
 1642         DEVMETHOD(device_detach,        m3_pci_detach),
 1643         DEVMETHOD(device_suspend,       m3_pci_suspend),
 1644         DEVMETHOD(device_resume,        m3_pci_resume),
 1645         DEVMETHOD(device_shutdown,      m3_pci_shutdown),
 1646         { 0, 0 }
 1647 };
 1648 
 1649 static driver_t m3_driver = {
 1650         "pcm",
 1651         m3_methods,
 1652         PCM_SOFTC_SIZE,
 1653 };
 1654 
 1655 DRIVER_MODULE(snd_maestro3, pci, m3_driver, pcm_devclass, 0, 0);
 1656 MODULE_DEPEND(snd_maestro3, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
 1657 MODULE_VERSION(snd_maestro3, 1);

Cache object: 7e79d4f78463dbd9a0dc9892f3a32ff9


[ 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.