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/isa/aria.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: aria.c,v 1.18 2003/05/03 18:11:26 wiz Exp $    */
    2 
    3 /*-
    4  * Copyright (c) 1995, 1996, 1998 Roland C. Dowdeswell.  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  * 3. All advertising materials mentioning features or use of this software
   15  *    must display the following acknowledgement:
   16  *      This product includes software developed by Roland C. Dowdeswell.
   17  * 4. The name of the authors may not be used to endorse or promote products
   18  *      derived from this software without specific prior written permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
   21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   23  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 /*-
   33  * TODO:
   34  *  o   Test the driver on cards other than a single
   35  *      Prometheus Aria 16.
   36  *  o   Look into where aria_prometheus_kludge() belongs.
   37  *  o   Add some DMA code.  It accomplishes its goal by
   38  *      direct IO at the moment.
   39  *  o   Different programs should be able to open the device
   40  *      with O_RDONLY and O_WRONLY at the same time.  But I
   41  *      do not see support for this in /sys/dev/audio.c, so
   42  *      I cannot effectively code it.
   43  *  o   We should nicely deal with the cards that can do mu-law
   44  *      and A-law output.
   45  *  o   Rework the mixer interface.
   46  *       o   Deal with the lvls better.  We need to do better mapping
   47  *           between logarithmic scales and the one byte that
   48  *           we are passed.
   49  *       o   Deal better with cards that have no mixer.
   50  */
   51 
   52 #include <sys/cdefs.h>
   53 __KERNEL_RCSID(0, "$NetBSD: aria.c,v 1.18 2003/05/03 18:11:26 wiz Exp $");
   54 
   55 #include <sys/param.h>
   56 #include <sys/systm.h>
   57 #include <sys/errno.h>
   58 #include <sys/ioctl.h>
   59 #include <sys/syslog.h>
   60 #include <sys/device.h>
   61 #include <sys/proc.h>
   62 #include <sys/buf.h>
   63 
   64 #include <machine/cpu.h>
   65 #include <machine/bus.h>
   66 
   67 #include <sys/audioio.h>
   68 #include <dev/audio_if.h>
   69 #include <dev/auconv.h>
   70 
   71 #include <dev/mulaw.h>
   72 #include <dev/isa/isavar.h>
   73 
   74 #include <dev/isa/ariareg.h>
   75 
   76 #define FREAD 1
   77 #define FWRITE 2
   78 
   79 #ifdef AUDIO_DEBUG
   80 #define DPRINTF(x)      printf x
   81 int     ariadebug = 0;
   82 #else
   83 #define DPRINTF(x)
   84 #endif
   85 
   86 struct aria_mixdev_info {
   87         u_char  num_channels;
   88         u_char  level[2];
   89         u_char  mute;
   90 };
   91 
   92 struct aria_mixmaster {
   93         u_char num_channels;
   94         u_char level[2];
   95         u_char treble[2];
   96         u_char bass[2];
   97 };
   98 
   99 struct aria_softc {
  100         struct  device sc_dev;          /* base device */
  101         void    *sc_ih;                 /* interrupt vectoring */
  102         bus_space_tag_t sc_iot;         /* Tag on 'da bus. */
  103         bus_space_handle_t sc_ioh;      /* Handle of iospace */
  104         isa_chipset_tag_t sc_ic;        /* ISA chipset info */
  105 
  106         u_short sc_open;                /* reference count of open calls */
  107         u_short sc_play;                /* non-paused play chans 2**chan */
  108         u_short sc_record;              /* non-paused record chans 2**chan */
  109 /* XXX -- keep this? */
  110         u_short sc_gain[2];             /* left/right gain (play) */
  111 
  112         u_long  sc_rate;                /* Sample rate for input and output */
  113         u_int   sc_encoding;            /* audio encoding -- mu-law/linear */
  114         int     sc_chans;               /* # of channels */
  115         int     sc_precision;           /* # bits per sample */
  116 
  117         u_long  sc_interrupts;          /* number of interrupts taken */
  118         void    (*sc_rintr)(void*);     /* record transfer completion intr handler */
  119         void    (*sc_pintr)(void*);     /* play transfer completion intr handler */
  120         void    *sc_rarg;               /* arg for sc_rintr() */
  121         void    *sc_parg;               /* arg for sc_pintr() */
  122 
  123         int     sc_blocksize;           /* literal dio block size */
  124         void    *sc_rdiobuffer;         /* record: where the next samples should be */
  125         void    *sc_pdiobuffer;         /* play:   where the next samples are */
  126 
  127         u_short sc_hardware;            /* bit field of hardware present */
  128 #define ARIA_TELEPHONE  0x0001          /* has telephone input */
  129 #define ARIA_MIXER      0x0002          /* has SC18075 digital mixer */
  130 #define ARIA_MODEL      0x0004          /* is SC18025 (=0) or SC18026 (=1) */
  131 
  132         struct aria_mixdev_info aria_mix[6];
  133         struct aria_mixmaster ariamix_master;
  134         u_char  aria_mix_source;
  135 
  136         int     sc_sendcmd_err;
  137 };
  138 
  139 int     ariaprobe __P((struct device *, struct cfdata *, void *));
  140 void    ariaattach __P((struct device *, struct device *, void *));
  141 void    ariaclose __P((void *));
  142 int     ariaopen __P((void *, int));
  143 int     ariareset __P((bus_space_tag_t, bus_space_handle_t));
  144 int     aria_reset __P((struct aria_softc *));
  145 int     aria_getdev __P((void *, struct audio_device *));
  146 
  147 void    aria_do_kludge __P((bus_space_tag_t, bus_space_handle_t, 
  148                             bus_space_handle_t, 
  149                             u_short, u_short, u_short, u_short));
  150 void    aria_prometheus_kludge __P((struct isa_attach_args *, 
  151                                     bus_space_handle_t));
  152 
  153 int     aria_query_encoding __P((void *, struct audio_encoding *));
  154 int     aria_round_blocksize __P((void *, int));
  155 int     aria_speaker_ctl __P((void *, int));
  156 int     aria_commit_settings __P((void *));
  157 int     aria_set_params __P((void *, int, int, 
  158                              struct audio_params *, struct audio_params *));
  159 int     aria_get_props __P((void *));
  160 
  161 int     aria_start_output __P((void *, void *, int, 
  162                                void (*) __P((void *)), void*));
  163 int     aria_start_input __P((void *, void *, int, 
  164                               void (*) __P((void *)), void*));
  165 
  166 int     aria_halt_input __P((void *));
  167 int     aria_halt_output __P((void *));
  168 
  169 int     aria_sendcmd __P((struct aria_softc *, u_short, int, int, int));
  170 
  171 u_short aria_getdspmem __P((struct aria_softc *, u_short));
  172 void    aria_putdspmem __P((struct aria_softc *, u_short, u_short));
  173 
  174 int     aria_intr __P((void *));
  175 short   ariaversion __P((struct aria_softc *));
  176 
  177 void    aria_set_mixer __P((struct aria_softc *, int));
  178 
  179 void    aria_mix_write __P((struct aria_softc *, int, int));
  180 int     aria_mix_read __P((struct aria_softc *, int));
  181 
  182 int     aria_mixer_set_port __P((void *, mixer_ctrl_t *));
  183 int     aria_mixer_get_port __P((void *, mixer_ctrl_t *));
  184 int     aria_mixer_query_devinfo __P((void *, mixer_devinfo_t *));
  185 
  186 CFATTACH_DECL(aria, sizeof(struct aria_softc),
  187     ariaprobe, ariaattach, NULL, NULL);
  188 
  189 /* XXX temporary test for 1.3 */
  190 #ifndef AudioNaux
  191 /* 1.3 */
  192 struct cfdriver aria_cd = {
  193         NULL, "aria", DV_DULL
  194 };
  195 #endif
  196 
  197 struct audio_device aria_device = {
  198         "Aria 16(se)",
  199         "x",
  200         "aria"
  201 };
  202 
  203 /*
  204  * Define our interface to the higher level audio driver.
  205  */
  206 
  207 struct audio_hw_if aria_hw_if = {
  208         ariaopen,
  209         ariaclose,
  210         NULL,
  211         aria_query_encoding,
  212         aria_set_params,
  213         aria_round_blocksize,
  214         aria_commit_settings,
  215         NULL,
  216         NULL,
  217         aria_start_output,
  218         aria_start_input,
  219         aria_halt_input,
  220         aria_halt_output,
  221         NULL,
  222         aria_getdev,
  223         NULL,
  224         aria_mixer_set_port,
  225         aria_mixer_get_port,
  226         aria_mixer_query_devinfo,
  227         NULL,
  228         NULL,
  229         NULL,
  230         NULL,
  231         aria_get_props,
  232         NULL,
  233         NULL,
  234         NULL,
  235 };
  236 
  237 /*
  238  * Probe / attach routines.
  239  */
  240 
  241 /*
  242  * Probe for the aria hardware.
  243  */
  244 int
  245 ariaprobe(parent, cf, aux)
  246         struct device *parent;
  247         struct cfdata *cf;
  248         void *aux;
  249 {
  250         bus_space_handle_t ioh;
  251         struct isa_attach_args *ia = aux;
  252 
  253         if (ia->ia_nio < 1)
  254                 return (0);
  255         if (ia->ia_nirq < 1)
  256                 return (0);
  257 
  258         if (ISA_DIRECT_CONFIG(ia))
  259                 return (0);
  260 
  261         if (!ARIA_BASE_VALID(ia->ia_io[0].ir_addr)) {
  262                 printf("aria: configured iobase %d invalid\n",
  263                     ia->ia_io[0].ir_addr);
  264                 return 0;
  265         }
  266                 
  267         if (!ARIA_IRQ_VALID(ia->ia_irq[0].ir_irq)) {
  268                 printf("aria: configured irq %d invalid\n",
  269                     ia->ia_irq[0].ir_irq);
  270                 return 0;
  271         }
  272 
  273         if (bus_space_map(ia->ia_iot, ia->ia_io[0].ir_addr, ARIADSP_NPORT,
  274             0, &ioh)) {
  275                 DPRINTF(("aria: aria probe failed\n"));
  276                 return 0;
  277         }
  278 
  279         if (cf->cf_flags & 1)
  280                 aria_prometheus_kludge(ia, ioh);
  281 
  282         if (ariareset(ia->ia_iot, ioh) != 0) {
  283                 DPRINTF(("aria: aria probe failed\n"));
  284                 bus_space_unmap(ia->ia_iot, ioh,  ARIADSP_NPORT);
  285                 return 0;
  286         }
  287 
  288         bus_space_unmap(ia->ia_iot, ioh, ARIADSP_NPORT);
  289 
  290         ia->ia_nio = 1;
  291         ia->ia_io[0].ir_size = ARIADSP_NPORT;
  292 
  293         ia->ia_nirq = 1;
  294 
  295         ia->ia_niomem = 0;
  296         ia->ia_ndrq = 0;
  297 
  298         DPRINTF(("aria: aria probe succeeded\n"));
  299         return 1;
  300 }
  301 
  302 /*
  303  * I didn't call this a kludge for
  304  * nothing.  This is cribbed from
  305  * ariainit, the author of that
  306  * disassembled some code to discover
  307  * how to set up the initial values of
  308  * the card.  Without this, the card
  309  * is dead. (It will not respond to _any_
  310  * input at all.)
  311  *
  312  * ariainit can be found (ftp) at:
  313  * ftp://ftp.wi.leidenuniv.nl/pub/audio/aria/programming/contrib/ariainit.zip
  314  * currently.
  315  */
  316 
  317 void
  318 aria_prometheus_kludge(ia, ioh1)
  319         struct isa_attach_args *ia;
  320         bus_space_handle_t ioh1;
  321 {
  322         bus_space_tag_t iot;
  323         bus_space_handle_t ioh;
  324         u_short end;
  325 
  326         DPRINTF(("aria: begin aria_prometheus_kludge\n"));
  327 
  328 /* Begin Config Sequence */
  329 
  330         iot = ia->ia_iot;
  331         bus_space_map(iot, 0x200, 8, 0, &ioh);
  332 
  333         bus_space_write_1(iot, ioh, 4, 0x4c);
  334         bus_space_write_1(iot, ioh, 5, 0x42);
  335         bus_space_write_1(iot, ioh, 6, 0x00);
  336         bus_space_write_2(iot, ioh, 0, 0x0f);
  337         bus_space_write_1(iot, ioh, 1, 0x00);
  338         bus_space_write_2(iot, ioh, 0, 0x02);
  339         bus_space_write_1(iot, ioh, 1, ia->ia_io[0].ir_addr>>2);
  340 
  341 /* 
  342  * These next three lines set up the iobase
  343  * and the irq; and disable the drq.  
  344  */
  345 
  346         aria_do_kludge(iot, ioh, ioh1, 0x111,
  347             ((ia->ia_io[0].ir_addr-0x280)>>2)+0xA0, 0xbf, 0xa0);
  348         aria_do_kludge(iot, ioh, ioh1, 0x011,
  349             ia->ia_irq[0].ir_irq-6, 0xf8, 0x00);
  350         aria_do_kludge(iot, ioh, ioh1, 0x011, 0x00, 0xef, 0x00);
  351 
  352 /* The rest of these lines just disable everything else */
  353 
  354         aria_do_kludge(iot, ioh, ioh1, 0x113, 0x00, 0x88, 0x00);
  355         aria_do_kludge(iot, ioh, ioh1, 0x013, 0x00, 0xf8, 0x00);
  356         aria_do_kludge(iot, ioh, ioh1, 0x013, 0x00, 0xef, 0x00);
  357         aria_do_kludge(iot, ioh, ioh1, 0x117, 0x00, 0x88, 0x00);
  358         aria_do_kludge(iot, ioh, ioh1, 0x017, 0x00, 0xff, 0x00);
  359 
  360 /* End Sequence */
  361 
  362         bus_space_write_1(iot, ioh, 0, 0x0f);
  363         end = bus_space_read_1(iot, ioh1, 0);
  364         bus_space_write_2(iot, ioh, 0, 0x0f);
  365         bus_space_write_1(iot, ioh, 1, end|0x80);
  366         bus_space_read_1(iot, ioh, 0);
  367 
  368         bus_space_unmap(iot, ioh, 8);
  369 /*
  370  * This delay is necessary for some reason,
  371  * at least it would crash, and sometimes not
  372  * probe properly if it did not exist.
  373  */
  374         delay(1000000);
  375 }
  376 
  377 void
  378 aria_do_kludge(iot, ioh, ioh1, func, bits, and, or)
  379         bus_space_tag_t iot;
  380         bus_space_handle_t ioh;
  381         bus_space_handle_t ioh1;
  382         u_short func;
  383         u_short bits;
  384         u_short and;
  385         u_short or;
  386 {
  387         u_int i;
  388         if (func & 0x100) {
  389                 func &= ~0x100;
  390                 if (bits) {
  391                         bus_space_write_2(iot, ioh, 0, func-1);
  392                         bus_space_write_1(iot, ioh, 1, bits);
  393                 }
  394         } else
  395                 or |= bits;
  396 
  397         bus_space_write_1(iot, ioh, 0, func);
  398         i = bus_space_read_1(iot, ioh1, 0);
  399         bus_space_write_2(iot, ioh, 0, func);
  400         bus_space_write_1(iot, ioh, 1, (i&and) | or);
  401 }
  402 
  403 /*
  404  * Attach hardware to driver, attach hardware driver to audio
  405  * pseudo-device driver.
  406  */
  407 void
  408 ariaattach(parent, self, aux)
  409         struct device *parent, *self;
  410         void *aux;
  411 {
  412         bus_space_handle_t ioh;
  413         struct aria_softc *sc = (void *)self;
  414         struct isa_attach_args *ia = aux;
  415         u_short i;
  416 
  417         if (bus_space_map(ia->ia_iot, ia->ia_io[0].ir_addr, ARIADSP_NPORT,
  418             0, &ioh))
  419                 panic("%s: can map io port range", self->dv_xname);
  420 
  421         sc->sc_iot = ia->ia_iot;
  422         sc->sc_ioh = ioh;
  423         sc->sc_ic = ia->ia_ic;
  424 
  425         sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq,
  426             IST_EDGE, IPL_AUDIO, aria_intr, sc);
  427 
  428         DPRINTF(("isa_intr_establish() returns (%x)\n", (unsigned) sc->sc_ih));
  429 
  430         i = aria_getdspmem(sc, ARIAA_HARDWARE_A);
  431 
  432         sc->sc_hardware  = 0;
  433         sc->sc_hardware |= ((i>>13)&0x01)==1 ? ARIA_TELEPHONE:0;
  434         sc->sc_hardware |= (((i>>5)&0x07))==0x04 ? ARIA_MIXER:0;
  435         sc->sc_hardware |= (aria_getdspmem(sc, ARIAA_MODEL_A)>=1)?ARIA_MODEL:0;
  436 
  437         sc->sc_open       = 0;
  438         sc->sc_play       = 0;
  439         sc->sc_record     = 0;
  440         sc->sc_rate       = 7875;
  441         sc->sc_chans      = 1;
  442         sc->sc_blocksize  = 1024;
  443         sc->sc_precision  = 8;
  444         sc->sc_rintr      = 0;
  445         sc->sc_rarg       = 0;
  446         sc->sc_pintr      = 0;
  447         sc->sc_parg       = 0;
  448         sc->sc_gain[0]       = 127;
  449         sc->sc_gain[1]       = 127;
  450 
  451         for (i=0; i<6; i++) {
  452                 if (i == ARIAMIX_TEL_LVL)
  453                         sc->aria_mix[i].num_channels = 1;
  454                 else
  455                         sc->aria_mix[i].num_channels = 2;
  456                 sc->aria_mix[i].level[0] = 127;
  457                 sc->aria_mix[i].level[1] = 127;
  458         }
  459 
  460         sc->ariamix_master.num_channels = 2;
  461         sc->ariamix_master.level[0] = 222;
  462         sc->ariamix_master.level[1] = 222;
  463         sc->ariamix_master.bass[0] = 127;
  464         sc->ariamix_master.bass[1] = 127;
  465         sc->ariamix_master.treble[0] = 127;
  466         sc->ariamix_master.treble[1] = 127;
  467         sc->aria_mix_source = 0;
  468 
  469         aria_commit_settings(sc);
  470 
  471         printf(": dsp %s", (ARIA_MODEL&sc->sc_hardware)?"SC18026":"SC18025");
  472         if (ARIA_TELEPHONE&sc->sc_hardware)
  473                 printf(", tel");
  474         if (ARIA_MIXER&sc->sc_hardware)
  475                 printf(", SC18075 mixer");
  476         printf("\n");
  477 
  478         sprintf(aria_device.version, "%s", 
  479                 ARIA_MODEL & sc->sc_hardware ? "SC18026" : "SC18025");
  480 
  481         audio_attach_mi(&aria_hw_if, (void *)sc, &sc->sc_dev);
  482 }
  483 
  484 /*
  485  * Various routines to interface to higher level audio driver
  486  */
  487 
  488 int
  489 ariaopen(addr, flags)
  490         void *addr;
  491         int flags;
  492 {
  493         struct aria_softc *sc = addr;
  494 
  495         DPRINTF(("ariaopen() called\n"));
  496     
  497         if (!sc)
  498                 return ENXIO;
  499         if ((flags&FREAD) && (sc->sc_open & ARIAR_OPEN_RECORD))
  500                 return ENXIO;
  501         if ((flags&FWRITE) && (sc->sc_open & ARIAR_OPEN_PLAY))
  502                 return ENXIO;
  503     
  504         if (flags&FREAD)
  505                 sc->sc_open |= ARIAR_OPEN_RECORD;
  506         if (flags&FWRITE)
  507                 sc->sc_open |= ARIAR_OPEN_PLAY;
  508         sc->sc_play  = 0;
  509         sc->sc_record= 0;
  510         sc->sc_rintr = 0;
  511         sc->sc_rarg  = 0;
  512         sc->sc_pintr = 0;
  513         sc->sc_parg  = 0;
  514 
  515         return 0;
  516 }
  517 
  518 int
  519 aria_getdev(addr, retp)
  520         void *addr;
  521         struct audio_device *retp;
  522 {
  523         *retp = aria_device;
  524         return 0;
  525 }
  526 
  527 /*
  528  * Various routines to interface to higher level audio driver
  529  */
  530 
  531 int
  532 aria_query_encoding(addr, fp)
  533     void *addr;
  534     struct audio_encoding *fp;
  535 {
  536         struct aria_softc *sc = addr;
  537 
  538         switch (fp->index) {
  539                 case 0:
  540                         strcpy(fp->name, AudioEmulaw);
  541                         fp->encoding = AUDIO_ENCODING_ULAW;
  542                         fp->precision = 8;
  543                         if ((ARIA_MODEL&sc->sc_hardware) == 0)
  544                                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  545                         break;
  546                 case 1:
  547                         strcpy(fp->name, AudioEalaw);
  548                         fp->encoding = AUDIO_ENCODING_ALAW;
  549                         fp->precision = 8;
  550                         if ((ARIA_MODEL&sc->sc_hardware) == 0)
  551                                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  552                         break;
  553                 case 2:
  554                         strcpy(fp->name, AudioEslinear);
  555                         fp->encoding = AUDIO_ENCODING_SLINEAR;
  556                         fp->precision = 8;
  557                         fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  558                         break;
  559                 case 3:
  560                         strcpy(fp->name, AudioEslinear_le);
  561                         fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
  562                         fp->precision = 16;
  563                         fp->flags = 0;
  564                         break;
  565                 case 4:
  566                         strcpy(fp->name, AudioEslinear_be);
  567                         fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
  568                         fp->precision = 16;
  569                         fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  570                         break;
  571                 case 5:
  572                         strcpy(fp->name, AudioEulinear);
  573                         fp->encoding = AUDIO_ENCODING_ULINEAR;
  574                         fp->precision = 8;
  575                         fp->flags = 0;
  576                         break;
  577                 case 6:
  578                         strcpy(fp->name, AudioEulinear_le);
  579                         fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
  580                         fp->precision = 16;
  581                         fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  582                         break;
  583                 case 7:
  584                         strcpy(fp->name, AudioEulinear_be);
  585                         fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
  586                         fp->precision = 16;
  587                         fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  588                         break;
  589                 default:
  590                         return(EINVAL);
  591                 /*NOTREACHED*/
  592         }
  593 
  594         return (0);
  595 }
  596 
  597 /*
  598  * Store blocksize in bytes.
  599  */
  600 
  601 int
  602 aria_round_blocksize(addr, blk)
  603         void *addr;
  604         int blk;
  605 {
  606         int i;
  607 #if 0 /* XXX -- this is being a tad bit of a problem... */
  608         for (i=64; i<1024; i*=2)
  609                 if (blk <= i)
  610                         break;
  611 #else
  612         i = 1024;
  613 #endif
  614         return(i);
  615 }
  616 
  617 int
  618 aria_get_props(addr)
  619         void *addr;
  620 {
  621         return AUDIO_PROP_FULLDUPLEX;
  622 }
  623 
  624 int
  625 aria_set_params(addr, setmode, usemode, p, r)
  626         void *addr;
  627         int setmode, usemode;
  628         struct audio_params *p, *r;
  629 {
  630         struct aria_softc *sc = addr;
  631 
  632         switch(p->encoding) {
  633         case AUDIO_ENCODING_ULAW:
  634         case AUDIO_ENCODING_ALAW:
  635         case AUDIO_ENCODING_SLINEAR:
  636         case AUDIO_ENCODING_SLINEAR_LE:
  637         case AUDIO_ENCODING_SLINEAR_BE:
  638         case AUDIO_ENCODING_ULINEAR:
  639         case AUDIO_ENCODING_ULINEAR_LE:
  640         case AUDIO_ENCODING_ULINEAR_BE:
  641                 break;
  642         default:
  643                 return (EINVAL);
  644         }
  645 
  646         if (p->sample_rate <= 9450)
  647                 p->sample_rate = 7875;
  648         else if (p->sample_rate <= 13387)
  649                 p->sample_rate = 11025;
  650         else if (p->sample_rate <= 18900)
  651                 p->sample_rate = 15750;
  652         else if (p->sample_rate <= 26775)
  653                 p->sample_rate = 22050;
  654         else if (p->sample_rate <= 37800)
  655                 p->sample_rate = 31500;
  656         else
  657                 p->sample_rate = 44100;
  658 
  659         sc->sc_encoding = p->encoding;
  660         sc->sc_precision = p->precision;
  661         sc->sc_chans = p->channels;
  662         sc->sc_rate = p->sample_rate;
  663 
  664         switch(p->encoding) {
  665         case AUDIO_ENCODING_ULAW:
  666                 if ((ARIA_MODEL&sc->sc_hardware) == 0) {
  667                         p->sw_code = mulaw_to_ulinear8;
  668                         r->sw_code = ulinear8_to_mulaw;
  669                 }
  670                 break;
  671         case AUDIO_ENCODING_ALAW:
  672                 if ((ARIA_MODEL&sc->sc_hardware) == 0) {
  673                         p->sw_code = alaw_to_ulinear8;
  674                         r->sw_code = ulinear8_to_alaw;
  675                 }
  676                 break;
  677         case AUDIO_ENCODING_SLINEAR:
  678                 p->sw_code = r->sw_code = change_sign8;
  679                 break;
  680         case AUDIO_ENCODING_ULINEAR_LE:
  681                 p->sw_code = r->sw_code = change_sign16_le;
  682                 break;
  683         case AUDIO_ENCODING_SLINEAR_BE:
  684                 p->sw_code = r->sw_code = swap_bytes;
  685                 break;
  686         case AUDIO_ENCODING_ULINEAR_BE:
  687                 p->sw_code = r->sw_code = swap_bytes_change_sign16_le;
  688                 break;
  689         }
  690 
  691         return 0;
  692 }
  693 
  694 /*
  695  * This is where all of the twiddling goes on.
  696  */
  697 
  698 int
  699 aria_commit_settings(addr)
  700         void *addr;
  701 {
  702         struct aria_softc *sc = addr;
  703         bus_space_tag_t iot = sc->sc_iot;
  704         bus_space_handle_t ioh = sc->sc_ioh;
  705         static u_char tones[16] = 
  706             { 7, 6, 5, 4, 3, 2, 1, 0, 8, 9, 10, 11, 12, 13, 14, 15 };
  707         u_short format;
  708         u_short left, right;
  709         u_short samp;
  710         u_char i;
  711 
  712         DPRINTF(("aria_commit_settings\n"));
  713 
  714         switch (sc->sc_rate) {
  715         case  7875: format = 0x00; samp = 0x60; break;
  716         case 11025: format = 0x00; samp = 0x40; break;
  717         case 15750: format = 0x10; samp = 0x60; break;
  718         case 22050: format = 0x10; samp = 0x40; break;
  719         case 31500: format = 0x10; samp = 0x20; break;
  720         case 44100: format = 0x20; samp = 0x00; break;
  721         default:    format = 0x00; samp = 0x40; break;/* XXX can we get here? */
  722         }
  723 
  724         if ((ARIA_MODEL&sc->sc_hardware) != 0) {
  725                 format |= (sc->sc_encoding==AUDIO_ENCODING_ULAW)?0x06:0x00;
  726                 format |= (sc->sc_encoding==AUDIO_ENCODING_ALAW)?0x08:0x00;
  727         }
  728                 
  729         format |= (sc->sc_precision==16)?0x02:0x00;
  730         format |= (sc->sc_chans==2)?1:0;
  731         samp |= bus_space_read_2(iot, ioh, ARIADSP_STATUS) & ~0x60;
  732 
  733         aria_sendcmd(sc, ARIADSPC_FORMAT, format, -1, -1);
  734         bus_space_write_2(iot, ioh, ARIADSP_CONTROL, samp);
  735 
  736         if (sc->sc_hardware&ARIA_MIXER) {
  737                 for (i = 0; i < 6; i++)
  738                         aria_set_mixer(sc, i);
  739  
  740                 if (sc->sc_chans==2) {
  741                         aria_sendcmd(sc, ARIADSPC_CHAN_VOL, ARIAR_PLAY_CHAN, 
  742                                      ((sc->sc_gain[0]+sc->sc_gain[1])/2)<<7,
  743                                      -1);
  744                         aria_sendcmd(sc, ARIADSPC_CHAN_PAN, ARIAR_PLAY_CHAN, 
  745                                      (sc->sc_gain[0]-sc->sc_gain[1])/4+0x40,
  746                                      -1);
  747                 } else {
  748                         aria_sendcmd(sc, ARIADSPC_CHAN_VOL, ARIAR_PLAY_CHAN, 
  749                                      sc->sc_gain[0]<<7, -1);
  750                         aria_sendcmd(sc, ARIADSPC_CHAN_PAN, ARIAR_PLAY_CHAN, 
  751                                      0x40, -1);
  752                 }
  753 
  754                 aria_sendcmd(sc, ARIADSPC_MASMONMODE, 
  755                              sc->ariamix_master.num_channels != 2, -1, -1);
  756 
  757                 aria_sendcmd(sc, ARIADSPC_MIXERVOL, 0x0004, 
  758                              sc->ariamix_master.level[0] << 7, 
  759                              sc->ariamix_master.level[1] << 7);
  760 
  761                 /* Convert treble/bass from byte to soundcard style */
  762 
  763                 left  = (tones[(sc->ariamix_master.treble[0]>>4)&0x0f]<<8) | 
  764                          tones[(sc->ariamix_master.bass[0]>>4)&0x0f];
  765                 right = (tones[(sc->ariamix_master.treble[1]>>4)&0x0f]<<8) | 
  766                          tones[(sc->ariamix_master.bass[1]>>4)&0x0f];
  767 
  768                 aria_sendcmd(sc, ARIADSPC_TONE, left, right, -1);
  769         }
  770 
  771         aria_sendcmd(sc, ARIADSPC_BLOCKSIZE, sc->sc_blocksize/2, -1, -1);
  772 
  773 /*
  774  * If we think that the card is recording or playing, start it up again here.
  775  * Some of the previous commands turn the channels off.
  776  */
  777 
  778         if (sc->sc_record&(1<<ARIAR_RECORD_CHAN))
  779                 aria_sendcmd(sc, ARIADSPC_START_REC, ARIAR_RECORD_CHAN, -1,-1);
  780 
  781         if (sc->sc_play&(1<<ARIAR_PLAY_CHAN))
  782                 aria_sendcmd(sc, ARIADSPC_START_PLAY, ARIAR_PLAY_CHAN, -1, -1);
  783 
  784         return(0);
  785 }
  786 
  787 void
  788 aria_set_mixer(sc, i)
  789         struct aria_softc *sc;  
  790         int i;
  791 {
  792         u_char source;
  793         switch(i) {
  794         case ARIAMIX_MIC_LVL:     source = 0x0001; break;
  795         case ARIAMIX_CD_LVL:      source = 0x0002; break;
  796         case ARIAMIX_LINE_IN_LVL: source = 0x0008; break;
  797         case ARIAMIX_TEL_LVL:     source = 0x0020; break;
  798         case ARIAMIX_AUX_LVL:     source = 0x0010; break;
  799         case ARIAMIX_DAC_LVL:     source = 0x0004; break;
  800         default:                  source = 0x0000; break;
  801         }
  802         
  803         if (source != 0x0000 && source != 0x0004) {
  804                 if (sc->aria_mix[i].mute == 1)
  805                         aria_sendcmd(sc, ARIADSPC_INPMONMODE, source, 3, -1);
  806                 else
  807                         aria_sendcmd(sc, ARIADSPC_INPMONMODE, source, 
  808                                      sc->aria_mix[i].num_channels != 2, -1); 
  809                 
  810                 aria_sendcmd(sc, ARIADSPC_INPMONMODE, 0x8000|source, 
  811                              sc->aria_mix[i].num_channels != 2, -1);
  812                 aria_sendcmd(sc, ARIADSPC_MIXERVOL, source, 
  813                              sc->aria_mix[i].level[0] << 7, 
  814                              sc->aria_mix[i].level[1] << 7);
  815         }
  816         
  817         if (sc->aria_mix_source == i) {
  818                 aria_sendcmd(sc, ARIADSPC_ADCSOURCE, source, -1, -1);
  819                 
  820                 if (sc->sc_open & ARIAR_OPEN_RECORD)
  821                         aria_sendcmd(sc, ARIADSPC_ADCCONTROL, 1, -1, -1);
  822                 else 
  823                         aria_sendcmd(sc, ARIADSPC_ADCCONTROL, 0, -1, -1);
  824         }
  825 }
  826 
  827 void
  828 ariaclose(addr)
  829         void *addr;
  830 {
  831         struct aria_softc *sc = addr;
  832 
  833         DPRINTF(("aria_close sc=0x%x\n", (unsigned) sc));
  834 
  835         sc->sc_rintr = 0;
  836         sc->sc_pintr = 0;
  837         sc->sc_rdiobuffer = 0;
  838         sc->sc_pdiobuffer = 0;
  839 
  840         if (sc->sc_play&(1<<ARIAR_PLAY_CHAN) &&
  841             sc->sc_open & ARIAR_OPEN_PLAY) {
  842                 aria_sendcmd(sc, ARIADSPC_STOP_PLAY, ARIAR_PLAY_CHAN, -1, -1);
  843                 sc->sc_play &= ~(1<<ARIAR_PLAY_CHAN);
  844         }
  845 
  846         if (sc->sc_record&(1<<ARIAR_RECORD_CHAN) &&
  847             sc->sc_open & ARIAR_OPEN_RECORD) {
  848                 aria_sendcmd(sc, ARIADSPC_STOP_REC, ARIAR_RECORD_CHAN, -1, -1);
  849                 sc->sc_record &= ~(1<<ARIAR_RECORD_CHAN);
  850         }
  851 
  852         sc->sc_open = 0;
  853 
  854         if (aria_reset(sc) != 0) {
  855                 delay(500);
  856                 aria_reset(sc);
  857         }
  858 }
  859 
  860 /*
  861  * Reset the hardware.
  862  */
  863 
  864 int ariareset(iot, ioh)
  865         bus_space_tag_t iot;
  866         bus_space_handle_t ioh;
  867 {
  868         struct aria_softc tmp, *sc = &tmp;
  869 
  870         sc->sc_iot = iot;
  871         sc->sc_ioh = ioh;
  872         return aria_reset(sc);
  873 }
  874 
  875 int
  876 aria_reset(sc)
  877         struct aria_softc *sc;
  878 {
  879         bus_space_tag_t iot = sc->sc_iot;
  880         bus_space_handle_t ioh = sc->sc_ioh;
  881         int fail=0;
  882         int i;
  883 
  884         bus_space_write_2(iot, ioh, ARIADSP_CONTROL, 
  885                           ARIAR_ARIA_SYNTH | ARIAR_SR22K|ARIAR_DSPINTWR);
  886         aria_putdspmem(sc, 0x6102, 0);
  887 
  888         fail |= aria_sendcmd(sc, ARIADSPC_SYSINIT, 0x0000, 0x0000, 0x0000);
  889 
  890         for (i=0; i < ARIAR_NPOLL; i++)
  891                 if (aria_getdspmem(sc, ARIAA_TASK_A) == 1)
  892                         break;
  893 
  894         bus_space_write_2(iot, ioh, ARIADSP_CONTROL, 
  895                           ARIAR_ARIA_SYNTH|ARIAR_SR22K | ARIAR_DSPINTWR |
  896                           ARIAR_PCINTWR);
  897         fail |= aria_sendcmd(sc, ARIADSPC_MODE, ARIAV_MODE_NO_SYNTH,-1,-1);
  898 
  899         return (fail);
  900 }
  901 
  902 /*
  903  * Lower-level routines
  904  */
  905 
  906 void
  907 aria_putdspmem(sc, loc, val)
  908         struct aria_softc *sc;
  909         u_short loc;
  910         u_short val;
  911 {
  912         bus_space_tag_t iot = sc->sc_iot;
  913         bus_space_handle_t ioh = sc->sc_ioh;
  914         bus_space_write_2(iot, ioh, ARIADSP_DMAADDRESS, loc);
  915         bus_space_write_2(iot, ioh, ARIADSP_DMADATA, val);
  916 }
  917 
  918 u_short
  919 aria_getdspmem(sc, loc)
  920         struct aria_softc *sc;
  921         u_short loc;
  922 {
  923         bus_space_tag_t iot = sc->sc_iot;
  924         bus_space_handle_t ioh = sc->sc_ioh;
  925         bus_space_write_2(iot, ioh, ARIADSP_DMAADDRESS, loc);
  926         return bus_space_read_2(iot, ioh, ARIADSP_DMADATA);
  927 }
  928 
  929 /*
  930  * aria_sendcmd()
  931  *  each full DSP command is unified into this
  932  *  function.
  933  */
  934 
  935 #define ARIASEND(data, flag) \
  936         for (i = ARIAR_NPOLL; \
  937              (bus_space_read_2(iot, ioh, ARIADSP_STATUS) & ARIAR_BUSY) && i>0; \
  938              i--) \
  939                 ; \
  940         if (bus_space_read_2(iot, ioh, ARIADSP_STATUS) & ARIAR_BUSY) \
  941                 fail |= flag; \
  942         bus_space_write_2(iot, ioh, ARIADSP_WRITE, (u_short)data)
  943 
  944 int
  945 aria_sendcmd(sc, command, arg1, arg2, arg3)
  946         struct aria_softc *sc;
  947         u_short command;
  948         int arg1;
  949         int arg2;
  950         int arg3;
  951 {
  952         bus_space_tag_t iot = sc->sc_iot;
  953         bus_space_handle_t ioh = sc->sc_ioh;
  954         int i, fail = 0;
  955 
  956         ARIASEND(command, 1);
  957         if (arg1 != -1) {
  958                 ARIASEND(arg1, 2);
  959         }
  960         if (arg2 != -1) {
  961                 ARIASEND(arg2, 4);
  962         }
  963         if (arg3 != -1) {
  964                 ARIASEND(arg3, 8);
  965         }
  966         ARIASEND(ARIADSPC_TERM, 16);
  967         
  968         if (fail) {
  969                 sc->sc_sendcmd_err++;
  970 #ifdef AUDIO_DEBUG
  971                 DPRINTF(("aria_sendcmd: failure=(%d) cmd=(0x%x) fail=(0x%x)\n",
  972                          sc->sc_sendcmd_err, command, fail));
  973 #endif
  974                 return -1;
  975         }
  976 
  977         return 0;
  978 }
  979 #undef ARIASEND
  980 
  981 int
  982 aria_halt_input(addr)
  983         void *addr;
  984 {
  985         struct aria_softc *sc = addr;
  986 
  987         DPRINTF(("aria_halt_input\n"));
  988 
  989         if (sc->sc_record & (1<<0)) {
  990                 aria_sendcmd(sc, ARIADSPC_STOP_REC, 0, -1, -1);
  991                 sc->sc_record &= ~(1<<0);
  992         }
  993 
  994         return(0);
  995 }
  996 
  997 int
  998 aria_halt_output(addr)
  999         void *addr;
 1000 {
 1001         struct aria_softc *sc = addr;
 1002 
 1003         DPRINTF(("aria_halt_output\n"));
 1004 
 1005         if (sc->sc_play & (1<<1)) {
 1006                 aria_sendcmd(sc, ARIADSPC_STOP_PLAY, 1, -1, -1);
 1007                 sc->sc_play &= ~(1<<1);
 1008         }
 1009 
 1010         return(0);
 1011 }
 1012 
 1013 /*
 1014  * Here we just set up the buffers.  If we receive
 1015  * an interrupt without these set, it is ignored.
 1016  */
 1017 
 1018 int
 1019 aria_start_input(addr, p, cc, intr, arg)
 1020         void *addr;
 1021         void *p;
 1022         int cc;
 1023         void (*intr) __P((void *));
 1024         void *arg;
 1025 {
 1026         struct aria_softc *sc = addr;
 1027 
 1028         DPRINTF(("aria_start_input %d @ %x\n", cc, (unsigned) p));
 1029 
 1030         if (cc != sc->sc_blocksize) {
 1031                 DPRINTF(("aria_start_input reqsize %d not sc_blocksize %d\n",
 1032                         cc, sc->sc_blocksize));
 1033                 return EINVAL;
 1034         }
 1035 
 1036         sc->sc_rarg = arg;
 1037         sc->sc_rintr = intr;
 1038         sc->sc_rdiobuffer = p;
 1039 
 1040         if (!(sc->sc_record&(1<<ARIAR_RECORD_CHAN))) {
 1041                 aria_sendcmd(sc, ARIADSPC_START_REC, ARIAR_RECORD_CHAN, -1,-1);
 1042                 sc->sc_record |= (1<<ARIAR_RECORD_CHAN);
 1043         }
 1044 
 1045         return 0;
 1046 }
 1047 
 1048 int
 1049 aria_start_output(addr, p, cc, intr, arg)
 1050         void *addr;
 1051         void *p;
 1052         int cc;
 1053         void (*intr) __P((void *));
 1054         void *arg;
 1055 {
 1056         struct aria_softc *sc = addr;
 1057 
 1058         DPRINTF(("aria_start_output %d @ %x\n", cc, (unsigned) p));
 1059 
 1060         if (cc != sc->sc_blocksize) {
 1061                 DPRINTF(("aria_start_output reqsize %d not sc_blocksize %d\n",
 1062                         cc, sc->sc_blocksize));
 1063                 return EINVAL;
 1064         }
 1065 
 1066         sc->sc_parg = arg;
 1067         sc->sc_pintr = intr;
 1068         sc->sc_pdiobuffer = p;
 1069 
 1070         if (!(sc->sc_play&(1<<ARIAR_PLAY_CHAN))) {
 1071                 aria_sendcmd(sc, ARIADSPC_START_PLAY, ARIAR_PLAY_CHAN, -1, -1);
 1072                 sc->sc_play |= (1<<ARIAR_PLAY_CHAN);
 1073         }
 1074 
 1075         return 0;
 1076 }
 1077 
 1078 /*
 1079  * Process an interrupt.  This should be a
 1080  * request (from the card) to write or read
 1081  * samples.
 1082  */
 1083 int
 1084 aria_intr(arg)
 1085         void *arg;
 1086 {
 1087         struct  aria_softc *sc = arg;
 1088         bus_space_tag_t iot = sc->sc_iot;
 1089         bus_space_handle_t ioh = sc->sc_ioh;
 1090         u_short *pdata = sc->sc_pdiobuffer;
 1091         u_short *rdata = sc->sc_rdiobuffer;
 1092         u_short address;
 1093 
 1094 #if 0 /*  XXX --  BAD BAD BAD (That this is #define'd out */
 1095         DPRINTF(("Checking to see if this is our intr\n"));
 1096 
 1097         if ((inw(iobase) & 1) != 0x1) 
 1098                 return 0;  /* not for us */
 1099 #endif
 1100 
 1101         sc->sc_interrupts++;
 1102 
 1103         DPRINTF(("aria_intr\n"));
 1104 
 1105         if ((sc->sc_open & ARIAR_OPEN_PLAY) && (pdata!=NULL)) {
 1106                 DPRINTF(("aria_intr play=(%x)\n", (unsigned) pdata));
 1107                 address = 0x8000 - 2*(sc->sc_blocksize);
 1108                 address+= aria_getdspmem(sc, ARIAA_PLAY_FIFO_A);
 1109                 bus_space_write_2(iot, ioh, ARIADSP_DMAADDRESS, address);
 1110                 bus_space_write_multi_2(iot, ioh, ARIADSP_DMADATA, pdata, 
 1111                                         sc->sc_blocksize / 2);
 1112                 if (sc->sc_pintr != NULL)
 1113                         (*sc->sc_pintr)(sc->sc_parg);
 1114         }
 1115 
 1116         if ((sc->sc_open & ARIAR_OPEN_RECORD) && (rdata!=NULL)) {
 1117                 DPRINTF(("aria_intr record=(%x)\n", (unsigned) rdata));
 1118                 address = 0x8000 - (sc->sc_blocksize);
 1119                 address+= aria_getdspmem(sc, ARIAA_REC_FIFO_A);
 1120                 bus_space_write_2(iot, ioh, ARIADSP_DMAADDRESS, address);
 1121                 bus_space_read_multi_2(iot, ioh, ARIADSP_DMADATA, rdata, 
 1122                                        sc->sc_blocksize / 2);
 1123                 if (sc->sc_rintr != NULL)
 1124                         (*sc->sc_rintr)(sc->sc_rarg);
 1125         }
 1126 
 1127         aria_sendcmd(sc, ARIADSPC_TRANSCOMPLETE, -1, -1, -1);
 1128 
 1129         return 1;
 1130 }
 1131 
 1132 int
 1133 aria_mixer_set_port(addr, cp)
 1134         void *addr;
 1135         mixer_ctrl_t *cp;
 1136 {
 1137         struct aria_softc *sc = addr;
 1138         int error = EINVAL;
 1139 
 1140         DPRINTF(("aria_mixer_set_port\n"));
 1141 
 1142         /* This could be done better, no mixer still has some controls. */
 1143         if (!(ARIA_MIXER & sc->sc_hardware))
 1144                 return ENXIO;
 1145 
 1146         if (cp->type == AUDIO_MIXER_VALUE) {
 1147                 mixer_level_t *mv = &cp->un.value;
 1148                 switch (cp->dev) {
 1149                 case ARIAMIX_MIC_LVL:
 1150                         if (mv->num_channels == 1 || mv->num_channels == 2) {
 1151                                 sc->aria_mix[ARIAMIX_MIC_LVL].num_channels = 
 1152                                         mv->num_channels;
 1153                                 sc->aria_mix[ARIAMIX_MIC_LVL].level[0] = 
 1154                                         mv->level[0];
 1155                                 sc->aria_mix[ARIAMIX_MIC_LVL].level[1] = 
 1156                                         mv->level[1];
 1157                                 error = 0;
 1158                         }
 1159                         break;
 1160         
 1161                 case ARIAMIX_LINE_IN_LVL:
 1162                         if (mv->num_channels == 1 || mv->num_channels == 2) {
 1163                                 sc->aria_mix[ARIAMIX_LINE_IN_LVL].num_channels=
 1164                                         mv->num_channels;
 1165                                 sc->aria_mix[ARIAMIX_LINE_IN_LVL].level[0] = 
 1166                                         mv->level[0];
 1167                                 sc->aria_mix[ARIAMIX_LINE_IN_LVL].level[1] = 
 1168                                         mv->level[1];
 1169                                 error = 0;
 1170                         }
 1171                         break;
 1172         
 1173                 case ARIAMIX_CD_LVL:
 1174                         if (mv->num_channels == 1 || mv->num_channels == 2) {
 1175                                 sc->aria_mix[ARIAMIX_CD_LVL].num_channels = 
 1176                                         mv->num_channels;
 1177                                 sc->aria_mix[ARIAMIX_CD_LVL].level[0] = 
 1178                                         mv->level[0];
 1179                                 sc->aria_mix[ARIAMIX_CD_LVL].level[1] = 
 1180                                         mv->level[1];
 1181                                 error = 0;
 1182                         }
 1183                         break;
 1184         
 1185                 case ARIAMIX_TEL_LVL:
 1186                         if (mv->num_channels == 1) {
 1187                                 sc->aria_mix[ARIAMIX_TEL_LVL].num_channels = 
 1188                                         mv->num_channels;
 1189                                 sc->aria_mix[ARIAMIX_TEL_LVL].level[0] = 
 1190                                         mv->level[0];
 1191                                 error = 0;
 1192                         }
 1193                         break;
 1194         
 1195                 case ARIAMIX_DAC_LVL:
 1196                         if (mv->num_channels == 1 || mv->num_channels == 2) {
 1197                                 sc->aria_mix[ARIAMIX_DAC_LVL].num_channels = 
 1198                                         mv->num_channels;
 1199                                 sc->aria_mix[ARIAMIX_DAC_LVL].level[0] = 
 1200                                         mv->level[0];
 1201                                 sc->aria_mix[ARIAMIX_DAC_LVL].level[1] = 
 1202                                         mv->level[1];
 1203                                 error = 0;
 1204                         }
 1205                         break;
 1206 
 1207                 case ARIAMIX_AUX_LVL:
 1208                         if (mv->num_channels == 1 || mv->num_channels == 2) {
 1209                                 sc->aria_mix[ARIAMIX_AUX_LVL].num_channels = 
 1210                                         mv->num_channels;
 1211                                 sc->aria_mix[ARIAMIX_AUX_LVL].level[0] = 
 1212                                         mv->level[0];
 1213                                 sc->aria_mix[ARIAMIX_AUX_LVL].level[1] = 
 1214                                         mv->level[1];
 1215                                 error = 0;
 1216                         }
 1217                         break;
 1218         
 1219                 case ARIAMIX_MASTER_LVL:
 1220                         if (mv->num_channels == 1 || mv->num_channels == 2) {
 1221                                 sc->ariamix_master.num_channels = 
 1222                                         mv->num_channels;
 1223                                 sc->ariamix_master.level[0] = mv->level[0];
 1224                                 sc->ariamix_master.level[1] = mv->level[1];
 1225                                 error = 0;
 1226                         }
 1227                         break;
 1228         
 1229                 case ARIAMIX_MASTER_TREBLE:
 1230                         if (mv->num_channels == 2) {
 1231                                 sc->ariamix_master.treble[0] = 
 1232                                         mv->level[0] == 0 ? 1 : mv->level[0];
 1233                                 sc->ariamix_master.treble[1] = 
 1234                                         mv->level[1] == 0 ? 1 : mv->level[1];
 1235                                 error = 0;
 1236                         }
 1237                         break;
 1238                 case ARIAMIX_MASTER_BASS:
 1239                         if (mv->num_channels == 2) {
 1240                                 sc->ariamix_master.bass[0] = 
 1241                                         mv->level[0] == 0 ? 1 : mv->level[0];
 1242                                 sc->ariamix_master.bass[1] = 
 1243                                         mv->level[1] == 0 ? 1 : mv->level[1];
 1244                                 error = 0;
 1245                         }
 1246                         break;
 1247                 case ARIAMIX_OUT_LVL:
 1248                         if (mv->num_channels == 1 || mv->num_channels == 2) {
 1249                                 sc->sc_gain[0] = mv->level[0];
 1250                                 sc->sc_gain[1] = mv->level[1];
 1251                                 error = 0;
 1252                         }
 1253                         break;
 1254                 default:
 1255                 }
 1256         }
 1257 
 1258         if (cp->type == AUDIO_MIXER_ENUM)
 1259                 switch(cp->dev) {
 1260                 case ARIAMIX_RECORD_SOURCE:
 1261                         if (cp->un.ord>=0 && cp->un.ord<=6) {
 1262                                 sc->aria_mix_source = cp->un.ord;
 1263                                 error = 0;
 1264                         }
 1265                         break;
 1266 
 1267                 case ARIAMIX_MIC_MUTE:
 1268                         if (cp->un.ord == 0 || cp->un.ord == 1) {
 1269                                 sc->aria_mix[ARIAMIX_MIC_LVL].mute =cp->un.ord;
 1270                                 error = 0;
 1271                         }
 1272                         break;
 1273 
 1274                 case ARIAMIX_LINE_IN_MUTE:
 1275                         if (cp->un.ord == 0 || cp->un.ord == 1) {
 1276                                 sc->aria_mix[ARIAMIX_LINE_IN_LVL].mute = 
 1277                                         cp->un.ord;
 1278                                 error = 0;
 1279                         }
 1280                         break;
 1281 
 1282                 case ARIAMIX_CD_MUTE:
 1283                         if (cp->un.ord == 0 || cp->un.ord == 1) {
 1284                                 sc->aria_mix[ARIAMIX_CD_LVL].mute = cp->un.ord;
 1285                                 error = 0;
 1286                         }
 1287                         break;
 1288 
 1289                 case ARIAMIX_DAC_MUTE:
 1290                         if (cp->un.ord == 0 || cp->un.ord == 1) {
 1291                                 sc->aria_mix[ARIAMIX_DAC_LVL].mute =cp->un.ord;
 1292                                 error = 0;
 1293                         }
 1294                         break;
 1295 
 1296                 case ARIAMIX_AUX_MUTE:
 1297                         if (cp->un.ord == 0 || cp->un.ord == 1) {
 1298                                 sc->aria_mix[ARIAMIX_AUX_LVL].mute =cp->un.ord;
 1299                                 error = 0;
 1300                         }
 1301                         break;
 1302 
 1303                 case ARIAMIX_TEL_MUTE:
 1304                         if (cp->un.ord == 0 || cp->un.ord == 1) {
 1305                                 sc->aria_mix[ARIAMIX_TEL_LVL].mute =cp->un.ord;
 1306                                 error = 0;
 1307                         }
 1308                         break;
 1309 
 1310                 default:
 1311                         /* NOTREACHED */
 1312                         return ENXIO;
 1313                 }
 1314 
 1315         return(error);
 1316 }
 1317 
 1318 int
 1319 aria_mixer_get_port(addr, cp)
 1320     void *addr;
 1321     mixer_ctrl_t *cp;
 1322 {
 1323         struct aria_softc *sc = addr;
 1324         int error = EINVAL;
 1325 
 1326         DPRINTF(("aria_mixer_get_port\n"));
 1327 
 1328         /* This could be done better, no mixer still has some controls. */
 1329         if (!(ARIA_MIXER&sc->sc_hardware))
 1330                 return ENXIO;
 1331 
 1332         switch (cp->dev) {
 1333         case ARIAMIX_MIC_LVL:
 1334                 if (cp->type == AUDIO_MIXER_VALUE) {
 1335                         cp->un.value.num_channels = 
 1336                                 sc->aria_mix[ARIAMIX_MIC_LVL].num_channels;
 1337                         cp->un.value.level[0] = 
 1338                                 sc->aria_mix[ARIAMIX_MIC_LVL].level[0];
 1339                         cp->un.value.level[1] = 
 1340                                 sc->aria_mix[ARIAMIX_MIC_LVL].level[1];
 1341                         error = 0;
 1342                 }
 1343                 break;
 1344                         
 1345         case ARIAMIX_LINE_IN_LVL:
 1346                 if (cp->type == AUDIO_MIXER_VALUE) {
 1347                         cp->un.value.num_channels = 
 1348                                 sc->aria_mix[ARIAMIX_LINE_IN_LVL].num_channels;
 1349                         cp->un.value.level[0] = 
 1350                                 sc->aria_mix[ARIAMIX_LINE_IN_LVL].level[0];
 1351                         cp->un.value.level[1] = 
 1352                                 sc->aria_mix[ARIAMIX_LINE_IN_LVL].level[1];
 1353                         error = 0;
 1354                 }
 1355                 break;
 1356 
 1357         case ARIAMIX_CD_LVL:
 1358                 if (cp->type == AUDIO_MIXER_VALUE) {
 1359                         cp->un.value.num_channels = 
 1360                                 sc->aria_mix[ARIAMIX_CD_LVL].num_channels;
 1361                         cp->un.value.level[0] = 
 1362                                 sc->aria_mix[ARIAMIX_CD_LVL].level[0];
 1363                         cp->un.value.level[1] = 
 1364                                 sc->aria_mix[ARIAMIX_CD_LVL].level[1];
 1365                         error = 0;
 1366                 }
 1367                 break;
 1368 
 1369         case ARIAMIX_TEL_LVL:
 1370                 if (cp->type == AUDIO_MIXER_VALUE) {
 1371                         cp->un.value.num_channels = 
 1372                                 sc->aria_mix[ARIAMIX_TEL_LVL].num_channels;
 1373                         cp->un.value.level[0] = 
 1374                                 sc->aria_mix[ARIAMIX_TEL_LVL].level[0];
 1375                         error = 0;
 1376                 }
 1377                 break;
 1378         case ARIAMIX_DAC_LVL:
 1379                 if (cp->type == AUDIO_MIXER_VALUE) {
 1380                         cp->un.value.num_channels = 
 1381                                 sc->aria_mix[ARIAMIX_DAC_LVL].num_channels;
 1382                         cp->un.value.level[0] = 
 1383                                 sc->aria_mix[ARIAMIX_DAC_LVL].level[0];
 1384                         cp->un.value.level[1] = 
 1385                                 sc->aria_mix[ARIAMIX_DAC_LVL].level[1];
 1386                         error = 0;
 1387                 }
 1388                 break;
 1389 
 1390         case ARIAMIX_AUX_LVL:
 1391                 if (cp->type == AUDIO_MIXER_VALUE) {
 1392                         cp->un.value.num_channels = 
 1393                                 sc->aria_mix[ARIAMIX_AUX_LVL].num_channels;
 1394                         cp->un.value.level[0] = 
 1395                                 sc->aria_mix[ARIAMIX_AUX_LVL].level[0];
 1396                         cp->un.value.level[1] = 
 1397                                 sc->aria_mix[ARIAMIX_AUX_LVL].level[1];
 1398                         error = 0;
 1399                 }
 1400                 break;
 1401 
 1402         case ARIAMIX_MIC_MUTE:
 1403                 if (cp->type == AUDIO_MIXER_ENUM) {
 1404                         cp->un.ord = sc->aria_mix[ARIAMIX_MIC_LVL].mute;
 1405                         error = 0;
 1406                 }
 1407                 break;
 1408 
 1409         case ARIAMIX_LINE_IN_MUTE:
 1410                 if (cp->type == AUDIO_MIXER_ENUM) {
 1411                         cp->un.ord = sc->aria_mix[ARIAMIX_LINE_IN_LVL].mute;
 1412                         error = 0;
 1413                 }
 1414                 break;
 1415 
 1416         case ARIAMIX_CD_MUTE:
 1417                 if (cp->type == AUDIO_MIXER_ENUM) {
 1418                         cp->un.ord = sc->aria_mix[ARIAMIX_CD_LVL].mute;
 1419                         error = 0;
 1420                 }
 1421                 break;
 1422 
 1423         case ARIAMIX_DAC_MUTE:
 1424                 if (cp->type == AUDIO_MIXER_ENUM) {
 1425                         cp->un.ord = sc->aria_mix[ARIAMIX_DAC_LVL].mute;
 1426                         error = 0;
 1427                 }
 1428                 break;
 1429 
 1430         case ARIAMIX_AUX_MUTE:
 1431                 if (cp->type == AUDIO_MIXER_ENUM) {
 1432                         cp->un.ord = sc->aria_mix[ARIAMIX_AUX_LVL].mute;
 1433                         error = 0;
 1434                 }
 1435                 break;
 1436 
 1437         case ARIAMIX_TEL_MUTE:
 1438                 if (cp->type == AUDIO_MIXER_ENUM) {
 1439                         cp->un.ord = sc->aria_mix[ARIAMIX_TEL_LVL].mute;
 1440                         error = 0;
 1441                 }
 1442                 break;
 1443 
 1444         case ARIAMIX_MASTER_LVL:
 1445                 if (cp->type == AUDIO_MIXER_VALUE) {
 1446                         cp->un.value.num_channels = 
 1447                                 sc->ariamix_master.num_channels;
 1448                         cp->un.value.level[0] = sc->ariamix_master.level[0];
 1449                         cp->un.value.level[1] = sc->ariamix_master.level[1];
 1450                         error = 0;
 1451                 }
 1452                 break;
 1453 
 1454         case ARIAMIX_MASTER_TREBLE:
 1455                 if (cp->type == AUDIO_MIXER_VALUE) {
 1456                         cp->un.value.num_channels = 2;
 1457                         cp->un.value.level[0] = sc->ariamix_master.treble[0];
 1458                         cp->un.value.level[1] = sc->ariamix_master.treble[1];
 1459                         error = 0;
 1460                 }
 1461                 break;
 1462 
 1463         case ARIAMIX_MASTER_BASS:
 1464                 if (cp->type == AUDIO_MIXER_VALUE) {
 1465                         cp->un.value.num_channels = 2;
 1466                         cp->un.value.level[0] = sc->ariamix_master.bass[0];
 1467                         cp->un.value.level[1] = sc->ariamix_master.bass[1];
 1468                         error = 0;
 1469                 }
 1470                 break;
 1471 
 1472         case ARIAMIX_OUT_LVL:
 1473                 if (cp->type == AUDIO_MIXER_VALUE) {
 1474                         cp->un.value.num_channels = sc->sc_chans;
 1475                         cp->un.value.level[0] = sc->sc_gain[0];
 1476                         cp->un.value.level[1] = sc->sc_gain[1];
 1477                         error = 0;
 1478                 }
 1479                 break;
 1480         case ARIAMIX_RECORD_SOURCE:
 1481                 if (cp->type == AUDIO_MIXER_ENUM) {
 1482                         cp->un.ord = sc->aria_mix_source;
 1483                         error = 0;
 1484                 }
 1485                 break;
 1486 
 1487         default:
 1488                 return ENXIO;
 1489                 /* NOT REACHED */
 1490         }
 1491 
 1492         return(error);
 1493 }
 1494 
 1495 int
 1496 aria_mixer_query_devinfo(addr, dip)
 1497            void *addr;
 1498            mixer_devinfo_t *dip;
 1499 {
 1500 
 1501         struct aria_softc *sc = addr;
 1502 
 1503         DPRINTF(("aria_mixer_query_devinfo\n"));
 1504 
 1505         /* This could be done better, no mixer still has some controls. */
 1506         if (!(ARIA_MIXER & sc->sc_hardware))
 1507                 return ENXIO;
 1508 
 1509         dip->prev = dip->next = AUDIO_MIXER_LAST;
 1510 
 1511         switch(dip->index) {
 1512         case ARIAMIX_MIC_LVL:
 1513                 dip->type = AUDIO_MIXER_VALUE;
 1514                 dip->mixer_class = ARIAMIX_INPUT_CLASS;
 1515                 dip->next = ARIAMIX_MIC_MUTE;
 1516                 strcpy(dip->label.name, AudioNmicrophone);
 1517                 dip->un.v.num_channels = 2;
 1518                 strcpy(dip->un.v.units.name, AudioNvolume);
 1519                 break;
 1520 
 1521         case ARIAMIX_LINE_IN_LVL:
 1522                 dip->type = AUDIO_MIXER_VALUE;
 1523                 dip->mixer_class = ARIAMIX_INPUT_CLASS;
 1524                 dip->next = ARIAMIX_LINE_IN_MUTE;
 1525                 strcpy(dip->label.name, AudioNline);
 1526                 dip->un.v.num_channels = 2;
 1527                 strcpy(dip->un.v.units.name, AudioNvolume);
 1528                 break;
 1529 
 1530         case ARIAMIX_CD_LVL:
 1531                 dip->type = AUDIO_MIXER_VALUE;
 1532                 dip->mixer_class = ARIAMIX_INPUT_CLASS;
 1533                 dip->next = ARIAMIX_CD_MUTE;
 1534                 strcpy(dip->label.name, AudioNcd);
 1535                 dip->un.v.num_channels = 2;
 1536                 strcpy(dip->un.v.units.name, AudioNvolume);
 1537                 break;
 1538 
 1539         case ARIAMIX_TEL_LVL:
 1540                 dip->type = AUDIO_MIXER_VALUE;
 1541                 dip->mixer_class = ARIAMIX_INPUT_CLASS;
 1542                 dip->next = ARIAMIX_TEL_MUTE;
 1543                 strcpy(dip->label.name, "telephone");
 1544                 dip->un.v.num_channels = 1;
 1545                 strcpy(dip->un.v.units.name, AudioNvolume);
 1546                 break;
 1547 
 1548         case ARIAMIX_DAC_LVL:
 1549                 dip->type = AUDIO_MIXER_VALUE;
 1550                 dip->mixer_class = ARIAMIX_INPUT_CLASS;
 1551                 dip->next = ARIAMIX_DAC_MUTE;
 1552                 strcpy(dip->label.name, AudioNdac);
 1553                 dip->un.v.num_channels = 1;
 1554                 strcpy(dip->un.v.units.name, AudioNvolume);
 1555                 break;
 1556 
 1557         case ARIAMIX_AUX_LVL:
 1558                 dip->type = AUDIO_MIXER_VALUE;
 1559                 dip->mixer_class = ARIAMIX_INPUT_CLASS;
 1560                 dip->next = ARIAMIX_AUX_MUTE;
 1561                 strcpy(dip->label.name, AudioNoutput);
 1562                 dip->un.v.num_channels = 1;
 1563                 strcpy(dip->un.v.units.name, AudioNvolume);
 1564                 break;
 1565 
 1566         case ARIAMIX_MIC_MUTE:
 1567                 dip->prev = ARIAMIX_MIC_LVL;
 1568                 goto mute;
 1569 
 1570         case ARIAMIX_LINE_IN_MUTE:
 1571                 dip->prev = ARIAMIX_LINE_IN_LVL;
 1572                 goto mute;
 1573         
 1574         case ARIAMIX_CD_MUTE:
 1575                 dip->prev = ARIAMIX_CD_LVL;
 1576                 goto mute;
 1577         
 1578         case ARIAMIX_DAC_MUTE:
 1579                 dip->prev = ARIAMIX_DAC_LVL;
 1580                 goto mute;
 1581 
 1582         case ARIAMIX_AUX_MUTE:
 1583                 dip->prev = ARIAMIX_AUX_LVL;
 1584                 goto mute;
 1585 
 1586         case ARIAMIX_TEL_MUTE:
 1587                 dip->prev = ARIAMIX_TEL_LVL;
 1588                 goto mute;
 1589 
 1590 mute:
 1591                 dip->mixer_class = ARIAMIX_INPUT_CLASS;
 1592                 dip->type = AUDIO_MIXER_ENUM;
 1593                 strcpy(dip->label.name, AudioNmute);
 1594                 dip->un.e.num_mem = 2;
 1595                 strcpy(dip->un.e.member[0].label.name, AudioNoff);
 1596                 dip->un.e.member[0].ord = 0;
 1597                 strcpy(dip->un.e.member[1].label.name, AudioNon);
 1598                 dip->un.e.member[1].ord = 1;
 1599                 break;
 1600 
 1601         case ARIAMIX_MASTER_LVL:
 1602                 dip->type = AUDIO_MIXER_VALUE;
 1603                 dip->mixer_class = ARIAMIX_OUTPUT_CLASS;
 1604                 dip->next = AUDIO_MIXER_LAST;
 1605                 strcpy(dip->label.name, AudioNvolume);
 1606                 dip->un.v.num_channels = 2;
 1607                 strcpy(dip->un.v.units.name, AudioNvolume);
 1608                 break;
 1609 
 1610         case ARIAMIX_MASTER_TREBLE:
 1611                 dip->type = AUDIO_MIXER_VALUE;
 1612                 dip->mixer_class = ARIAMIX_EQ_CLASS;
 1613                 strcpy(dip->label.name, AudioNtreble);
 1614                 dip->un.v.num_channels = 2;
 1615                 strcpy(dip->un.v.units.name, AudioNtreble);
 1616                 break;
 1617 
 1618         case ARIAMIX_MASTER_BASS:
 1619                 dip->type = AUDIO_MIXER_VALUE;
 1620                 dip->mixer_class = ARIAMIX_EQ_CLASS;
 1621                 strcpy(dip->label.name, AudioNbass);
 1622                 dip->un.v.num_channels = 2;
 1623                 strcpy(dip->un.v.units.name, AudioNbass);
 1624                 break;
 1625 
 1626         case ARIAMIX_OUT_LVL:
 1627                 dip->type = AUDIO_MIXER_VALUE;
 1628                 dip->mixer_class = ARIAMIX_OUTPUT_CLASS;
 1629                 strcpy(dip->label.name, AudioNoutput);
 1630                 dip->un.v.num_channels = 2;
 1631                 strcpy(dip->un.v.units.name, AudioNvolume);
 1632                 break;
 1633 
 1634         case ARIAMIX_RECORD_SOURCE:
 1635                 dip->mixer_class = ARIAMIX_RECORD_CLASS;
 1636                 dip->type = AUDIO_MIXER_ENUM;
 1637                 strcpy(dip->label.name, AudioNsource);
 1638                 dip->un.e.num_mem = 6;
 1639                 strcpy(dip->un.e.member[0].label.name, AudioNoutput);
 1640                 dip->un.e.member[0].ord = ARIAMIX_AUX_LVL;
 1641                 strcpy(dip->un.e.member[1].label.name, AudioNmicrophone);
 1642                 dip->un.e.member[1].ord = ARIAMIX_MIC_LVL;
 1643                 strcpy(dip->un.e.member[2].label.name, AudioNdac);
 1644                 dip->un.e.member[2].ord = ARIAMIX_DAC_LVL;
 1645                 strcpy(dip->un.e.member[3].label.name, AudioNline);
 1646                 dip->un.e.member[3].ord = ARIAMIX_LINE_IN_LVL;
 1647                 strcpy(dip->un.e.member[4].label.name, AudioNcd);
 1648                 dip->un.e.member[4].ord = ARIAMIX_CD_LVL;
 1649                 strcpy(dip->un.e.member[5].label.name, "telephone");
 1650                 dip->un.e.member[5].ord = ARIAMIX_TEL_LVL;
 1651                 break;
 1652 
 1653         case ARIAMIX_INPUT_CLASS:
 1654                 dip->type = AUDIO_MIXER_CLASS;
 1655                 dip->mixer_class = ARIAMIX_INPUT_CLASS;
 1656                 strcpy(dip->label.name, AudioCinputs);
 1657                 break;
 1658 
 1659         case ARIAMIX_OUTPUT_CLASS:
 1660                 dip->type = AUDIO_MIXER_CLASS;
 1661                 dip->mixer_class = ARIAMIX_OUTPUT_CLASS;
 1662                 strcpy(dip->label.name, AudioCoutputs);
 1663                 break;
 1664 
 1665         case ARIAMIX_RECORD_CLASS:
 1666                 dip->type = AUDIO_MIXER_CLASS;
 1667                 dip->mixer_class = ARIAMIX_RECORD_CLASS;
 1668                 strcpy(dip->label.name, AudioCrecord);
 1669                 break;
 1670 
 1671         case ARIAMIX_EQ_CLASS:
 1672                 dip->type = AUDIO_MIXER_CLASS;
 1673                 dip->mixer_class = ARIAMIX_EQ_CLASS;
 1674                 strcpy(dip->label.name, AudioCequalization);
 1675                 break;
 1676 
 1677         default:
 1678                 return ENXIO;
 1679                 /*NOTREACHED*/
 1680         }
 1681         return 0;
 1682 }

Cache object: 836d996d87d4ff07acc7f181d5acb5b4


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