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/ic/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 /*      $NetBSD: cs4231.c,v 1.23 2008/04/28 20:23:49 martin Exp $       */
    2 
    3 /*-
    4  * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Paul Kranenburg.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __KERNEL_RCSID(0, "$NetBSD: cs4231.c,v 1.23 2008/04/28 20:23:49 martin Exp $");
   34 
   35 #include "audio.h"
   36 #if NAUDIO > 0
   37 
   38 #include <sys/param.h>
   39 #include <sys/systm.h>
   40 #include <sys/errno.h>
   41 #include <sys/device.h>
   42 #include <sys/malloc.h>
   43 
   44 #include <machine/autoconf.h>
   45 #include <machine/bus.h>
   46 #include <sys/cpu.h>
   47 
   48 #include <sys/audioio.h>
   49 #include <dev/audio_if.h>
   50 
   51 #include <dev/ic/ad1848reg.h>
   52 #include <dev/ic/cs4231reg.h>
   53 #include <dev/ic/ad1848var.h>
   54 #include <dev/ic/cs4231var.h>
   55 
   56 /*---*/
   57 #define CSAUDIO_DAC_LVL         0
   58 #define CSAUDIO_LINE_IN_LVL     1
   59 #define CSAUDIO_MONO_LVL        2
   60 #define CSAUDIO_CD_LVL          3
   61 #define CSAUDIO_OUTPUT_LVL      4
   62 #define CSAUDIO_OUT_LVL         5
   63 #define CSAUDIO_LINE_IN_MUTE    6
   64 #define CSAUDIO_DAC_MUTE        7
   65 #define CSAUDIO_CD_MUTE         8
   66 #define CSAUDIO_MONO_MUTE       9
   67 #define CSAUDIO_OUTPUT_MUTE     10
   68 #define CSAUDIO_OUT_MUTE        11
   69 #define CSAUDIO_REC_LVL         12
   70 #define CSAUDIO_RECORD_SOURCE   13
   71 
   72 #define CSAUDIO_INPUT_CLASS     14
   73 #define CSAUDIO_MONITOR_CLASS   15
   74 #define CSAUDIO_RECORD_CLASS    16
   75 
   76 #ifdef AUDIO_DEBUG
   77 int     cs4231_debug = 0;
   78 #define DPRINTF(x)      if (cs4231_debug) printf x
   79 #else
   80 #define DPRINTF(x)
   81 #endif
   82 
   83 struct audio_device cs4231_device = {
   84         "cs4231",
   85         "x",
   86         "audio"
   87 };
   88 
   89 
   90 /* ad1848 sc_{read,write}reg */
   91 static int      cs4231_read(struct ad1848_softc *, int);
   92 static void     cs4231_write(struct ad1848_softc *, int, int);
   93 
   94 int
   95 cs4231_read(struct ad1848_softc *sc, int index)
   96 {
   97 
   98         return bus_space_read_1(sc->sc_iot, sc->sc_ioh, (index << 2));
   99 }
  100 
  101 void
  102 cs4231_write(struct ad1848_softc *sc, int index, int value)
  103 {
  104 
  105         bus_space_write_1(sc->sc_iot, sc->sc_ioh, (index << 2), value);
  106 }
  107 
  108 
  109 void
  110 cs4231_common_attach(struct cs4231_softc *sc, bus_space_handle_t ioh)
  111 {
  112         char *buf;
  113         int reg;
  114 
  115         sc->sc_ad1848.parent = sc;
  116         sc->sc_ad1848.sc_iot = sc->sc_bustag;
  117         sc->sc_ad1848.sc_ioh = ioh;
  118         sc->sc_ad1848.sc_readreg = cs4231_read;
  119         sc->sc_ad1848.sc_writereg = cs4231_write;
  120 
  121         sc->sc_playback.t_name = "playback";
  122         sc->sc_capture.t_name = "capture";
  123 
  124         evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR,
  125                              NULL,
  126                              device_xname(&sc->sc_ad1848.sc_dev), "total");
  127 
  128         evcnt_attach_dynamic(&sc->sc_playback.t_intrcnt, EVCNT_TYPE_INTR,
  129                              &sc->sc_intrcnt,
  130                              device_xname(&sc->sc_ad1848.sc_dev), "playback");
  131 
  132         evcnt_attach_dynamic(&sc->sc_playback.t_ierrcnt, EVCNT_TYPE_INTR,
  133                              &sc->sc_intrcnt,
  134                              device_xname(&sc->sc_ad1848.sc_dev), "perrors");
  135 
  136         evcnt_attach_dynamic(&sc->sc_capture.t_intrcnt, EVCNT_TYPE_INTR,
  137                              &sc->sc_intrcnt,
  138                              device_xname(&sc->sc_ad1848.sc_dev), "capture");
  139 
  140         evcnt_attach_dynamic(&sc->sc_capture.t_ierrcnt, EVCNT_TYPE_INTR,
  141                              &sc->sc_intrcnt,
  142                              device_xname(&sc->sc_ad1848.sc_dev), "cerrors");
  143 
  144         /* put chip in native mode to access (extended) ID register */
  145         reg = ad_read(&sc->sc_ad1848, SP_MISC_INFO);
  146         ad_write(&sc->sc_ad1848, SP_MISC_INFO, reg | MODE2);
  147 
  148         /* read version numbers from I25 */
  149         reg = ad_read(&sc->sc_ad1848, CS_VERSION_ID);
  150         switch (reg & (CS_VERSION_NUMBER | CS_VERSION_CHIPID)) {
  151         case 0xa0:
  152                 sc->sc_ad1848.chip_name = "CS4231A";
  153                 break;
  154         case 0x80:
  155                 sc->sc_ad1848.chip_name = "CS4231";
  156                 break;
  157         case 0x82:
  158                 sc->sc_ad1848.chip_name = "CS4232";
  159                 break;
  160         case 0xa2:
  161                 sc->sc_ad1848.chip_name = "CS4232C";
  162                 break;
  163         default:
  164                 if ((buf = malloc(32, M_TEMP, M_NOWAIT)) != NULL) {
  165                         snprintf(buf, 32, "unknown rev: %x/%x",
  166                             reg&0xe0, reg&7);
  167                         sc->sc_ad1848.chip_name = buf;
  168                 }
  169         }
  170 
  171         sc->sc_ad1848.mode = 2; /* put ad1848 driver in `MODE 2' mode */
  172         ad1848_attach(&sc->sc_ad1848);
  173 }
  174 
  175 void *
  176 cs4231_malloc(void *addr, int direction, size_t size,
  177     struct malloc_type *pool, int flags)
  178 {
  179         struct cs4231_softc *sc;
  180         bus_dma_tag_t dmatag;
  181         struct cs_dma *p;
  182 
  183         sc = addr;
  184         dmatag = sc->sc_dmatag;
  185         p = malloc(sizeof(*p), pool, flags);
  186         if (p == NULL)
  187                 return NULL;
  188 
  189         /* Allocate a DMA map */
  190         if (bus_dmamap_create(dmatag, size, 1, size, 0,
  191             BUS_DMA_NOWAIT, &p->dmamap) != 0)
  192                 goto fail1;
  193 
  194         /* Allocate DMA memory */
  195         p->size = size;
  196         if (bus_dmamem_alloc(dmatag, size, 64*1024, 0,
  197             p->segs, sizeof(p->segs)/sizeof(p->segs[0]),
  198             &p->nsegs, BUS_DMA_NOWAIT) != 0)
  199                 goto fail2;
  200 
  201         /* Map DMA memory into kernel space */
  202         if (bus_dmamem_map(dmatag, p->segs, p->nsegs, p->size,
  203             &p->addr, BUS_DMA_NOWAIT|BUS_DMA_COHERENT) != 0)
  204                 goto fail3;
  205 
  206         /* Load the buffer */
  207         if (bus_dmamap_load(dmatag, p->dmamap,
  208             p->addr, size, NULL, BUS_DMA_NOWAIT) != 0)
  209                 goto fail4;
  210 
  211         p->next = sc->sc_dmas;
  212         sc->sc_dmas = p;
  213         return p->addr;
  214 
  215 fail4:
  216         bus_dmamem_unmap(dmatag, p->addr, p->size);
  217 fail3:
  218         bus_dmamem_free(dmatag, p->segs, p->nsegs);
  219 fail2:
  220         bus_dmamap_destroy(dmatag, p->dmamap);
  221 fail1:
  222         free(p, pool);
  223         return NULL;
  224 }
  225 
  226 void
  227 cs4231_free(void *addr, void *ptr, struct malloc_type *pool)
  228 {
  229         struct cs4231_softc *sc;
  230         bus_dma_tag_t dmatag;
  231         struct cs_dma *p, **pp;
  232 
  233         sc = addr;
  234         dmatag = sc->sc_dmatag;
  235         for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &(*pp)->next) {
  236                 if (p->addr != ptr)
  237                         continue;
  238                 bus_dmamap_unload(dmatag, p->dmamap);
  239                 bus_dmamem_unmap(dmatag, p->addr, p->size);
  240                 bus_dmamem_free(dmatag, p->segs, p->nsegs);
  241                 bus_dmamap_destroy(dmatag, p->dmamap);
  242                 *pp = p->next;
  243                 free(p, pool);
  244                 return;
  245         }
  246         printf("cs4231_free: rogue pointer\n");
  247 }
  248 
  249 
  250 /*
  251  * Set up transfer and return DMA address and byte count in paddr and psize
  252  * for bus dependent trigger_{in,out}put to load into the DMA controller.
  253  */
  254 int
  255 cs4231_transfer_init(
  256         struct cs4231_softc *sc,
  257         struct cs_transfer *t,
  258         bus_addr_t *paddr,
  259         bus_size_t *psize,
  260         void *start, void *end,
  261         int blksize,
  262         void (*intr)(void *),
  263         void *arg)
  264 {
  265         struct cs_dma *p;
  266         vsize_t n;
  267 
  268         if (t->t_active) {
  269                 printf("%s: %s already running\n",
  270                        device_xname(&sc->sc_ad1848.sc_dev), t->t_name);
  271                 return EINVAL;
  272         }
  273 
  274         t->t_intr = intr;
  275         t->t_arg = arg;
  276 
  277         for (p = sc->sc_dmas; p != NULL && p->addr != start; p = p->next)
  278                 continue;
  279         if (p == NULL) {
  280                 printf("%s: bad %s addr %p\n",
  281                        device_xname(&sc->sc_ad1848.sc_dev), t->t_name, start);
  282                 return EINVAL;
  283         }
  284 
  285         n = (char *)end - (char *)start;
  286 
  287         t->t_dma = p;           /* the DMA memory segment */
  288         t->t_segsz = n;         /* size of DMA segment */
  289         t->t_blksz = blksize;   /* do transfers in blksize chunks */
  290 
  291         if (n > t->t_blksz)
  292                 n = t->t_blksz;
  293 
  294         t->t_cnt = n;
  295 
  296         /* for caller to load into DMA controller */
  297         *paddr = t->t_dma->dmamap->dm_segs[0].ds_addr;
  298         *psize = n;
  299 
  300         DPRINTF(("%s: init %s: [%p..%p] %lu bytes %lu blocks;"
  301                  " DMA at 0x%lx count %lu\n",
  302                  device_xname(&sc->sc_ad1848.sc_dev), t->t_name,
  303                  start, end, (u_long)t->t_segsz, (u_long)t->t_blksz,
  304                  (u_long)*paddr, (u_long)*psize));
  305 
  306         t->t_active = 1;
  307         return 0;
  308 }
  309 
  310 /*
  311  * Compute next DMA address/counter, update transfer status.
  312  */
  313 void
  314 cs4231_transfer_advance(struct cs_transfer *t, bus_addr_t *paddr,
  315     bus_size_t *psize)
  316 {
  317         bus_addr_t dmabase, nextaddr;
  318         bus_size_t togo;
  319 
  320         dmabase = t->t_dma->dmamap->dm_segs[0].ds_addr;
  321 
  322         togo = t->t_segsz - t->t_cnt;
  323         if (togo == 0) {        /* roll over */
  324                 nextaddr = dmabase;
  325                 t->t_cnt = togo = t->t_blksz;
  326         } else {
  327                 nextaddr = dmabase + t->t_cnt;
  328                 if (togo > t->t_blksz)
  329                         togo = t->t_blksz;
  330                 t->t_cnt += togo;
  331         }
  332 
  333         /* for caller to load into DMA controller */
  334         *paddr = nextaddr;
  335         *psize = togo;
  336 }
  337 
  338 
  339 int
  340 cs4231_open(void *addr, int flags)
  341 {
  342         struct cs4231_softc *sc;
  343 
  344         sc = addr;
  345         DPRINTF(("sa_open: unit %p\n", sc));
  346 
  347         sc->sc_playback.t_active = 0;
  348         sc->sc_playback.t_intr = NULL;
  349         sc->sc_playback.t_arg = NULL;
  350 
  351         sc->sc_capture.t_active = 0;
  352         sc->sc_capture.t_intr = NULL;
  353         sc->sc_capture.t_arg = NULL;
  354 
  355         /* no interrupts from ad1848 */
  356         ad_write(&sc->sc_ad1848, SP_PIN_CONTROL, 0);
  357         ad1848_reset(&sc->sc_ad1848);
  358 
  359         DPRINTF(("sa_open: ok -> sc=%p\n", sc));
  360         return 0;
  361 }
  362 
  363 void
  364 cs4231_close(void *addr)
  365 {
  366 
  367         DPRINTF(("sa_close: sc=%p\n", addr));
  368 
  369         /* audio(9) already called halt methods */
  370 
  371         DPRINTF(("sa_close: closed.\n"));
  372 }
  373 
  374 int
  375 cs4231_getdev(void *addr, struct audio_device *retp)
  376 {
  377 
  378         *retp = cs4231_device;
  379         return 0;
  380 }
  381 
  382 static const ad1848_devmap_t csmapping[] = {
  383         { CSAUDIO_DAC_LVL, AD1848_KIND_LVL, AD1848_AUX1_CHANNEL },
  384         { CSAUDIO_LINE_IN_LVL, AD1848_KIND_LVL, AD1848_LINE_CHANNEL },
  385         { CSAUDIO_MONO_LVL, AD1848_KIND_LVL, AD1848_MONO_CHANNEL },
  386         { CSAUDIO_CD_LVL, AD1848_KIND_LVL, AD1848_AUX2_CHANNEL },
  387         { CSAUDIO_OUTPUT_LVL, AD1848_KIND_LVL, AD1848_MONITOR_CHANNEL },
  388         { CSAUDIO_OUT_LVL, AD1848_KIND_LVL, AD1848_DAC_CHANNEL },
  389         { CSAUDIO_DAC_MUTE, AD1848_KIND_MUTE, AD1848_AUX1_CHANNEL },
  390         { CSAUDIO_LINE_IN_MUTE, AD1848_KIND_MUTE, AD1848_LINE_CHANNEL },
  391         { CSAUDIO_MONO_MUTE, AD1848_KIND_MUTE, AD1848_MONO_CHANNEL },
  392         { CSAUDIO_CD_MUTE, AD1848_KIND_MUTE, AD1848_AUX2_CHANNEL },
  393         { CSAUDIO_OUTPUT_MUTE, AD1848_KIND_MUTE, AD1848_MONITOR_CHANNEL },
  394         { CSAUDIO_OUT_MUTE, AD1848_KIND_MUTE, AD1848_OUT_CHANNEL },
  395         { CSAUDIO_REC_LVL, AD1848_KIND_RECORDGAIN, -1 },
  396         { CSAUDIO_RECORD_SOURCE, AD1848_KIND_RECORDSOURCE, -1 }
  397 };
  398 
  399 static int nummap = sizeof(csmapping) / sizeof(csmapping[0]);
  400 
  401 
  402 int
  403 cs4231_set_port(void *addr, mixer_ctrl_t *cp)
  404 {
  405         struct ad1848_softc *ac;
  406 
  407         DPRINTF(("cs4231_set_port: port=%d", cp->dev));
  408         ac = addr;
  409         return ad1848_mixer_set_port(ac, csmapping, nummap, cp);
  410 }
  411 
  412 int
  413 cs4231_get_port(void *addr, mixer_ctrl_t *cp)
  414 {
  415         struct ad1848_softc *ac;
  416 
  417         DPRINTF(("cs4231_get_port: port=%d", cp->dev));
  418         ac = addr;
  419         return ad1848_mixer_get_port(ac, csmapping, nummap, cp);
  420 }
  421 
  422 int
  423 cs4231_get_props(void *addr)
  424 {
  425 
  426         return AUDIO_PROP_FULLDUPLEX;
  427 }
  428 
  429 int
  430 cs4231_query_devinfo(void *addr, mixer_devinfo_t *dip)
  431 {
  432 
  433         switch(dip->index) {
  434 
  435         case CSAUDIO_DAC_LVL:           /*  dacout */
  436                 dip->type = AUDIO_MIXER_VALUE;
  437                 dip->mixer_class = CSAUDIO_INPUT_CLASS;
  438                 dip->prev = AUDIO_MIXER_LAST;
  439                 dip->next = CSAUDIO_DAC_MUTE;
  440                 strcpy(dip->label.name, AudioNdac);
  441                 dip->un.v.num_channels = 2;
  442                 strcpy(dip->un.v.units.name, AudioNvolume);
  443                 break;
  444 
  445         case CSAUDIO_LINE_IN_LVL:       /* line */
  446                 dip->type = AUDIO_MIXER_VALUE;
  447                 dip->mixer_class = CSAUDIO_INPUT_CLASS;
  448                 dip->prev = AUDIO_MIXER_LAST;
  449                 dip->next = CSAUDIO_LINE_IN_MUTE;
  450                 strcpy(dip->label.name, AudioNline);
  451                 dip->un.v.num_channels = 2;
  452                 strcpy(dip->un.v.units.name, AudioNvolume);
  453                 break;
  454 
  455         case CSAUDIO_MONO_LVL:  /* mono/microphone mixer */
  456                 dip->type = AUDIO_MIXER_VALUE;
  457                 dip->mixer_class = CSAUDIO_INPUT_CLASS;
  458                 dip->prev = AUDIO_MIXER_LAST;
  459                 dip->next = CSAUDIO_MONO_MUTE;
  460                 strcpy(dip->label.name, AudioNmicrophone);
  461                 dip->un.v.num_channels = 1;
  462                 strcpy(dip->un.v.units.name, AudioNvolume);
  463                 break;
  464 
  465         case CSAUDIO_CD_LVL:            /* cd */
  466                 dip->type = AUDIO_MIXER_VALUE;
  467                 dip->mixer_class = CSAUDIO_INPUT_CLASS;
  468                 dip->prev = AUDIO_MIXER_LAST;
  469                 dip->next = CSAUDIO_CD_MUTE;
  470                 strcpy(dip->label.name, AudioNcd);
  471                 dip->un.v.num_channels = 2;
  472                 strcpy(dip->un.v.units.name, AudioNvolume);
  473                 break;
  474 
  475 
  476         case CSAUDIO_OUTPUT_LVL:        /* monitor level */
  477                 dip->type = AUDIO_MIXER_VALUE;
  478                 dip->mixer_class = CSAUDIO_MONITOR_CLASS;
  479                 dip->next = CSAUDIO_OUTPUT_MUTE;
  480                 dip->prev = AUDIO_MIXER_LAST;
  481                 strcpy(dip->label.name, AudioNmonitor);
  482                 dip->un.v.num_channels = 1;
  483                 strcpy(dip->un.v.units.name, AudioNvolume);
  484                 break;
  485 
  486         case CSAUDIO_OUT_LVL:           /* cs4231 output volume */
  487                 dip->type = AUDIO_MIXER_VALUE;
  488                 dip->mixer_class = CSAUDIO_MONITOR_CLASS;
  489                 dip->next = dip->prev = AUDIO_MIXER_LAST;
  490                 strcpy(dip->label.name, AudioNmaster);
  491                 dip->un.v.num_channels = 2;
  492                 strcpy(dip->un.v.units.name, AudioNvolume);
  493                 break;
  494 
  495         case CSAUDIO_OUT_MUTE: /* mute built-in speaker */
  496                 dip->mixer_class = CSAUDIO_MONITOR_CLASS;
  497                 dip->type = AUDIO_MIXER_ENUM;
  498                 dip->prev = CSAUDIO_MONITOR_CLASS;
  499                 dip->next = AUDIO_MIXER_LAST;
  500                 strcpy(dip->label.name, AudioNmono);
  501                 /* names reversed, this is a "mute" value used as "mono enabled" */
  502                 dip->un.e.num_mem = 2;
  503                 strcpy(dip->un.e.member[0].label.name, AudioNon);
  504                 dip->un.e.member[0].ord = 0;
  505                 strcpy(dip->un.e.member[1].label.name, AudioNoff);
  506                 dip->un.e.member[1].ord = 1;
  507                 break;
  508 
  509         case CSAUDIO_LINE_IN_MUTE:
  510                 dip->mixer_class = CSAUDIO_INPUT_CLASS;
  511                 dip->type = AUDIO_MIXER_ENUM;
  512                 dip->prev = CSAUDIO_LINE_IN_LVL;
  513                 dip->next = AUDIO_MIXER_LAST;
  514                 goto mute;
  515 
  516         case CSAUDIO_DAC_MUTE:
  517                 dip->mixer_class = CSAUDIO_INPUT_CLASS;
  518                 dip->type = AUDIO_MIXER_ENUM;
  519                 dip->prev = CSAUDIO_DAC_LVL;
  520                 dip->next = AUDIO_MIXER_LAST;
  521                 goto mute;
  522 
  523         case CSAUDIO_CD_MUTE:
  524                 dip->mixer_class = CSAUDIO_INPUT_CLASS;
  525                 dip->type = AUDIO_MIXER_ENUM;
  526                 dip->prev = CSAUDIO_CD_LVL;
  527                 dip->next = AUDIO_MIXER_LAST;
  528                 goto mute;
  529 
  530         case CSAUDIO_MONO_MUTE:
  531                 dip->mixer_class = CSAUDIO_INPUT_CLASS;
  532                 dip->type = AUDIO_MIXER_ENUM;
  533                 dip->prev = CSAUDIO_MONO_LVL;
  534                 dip->next = AUDIO_MIXER_LAST;
  535                 goto mute;
  536 
  537         case CSAUDIO_OUTPUT_MUTE:
  538                 dip->mixer_class = CSAUDIO_MONITOR_CLASS;
  539                 dip->type = AUDIO_MIXER_ENUM;
  540                 dip->prev = CSAUDIO_OUTPUT_LVL;
  541                 dip->next = AUDIO_MIXER_LAST;
  542         mute:
  543                 strcpy(dip->label.name, AudioNmute);
  544                 dip->un.e.num_mem = 2;
  545                 strcpy(dip->un.e.member[0].label.name, AudioNoff);
  546                 dip->un.e.member[0].ord = 0;
  547                 strcpy(dip->un.e.member[1].label.name, AudioNon);
  548                 dip->un.e.member[1].ord = 1;
  549                 break;
  550 
  551         case CSAUDIO_REC_LVL:   /* record level */
  552                 dip->type = AUDIO_MIXER_VALUE;
  553                 dip->mixer_class = CSAUDIO_RECORD_CLASS;
  554                 dip->prev = AUDIO_MIXER_LAST;
  555                 dip->next = CSAUDIO_RECORD_SOURCE;
  556                 strcpy(dip->label.name, AudioNrecord);
  557                 dip->un.v.num_channels = 2;
  558                 strcpy(dip->un.v.units.name, AudioNvolume);
  559                 break;
  560 
  561         case CSAUDIO_RECORD_SOURCE:
  562                 dip->mixer_class = CSAUDIO_RECORD_CLASS;
  563                 dip->type = AUDIO_MIXER_ENUM;
  564                 dip->prev = CSAUDIO_REC_LVL;
  565                 dip->next = AUDIO_MIXER_LAST;
  566                 strcpy(dip->label.name, AudioNsource);
  567                 dip->un.e.num_mem = 4;
  568                 strcpy(dip->un.e.member[0].label.name, AudioNoutput);
  569                 dip->un.e.member[0].ord = DAC_IN_PORT;
  570                 strcpy(dip->un.e.member[1].label.name, AudioNmicrophone);
  571                 dip->un.e.member[1].ord = MIC_IN_PORT;
  572                 strcpy(dip->un.e.member[2].label.name, AudioNdac);
  573                 dip->un.e.member[2].ord = AUX1_IN_PORT;
  574                 strcpy(dip->un.e.member[3].label.name, AudioNline);
  575                 dip->un.e.member[3].ord = LINE_IN_PORT;
  576                 break;
  577 
  578         case CSAUDIO_INPUT_CLASS:               /* input class descriptor */
  579                 dip->type = AUDIO_MIXER_CLASS;
  580                 dip->mixer_class = CSAUDIO_INPUT_CLASS;
  581                 dip->next = dip->prev = AUDIO_MIXER_LAST;
  582                 strcpy(dip->label.name, AudioCinputs);
  583                 break;
  584 
  585         case CSAUDIO_MONITOR_CLASS:             /* output class descriptor */
  586                 dip->type = AUDIO_MIXER_CLASS;
  587                 dip->mixer_class = CSAUDIO_MONITOR_CLASS;
  588                 dip->next = dip->prev = AUDIO_MIXER_LAST;
  589                 strcpy(dip->label.name, AudioCmonitor);
  590                 break;
  591 
  592         case CSAUDIO_RECORD_CLASS:              /* record source class */
  593                 dip->type = AUDIO_MIXER_CLASS;
  594                 dip->mixer_class = CSAUDIO_RECORD_CLASS;
  595                 dip->next = dip->prev = AUDIO_MIXER_LAST;
  596                 strcpy(dip->label.name, AudioCrecord);
  597                 break;
  598 
  599         default:
  600                 return ENXIO;
  601                 /*NOTREACHED*/
  602         }
  603         DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
  604 
  605         return 0;
  606 }
  607 
  608 #endif /* NAUDIO > 0 */

Cache object: 4109c020ec9c2fc39f8344cf6c886b43


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