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/sbus/cs4231.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) 1999 Jason L. Wright (jason@thought.net)
    3  * Copyright (c) 2004 Pyun YongHyeon
    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 ``AS IS'' AND ANY EXPRESS OR
   16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   18  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
   19  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   21  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   23  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   24  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   25  * POSSIBILITY OF SUCH DAMAGE.
   26  *
   27  * Effort sponsored in part by the Defense Advanced Research Projects
   28  * Agency (DARPA) and Air Force Research Laboratory, Air Force
   29  * Materiel Command, USAF, under agreement number F30602-01-2-0537.
   30  *
   31  *      from: OpenBSD: cs4231.c,v 1.21 2003/07/03 20:36:07 jason Exp
   32  */
   33 
   34 /*
   35  * Driver for CS4231 based audio found in some sun4m systems (cs4231)
   36  * based on ideas from the S/Linux project and the NetBSD project.
   37  */
   38 
   39 #include <sys/cdefs.h>
   40 __FBSDID("$FreeBSD$");
   41 
   42 #include <sys/param.h>
   43 #include <sys/systm.h>
   44 #include <sys/bus.h>
   45 #include <sys/kernel.h>
   46 #include <sys/resource.h>
   47 
   48 #include <dev/ofw/ofw_bus.h>
   49 #include <dev/ofw/openfirm.h>
   50 #include <machine/bus.h>
   51 #include <machine/ofw_machdep.h>
   52 
   53 #include <dev/sound/pcm/sound.h>
   54 #include <dev/sound/sbus/apcdmareg.h>
   55 #include <dev/sound/sbus/cs4231.h>
   56 
   57 #include <sparc64/sbus/sbusvar.h>
   58 #include <sparc64/ebus/ebusreg.h>
   59 
   60 #include "mixer_if.h"
   61 
   62 /*
   63  * The driver supports CS4231A audio chips found on Sbus/Ebus based 
   64  * UltraSPARCs. Though, CS4231A says it supports full-duplex mode, I
   65  * doubt it due to the lack of independent sampling frequency register
   66  * for playback/capture.
   67  * Since I couldn't find any documentation for APCDMA programming
   68  * information, I guessed the usage of APCDMA from that of OpenBSD's
   69  * driver. The EBDMA infomation of PCIO can be obtained from
   70  *  http://solutions.sun.com/embedded/databook/web/microprocessors/pcio.html
   71  * And CS4231A datasheet can also be obtained from
   72  *  ftp://ftp.alsa-project.org/pub/manuals/cirrus/4231a.pdf
   73  *
   74  * Audio capture(recording) was not tested at all and may have bugs.
   75  * Sorry, I don't have microphone. Don't try to use full-duplex mode.
   76  * It wouldn't work.
   77  */
   78 #define CS_TIMEOUT              90000
   79 
   80 #define CS4231_MIN_BUF_SZ       (16*1024)
   81 #define CS4231_DEFAULT_BUF_SZ   (32*1024)
   82 #define CS4231_MAX_BUF_SZ       (64*1024)
   83 #define CS4231_MAX_BLK_SZ       (8*1024)
   84 #define CS4231_MAX_APC_DMA_SZ   (8*1024)
   85 
   86 
   87 #undef CS4231_DEBUG
   88 #ifdef CS4231_DEBUG
   89 #define DPRINTF(x)              printf x
   90 #else
   91 #define DPRINTF(x)
   92 #endif
   93 #define CS4231_AUTO_CALIBRATION
   94 
   95 struct cs4231_softc;
   96 
   97 struct cs4231_channel {
   98         struct cs4231_softc     *parent;
   99         struct pcm_channel      *channel;
  100         struct snd_dbuf         *buffer;
  101         u_int32_t               format;
  102         u_int32_t               speed;
  103         u_int32_t               nextaddr;
  104         u_int32_t               togo;
  105         int                     dir;
  106         int                     locked;
  107 };
  108 
  109 #define CS4231_RES_MEM_MAX      4
  110 #define CS4231_RES_IRQ_MAX      2
  111 struct cs4231_softc {
  112         struct device           *sc_dev;
  113         int                     sc_rid[CS4231_RES_MEM_MAX];
  114         struct resource         *sc_res[CS4231_RES_MEM_MAX];
  115         bus_space_handle_t      sc_regh[CS4231_RES_MEM_MAX];
  116         bus_space_tag_t         sc_regt[CS4231_RES_MEM_MAX];
  117 
  118         int                     sc_irqrid[CS4231_RES_IRQ_MAX];
  119         struct resource         *sc_irqres[CS4231_RES_IRQ_MAX];
  120         void                    *sc_ih[CS4231_RES_IRQ_MAX];
  121         bus_dma_tag_t           sc_dmat[CS4231_RES_IRQ_MAX];
  122         int                     sc_burst;
  123 
  124         u_int32_t               sc_bufsz;
  125         struct cs4231_channel   sc_pch;
  126         struct cs4231_channel   sc_rch;
  127         int                     sc_enabled;
  128         int                     sc_rtype;
  129         int                     sc_nmres;
  130         int                     sc_nires;
  131         int                     sc_codecv;
  132         int                     sc_chipvid;
  133         int                     sc_flags;
  134 #define CS4231_SBUS             0x01
  135 #define CS4231_EBUS             0x02
  136 
  137         struct mtx              *sc_lock;
  138 };
  139 
  140 struct mix_table {
  141         u_int32_t       reg:8;
  142         u_int32_t       bits:8;
  143         u_int32_t       mute:8;
  144         u_int32_t       shift:4;
  145         u_int32_t       neg:1;
  146         u_int32_t       avail:1;
  147         u_int32_t       recdev:1;
  148 };
  149 
  150 static int      cs4231_bus_probe(device_t);
  151 static int      cs4231_sbus_attach(device_t);
  152 static int      cs4231_ebus_attach(device_t);
  153 static int      cs4231_attach_common(struct cs4231_softc *);
  154 static int      cs4231_bus_detach(device_t);
  155 static int      cs4231_bus_suspend(device_t);
  156 static int      cs4231_bus_resume(device_t);
  157 static void     cs4231_getversion(struct cs4231_softc *);
  158 static void     cs4231_free_resource(struct cs4231_softc *);
  159 static void     cs4231_ebdma_reset(struct cs4231_softc *);
  160 static void     cs4231_power_reset(struct cs4231_softc *, int);
  161 static int      cs4231_enable(struct cs4231_softc *, int);
  162 static void     cs4231_disable(struct cs4231_softc *);
  163 static void     cs4231_write(struct cs4231_softc *, u_int8_t, u_int8_t);
  164 static u_int8_t cs4231_read(struct cs4231_softc *, u_int8_t);
  165 static void     cs4231_sbus_intr(void *);
  166 static void     cs4231_ebus_pintr(void *arg);
  167 static void     cs4231_ebus_cintr(void *arg);
  168 static int      cs4231_mixer_init(struct snd_mixer *);
  169 static void     cs4231_mixer_set_value(struct cs4231_softc *,
  170     const struct mix_table *, u_int8_t);
  171 static int      cs4231_mixer_set(struct snd_mixer *, u_int32_t, u_int32_t,
  172     u_int32_t);
  173 static int      cs4231_mixer_setrecsrc(struct snd_mixer *, u_int32_t);
  174 static void     *cs4231_chan_init(kobj_t, void *, struct snd_dbuf *,
  175     struct pcm_channel *, int);
  176 static int      cs4231_chan_setformat(kobj_t, void *, u_int32_t);
  177 static int      cs4231_chan_setspeed(kobj_t, void *, u_int32_t);
  178 static void     cs4231_chan_fs(struct cs4231_softc *, int, u_int8_t);
  179 static int      cs4231_chan_setblocksize(kobj_t, void *, u_int32_t);
  180 static int      cs4231_chan_trigger(kobj_t, void *, int);
  181 static int      cs4231_chan_getptr(kobj_t, void *);
  182 static struct pcmchan_caps *
  183     cs4231_chan_getcaps(kobj_t, void *);
  184 static void     cs4231_trigger(struct cs4231_channel *);
  185 static void     cs4231_apcdma_trigger(struct cs4231_softc *,
  186     struct cs4231_channel *);
  187 static void     cs4231_ebdma_trigger(struct cs4231_softc *,
  188     struct cs4231_channel *);
  189 static void     cs4231_halt(struct cs4231_channel *);
  190 
  191 #define CS4231_LOCK(sc)         snd_mtxlock(sc->sc_lock)
  192 #define CS4231_UNLOCK(sc)       snd_mtxunlock(sc->sc_lock)
  193 #define CS4231_LOCK_ASSERT(sc)  snd_mtxassert(sc->sc_lock)
  194 
  195 #define CS_WRITE(sc,r,v)        \
  196     bus_space_write_1((sc)->sc_regt[0], (sc)->sc_regh[0], (r) << 2, (v))
  197 #define CS_READ(sc,r)           \
  198     bus_space_read_1((sc)->sc_regt[0], (sc)->sc_regh[0], (r) << 2)
  199 
  200 #define APC_WRITE(sc,r,v)       \
  201     bus_space_write_4(sc->sc_regt[0], sc->sc_regh[0], r, v)
  202 #define APC_READ(sc,r)          \
  203     bus_space_read_4(sc->sc_regt[0], sc->sc_regh[0], r)
  204 
  205 #define EBDMA_P_WRITE(sc,r,v)   \
  206     bus_space_write_4((sc)->sc_regt[1], (sc)->sc_regh[1], (r), (v))
  207 #define EBDMA_P_READ(sc,r)      \
  208     bus_space_read_4((sc)->sc_regt[1], (sc)->sc_regh[1], (r))
  209 
  210 #define EBDMA_C_WRITE(sc,r,v)   \
  211     bus_space_write_4((sc)->sc_regt[2], (sc)->sc_regh[2], (r), (v))
  212 #define EBDMA_C_READ(sc,r)      \
  213     bus_space_read_4((sc)->sc_regt[2], (sc)->sc_regh[2], (r))
  214 
  215 #define AUXIO_CODEC             0x00
  216 #define AUXIO_WRITE(sc,r,v)     \
  217     bus_space_write_4((sc)->sc_regt[3], (sc)->sc_regh[3], (r), (v))
  218 #define AUXIO_READ(sc,r)        \
  219     bus_space_read_4((sc)->sc_regt[3], (sc)->sc_regh[3], (r))
  220 
  221 #define CODEC_WARM_RESET        0
  222 #define CODEC_COLD_RESET        1
  223 
  224 /* SBus */
  225 static device_method_t cs4231_sbus_methods[] = {
  226         DEVMETHOD(device_probe,         cs4231_bus_probe),
  227         DEVMETHOD(device_attach,        cs4231_sbus_attach),
  228         DEVMETHOD(device_detach,        cs4231_bus_detach),
  229         DEVMETHOD(device_suspend,       cs4231_bus_suspend),
  230         DEVMETHOD(device_resume,        cs4231_bus_resume),
  231         {0, 0}
  232 };
  233 
  234 static driver_t cs4231_sbus_driver = {
  235         "pcm",
  236         cs4231_sbus_methods,
  237         PCM_SOFTC_SIZE
  238 };
  239 
  240 DRIVER_MODULE(snd_audiocs, sbus, cs4231_sbus_driver, pcm_devclass, 0, 0);
  241 
  242 /* EBus */
  243 static device_method_t cs4231_ebus_methods[] = {
  244         DEVMETHOD(device_probe,         cs4231_bus_probe),
  245         DEVMETHOD(device_attach,        cs4231_ebus_attach),
  246         DEVMETHOD(device_detach,        cs4231_bus_detach),
  247         DEVMETHOD(device_suspend,       cs4231_bus_suspend),
  248         DEVMETHOD(device_resume,        cs4231_bus_resume),
  249         {0, 0}
  250 };
  251 
  252 static driver_t cs4231_ebus_driver = {
  253         "pcm",
  254         cs4231_ebus_methods,
  255         PCM_SOFTC_SIZE
  256 };
  257 
  258 DRIVER_MODULE(snd_audiocs, ebus, cs4231_ebus_driver, pcm_devclass, 0, 0);
  259 MODULE_DEPEND(snd_audiocs, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
  260 MODULE_VERSION(snd_audiocs, 1);
  261 
  262 
  263 static u_int32_t cs4231_fmt[] = {
  264         AFMT_U8,
  265         AFMT_STEREO | AFMT_U8,
  266         AFMT_MU_LAW,
  267         AFMT_STEREO | AFMT_MU_LAW,
  268         AFMT_A_LAW,
  269         AFMT_STEREO | AFMT_A_LAW,
  270         AFMT_IMA_ADPCM,
  271         AFMT_STEREO | AFMT_IMA_ADPCM,
  272         AFMT_S16_LE,
  273         AFMT_STEREO | AFMT_S16_LE,
  274         AFMT_S16_BE,
  275         AFMT_STEREO | AFMT_S16_BE,
  276         0
  277 };
  278 
  279 static struct pcmchan_caps cs4231_caps = {5510, 48000, cs4231_fmt, 0};
  280 
  281 /*
  282  * sound(4) channel interface
  283  */
  284 static kobj_method_t cs4231_chan_methods[] = {
  285         KOBJMETHOD(channel_init,                cs4231_chan_init),
  286         KOBJMETHOD(channel_setformat,           cs4231_chan_setformat),
  287         KOBJMETHOD(channel_setspeed,            cs4231_chan_setspeed),
  288         KOBJMETHOD(channel_setblocksize,        cs4231_chan_setblocksize),
  289         KOBJMETHOD(channel_trigger,             cs4231_chan_trigger),
  290         KOBJMETHOD(channel_getptr,              cs4231_chan_getptr),
  291         KOBJMETHOD(channel_getcaps,             cs4231_chan_getcaps),
  292         { 0, 0 }
  293 };
  294 CHANNEL_DECLARE(cs4231_chan); 
  295 
  296 /*
  297  * sound(4) mixer interface
  298  */
  299 static kobj_method_t cs4231_mixer_methods[] = {
  300         KOBJMETHOD(mixer_init,          cs4231_mixer_init),
  301         KOBJMETHOD(mixer_set,           cs4231_mixer_set),
  302         KOBJMETHOD(mixer_setrecsrc,     cs4231_mixer_setrecsrc),
  303         { 0, 0 }
  304 };
  305 MIXER_DECLARE(cs4231_mixer);
  306 
  307 static int
  308 cs4231_bus_probe(device_t dev)
  309 {
  310         const char *name;
  311 
  312         name = ofw_bus_get_name(dev);
  313         if (strcmp("SUNW,CS4231", name) == 0) {
  314                 device_set_desc(dev, "Sun Audiocs");
  315                 return (0);
  316         }
  317         return (ENXIO);
  318 }
  319 
  320 static int
  321 cs4231_sbus_attach(device_t dev)
  322 {
  323         struct snddev_info *d;
  324         struct cs4231_softc *sc;
  325         int burst;
  326 
  327         d = device_get_softc(dev);
  328         sc = malloc(sizeof(struct cs4231_softc), M_DEVBUF, M_NOWAIT | M_ZERO);
  329         if (sc == NULL) {
  330                 device_printf(dev, "cannot allocate softc\n");
  331                 return (ENOMEM);
  332         }
  333         sc->sc_dev = dev;
  334         /*
  335          * XXX
  336          * No public documentation exists on programming burst size of APCDMA.
  337          */
  338         burst = sbus_get_burstsz(sc->sc_dev);
  339         if ((burst & SBUS_BURST_64))
  340                 sc->sc_burst = 64;
  341         else if ((burst & SBUS_BURST_32))
  342                 sc->sc_burst = 32;
  343         else if ((burst & SBUS_BURST_16))
  344                 sc->sc_burst = 16;
  345         else
  346                 sc->sc_burst = 0;
  347         sc->sc_flags = CS4231_SBUS;
  348         sc->sc_rtype = SYS_RES_MEMORY;
  349         sc->sc_nmres = 1;
  350         sc->sc_nires = 1;
  351         return cs4231_attach_common(sc);
  352 }
  353 
  354 static int
  355 cs4231_ebus_attach(device_t dev)
  356 {
  357         struct snddev_info *d;
  358         struct cs4231_softc *sc;
  359 
  360         d = device_get_softc(dev);
  361         sc = malloc(sizeof(struct cs4231_softc), M_DEVBUF, M_NOWAIT | M_ZERO);
  362         if (sc == NULL) {
  363                 device_printf(dev, "cannot allocate softc\n");
  364                 return (ENOMEM);
  365         }
  366         sc->sc_dev = dev;
  367         sc->sc_burst = EBDCSR_BURST_1;
  368         sc->sc_rtype = SYS_RES_IOPORT;
  369         sc->sc_nmres = CS4231_RES_MEM_MAX;
  370         sc->sc_nires = CS4231_RES_IRQ_MAX;
  371         sc->sc_flags = CS4231_EBUS;
  372         return cs4231_attach_common(sc);
  373 }
  374 
  375 static int
  376 cs4231_attach_common(struct cs4231_softc *sc)
  377 {
  378         char status[SND_STATUSLEN];
  379         driver_intr_t *ihandler;
  380         int i;
  381 
  382         sc->sc_lock = snd_mtxcreate(device_get_nameunit(sc->sc_dev),
  383             "sound softc");
  384         if (sc->sc_lock == NULL) {
  385                 device_printf(sc->sc_dev, "cannot create mutex\n");
  386                 free(sc, M_DEVBUF);
  387                 return (ENXIO);
  388         }
  389 
  390         for (i = 0; i < sc->sc_nmres; i++) {
  391                 sc->sc_rid[i] = i;
  392                 if ((sc->sc_res[i] = bus_alloc_resource_any(sc->sc_dev,
  393                     sc->sc_rtype, &sc->sc_rid[i], RF_ACTIVE)) == NULL) {
  394                         device_printf(sc->sc_dev,
  395                             "cannot map register %d\n", i);
  396                         goto fail;
  397                 }
  398                 sc->sc_regt[i] = rman_get_bustag(sc->sc_res[i]);
  399                 sc->sc_regh[i] = rman_get_bushandle(sc->sc_res[i]);
  400         }
  401         for (i = 0; i < sc->sc_nires; i++) {
  402                 sc->sc_irqrid[i] = i;
  403                 if ((sc->sc_irqres[i] = bus_alloc_resource_any(sc->sc_dev,
  404                     SYS_RES_IRQ, &sc->sc_irqrid[i], RF_SHAREABLE | RF_ACTIVE))
  405                     == NULL) {
  406                         if ((sc->sc_flags & CS4231_SBUS) != 0)
  407                                 device_printf(sc->sc_dev,
  408                                     "cannot allocate interrupt\n");
  409                         else
  410                                 device_printf(sc->sc_dev, "cannot allocate %s "
  411                                     "interrupt\n", i == 0 ? "capture" :
  412                                     "playback");
  413                         goto fail;
  414                 }
  415         }
  416 
  417         ihandler = cs4231_sbus_intr;
  418         for (i = 0; i < sc->sc_nires; i++) {
  419                 if ((sc->sc_flags & CS4231_EBUS) != 0) {
  420                         if (i == 0)
  421                                 ihandler = cs4231_ebus_cintr;
  422                         else
  423                                 ihandler = cs4231_ebus_pintr;
  424                 }
  425                 if (snd_setup_intr(sc->sc_dev, sc->sc_irqres[i], INTR_MPSAFE,
  426                     ihandler, sc, &sc->sc_ih[i])) {
  427                         if ((sc->sc_flags & CS4231_SBUS) != 0)
  428                                 device_printf(sc->sc_dev,
  429                                     "cannot set up interrupt\n");
  430                         else
  431                                 device_printf(sc->sc_dev, "cannot set up %s "
  432                                     " interrupt\n", i == 0 ? "capture" :
  433                                     "playback");
  434                         goto fail;
  435                 }
  436         }
  437 
  438         sc->sc_bufsz = pcm_getbuffersize(sc->sc_dev, CS4231_MIN_BUF_SZ,
  439             CS4231_DEFAULT_BUF_SZ, CS4231_MAX_BUF_SZ);
  440         for (i = 0; i < sc->sc_nires; i++) {
  441                 if (bus_dma_tag_create(
  442                     NULL,                       /* parent */
  443                     64, 0,                      /* alignment, boundary */
  444                     BUS_SPACE_MAXADDR_32BIT,    /* lowaddr */
  445                     BUS_SPACE_MAXADDR,          /* highaddr */
  446                     NULL, NULL,                 /* filtfunc, filtfuncarg */
  447                     sc->sc_bufsz,               /* maxsize */
  448                     1,                          /* nsegments */
  449                     sc->sc_bufsz,               /* maxsegsz */
  450                     BUS_DMA_ALLOCNOW,           /* flags */
  451                     NULL,                       /* lockfunc */
  452                     NULL,                       /* lockfuncarg */
  453                     &sc->sc_dmat[i])) {
  454                         if ((sc->sc_flags & CS4231_SBUS) != 0)
  455                                 device_printf(sc->sc_dev,
  456                                     "cannot allocate DMA tag\n");
  457                         else
  458                                 device_printf(sc->sc_dev, "cannot allocate %s "
  459                                     "DMA tag\n", i == 0 ? "capture" :
  460                                     "playback");
  461                         goto fail;
  462                 }
  463         }
  464         cs4231_enable(sc, CODEC_WARM_RESET);
  465         cs4231_getversion(sc);
  466         if (mixer_init(sc->sc_dev, &cs4231_mixer_class, sc) != 0)
  467                 goto fail;
  468         if (pcm_register(sc->sc_dev, sc, 1, 1)) {
  469                 device_printf(sc->sc_dev, "cannot register to pcm\n");
  470                 goto fail;
  471         }
  472         if (pcm_addchan(sc->sc_dev, PCMDIR_REC, &cs4231_chan_class, sc) != 0)
  473                 goto chan_fail;
  474         if (pcm_addchan(sc->sc_dev, PCMDIR_PLAY, &cs4231_chan_class, sc) != 0)
  475                 goto chan_fail;
  476         if ((sc->sc_flags & CS4231_SBUS) != 0)
  477                 snprintf(status, SND_STATUSLEN, "at mem 0x%lx irq %ld bufsz %u",
  478                     rman_get_start(sc->sc_res[0]),
  479                     rman_get_start(sc->sc_irqres[0]), sc->sc_bufsz);
  480         else
  481                 snprintf(status, SND_STATUSLEN, "at io 0x%lx 0x%lx 0x%lx 0x%lx "
  482                     "irq %ld %ld bufsz %u", rman_get_start(sc->sc_res[0]),
  483                     rman_get_start(sc->sc_res[1]),
  484                     rman_get_start(sc->sc_res[2]),
  485                     rman_get_start(sc->sc_res[3]),
  486                     rman_get_start(sc->sc_irqres[0]),
  487                     rman_get_start(sc->sc_irqres[1]), sc->sc_bufsz);
  488         pcm_setstatus(sc->sc_dev, status);
  489         return (0);
  490 
  491 chan_fail:
  492         pcm_unregister(sc->sc_dev);
  493 fail:
  494         cs4231_free_resource(sc);
  495         return (ENXIO);
  496 }
  497 
  498 static int
  499 cs4231_bus_detach(device_t dev)
  500 {
  501         struct cs4231_softc *sc;
  502         struct cs4231_channel *pch, *rch;
  503         int error;
  504 
  505         sc = pcm_getdevinfo(dev);
  506         CS4231_LOCK(sc);
  507         pch = &sc->sc_pch;
  508         rch = &sc->sc_pch;
  509         if (pch->locked || rch->locked) {
  510                 CS4231_UNLOCK(sc);
  511                 return (EBUSY);
  512         }
  513         /*
  514          * Since EBDMA requires valid DMA buffer to drain its FIFO, we need
  515          * real DMA buffer for draining.
  516          */
  517         if ((sc->sc_flags & CS4231_EBUS) != 0)
  518                 cs4231_ebdma_reset(sc);
  519         CS4231_UNLOCK(sc);
  520         error = pcm_unregister(dev);
  521         if (error)
  522                 return (error);
  523         cs4231_free_resource(sc);
  524         return (0);
  525 }
  526 
  527 static int
  528 cs4231_bus_suspend(device_t dev)
  529 {
  530 
  531         return (ENXIO);
  532 }
  533 
  534 static int
  535 cs4231_bus_resume(device_t dev)
  536 {
  537 
  538         return (ENXIO);
  539 }
  540 
  541 static void
  542 cs4231_getversion(struct cs4231_softc *sc)
  543 {
  544         u_int8_t v;
  545 
  546         v = cs4231_read(sc, CS_MISC_INFO);
  547         sc->sc_codecv = v & CS_CODEC_ID_MASK;
  548         v = cs4231_read(sc, CS_VERSION_ID);
  549         v &= (CS_VERSION_NUMBER | CS_VERSION_CHIPID);
  550         sc->sc_chipvid = v;
  551         switch(v) {
  552                 case 0x80:
  553                         device_printf(sc->sc_dev, "<CS4231 Codec Id. %d>\n",
  554                             sc->sc_codecv);
  555                         break;
  556                 case 0xa0:
  557                         device_printf(sc->sc_dev, "<CS4231A Codec Id. %d>\n",
  558                             sc->sc_codecv);
  559                         break;
  560                 case 0x82:
  561                         device_printf(sc->sc_dev, "<CS4232 Codec Id. %d>\n",
  562                             sc->sc_codecv);
  563                         break;
  564                 default:
  565                         device_printf(sc->sc_dev,
  566                             "<Unknown 0x%x Codec Id. %d\n", v, sc->sc_codecv);
  567                         break;
  568         }
  569 }
  570 
  571 static void
  572 cs4231_ebdma_reset(struct cs4231_softc *sc)
  573 {
  574         int i;
  575 
  576         /* playback */
  577         EBDMA_P_WRITE(sc, EBDMA_DCSR,
  578             EBDMA_P_READ(sc, EBDMA_DCSR) & ~(EBDCSR_INTEN | EBDCSR_NEXTEN));
  579         EBDMA_P_WRITE(sc, EBDMA_DCSR, EBDCSR_RESET);
  580         for (i = CS_TIMEOUT;
  581             i && EBDMA_P_READ(sc, EBDMA_DCSR) & EBDCSR_DRAIN; i--)
  582                 DELAY(1);
  583         if (i == 0)
  584                 device_printf(sc->sc_dev,
  585                     "timeout waiting for playback DMA reset\n");
  586         EBDMA_P_WRITE(sc, EBDMA_DCSR, sc->sc_burst);
  587         /* capture */
  588         EBDMA_C_WRITE(sc, EBDMA_DCSR,
  589             EBDMA_C_READ(sc, EBDMA_DCSR) & ~(EBDCSR_INTEN | EBDCSR_NEXTEN));
  590         EBDMA_C_WRITE(sc, EBDMA_DCSR, EBDCSR_RESET);
  591         for (i = CS_TIMEOUT;
  592             i && EBDMA_C_READ(sc, EBDMA_DCSR) & EBDCSR_DRAIN; i--)
  593                 DELAY(1);
  594         if (i == 0)
  595                 device_printf(sc->sc_dev,
  596                     "timeout waiting for capture DMA reset\n");
  597         EBDMA_C_WRITE(sc, EBDMA_DCSR, sc->sc_burst);
  598 }
  599 
  600 static void
  601 cs4231_power_reset(struct cs4231_softc *sc, int how)
  602 {
  603         u_int32_t v;
  604         int i;
  605 
  606         if ((sc->sc_flags & CS4231_SBUS) != 0) {
  607                 APC_WRITE(sc, APC_CSR, APC_CSR_RESET);
  608                 DELAY(10);
  609                 APC_WRITE(sc, APC_CSR, 0);
  610                 DELAY(10);
  611                 APC_WRITE(sc,
  612                     APC_CSR, APC_READ(sc, APC_CSR) | APC_CSR_CODEC_RESET);
  613                 DELAY(20);
  614                 APC_WRITE(sc,
  615                     APC_CSR, APC_READ(sc, APC_CSR) & (~APC_CSR_CODEC_RESET));
  616         } else {
  617                 v = AUXIO_READ(sc, AUXIO_CODEC);
  618                 if (how == CODEC_WARM_RESET && v != 0) {
  619                         AUXIO_WRITE(sc, AUXIO_CODEC, 0);
  620                         DELAY(20);
  621                 } else if (how == CODEC_COLD_RESET){
  622                         AUXIO_WRITE(sc, AUXIO_CODEC, 1);
  623                         DELAY(20);
  624                         AUXIO_WRITE(sc, AUXIO_CODEC, 0);
  625                         DELAY(20);
  626                 }
  627                 cs4231_ebdma_reset(sc);
  628         }
  629 
  630         for (i = CS_TIMEOUT;
  631             i && CS_READ(sc, CS4231_IADDR) == CS_IN_INIT; i--)
  632                 DELAY(10);
  633         if (i == 0)
  634                 device_printf(sc->sc_dev, "timeout waiting for reset\n");
  635 
  636         /* turn on cs4231 mode */
  637         cs4231_write(sc, CS_MISC_INFO,
  638             cs4231_read(sc, CS_MISC_INFO) | CS_MODE2);
  639         /* enable interupts & clear CSR */
  640         cs4231_write(sc, CS_PIN_CONTROL,
  641             cs4231_read(sc, CS_PIN_CONTROL) | INTERRUPT_ENABLE);
  642         CS_WRITE(sc, CS4231_STATUS, 0);
  643         /* enable DAC output */
  644         cs4231_write(sc, CS_LEFT_OUTPUT_CONTROL,
  645             cs4231_read(sc, CS_LEFT_OUTPUT_CONTROL) & ~OUTPUT_MUTE);
  646         cs4231_write(sc, CS_RIGHT_OUTPUT_CONTROL,
  647             cs4231_read(sc, CS_RIGHT_OUTPUT_CONTROL) & ~OUTPUT_MUTE);
  648         /* mute AUX1 since it generates noises */
  649         cs4231_write(sc, CS_LEFT_AUX1_CONTROL,
  650             cs4231_read(sc, CS_LEFT_AUX1_CONTROL) | AUX_INPUT_MUTE);
  651         cs4231_write(sc, CS_RIGHT_AUX1_CONTROL,
  652             cs4231_read(sc, CS_RIGHT_AUX1_CONTROL) | AUX_INPUT_MUTE);
  653         /* protect buffer underrun and set output level to 0dB */
  654         cs4231_write(sc, CS_ALT_FEATURE1,
  655             cs4231_read(sc, CS_ALT_FEATURE1) | CS_DAC_ZERO | CS_OUTPUT_LVL);
  656         /* enable high pass filter, dual xtal was disabled due to noises */
  657         cs4231_write(sc, CS_ALT_FEATURE2,
  658             cs4231_read(sc, CS_ALT_FEATURE2) | CS_HPF_ENABLE);
  659 }
  660 
  661 static int
  662 cs4231_enable(struct cs4231_softc *sc, int how)
  663 {
  664         cs4231_power_reset(sc, how);
  665         sc->sc_enabled = 1;
  666         return (0);
  667 }
  668 
  669 static void
  670 cs4231_disable(struct cs4231_softc *sc)
  671 {
  672         u_int8_t v;
  673 
  674         CS4231_LOCK_ASSERT(sc);
  675 
  676         if (sc->sc_enabled == 0)
  677                 return;
  678         sc->sc_enabled = 0;
  679         CS4231_UNLOCK(sc);
  680         cs4231_halt(&sc->sc_pch);
  681         cs4231_halt(&sc->sc_rch);
  682         CS4231_LOCK(sc);
  683         v = cs4231_read(sc, CS_PIN_CONTROL) & ~INTERRUPT_ENABLE;
  684         cs4231_write(sc, CS_PIN_CONTROL, v);
  685 
  686         if ((sc->sc_flags & CS4231_SBUS) != 0) {
  687                 APC_WRITE(sc, APC_CSR, APC_CSR_RESET);
  688                 DELAY(10);
  689                 APC_WRITE(sc, APC_CSR, 0);
  690                 DELAY(10);
  691         } else
  692                 cs4231_ebdma_reset(sc);
  693 }
  694 
  695 static void
  696 cs4231_free_resource(struct cs4231_softc *sc)
  697 {
  698         int i;
  699 
  700         CS4231_LOCK(sc);
  701         cs4231_disable(sc);
  702         CS4231_UNLOCK(sc);
  703         for (i = 0; i < sc->sc_nires; i++) {
  704                 if (sc->sc_irqres[i]) {
  705                         if (sc->sc_ih[i]) {
  706                                 bus_teardown_intr(sc->sc_dev, sc->sc_irqres[i],
  707                                     sc->sc_ih[i]);
  708                                 sc->sc_ih[i] = NULL;
  709                         }
  710                         bus_release_resource(sc->sc_dev, SYS_RES_IRQ,
  711                             sc->sc_irqrid[i], sc->sc_irqres[i]);
  712                         sc->sc_irqres[i] = NULL;
  713                 }
  714         }
  715         for (i = 0; i < sc->sc_nires; i++) {
  716                 if (sc->sc_dmat[i])
  717                         bus_dma_tag_destroy(sc->sc_dmat[i]);
  718         }
  719         for (i = 0; i < sc->sc_nmres; i++) {
  720                 if (sc->sc_res[i])
  721                         bus_release_resource(sc->sc_dev, sc->sc_rtype,
  722                             sc->sc_rid[i], sc->sc_res[i]);
  723         }
  724         snd_mtxfree(sc->sc_lock);
  725         free(sc, M_DEVBUF);
  726 }
  727 
  728 static void
  729 cs4231_write(struct cs4231_softc *sc, u_int8_t r, u_int8_t v)
  730 {
  731         CS_WRITE(sc, CS4231_IADDR, r);
  732         CS_WRITE(sc, CS4231_IDATA, v);
  733 }
  734 
  735 static u_int8_t
  736 cs4231_read(struct cs4231_softc *sc, u_int8_t r)
  737 {
  738         CS_WRITE(sc, CS4231_IADDR, r);
  739         return (CS_READ(sc, CS4231_IDATA));
  740 }
  741 
  742 static void
  743 cs4231_sbus_intr(void *arg)
  744 {
  745         struct cs4231_softc *sc;
  746         struct cs4231_channel *pch, *rch;
  747         u_int32_t csr;
  748         u_int8_t status;
  749 
  750         sc = arg;
  751         CS4231_LOCK(sc);
  752 
  753         csr = APC_READ(sc, APC_CSR);
  754         if ((csr & APC_CSR_GI) == 0) {
  755                 CS4231_UNLOCK(sc);
  756                 return;
  757         }
  758         APC_WRITE(sc, APC_CSR, csr);
  759 
  760         if ((csr & APC_CSR_EIE) && (csr & APC_CSR_EI)) {
  761                 status = cs4231_read(sc, CS_TEST_AND_INIT);
  762                 device_printf(sc->sc_dev,
  763                     "apc error interrupt : stat = 0x%x\n", status);
  764         }
  765 
  766         pch = rch = NULL;
  767         if ((csr & APC_CSR_PMIE) && (csr & APC_CSR_PMI)) {
  768                 u_long nextaddr, saddr;
  769                 u_int32_t togo;
  770 
  771                 pch = &sc->sc_pch;
  772                 togo = pch->togo;
  773                 saddr = sndbuf_getbufaddr(pch->buffer);
  774                 nextaddr = pch->nextaddr + togo;
  775                 if (nextaddr >=  saddr + sndbuf_getsize(pch->buffer))
  776                         nextaddr = saddr;
  777                 APC_WRITE(sc, APC_PNVA, nextaddr);
  778                 APC_WRITE(sc, APC_PNC, togo);
  779                 pch->nextaddr = nextaddr;
  780         }
  781 
  782         if ((csr & APC_CSR_CIE) && (csr & APC_CSR_CI) && (csr & APC_CSR_CD)) {
  783                 u_long nextaddr, saddr;
  784                 u_int32_t togo;
  785 
  786                 rch = &sc->sc_rch;
  787                 togo = rch->togo;
  788                 saddr = sndbuf_getbufaddr(rch->buffer);
  789                 nextaddr = rch->nextaddr + togo;
  790                 if (nextaddr >= saddr + sndbuf_getsize(rch->buffer))
  791                         nextaddr = saddr; 
  792                 APC_WRITE(sc, APC_CNVA, nextaddr);
  793                 APC_WRITE(sc, APC_CNC, togo);
  794                 rch->nextaddr = nextaddr;
  795         }
  796         CS4231_UNLOCK(sc);
  797         if (pch)
  798                 chn_intr(pch->channel);
  799         if (rch)
  800                 chn_intr(rch->channel);
  801 }
  802 
  803 /* playback interrupt handler */
  804 static void
  805 cs4231_ebus_pintr(void *arg)
  806 {
  807         struct cs4231_softc *sc;
  808         struct cs4231_channel *ch;
  809         u_int32_t csr;
  810         u_int8_t status;
  811 
  812         sc = arg;
  813         CS4231_LOCK(sc);
  814 
  815         csr = EBDMA_P_READ(sc, EBDMA_DCSR);
  816         if ((csr & EBDCSR_INT) == 0) {
  817                 CS4231_UNLOCK(sc);
  818                 return;
  819         }
  820 
  821         if ((csr & EBDCSR_ERR)) {
  822                 status = cs4231_read(sc, CS_TEST_AND_INIT);
  823                 device_printf(sc->sc_dev,
  824                     "ebdma error interrupt : stat = 0x%x\n", status);
  825         }
  826         EBDMA_P_WRITE(sc, EBDMA_DCSR, csr | EBDCSR_TC);
  827 
  828         ch = NULL;
  829         if (csr & EBDCSR_TC) {
  830                 u_long nextaddr, saddr;
  831                 u_int32_t togo;
  832 
  833                 ch = &sc->sc_pch;
  834                 togo = ch->togo;
  835                 saddr = sndbuf_getbufaddr(ch->buffer);
  836                 nextaddr = ch->nextaddr + togo;
  837                 if (nextaddr >=  saddr + sndbuf_getsize(ch->buffer))
  838                         nextaddr = saddr;
  839                 /*
  840                  * EBDMA_DCNT is loaded automatically
  841                  * EBDMA_P_WRITE(sc, EBDMA_DCNT, togo);
  842                  */
  843                 EBDMA_P_WRITE(sc, EBDMA_DADDR, nextaddr);
  844                 ch->nextaddr = nextaddr;
  845         }
  846         CS4231_UNLOCK(sc);
  847         if (ch)
  848                 chn_intr(ch->channel);
  849 }
  850 
  851 /* capture interrupt handler */
  852 static void
  853 cs4231_ebus_cintr(void *arg)
  854 {
  855         struct cs4231_softc *sc;
  856         struct cs4231_channel *ch;
  857         u_int32_t csr;
  858         u_int8_t status;
  859 
  860         sc = arg;
  861         CS4231_LOCK(sc);
  862 
  863         csr = EBDMA_C_READ(sc, EBDMA_DCSR);
  864         if ((csr & EBDCSR_INT) == 0) {
  865                 CS4231_UNLOCK(sc);
  866                 return;
  867         }
  868         if ((csr & EBDCSR_ERR)) {
  869                 status = cs4231_read(sc, CS_TEST_AND_INIT);
  870                 device_printf(sc->sc_dev,
  871                     "dma error interrupt : stat = 0x%x\n", status);
  872         }
  873         EBDMA_C_WRITE(sc, EBDMA_DCSR, csr | EBDCSR_TC);
  874 
  875         ch = NULL;
  876         if (csr & EBDCSR_TC) {
  877                 u_long nextaddr, saddr;
  878                 u_int32_t togo;
  879 
  880                 ch = &sc->sc_rch;
  881                 togo = ch->togo;
  882                 saddr = sndbuf_getbufaddr(ch->buffer);
  883                 nextaddr = ch->nextaddr + togo;
  884                 if (nextaddr >= saddr + sndbuf_getblksz(ch->buffer))
  885                         nextaddr = saddr; 
  886                 /*
  887                  * EBDMA_DCNT is loaded automatically
  888                  * EBDMA_C_WRITE(sc, EBDMA_DCNT, togo);
  889                  */
  890                 EBDMA_C_WRITE(sc, EBDMA_DADDR, nextaddr);
  891                 ch->nextaddr = nextaddr;
  892         }
  893         CS4231_UNLOCK(sc);
  894         if (ch)
  895                 chn_intr(ch->channel);
  896 }
  897 
  898 static const struct mix_table cs4231_mix_table[SOUND_MIXER_NRDEVICES][2] = {
  899         [SOUND_MIXER_PCM] = {
  900                 { CS_LEFT_OUTPUT_CONTROL,       6, OUTPUT_MUTE, 0, 1, 1, 0 },
  901                 { CS_RIGHT_OUTPUT_CONTROL,      6, OUTPUT_MUTE, 0, 1, 1, 0 }
  902         },
  903         [SOUND_MIXER_SPEAKER] = {
  904                 { CS_MONO_IO_CONTROL,           4, MONO_OUTPUT_MUTE, 0, 1, 1, 0 },
  905                 { CS_REG_NONE,                  0, 0, 0, 0, 1, 0 }
  906         },
  907         [SOUND_MIXER_LINE] = {
  908                 { CS_LEFT_LINE_CONTROL,         5, LINE_INPUT_MUTE, 0, 1, 1, 1 },
  909                 { CS_RIGHT_LINE_CONTROL,        5, LINE_INPUT_MUTE, 0, 1, 1, 1 }
  910         },
  911         /*
  912          * AUX1 : removed intentionally since it generates noises
  913          * AUX2 : Ultra1/Ultra2 has no internal CD-ROM audio in
  914          */
  915         [SOUND_MIXER_CD] = {
  916                 { CS_LEFT_AUX2_CONTROL,         5, LINE_INPUT_MUTE, 0, 1, 1, 1 },
  917                 { CS_RIGHT_AUX2_CONTROL,        5, LINE_INPUT_MUTE, 0, 1, 1, 1 }
  918         },
  919         [SOUND_MIXER_MIC] = {
  920                 { CS_LEFT_INPUT_CONTROL,        4, 0, 0, 0, 1, 1 },
  921                 { CS_RIGHT_INPUT_CONTROL,       4, 0, 0, 0, 1, 1 }
  922         },
  923         [SOUND_MIXER_IGAIN] = {
  924                 { CS_LEFT_INPUT_CONTROL,        4, 0, 0, 1, 0 },
  925                 { CS_RIGHT_INPUT_CONTROL,       4, 0, 0, 1, 0 }
  926         }
  927 };
  928 
  929 static int
  930 cs4231_mixer_init(struct snd_mixer *m)
  931 {
  932         u_int32_t v;
  933         int i;
  934 
  935         v = 0;
  936         for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
  937                 if (cs4231_mix_table[i][0].avail != 0)
  938                         v |= (1 << i);
  939         mix_setdevs(m, v);
  940         v = 0;
  941         for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
  942                 if (cs4231_mix_table[i][0].recdev != 0)
  943                         v |= (1 << i);
  944         mix_setrecdevs(m, v);
  945         return (0);
  946 }
  947 
  948 static void
  949 cs4231_mixer_set_value(struct cs4231_softc *sc,  const struct mix_table *mt,
  950     u_int8_t v)
  951 {
  952         u_int8_t mask, reg;
  953         u_int8_t old, shift, val;
  954 
  955         if (mt->avail == 0 || mt->reg == CS_REG_NONE)
  956                 return;
  957         reg = mt->reg;
  958         if (mt->neg != 0)
  959                 val = 100 - v;
  960         else
  961                 val = v;
  962         mask = (1 << mt->bits) - 1;
  963         val = ((val * mask) + 50) / 100;
  964         shift = mt->shift;
  965         val <<= shift;
  966         if (v == 0)
  967                 val |= mt->mute;
  968         old = cs4231_read(sc, reg);
  969         old &= ~(mt->mute | (mask << shift));
  970         val |= old;
  971         if (reg == CS_LEFT_INPUT_CONTROL || reg == CS_RIGHT_INPUT_CONTROL) {
  972                 if ((val & (mask << shift)) != 0)
  973                         val |= ADC_INPUT_GAIN_ENABLE;
  974                 else
  975                         val &= ~ADC_INPUT_GAIN_ENABLE;
  976         }
  977         cs4231_write(sc, reg, val);     
  978 }
  979 
  980 static int
  981 cs4231_mixer_set(struct snd_mixer *m, u_int32_t dev, u_int32_t left,
  982     u_int32_t right)
  983 {
  984         struct cs4231_softc *sc;
  985 
  986         sc = mix_getdevinfo(m);
  987         CS4231_LOCK(sc);
  988         cs4231_mixer_set_value(sc, &cs4231_mix_table[dev][0], left);
  989         cs4231_mixer_set_value(sc, &cs4231_mix_table[dev][1], right);
  990         CS4231_UNLOCK(sc);
  991 
  992         return (left | (right << 8));
  993 }
  994 
  995 static int
  996 cs4231_mixer_setrecsrc(struct snd_mixer *m, u_int32_t src)
  997 {
  998         struct cs4231_softc *sc;
  999         u_int8_t        v;
 1000 
 1001         sc = mix_getdevinfo(m);
 1002         switch (src) {
 1003         case SOUND_MASK_LINE:
 1004                 v = CS_IN_LINE;
 1005                 break;
 1006 
 1007         case SOUND_MASK_CD:
 1008                 v = CS_IN_DAC;
 1009                 break;
 1010 
 1011         case SOUND_MASK_MIC:
 1012         default:
 1013                 v = CS_IN_MIC;
 1014                 src = SOUND_MASK_MIC;
 1015                 break;
 1016         }
 1017         CS4231_LOCK(sc);
 1018         cs4231_write(sc, CS_LEFT_INPUT_CONTROL,
 1019             (cs4231_read(sc, CS_LEFT_INPUT_CONTROL) & CS_IN_MASK) | v);
 1020         cs4231_write(sc, CS_RIGHT_INPUT_CONTROL,
 1021             (cs4231_read(sc, CS_RIGHT_INPUT_CONTROL) & CS_IN_MASK) | v);
 1022         CS4231_UNLOCK(sc);
 1023 
 1024         return (src);
 1025 }
 1026 
 1027 static void *
 1028 cs4231_chan_init(kobj_t obj, void *dev, struct snd_dbuf *b,
 1029     struct pcm_channel *c, int dir)
 1030 {
 1031         struct cs4231_softc *sc;
 1032         struct cs4231_channel *ch;
 1033         bus_dma_tag_t dmat;
 1034 
 1035         sc = dev;
 1036         ch = (dir == PCMDIR_PLAY) ? &sc->sc_pch : &sc->sc_rch;
 1037         ch->parent = sc;
 1038         ch->channel = c;
 1039         ch->dir = dir;
 1040         ch->buffer = b;
 1041         if ((sc->sc_flags & CS4231_SBUS) != 0)
 1042                 dmat = sc->sc_dmat[0];
 1043         else {
 1044                 if (dir == PCMDIR_PLAY)
 1045                         dmat = sc->sc_dmat[1];
 1046                 else
 1047                         dmat = sc->sc_dmat[0];
 1048         }
 1049         if (sndbuf_alloc(ch->buffer, dmat, sc->sc_bufsz) != 0)
 1050                 return (NULL);
 1051         DPRINTF(("%s channel addr: 0x%lx\n", dir == PCMDIR_PLAY ? "playback" :
 1052             "capture", sndbuf_getbufaddr(ch->buffer)));
 1053 
 1054         return (ch);
 1055 }
 1056 
 1057 static int
 1058 cs4231_chan_setformat(kobj_t obj, void *data, u_int32_t format)
 1059 {
 1060         struct cs4231_softc *sc;
 1061         struct cs4231_channel *ch;
 1062         u_int32_t encoding;
 1063         u_int8_t fs, v;
 1064 
 1065         ch = data;
 1066         sc = ch->parent;
 1067 
 1068         CS4231_LOCK(sc);
 1069         if (ch->format == format) {
 1070                 CS4231_UNLOCK(sc);
 1071                 return (0);
 1072         }
 1073 
 1074         encoding = format & ~AFMT_STEREO;
 1075         fs = 0;
 1076         switch (encoding) {
 1077         case AFMT_U8:
 1078                 fs = CS_AFMT_U8;
 1079                 break;
 1080         case AFMT_MU_LAW:
 1081                 fs = CS_AFMT_MU_LAW;
 1082                 break;
 1083         case AFMT_S16_LE:
 1084                 fs = CS_AFMT_S16_LE;
 1085                 break;
 1086         case AFMT_A_LAW:
 1087                 fs = CS_AFMT_A_LAW;
 1088                 break;
 1089         case AFMT_IMA_ADPCM:
 1090                 fs = CS_AFMT_IMA_ADPCM;
 1091                 break;
 1092         case AFMT_S16_BE:
 1093                 fs = CS_AFMT_S16_BE;
 1094                 break;
 1095         default:
 1096                 fs = CS_AFMT_U8;
 1097                 format = AFMT_U8;
 1098                 break;
 1099         }
 1100 
 1101         if (format & AFMT_STEREO)
 1102                 fs |= CS_AFMT_STEREO;
 1103         
 1104         DPRINTF(("FORMAT: %s : 0x%x\n", ch->dir == PCMDIR_PLAY ? "playback" :
 1105             "capture", format));
 1106         v = cs4231_read(sc, CS_CLOCK_DATA_FORMAT);
 1107         v &= CS_CLOCK_DATA_FORMAT_MASK;
 1108         fs |= v;
 1109         cs4231_chan_fs(sc, ch->dir, fs);
 1110         ch->format = format;
 1111         CS4231_UNLOCK(sc);
 1112 
 1113         return (0);
 1114 }
 1115 
 1116 static int
 1117 cs4231_chan_setspeed(kobj_t obj, void *data, u_int32_t speed)
 1118 {
 1119         typedef struct {
 1120                 u_int32_t speed;
 1121                 u_int8_t bits;
 1122         } speed_struct;
 1123 
 1124         const static speed_struct speed_table[] = {
 1125                 {5510,  (0 << 1) | CLOCK_XTAL2},
 1126                 {5510,  (0 << 1) | CLOCK_XTAL2},
 1127                 {6620,  (7 << 1) | CLOCK_XTAL2},
 1128                 {8000,  (0 << 1) | CLOCK_XTAL1},
 1129                 {9600,  (7 << 1) | CLOCK_XTAL1},
 1130                 {11025, (1 << 1) | CLOCK_XTAL2},
 1131                 {16000, (1 << 1) | CLOCK_XTAL1},
 1132                 {18900, (2 << 1) | CLOCK_XTAL2},
 1133                 {22050, (3 << 1) | CLOCK_XTAL2},
 1134                 {27420, (2 << 1) | CLOCK_XTAL1},
 1135                 {32000, (3 << 1) | CLOCK_XTAL1},
 1136                 {33075, (6 << 1) | CLOCK_XTAL2},
 1137                 {33075, (4 << 1) | CLOCK_XTAL2},
 1138                 {44100, (5 << 1) | CLOCK_XTAL2},
 1139                 {48000, (6 << 1) | CLOCK_XTAL1},
 1140         };
 1141 
 1142         struct cs4231_softc *sc;
 1143         struct cs4231_channel *ch;
 1144         int i, n, sel;
 1145         u_int8_t fs;
 1146 
 1147         ch = data;
 1148         sc = ch->parent;
 1149         CS4231_LOCK(sc);
 1150         if (ch->speed == speed) {
 1151                 CS4231_UNLOCK(sc);
 1152                 return (speed);
 1153         }
 1154         n = sizeof(speed_table) / sizeof(speed_struct);
 1155 
 1156         for (i = 1, sel =0; i < n - 1; i++)
 1157                 if (abs(speed - speed_table[i].speed) <
 1158                     abs(speed - speed_table[sel].speed))
 1159                         sel = i;        
 1160         DPRINTF(("SPEED: %s : %dHz -> %dHz\n", ch->dir == PCMDIR_PLAY ?
 1161             "playback" : "capture", speed, speed_table[sel].speed));
 1162         speed = speed_table[sel].speed;
 1163 
 1164         fs = cs4231_read(sc, CS_CLOCK_DATA_FORMAT);
 1165         fs &= ~CS_CLOCK_DATA_FORMAT_MASK;
 1166         fs |= speed_table[sel].bits;
 1167         cs4231_chan_fs(sc, ch->dir, fs);
 1168         ch->speed = speed;
 1169         CS4231_UNLOCK(sc);
 1170 
 1171         return (speed);
 1172 }
 1173 
 1174 static void
 1175 cs4231_chan_fs(struct cs4231_softc *sc, int dir, u_int8_t fs)
 1176 {
 1177         int i, doreset;
 1178 #ifdef CS4231_AUTO_CALIBRATION
 1179         u_int8_t v;
 1180 #endif
 1181 
 1182         CS4231_LOCK_ASSERT(sc);
 1183 
 1184         /* set autocalibration */
 1185         doreset = 0;
 1186 #ifdef CS4231_AUTO_CALIBRATION
 1187         v = cs4231_read(sc, CS_INTERFACE_CONFIG) | AUTO_CAL_ENABLE;
 1188         CS_WRITE(sc, CS4231_IADDR, MODE_CHANGE_ENABLE);
 1189         CS_WRITE(sc, CS4231_IADDR, MODE_CHANGE_ENABLE | CS_INTERFACE_CONFIG);
 1190         CS_WRITE(sc, CS4231_IDATA, v);
 1191 #endif
 1192 
 1193         /*
 1194          * We always need to write CS_CLOCK_DATA_FORMAT register since
 1195          * the clock frequency is shared with playback/capture.
 1196          */
 1197         CS_WRITE(sc, CS4231_IADDR, MODE_CHANGE_ENABLE | CS_CLOCK_DATA_FORMAT);
 1198         CS_WRITE(sc, CS4231_IDATA, fs);
 1199         CS_READ(sc, CS4231_IDATA);
 1200         CS_READ(sc, CS4231_IDATA);
 1201         for (i = CS_TIMEOUT;
 1202             i && CS_READ(sc, CS4231_IADDR) == CS_IN_INIT; i--)
 1203                 DELAY(10);
 1204         if (i == 0) {
 1205                 device_printf(sc->sc_dev, "timeout setting playback speed\n");
 1206                 doreset++;
 1207         }
 1208 
 1209         /*
 1210          * capture channel
 1211          * cs4231 doesn't allow seperate fs setup for playback/capture.
 1212          * I believe this will break full-duplex operation.
 1213          */
 1214         if (dir == PCMDIR_REC) {
 1215                 CS_WRITE(sc, CS4231_IADDR, MODE_CHANGE_ENABLE | CS_REC_FORMAT);
 1216                 CS_WRITE(sc, CS4231_IDATA, fs);
 1217                 CS_READ(sc, CS4231_IDATA);
 1218                 CS_READ(sc, CS4231_IDATA);
 1219                 for (i = CS_TIMEOUT;
 1220                     i && CS_READ(sc, CS4231_IADDR) == CS_IN_INIT; i--)
 1221                         DELAY(10);
 1222                 if (i == 0) {
 1223                         device_printf(sc->sc_dev,
 1224                             "timeout setting capture format\n");
 1225                         doreset++;
 1226                 }
 1227         }
 1228 
 1229         CS_WRITE(sc, CS4231_IADDR, 0);
 1230         for (i = CS_TIMEOUT;
 1231             i && CS_READ(sc, CS4231_IADDR) == CS_IN_INIT; i--)
 1232                 DELAY(10);
 1233         if (i == 0) {
 1234                 device_printf(sc->sc_dev, "timeout waiting for !MCE\n");
 1235                 doreset++;
 1236         }
 1237 
 1238 #ifdef CS4231_AUTO_CALIBRATION
 1239         CS_WRITE(sc, CS4231_IADDR, CS_TEST_AND_INIT);
 1240         for (i = CS_TIMEOUT;
 1241             i && CS_READ(sc, CS4231_IDATA) & AUTO_CAL_IN_PROG; i--)
 1242                 DELAY(10);
 1243         if (i == 0) {
 1244                 device_printf(sc->sc_dev,
 1245                     "timeout waiting for autocalibration\n");
 1246                 doreset++;
 1247         }
 1248 #endif
 1249         if (doreset) {
 1250                 /*
 1251                  * Maybe the last resort to avoid a dreadful message like
 1252                  * "pcm0:play:0: play interrupt timeout, channel dead" would
 1253                  * be hardware reset.
 1254                  */
 1255                 device_printf(sc->sc_dev, "trying to hardware reset\n");
 1256                 cs4231_disable(sc);
 1257                 cs4231_enable(sc, CODEC_COLD_RESET);
 1258                 CS4231_UNLOCK(sc); /* XXX */
 1259                 if (mixer_reinit(sc->sc_dev) != 0) 
 1260                         device_printf(sc->sc_dev,
 1261                             "unable to reinitialize the mixer\n");
 1262                 CS4231_LOCK(sc);
 1263         }
 1264 }
 1265 
 1266 static int
 1267 cs4231_chan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
 1268 {
 1269         struct cs4231_softc *sc;
 1270         struct cs4231_channel *ch;
 1271         int nblks, error;
 1272 
 1273         ch = data;
 1274         sc = ch->parent;
 1275 
 1276         if (blocksize > CS4231_MAX_BLK_SZ)
 1277                 blocksize = CS4231_MAX_BLK_SZ;
 1278         nblks = sc->sc_bufsz / blocksize;
 1279         error = sndbuf_resize(ch->buffer, nblks, blocksize);
 1280         if (error != 0)
 1281                 device_printf(sc->sc_dev,
 1282                     "unable to block size, blksz = %d, error = %d\n",
 1283                     blocksize, error);
 1284 
 1285         return (blocksize);
 1286 }
 1287 
 1288 static int
 1289 cs4231_chan_trigger(kobj_t obj, void *data, int go)
 1290 {
 1291         struct cs4231_channel *ch;
 1292 
 1293         ch = data;
 1294         switch (go) {
 1295         case PCMTRIG_EMLDMAWR:
 1296         case PCMTRIG_EMLDMARD:
 1297                 break;
 1298         case PCMTRIG_START:
 1299                 cs4231_trigger(ch);
 1300                 break;
 1301         case PCMTRIG_ABORT:
 1302         case PCMTRIG_STOP:
 1303                 cs4231_halt(ch);
 1304                 break;
 1305         default:
 1306                 break;
 1307         }
 1308 
 1309         return (0);
 1310 }
 1311 
 1312 static int
 1313 cs4231_chan_getptr(kobj_t obj, void *data)
 1314 {
 1315         struct cs4231_softc *sc;
 1316         struct cs4231_channel *ch;
 1317         u_int32_t cur;
 1318         int ptr, sz;
 1319 
 1320         ch = data;
 1321         sc = ch->parent;
 1322 
 1323         CS4231_LOCK(sc);
 1324         if ((sc->sc_flags & CS4231_SBUS) != 0)
 1325                 cur = (ch->dir == PCMDIR_PLAY) ? APC_READ(sc, APC_PVA) :
 1326                     APC_READ(sc, APC_CVA);
 1327         else
 1328                 cur = (ch->dir == PCMDIR_PLAY) ? EBDMA_P_READ(sc, EBDMA_DADDR) :
 1329                         EBDMA_C_READ(sc, EBDMA_DADDR);
 1330         sz = sndbuf_getsize(ch->buffer);
 1331         ptr = cur - sndbuf_getbufaddr(ch->buffer) + sz;
 1332         CS4231_UNLOCK(sc);
 1333 
 1334         ptr %= sz;
 1335         return (ptr);
 1336 }
 1337 
 1338 static struct pcmchan_caps *
 1339 cs4231_chan_getcaps(kobj_t obj, void *data)
 1340 {
 1341 
 1342         return (&cs4231_caps);
 1343 }
 1344 
 1345 static void
 1346 cs4231_trigger(struct cs4231_channel *ch)
 1347 {
 1348         struct cs4231_softc *sc;
 1349 
 1350         sc = ch->parent;
 1351         if ((sc->sc_flags & CS4231_SBUS) != 0)
 1352                 cs4231_apcdma_trigger(sc, ch);
 1353         else
 1354                 cs4231_ebdma_trigger(sc, ch);
 1355 }
 1356 
 1357 static void
 1358 cs4231_apcdma_trigger(struct cs4231_softc *sc, struct cs4231_channel *ch)
 1359 {
 1360         u_int32_t csr, togo;
 1361         u_int32_t nextaddr;
 1362 
 1363         CS4231_LOCK(sc);
 1364         if (ch->locked) {
 1365                 device_printf(sc->sc_dev, "%s channel already triggered\n",
 1366                     ch->dir == PCMDIR_PLAY ? "playback" : "capture");
 1367                 CS4231_UNLOCK(sc);
 1368                 return;
 1369         }
 1370 
 1371         nextaddr = sndbuf_getbufaddr(ch->buffer);
 1372         togo = sndbuf_getsize(ch->buffer) / 2;
 1373         if (togo > CS4231_MAX_APC_DMA_SZ)
 1374                 togo = CS4231_MAX_APC_DMA_SZ;
 1375         ch->togo = togo;
 1376         if (ch->dir == PCMDIR_PLAY) {
 1377                 DPRINTF(("TRG: PNVA = 0x%x, togo = 0x%x\n", nextaddr, togo));
 1378 
 1379                 cs4231_read(sc, CS_TEST_AND_INIT); /* clear pending error */
 1380                 csr = APC_READ(sc, APC_CSR);
 1381                 APC_WRITE(sc, APC_PNVA, nextaddr);
 1382                 APC_WRITE(sc, APC_PNC, togo);
 1383                         
 1384                 if ((csr & APC_CSR_PDMA_GO) == 0 ||
 1385                     (csr & APC_CSR_PPAUSE) != 0) {
 1386                         APC_WRITE(sc, APC_CSR, APC_READ(sc, APC_CSR) &
 1387                             ~(APC_CSR_PIE | APC_CSR_PPAUSE));
 1388                         APC_WRITE(sc, APC_CSR, APC_READ(sc, APC_CSR) |
 1389                             APC_CSR_GIE | APC_CSR_PIE | APC_CSR_EIE |
 1390                             APC_CSR_EI | APC_CSR_PMIE | APC_CSR_PDMA_GO);
 1391                         cs4231_write(sc, CS_INTERFACE_CONFIG,
 1392                             cs4231_read(sc, CS_INTERFACE_CONFIG) |
 1393                             PLAYBACK_ENABLE);
 1394                 }
 1395                 /* load next address */
 1396                 if (APC_READ(sc, APC_CSR) & APC_CSR_PD) {
 1397                         nextaddr += togo;
 1398                         APC_WRITE(sc, APC_PNVA, nextaddr);
 1399                         APC_WRITE(sc, APC_PNC, togo);
 1400                 }
 1401         } else {
 1402                 DPRINTF(("TRG: CNVA = 0x%x, togo = 0x%x\n", nextaddr, togo));
 1403 
 1404                 cs4231_read(sc, CS_TEST_AND_INIT); /* clear pending error */
 1405                 APC_WRITE(sc, APC_CNVA, nextaddr);
 1406                 APC_WRITE(sc, APC_CNC, togo);
 1407                 csr = APC_READ(sc, APC_CSR);
 1408                 if ((csr & APC_CSR_CDMA_GO) == 0 ||
 1409                     (csr & APC_CSR_CPAUSE) != 0) {
 1410                         csr &= APC_CSR_CPAUSE;
 1411                         csr |= APC_CSR_GIE | APC_CSR_CMIE | APC_CSR_CIE |
 1412                             APC_CSR_EI | APC_CSR_CDMA_GO;
 1413                         APC_WRITE(sc, APC_CSR, csr);
 1414                         cs4231_write(sc, CS_INTERFACE_CONFIG,
 1415                             cs4231_read(sc, CS_INTERFACE_CONFIG) |
 1416                             CAPTURE_ENABLE);
 1417                 }
 1418                 /* load next address */
 1419                 if (APC_READ(sc, APC_CSR) & APC_CSR_CD) {
 1420                         nextaddr += togo;
 1421                         APC_WRITE(sc, APC_CNVA, nextaddr);
 1422                         APC_WRITE(sc, APC_CNC, togo);
 1423                 }
 1424         }
 1425         ch->nextaddr = nextaddr;
 1426         ch->locked = 1;
 1427         CS4231_UNLOCK(sc);
 1428 }
 1429 
 1430 static void
 1431 cs4231_ebdma_trigger(struct cs4231_softc *sc, struct cs4231_channel *ch)
 1432 {
 1433         u_int32_t csr, togo;
 1434         u_int32_t nextaddr;
 1435 
 1436         CS4231_LOCK(sc);
 1437         if (ch->locked) {
 1438                 device_printf(sc->sc_dev, "%s channel already triggered\n",
 1439                     ch->dir == PCMDIR_PLAY ? "playback" : "capture");
 1440                 CS4231_UNLOCK(sc);
 1441                 return;
 1442         }
 1443 
 1444         nextaddr = sndbuf_getbufaddr(ch->buffer);
 1445         togo = sndbuf_getsize(ch->buffer) / 2;
 1446         if (togo % 64 == 0)
 1447                 sc->sc_burst = EBDCSR_BURST_16;
 1448         else if (togo % 32 == 0)
 1449                 sc->sc_burst = EBDCSR_BURST_8;
 1450         else if (togo % 16 == 0)
 1451                 sc->sc_burst = EBDCSR_BURST_4;
 1452         else 
 1453                 sc->sc_burst = EBDCSR_BURST_1;
 1454         ch->togo = togo;
 1455         DPRINTF(("TRG: DNAR = 0x%x, togo = 0x%x\n", nextaddr, togo));
 1456         if (ch->dir == PCMDIR_PLAY) {
 1457                 cs4231_read(sc, CS_TEST_AND_INIT); /* clear pending error */
 1458                 csr = EBDMA_P_READ(sc, EBDMA_DCSR);
 1459 
 1460                 if (csr & EBDCSR_DMAEN) {
 1461                         EBDMA_P_WRITE(sc, EBDMA_DCNT, togo);
 1462                         EBDMA_P_WRITE(sc, EBDMA_DADDR, nextaddr);
 1463                 } else {
 1464                         EBDMA_P_WRITE(sc, EBDMA_DCSR, EBDCSR_RESET);
 1465                         EBDMA_P_WRITE(sc, EBDMA_DCSR, sc->sc_burst);
 1466                         EBDMA_P_WRITE(sc, EBDMA_DCNT, togo);
 1467                         EBDMA_P_WRITE(sc, EBDMA_DADDR, nextaddr);
 1468 
 1469                         EBDMA_P_WRITE(sc, EBDMA_DCSR, sc->sc_burst |
 1470                             EBDCSR_DMAEN | EBDCSR_INTEN | EBDCSR_CNTEN |
 1471                             EBDCSR_NEXTEN);
 1472                         cs4231_write(sc, CS_INTERFACE_CONFIG,
 1473                             cs4231_read(sc, CS_INTERFACE_CONFIG) |
 1474                             PLAYBACK_ENABLE);
 1475                 }
 1476                 /* load next address */
 1477                 if (EBDMA_P_READ(sc, EBDMA_DCSR) & EBDCSR_A_LOADED) {
 1478                         nextaddr += togo;
 1479                         EBDMA_P_WRITE(sc, EBDMA_DCNT, togo);
 1480                         EBDMA_P_WRITE(sc, EBDMA_DADDR, nextaddr);
 1481                 }
 1482         } else {
 1483                 cs4231_read(sc, CS_TEST_AND_INIT); /* clear pending error */
 1484                 csr = EBDMA_C_READ(sc, EBDMA_DCSR);
 1485 
 1486                 if (csr & EBDCSR_DMAEN) {
 1487                         EBDMA_C_WRITE(sc, EBDMA_DCNT, togo);
 1488                         EBDMA_C_WRITE(sc, EBDMA_DADDR, nextaddr);
 1489                 } else {
 1490                         EBDMA_C_WRITE(sc, EBDMA_DCSR, EBDCSR_RESET);
 1491                         EBDMA_C_WRITE(sc, EBDMA_DCSR, sc->sc_burst);
 1492                         EBDMA_C_WRITE(sc, EBDMA_DCNT, togo);
 1493                         EBDMA_C_WRITE(sc, EBDMA_DADDR, nextaddr);
 1494 
 1495                         EBDMA_C_WRITE(sc, EBDMA_DCSR, sc->sc_burst |
 1496                             EBDCSR_WRITE | EBDCSR_DMAEN | EBDCSR_INTEN |
 1497                             EBDCSR_CNTEN | EBDCSR_NEXTEN);
 1498                         cs4231_write(sc, CS_INTERFACE_CONFIG,
 1499                             cs4231_read(sc, CS_INTERFACE_CONFIG) |
 1500                             CAPTURE_ENABLE);
 1501                 }
 1502                 /* load next address */
 1503                 if (EBDMA_C_READ(sc, EBDMA_DCSR) & EBDCSR_A_LOADED) {
 1504                         nextaddr += togo;
 1505                         EBDMA_C_WRITE(sc, EBDMA_DCNT, togo);
 1506                         EBDMA_C_WRITE(sc, EBDMA_DADDR, nextaddr);
 1507                 }
 1508         }
 1509         ch->nextaddr = nextaddr;
 1510         ch->locked = 1;
 1511         CS4231_UNLOCK(sc);
 1512 }
 1513 
 1514 static void
 1515 cs4231_halt(struct cs4231_channel *ch)
 1516 {
 1517         struct cs4231_softc *sc;
 1518         u_int8_t status;
 1519         int i;
 1520 
 1521         sc = ch->parent;
 1522         CS4231_LOCK(sc);
 1523         if (ch->locked == 0) {
 1524                 CS4231_UNLOCK(sc);
 1525                 return;
 1526         }
 1527 
 1528         if (ch->dir == PCMDIR_PLAY ) {
 1529                 if ((sc->sc_flags & CS4231_SBUS) != 0) {
 1530                         /* XXX Kills some capture bits */
 1531                         APC_WRITE(sc, APC_CSR, APC_READ(sc, APC_CSR) &
 1532                             ~(APC_CSR_EI | APC_CSR_GIE | APC_CSR_PIE |
 1533                             APC_CSR_EIE | APC_CSR_PDMA_GO | APC_CSR_PMIE));
 1534                 } else {
 1535                         EBDMA_P_WRITE(sc, EBDMA_DCSR,
 1536                             EBDMA_P_READ(sc, EBDMA_DCSR) & ~EBDCSR_DMAEN);
 1537                 }
 1538                 /* Waiting for playback FIFO to empty */
 1539                 status = cs4231_read(sc, CS_TEST_AND_INIT);
 1540                 for (i = CS_TIMEOUT;
 1541                     i && (status & PLAYBACK_UNDERRUN) == 0; i--) {
 1542                         DELAY(5);
 1543                         status = cs4231_read(sc, CS_TEST_AND_INIT);
 1544                 }
 1545                 if (i == 0)
 1546                         device_printf(sc->sc_dev, "timeout waiting for "
 1547                             "playback FIFO drain\n");
 1548                 cs4231_write(sc, CS_INTERFACE_CONFIG,
 1549                     cs4231_read(sc, CS_INTERFACE_CONFIG) & (~PLAYBACK_ENABLE));
 1550         } else {
 1551                 if ((sc->sc_flags & CS4231_SBUS) != 0) {
 1552                         /* XXX Kills some playback bits */
 1553                         APC_WRITE(sc, APC_CSR, APC_CSR_CAPTURE_PAUSE);
 1554                 } else {
 1555                         EBDMA_C_WRITE(sc, EBDMA_DCSR,
 1556                             EBDMA_C_READ(sc, EBDMA_DCSR) & ~EBDCSR_DMAEN);
 1557                 }
 1558                 /* Waiting for capture FIFO to empty */
 1559                 status = cs4231_read(sc, CS_TEST_AND_INIT);
 1560                 for (i = CS_TIMEOUT;
 1561                     i && (status & CAPTURE_OVERRUN) == 0; i--) {
 1562                         DELAY(5);
 1563                         status = cs4231_read(sc, CS_TEST_AND_INIT);
 1564                 }
 1565                 if (i == 0)
 1566                         device_printf(sc->sc_dev, "timeout waiting for "
 1567                             "capture FIFO drain\n");
 1568                 cs4231_write(sc, CS_INTERFACE_CONFIG,
 1569                     cs4231_read(sc, CS_INTERFACE_CONFIG) & (~CAPTURE_ENABLE));
 1570         }
 1571         ch->locked = 0;
 1572         CS4231_UNLOCK(sc);
 1573 }

Cache object: 6ebecd32fbc307026ccc12e6f5268252


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