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.32 2019/11/10 21:16:35 chs 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.32 2019/11/10 21:16:35 chs 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/bus.h>
   43 #include <sys/kmem.h>
   44 #include <sys/malloc.h>
   45 
   46 #include <machine/autoconf.h>
   47 #include <sys/cpu.h>
   48 
   49 #include <sys/audioio.h>
   50 #include <dev/audio/audio_if.h>
   51 
   52 #include <dev/ic/ad1848reg.h>
   53 #include <dev/ic/cs4231reg.h>
   54 #include <dev/ic/ad1848var.h>
   55 #include <dev/ic/cs4231var.h>
   56 
   57 /*---*/
   58 #define CSAUDIO_DAC_LVL         0
   59 #define CSAUDIO_LINE_IN_LVL     1
   60 #define CSAUDIO_MONO_LVL        2
   61 #define CSAUDIO_CD_LVL          3
   62 #define CSAUDIO_OUTPUT_LVL      4
   63 #define CSAUDIO_OUT_LVL         5
   64 #define CSAUDIO_LINE_IN_MUTE    6
   65 #define CSAUDIO_DAC_MUTE        7
   66 #define CSAUDIO_CD_MUTE         8
   67 #define CSAUDIO_MONO_MUTE       9
   68 #define CSAUDIO_OUTPUT_MUTE     10
   69 #define CSAUDIO_OUT_MUTE        11
   70 #define CSAUDIO_REC_LVL         12
   71 #define CSAUDIO_RECORD_SOURCE   13
   72 
   73 #define CSAUDIO_INPUT_CLASS     14
   74 #define CSAUDIO_MONITOR_CLASS   15
   75 #define CSAUDIO_RECORD_CLASS    16
   76 
   77 #ifdef AUDIO_DEBUG
   78 int     cs4231_debug = 0;
   79 #define DPRINTF(x)      if (cs4231_debug) printf x
   80 #else
   81 #define DPRINTF(x)
   82 #endif
   83 
   84 struct audio_device cs4231_device = {
   85         "cs4231",
   86         "x",
   87         "audio"
   88 };
   89 
   90 
   91 /* ad1848 sc_{read,write}reg */
   92 static int      cs4231_read(struct ad1848_softc *, int);
   93 static void     cs4231_write(struct ad1848_softc *, int, int);
   94 
   95 int
   96 cs4231_read(struct ad1848_softc *sc, int index)
   97 {
   98 
   99         return bus_space_read_1(sc->sc_iot, sc->sc_ioh, (index << 2));
  100 }
  101 
  102 void
  103 cs4231_write(struct ad1848_softc *sc, int index, int value)
  104 {
  105 
  106         bus_space_write_1(sc->sc_iot, sc->sc_ioh, (index << 2), value);
  107 }
  108 
  109 
  110 void
  111 cs4231_common_attach(struct cs4231_softc *sc, device_t self,
  112     bus_space_handle_t ioh)
  113 {
  114         char *buf;
  115         int reg;
  116 
  117         sc->sc_ad1848.parent = sc;
  118         sc->sc_ad1848.sc_dev = self;
  119         sc->sc_ad1848.sc_iot = sc->sc_bustag;
  120         sc->sc_ad1848.sc_ioh = ioh;
  121         sc->sc_ad1848.sc_readreg = cs4231_read;
  122         sc->sc_ad1848.sc_writereg = cs4231_write;
  123 
  124         sc->sc_playback.t_name = "playback";
  125         sc->sc_capture.t_name = "capture";
  126 
  127         evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR,
  128                              NULL,
  129                              device_xname(sc->sc_ad1848.sc_dev), "total");
  130 
  131         evcnt_attach_dynamic(&sc->sc_playback.t_intrcnt, EVCNT_TYPE_INTR,
  132                              &sc->sc_intrcnt,
  133                              device_xname(sc->sc_ad1848.sc_dev), "playback");
  134 
  135         evcnt_attach_dynamic(&sc->sc_playback.t_ierrcnt, EVCNT_TYPE_INTR,
  136                              &sc->sc_intrcnt,
  137                              device_xname(sc->sc_ad1848.sc_dev), "perrors");
  138 
  139         evcnt_attach_dynamic(&sc->sc_capture.t_intrcnt, EVCNT_TYPE_INTR,
  140                              &sc->sc_intrcnt,
  141                              device_xname(sc->sc_ad1848.sc_dev), "capture");
  142 
  143         evcnt_attach_dynamic(&sc->sc_capture.t_ierrcnt, EVCNT_TYPE_INTR,
  144                              &sc->sc_intrcnt,
  145                              device_xname(sc->sc_ad1848.sc_dev), "cerrors");
  146 
  147         /* put chip in native mode to access (extended) ID register */
  148         reg = ad_read(&sc->sc_ad1848, SP_MISC_INFO);
  149         ad_write(&sc->sc_ad1848, SP_MISC_INFO, reg | MODE2);
  150 
  151         /* read version numbers from I25 */
  152         reg = ad_read(&sc->sc_ad1848, CS_VERSION_ID);
  153         switch (reg & (CS_VERSION_NUMBER | CS_VERSION_CHIPID)) {
  154         case 0xa0:
  155                 sc->sc_ad1848.chip_name = "CS4231A";
  156                 break;
  157         case 0x80:
  158                 sc->sc_ad1848.chip_name = "CS4231";
  159                 break;
  160         case 0x82:
  161                 sc->sc_ad1848.chip_name = "CS4232";
  162                 break;
  163         case 0xa2:
  164                 sc->sc_ad1848.chip_name = "CS4232C";
  165                 break;
  166         default:
  167                 buf = malloc(32, M_TEMP, M_WAITOK);
  168                 snprintf(buf, 32, "unknown rev: %x/%x",
  169                     reg&0xe0, reg&7);
  170                 sc->sc_ad1848.chip_name = buf;
  171         }
  172 
  173         sc->sc_ad1848.mode = 2; /* put ad1848 driver in `MODE 2' mode */
  174         ad1848_attach(&sc->sc_ad1848);
  175 }
  176 
  177 void *
  178 cs4231_malloc(void *addr, int direction, size_t size)
  179 {
  180         struct cs4231_softc *sc;
  181         bus_dma_tag_t dmatag;
  182         struct cs_dma *p;
  183 
  184         sc = addr;
  185         dmatag = sc->sc_dmatag;
  186         p = kmem_alloc(sizeof(*p), KM_SLEEP);
  187 
  188         /* Allocate a DMA map */
  189         if (bus_dmamap_create(dmatag, size, 1, size, 0,
  190             BUS_DMA_NOWAIT, &p->dmamap) != 0)
  191                 goto fail1;
  192 
  193         /* Allocate DMA memory */
  194         p->size = size;
  195         if (bus_dmamem_alloc(dmatag, size, 64*1024, 0,
  196             p->segs, sizeof(p->segs)/sizeof(p->segs[0]),
  197             &p->nsegs, BUS_DMA_NOWAIT) != 0)
  198                 goto fail2;
  199 
  200         /* Map DMA memory into kernel space */
  201         if (bus_dmamem_map(dmatag, p->segs, p->nsegs, p->size,
  202             &p->addr, BUS_DMA_NOWAIT|BUS_DMA_COHERENT) != 0)
  203                 goto fail3;
  204 
  205         /* Load the buffer */
  206         if (bus_dmamap_load(dmatag, p->dmamap,
  207             p->addr, size, NULL, BUS_DMA_NOWAIT) != 0)
  208                 goto fail4;
  209 
  210         p->next = sc->sc_dmas;
  211         sc->sc_dmas = p;
  212         return p->addr;
  213 
  214 fail4:
  215         bus_dmamem_unmap(dmatag, p->addr, p->size);
  216 fail3:
  217         bus_dmamem_free(dmatag, p->segs, p->nsegs);
  218 fail2:
  219         bus_dmamap_destroy(dmatag, p->dmamap);
  220 fail1:
  221         kmem_free(p, sizeof(*p));
  222         return NULL;
  223 }
  224 
  225 void
  226 cs4231_free(void *addr, void *ptr, size_t size)
  227 {
  228         struct cs4231_softc *sc;
  229         bus_dma_tag_t dmatag;
  230         struct cs_dma *p, **pp;
  231 
  232         sc = addr;
  233         dmatag = sc->sc_dmatag;
  234         for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &(*pp)->next) {
  235                 if (p->addr != ptr)
  236                         continue;
  237                 bus_dmamap_unload(dmatag, p->dmamap);
  238                 bus_dmamem_unmap(dmatag, p->addr, p->size);
  239                 bus_dmamem_free(dmatag, p->segs, p->nsegs);
  240                 bus_dmamap_destroy(dmatag, p->dmamap);
  241                 *pp = p->next;
  242                 kmem_free(p, sizeof(*p));
  243                 return;
  244         }
  245         printf("cs4231_free: rogue pointer\n");
  246 }
  247 
  248 
  249 /*
  250  * Set up transfer and return DMA address and byte count in paddr and psize
  251  * for bus dependent trigger_{in,out}put to load into the DMA controller.
  252  */
  253 int
  254 cs4231_transfer_init(
  255         struct cs4231_softc *sc,
  256         struct cs_transfer *t,
  257         bus_addr_t *paddr,
  258         bus_size_t *psize,
  259         void *start, void *end,
  260         int blksize,
  261         void (*intr)(void *),
  262         void *arg)
  263 {
  264         struct cs_dma *p;
  265         vsize_t n;
  266 
  267         if (t->t_active) {
  268                 printf("%s: %s already running\n",
  269                        device_xname(sc->sc_ad1848.sc_dev), t->t_name);
  270                 return EINVAL;
  271         }
  272 
  273         t->t_intr = intr;
  274         t->t_arg = arg;
  275 
  276         for (p = sc->sc_dmas; p != NULL && p->addr != start; p = p->next)
  277                 continue;
  278         if (p == NULL) {
  279                 printf("%s: bad %s addr %p\n",
  280                        device_xname(sc->sc_ad1848.sc_dev), t->t_name, start);
  281                 return EINVAL;
  282         }
  283 
  284         n = (char *)end - (char *)start;
  285 
  286         t->t_dma = p;           /* the DMA memory segment */
  287         t->t_segsz = n;         /* size of DMA segment */
  288         t->t_blksz = blksize;   /* do transfers in blksize chunks */
  289 
  290         if (n > t->t_blksz)
  291                 n = t->t_blksz;
  292 
  293         t->t_cnt = n;
  294 
  295         /* for caller to load into DMA controller */
  296         *paddr = t->t_dma->dmamap->dm_segs[0].ds_addr;
  297         *psize = n;
  298 
  299         DPRINTF(("%s: init %s: [%p..%p] %lu bytes %lu blocks;"
  300                  " DMA at 0x%lx count %lu\n",
  301                  device_xname(sc->sc_ad1848.sc_dev), t->t_name,
  302                  start, end, (u_long)t->t_segsz, (u_long)t->t_blksz,
  303                  (u_long)*paddr, (u_long)*psize));
  304 
  305         t->t_active = 1;
  306         return 0;
  307 }
  308 
  309 /*
  310  * Compute next DMA address/counter, update transfer status.
  311  */
  312 void
  313 cs4231_transfer_advance(struct cs_transfer *t, bus_addr_t *paddr,
  314     bus_size_t *psize)
  315 {
  316         bus_addr_t dmabase, nextaddr;
  317         bus_size_t togo;
  318 
  319         dmabase = t->t_dma->dmamap->dm_segs[0].ds_addr;
  320 
  321         togo = t->t_segsz - t->t_cnt;
  322         if (togo == 0) {        /* roll over */
  323                 nextaddr = dmabase;
  324                 t->t_cnt = togo = t->t_blksz;
  325         } else {
  326                 nextaddr = dmabase + t->t_cnt;
  327                 if (togo > t->t_blksz)
  328                         togo = t->t_blksz;
  329                 t->t_cnt += togo;
  330         }
  331 
  332         /* for caller to load into DMA controller */
  333         *paddr = nextaddr;
  334         *psize = togo;
  335 }
  336 
  337 
  338 int
  339 cs4231_open(void *addr, int flags)
  340 {
  341         struct cs4231_softc *sc;
  342 
  343         sc = addr;
  344         DPRINTF(("sa_open: unit %p\n", sc));
  345 
  346         sc->sc_playback.t_active = 0;
  347         sc->sc_playback.t_intr = NULL;
  348         sc->sc_playback.t_arg = NULL;
  349 
  350         sc->sc_capture.t_active = 0;
  351         sc->sc_capture.t_intr = NULL;
  352         sc->sc_capture.t_arg = NULL;
  353 
  354         /* no interrupts from ad1848 */
  355         ad_write(&sc->sc_ad1848, SP_PIN_CONTROL, 0);
  356         ad1848_reset(&sc->sc_ad1848);
  357 
  358         DPRINTF(("sa_open: ok -> sc=%p\n", sc));
  359         return 0;
  360 }
  361 
  362 void
  363 cs4231_close(void *addr)
  364 {
  365 
  366         DPRINTF(("sa_close: sc=%p\n", addr));
  367 
  368         /* audio(9) already called halt methods */
  369 
  370         DPRINTF(("sa_close: closed.\n"));
  371 }
  372 
  373 int
  374 cs4231_getdev(void *addr, struct audio_device *retp)
  375 {
  376 
  377         *retp = cs4231_device;
  378         return 0;
  379 }
  380 
  381 static const ad1848_devmap_t csmapping[] = {
  382         { CSAUDIO_DAC_LVL, AD1848_KIND_LVL, AD1848_AUX1_CHANNEL },
  383         { CSAUDIO_LINE_IN_LVL, AD1848_KIND_LVL, AD1848_LINE_CHANNEL },
  384         { CSAUDIO_MONO_LVL, AD1848_KIND_LVL, AD1848_MONO_CHANNEL },
  385         { CSAUDIO_CD_LVL, AD1848_KIND_LVL, AD1848_AUX2_CHANNEL },
  386         { CSAUDIO_OUTPUT_LVL, AD1848_KIND_LVL, AD1848_MONITOR_CHANNEL },
  387         { CSAUDIO_OUT_LVL, AD1848_KIND_LVL, AD1848_DAC_CHANNEL },
  388         { CSAUDIO_DAC_MUTE, AD1848_KIND_MUTE, AD1848_AUX1_CHANNEL },
  389         { CSAUDIO_LINE_IN_MUTE, AD1848_KIND_MUTE, AD1848_LINE_CHANNEL },
  390         { CSAUDIO_MONO_MUTE, AD1848_KIND_MUTE, AD1848_MONO_CHANNEL },
  391         { CSAUDIO_CD_MUTE, AD1848_KIND_MUTE, AD1848_AUX2_CHANNEL },
  392         { CSAUDIO_OUTPUT_MUTE, AD1848_KIND_MUTE, AD1848_MONITOR_CHANNEL },
  393         { CSAUDIO_OUT_MUTE, AD1848_KIND_MUTE, AD1848_OUT_CHANNEL },
  394         { CSAUDIO_REC_LVL, AD1848_KIND_RECORDGAIN, -1 },
  395         { CSAUDIO_RECORD_SOURCE, AD1848_KIND_RECORDSOURCE, -1 }
  396 };
  397 
  398 static int nummap = sizeof(csmapping) / sizeof(csmapping[0]);
  399 
  400 
  401 int
  402 cs4231_set_port(void *addr, mixer_ctrl_t *cp)
  403 {
  404         struct ad1848_softc *ac;
  405 
  406         DPRINTF(("cs4231_set_port: port=%d", cp->dev));
  407         ac = addr;
  408         return ad1848_mixer_set_port(ac, csmapping, nummap, cp);
  409 }
  410 
  411 int
  412 cs4231_get_port(void *addr, mixer_ctrl_t *cp)
  413 {
  414         struct ad1848_softc *ac;
  415 
  416         DPRINTF(("cs4231_get_port: port=%d", cp->dev));
  417         ac = addr;
  418         return ad1848_mixer_get_port(ac, csmapping, nummap, cp);
  419 }
  420 
  421 int
  422 cs4231_get_props(void *addr)
  423 {
  424 
  425         return AUDIO_PROP_PLAYBACK | AUDIO_PROP_CAPTURE |
  426             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                 dip->un.v.delta = 16;
  493                 strcpy(dip->un.v.units.name, AudioNvolume);
  494                 break;
  495 
  496         case CSAUDIO_OUT_MUTE: /* mute built-in speaker */
  497                 dip->mixer_class = CSAUDIO_MONITOR_CLASS;
  498                 dip->type = AUDIO_MIXER_ENUM;
  499                 dip->prev = CSAUDIO_MONITOR_CLASS;
  500                 dip->next = AUDIO_MIXER_LAST;
  501                 strcpy(dip->label.name, AudioNmono);
  502                 /* names reversed, this is a "mute" value used as "mono enabled" */
  503                 dip->un.e.num_mem = 2;
  504                 strcpy(dip->un.e.member[0].label.name, AudioNon);
  505                 dip->un.e.member[0].ord = 0;
  506                 strcpy(dip->un.e.member[1].label.name, AudioNoff);
  507                 dip->un.e.member[1].ord = 1;
  508                 break;
  509 
  510         case CSAUDIO_LINE_IN_MUTE:
  511                 dip->mixer_class = CSAUDIO_INPUT_CLASS;
  512                 dip->type = AUDIO_MIXER_ENUM;
  513                 dip->prev = CSAUDIO_LINE_IN_LVL;
  514                 dip->next = AUDIO_MIXER_LAST;
  515                 goto mute;
  516 
  517         case CSAUDIO_DAC_MUTE:
  518                 dip->mixer_class = CSAUDIO_INPUT_CLASS;
  519                 dip->type = AUDIO_MIXER_ENUM;
  520                 dip->prev = CSAUDIO_DAC_LVL;
  521                 dip->next = AUDIO_MIXER_LAST;
  522                 goto mute;
  523 
  524         case CSAUDIO_CD_MUTE:
  525                 dip->mixer_class = CSAUDIO_INPUT_CLASS;
  526                 dip->type = AUDIO_MIXER_ENUM;
  527                 dip->prev = CSAUDIO_CD_LVL;
  528                 dip->next = AUDIO_MIXER_LAST;
  529                 goto mute;
  530 
  531         case CSAUDIO_MONO_MUTE:
  532                 dip->mixer_class = CSAUDIO_INPUT_CLASS;
  533                 dip->type = AUDIO_MIXER_ENUM;
  534                 dip->prev = CSAUDIO_MONO_LVL;
  535                 dip->next = AUDIO_MIXER_LAST;
  536                 goto mute;
  537 
  538         case CSAUDIO_OUTPUT_MUTE:
  539                 dip->mixer_class = CSAUDIO_MONITOR_CLASS;
  540                 dip->type = AUDIO_MIXER_ENUM;
  541                 dip->prev = CSAUDIO_OUTPUT_LVL;
  542                 dip->next = AUDIO_MIXER_LAST;
  543         mute:
  544                 strcpy(dip->label.name, AudioNmute);
  545                 dip->un.e.num_mem = 2;
  546                 strcpy(dip->un.e.member[0].label.name, AudioNoff);
  547                 dip->un.e.member[0].ord = 0;
  548                 strcpy(dip->un.e.member[1].label.name, AudioNon);
  549                 dip->un.e.member[1].ord = 1;
  550                 break;
  551 
  552         case CSAUDIO_REC_LVL:   /* record level */
  553                 dip->type = AUDIO_MIXER_VALUE;
  554                 dip->mixer_class = CSAUDIO_RECORD_CLASS;
  555                 dip->prev = AUDIO_MIXER_LAST;
  556                 dip->next = CSAUDIO_RECORD_SOURCE;
  557                 strcpy(dip->label.name, AudioNrecord);
  558                 dip->un.v.num_channels = 2;
  559                 strcpy(dip->un.v.units.name, AudioNvolume);
  560                 break;
  561 
  562         case CSAUDIO_RECORD_SOURCE:
  563                 dip->mixer_class = CSAUDIO_RECORD_CLASS;
  564                 dip->type = AUDIO_MIXER_ENUM;
  565                 dip->prev = CSAUDIO_REC_LVL;
  566                 dip->next = AUDIO_MIXER_LAST;
  567                 strcpy(dip->label.name, AudioNsource);
  568                 dip->un.e.num_mem = 4;
  569                 strcpy(dip->un.e.member[0].label.name, AudioNoutput);
  570                 dip->un.e.member[0].ord = DAC_IN_PORT;
  571                 strcpy(dip->un.e.member[1].label.name, AudioNmicrophone);
  572                 dip->un.e.member[1].ord = MIC_IN_PORT;
  573                 strcpy(dip->un.e.member[2].label.name, AudioNdac);
  574                 dip->un.e.member[2].ord = AUX1_IN_PORT;
  575                 strcpy(dip->un.e.member[3].label.name, AudioNline);
  576                 dip->un.e.member[3].ord = LINE_IN_PORT;
  577                 break;
  578 
  579         case CSAUDIO_INPUT_CLASS:               /* input class descriptor */
  580                 dip->type = AUDIO_MIXER_CLASS;
  581                 dip->mixer_class = CSAUDIO_INPUT_CLASS;
  582                 dip->next = dip->prev = AUDIO_MIXER_LAST;
  583                 strcpy(dip->label.name, AudioCinputs);
  584                 break;
  585 
  586         case CSAUDIO_MONITOR_CLASS:             /* output class descriptor */
  587                 dip->type = AUDIO_MIXER_CLASS;
  588                 dip->mixer_class = CSAUDIO_MONITOR_CLASS;
  589                 dip->next = dip->prev = AUDIO_MIXER_LAST;
  590                 strcpy(dip->label.name, AudioCoutputs);
  591                 break;
  592 
  593         case CSAUDIO_RECORD_CLASS:              /* record source class */
  594                 dip->type = AUDIO_MIXER_CLASS;
  595                 dip->mixer_class = CSAUDIO_RECORD_CLASS;
  596                 dip->next = dip->prev = AUDIO_MIXER_LAST;
  597                 strcpy(dip->label.name, AudioCrecord);
  598                 break;
  599 
  600         default:
  601                 return ENXIO;
  602                 /*NOTREACHED*/
  603         }
  604         DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
  605 
  606         return 0;
  607 }
  608 
  609 #endif /* NAUDIO > 0 */

Cache object: 77007183d24cf1b3e30e212eabcf8f94


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