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/pss.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: pss.c,v 1.64 2003/05/03 18:11:28 wiz Exp $     */
    2 
    3 /* XXX THIS DRIVER IS BROKEN.  IT WILL NOT EVEN COMPILE. */
    4 
    5 /*
    6  * Copyright (c) 1994 John Brezak
    7  * Copyright (c) 1991-1993 Regents of the University of California.
    8  * All rights reserved.
    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  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *      This product includes software developed by the Computer Systems
   21  *      Engineering Group at Lawrence Berkeley Laboratory.
   22  * 4. Neither the name of the University nor of the Laboratory may be used
   23  *    to endorse or promote products derived from this software without
   24  *    specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   36  * SUCH DAMAGE.
   37  *
   38  */
   39 
   40 /*
   41  * Copyright (c) 1993 Analog Devices Inc. All rights reserved
   42  *
   43  * Portions provided by Marc.Hoffman@analog.com and
   44  * Greg.Yukna@analog.com .
   45  *
   46  */
   47 
   48 /*
   49  * Todo:
   50  *      - Provide PSS driver to access DSP
   51  *      - Provide MIDI driver to access MPU
   52  *      - Finish support for CD drive (Sony and SCSI)
   53  */
   54 
   55 #include <sys/cdefs.h>
   56 __KERNEL_RCSID(0, "$NetBSD: pss.c,v 1.64 2003/05/03 18:11:28 wiz Exp $");
   57 
   58 #include <sys/param.h>
   59 #include <sys/systm.h>
   60 #include <sys/device.h>
   61 #include <sys/errno.h>
   62 
   63 #include <machine/cpu.h>
   64 #include <machine/intr.h>
   65 #include <machine/bus.h>
   66 #include <machine/pio.h>
   67 
   68 #include <sys/audioio.h>
   69 #include <dev/audio_if.h>
   70 
   71 #include <dev/isa/isavar.h>
   72 #include <dev/isa/isadmavar.h>
   73 
   74 #include <dev/isa/ad1848var.h>
   75 #include <dev/isa/wssreg.h>
   76 #include <dev/isa/pssreg.h>
   77 
   78 /* XXX Default WSS base */
   79 #define WSS_BASE_ADDRESS 0x0530
   80 
   81 /*
   82  * Mixer devices
   83  */
   84 #define PSS_MIC_IN_LVL          0
   85 #define PSS_LINE_IN_LVL         1
   86 #define PSS_DAC_LVL             2
   87 #define PSS_REC_LVL             3
   88 #define PSS_MONITOR_LVL         4
   89 #define PSS_MASTER_VOL          5
   90 #define PSS_MASTER_TREBLE       6
   91 #define PSS_MASTER_BASS         7
   92 #define PSS_MIC_IN_MUTE         8
   93 #define PSS_LINE_IN_MUTE        9
   94 #define PSS_DAC_MUTE            10
   95 #define PSS_MONITOR_MUTE        11
   96 
   97 #define PSS_OUTPUT_MODE         12
   98 #define         PSS_SPKR_MONO   0
   99 #define         PSS_SPKR_STEREO 1
  100 #define         PSS_SPKR_PSEUDO 2
  101 #define         PSS_SPKR_SPATIAL 3
  102 
  103 #define PSS_RECORD_SOURCE       13
  104 
  105 /* Classes */
  106 #define PSS_INPUT_CLASS         14
  107 #define PSS_RECORD_CLASS        15
  108 #define PSS_MONITOR_CLASS       16
  109 #define PSS_OUTPUT_CLASS        17
  110 
  111 
  112 struct pss_softc {
  113         struct  device sc_dev;          /* base device */
  114         void    *sc_ih;                 /* interrupt vectoring */
  115 
  116         int     sc_iobase;              /* I/O port base address */
  117         int     sc_drq;                 /* DMA channel */
  118 
  119         struct  ad1848_softc *ad1848_sc;
  120         
  121         int     out_port;
  122         
  123         struct  ad1848_volume master_volume;
  124         int     master_mode;
  125         
  126         int     monitor_treble;
  127         int     monitor_bass;
  128 
  129         int     mic_mute, cd_mute, dac_mute;
  130 };
  131 
  132 #ifdef notyet
  133 struct mpu_softc {
  134         struct  device sc_dev;          /* base device */
  135         void    *sc_ih;                 /* interrupt vectoring */
  136     
  137         int     sc_iobase;              /* MIDI I/O port base address */
  138         int     sc_irq;                 /* MIDI interrupt */
  139 };
  140 
  141 struct pcd_softc {
  142         struct  device sc_dev;          /* base device */
  143         void    *sc_ih;                 /* interrupt vectoring */
  144 
  145         int     sc_iobase;              /* CD I/O port base address */
  146         int     sc_irq;                 /* CD interrupt */
  147 };
  148 #endif
  149 
  150 #ifdef AUDIO_DEBUG
  151 #define DPRINTF(x)      if (pssdebug) printf x
  152 int     pssdebug = 0;
  153 #else
  154 #define DPRINTF(x)
  155 #endif
  156 
  157 int     pssprobe __P((struct device *, struct cfdata *, void *));
  158 void    pssattach __P((struct device *, struct device *, void *));
  159 static  int pssfind __P((struct device *, struct pss_softc *, 
  160                          struct isa_attach_args *));
  161 
  162 int     spprobe __P((struct device *, struct cfdata *, void *));
  163 void    spattach __P((struct device *, struct device *, void *));
  164 static  int spfind __P((struct device *, struct ad1848_isa_softc *, 
  165                         struct isa_attach_args *));
  166 
  167 #ifdef notyet
  168 int     mpuprobe __P((struct device *, struct cfdata *, void *));
  169 void    mpuattach __P((struct device *, struct device *, void *));
  170 
  171 int     pcdprobe __P((struct device *, struct cfdata *, void *));
  172 void    pcdattach __P((struct device *, struct device *, void *));
  173 #endif
  174 
  175 int     pssintr __P((void *));
  176 #ifdef notyet
  177 int     mpuintr __P((void *));
  178 #endif
  179 
  180 int     pss_speaker_ctl __P((void *, int));
  181 
  182 int     pss_getdev __P((void *, struct audio_device *));
  183 
  184 int     pss_mixer_set_port __P((void *, mixer_ctrl_t *));
  185 int     pss_mixer_get_port __P((void *, mixer_ctrl_t *));
  186 int     pss_query_devinfo __P((void *, mixer_devinfo_t *));
  187 
  188 #ifdef PSS_DSP
  189 void    pss_dspwrite __P((struct pss_softc *, int));
  190 #endif
  191 void    pss_setaddr __P((int, int));
  192 int     pss_setint __P((int, int));
  193 int     pss_setdma __P((int, int));
  194 int     pss_testirq __P((struct pss_softc *, int));
  195 int     pss_testdma __P((struct pss_softc *, int));
  196 #ifdef notyet
  197 int     pss_reset_dsp __P((struct pss_softc *));
  198 int     pss_download_dsp __P((struct pss_softc *, u_char *, int));
  199 #endif
  200 #ifdef AUDIO_DEBUG
  201 void    pss_dump_regs __P((struct pss_softc *));
  202 #endif
  203 int     pss_set_master_gain __P((struct pss_softc *, struct ad1848_volume *));
  204 int     pss_set_master_mode __P((struct pss_softc *, int));
  205 int     pss_set_treble __P((struct pss_softc *, u_int));
  206 int     pss_set_bass __P((struct pss_softc *, u_int));
  207 int     pss_get_master_gain __P((struct pss_softc *, struct ad1848_volume *));
  208 int     pss_get_master_mode __P((struct pss_softc *, u_int *));
  209 int     pss_get_treble __P((struct pss_softc *, u_char *));
  210 int     pss_get_bass __P((struct pss_softc *, u_char *));
  211 
  212 #ifdef AUDIO_DEBUG
  213 void    wss_dump_regs __P((struct ad1848_isa_softc *));
  214 #endif
  215 
  216 /*
  217  * Define our interface to the higher level audio driver.
  218  */
  219 
  220 struct audio_hw_if pss_audio_if = {
  221         ad1848_isa_open,
  222         ad1848_isa_close,
  223         NULL,
  224         ad1848_query_encoding,
  225         ad1848_set_params,
  226         ad1848_round_blocksize,
  227         ad1848_commit_settings,
  228         NULL,
  229         NULL,
  230         NULL,
  231         NULL,
  232         ad1848_isa_halt_output,
  233         ad1848_isa_halt_input,
  234         pss_speaker_ctl,
  235         pss_getdev,
  236         NULL,
  237         pss_mixer_set_port,
  238         pss_mixer_get_port,
  239         pss_query_devinfo,
  240         ad1848_isa_malloc,
  241         ad1848_isa_free,
  242         ad1848_isa_round_buffersize,
  243         ad1848_isa_mappage,
  244         ad1848_isa_get_props,
  245         ad1848_isa_trigger_output,
  246         ad1848_isa_trigger_input,
  247         NULL,
  248 };
  249 
  250 /* Interrupt translation for WSS config */
  251 static u_char wss_interrupt_bits[16] = {
  252     0xff, 0xff, 0xff, 0xff,
  253     0xff, 0xff, 0xff, 0x08,
  254     0xff, 0x10, 0x18, 0x20,
  255     0xff, 0xff, 0xff, 0xff
  256 };
  257 /* ditto for WSS DMA channel */
  258 static u_char wss_dma_bits[4] = {1, 2, 0, 3};
  259 
  260 CFATTACH_DECL(pss, sizeof(struct pss_softc),
  261     pssprobe, pssattach, NULL, NULL);
  262 
  263 CFATTACH_DECL(sp, sizeof(struct ad1848_isa_softc),
  264     spprobe, spattach, NULL, NULL);
  265 
  266 #ifdef notyet
  267 CFATTACH_DECL(mpu, sizeof(struct mpu_softc),
  268     mpuprobe, mpuattach, NULL, NULL);
  269 
  270 CFATTACH_DECL(pcd, sizeof(struct pcd_softc),
  271     pcdprobe, pcdattach, NULL, NULL);
  272 
  273 #endif
  274 
  275 struct audio_device pss_device = {
  276         "pss,ad1848",
  277         "",
  278         "PSS"
  279 };
  280 
  281 #ifdef PSS_DSP
  282 void
  283 pss_dspwrite(sc, data)
  284         struct pss_softc *sc;
  285         int data;
  286 {
  287     int i;
  288     int pss_base = sc->sc_iobase;
  289 
  290     /*
  291      * Note! the i<5000000 is an emergency exit. The dsp_command() is sometimes
  292      * called while interrupts are disabled. This means that the timer is
  293      * disabled also. However the timeout situation is a abnormal condition.
  294      * Normally the DSP should be ready to accept commands after just couple of
  295      * loops.
  296      */
  297     for (i = 0; i < 5000000; i++) {
  298         if (inw(pss_base+PSS_STATUS) & PSS_WRITE_EMPTY) {
  299             outw(pss_base+PSS_DATA, data);
  300             return;
  301         }
  302     }
  303     printf ("pss: DSP Command (%04x) Timeout.\n", data);
  304 }
  305 #endif /* PSS_DSP */
  306 
  307 void
  308 pss_setaddr(addr, configAddr)
  309         int addr;
  310         int configAddr;
  311 {
  312     int val;
  313     
  314     val = inw(configAddr);
  315     val &= ADDR_MASK;
  316     val |= (addr << 4);
  317     outw(configAddr,val);
  318 }
  319 
  320 /* pss_setint
  321  * This function sets the correct bits in the 
  322  * configuration register to 
  323  * enable the chosen interrupt.
  324  */
  325 int
  326 pss_setint(intNum, configAddress)
  327         int intNum;
  328         int configAddress;
  329 {
  330     int val;
  331 
  332     switch(intNum) {
  333     case 3:
  334         val = inw(configAddress);
  335         val &= INT_MASK;
  336         val |= INT_3_BITS;
  337         break;
  338     case 5:
  339         val = inw(configAddress);
  340         val &= INT_MASK;
  341         val |= INT_5_BITS;
  342         break;
  343     case 7:
  344         val = inw(configAddress);
  345         val &= INT_MASK;
  346         val |= INT_7_BITS;
  347         break;
  348     case 9:
  349         val = inw(configAddress);
  350         val &= INT_MASK;
  351         val |= INT_9_BITS;
  352         break;
  353     case 10:
  354         val = inw(configAddress);
  355         val &= INT_MASK;
  356         val |= INT_10_BITS;
  357         break;
  358     case 11:
  359         val = inw(configAddress);
  360         val &= INT_MASK;
  361         val |= INT_11_BITS;
  362         break;
  363     case 12:
  364         val = inw(configAddress);
  365         val &= INT_MASK;
  366         val |= INT_12_BITS;
  367         break;
  368     default:
  369         DPRINTF(("pss_setint: invalid irq (%d)\n", intNum));
  370         return 1;
  371     }
  372     outw(configAddress,val);
  373     return 0;
  374 }
  375 
  376 int
  377 pss_setdma(dmaNum, configAddress)
  378         int dmaNum;
  379         int configAddress;
  380 {
  381     int val;
  382     
  383     switch(dmaNum) {
  384     case 0:
  385         val = inw(configAddress);
  386         val &= DMA_MASK;
  387         val |= DMA_0_BITS;
  388         break;
  389     case 1:
  390         val = inw(configAddress);
  391         val &= DMA_MASK;
  392         val |= DMA_1_BITS;
  393         break;
  394     case 3:
  395         val = inw(configAddress);
  396         val &= DMA_MASK;
  397         val |= DMA_3_BITS;
  398         break;
  399     case 5:
  400         val = inw(configAddress);
  401         val &= DMA_MASK;
  402         val |= DMA_5_BITS;
  403         break;
  404     case 6:
  405         val = inw(configAddress);
  406         val &= DMA_MASK;
  407         val |= DMA_6_BITS;
  408         break;
  409     case 7:
  410         val = inw(configAddress);
  411         val &= DMA_MASK;
  412         val |= DMA_7_BITS;
  413         break;
  414     default:
  415         DPRINTF(("pss_setdma: invalid drq (%d)\n", dmaNum));
  416         return 1;
  417     }
  418     outw(configAddress, val);
  419     return 0;
  420 }
  421 
  422 /*
  423  * This function tests an interrupt number to see if
  424  * it is available. It takes the interrupt button
  425  * as its argument and returns TRUE if the interrupt
  426  * is ok.
  427 */
  428 int
  429 pss_testirq(struct pss_softc *sc, int intNum)
  430 {
  431     int config = sc->sc_iobase + PSS_CONFIG;
  432     int val;
  433     int ret;
  434     int i;
  435 
  436     /* Set the interrupt bits */
  437     switch(intNum) {
  438     case 3:
  439         val = inw(config);
  440         val &= INT_MASK;        /* Special: 0 */
  441         break;
  442     case 5:
  443         val = inw(config);
  444         val &= INT_MASK;
  445         val |= INT_TEST_BIT | INT_5_BITS;
  446         break;
  447     case 7:
  448         val = inw(config);
  449         val &= INT_MASK;
  450         val |= INT_TEST_BIT | INT_7_BITS;
  451         break;
  452     case 9:
  453         val = inw(config);
  454         val &= INT_MASK;
  455         val |= INT_TEST_BIT | INT_9_BITS;
  456         break;
  457     case 10:
  458         val = inw(config);
  459         val &= INT_MASK;
  460         val |= INT_TEST_BIT | INT_10_BITS;
  461         break;
  462     case 11:
  463         val = inw(config);
  464         val &= INT_MASK;
  465         val |= INT_TEST_BIT | INT_11_BITS;
  466         break;
  467     case 12:
  468         val = inw(config);
  469         val &= INT_MASK;
  470         val |= INT_TEST_BIT | INT_12_BITS;
  471         break;
  472     default:
  473         DPRINTF(("pss_testirq: invalid irq (%d)\n", intNum));
  474         return 0;
  475     }
  476     outw(config, val);
  477 
  478     /* Check if the interrupt is in use */
  479     /* Do it a few times in case there is a delay */
  480     ret = 0;
  481     for (i = 0; i < 5; i++) {
  482         val = inw(config);
  483         if (val & INT_TEST_PASS) {
  484             ret = 1;
  485             break;
  486         }
  487     }
  488 
  489     /* Clear the Test bit and the interrupt bits */
  490     val = inw(config);
  491     val &= INT_TEST_BIT_MASK & INT_MASK;
  492     outw(config, val);
  493     return(ret);
  494 }
  495 
  496 /*
  497  * This function tests a DMA channel to see if
  498  * it is available. It takes the DMA channel button
  499  * as its argument and returns TRUE if the channel
  500  * is ok.
  501  */
  502 int
  503 pss_testdma(sc, dmaNum)
  504         struct pss_softc *sc;
  505         int dmaNum;
  506 {
  507     int config = sc->sc_iobase + PSS_CONFIG;
  508     int val;
  509     int i, ret;
  510 
  511     switch (dmaNum) {
  512     case 0:
  513         val = inw(config);
  514         val &= DMA_MASK;
  515         val |= DMA_TEST_BIT | DMA_0_BITS;
  516         break;
  517     case 1:
  518         val = inw(config);
  519         val &= DMA_MASK;
  520         val |= DMA_TEST_BIT | DMA_1_BITS;
  521         break;
  522     case 3:
  523         val = inw(config);
  524         val &= DMA_MASK;
  525         val |= DMA_TEST_BIT | DMA_3_BITS;
  526         break;
  527     case 5:
  528         val = inw(config);
  529         val &= DMA_MASK;
  530         val |= DMA_TEST_BIT | DMA_5_BITS;
  531         break;
  532     case 6:
  533         val = inw(config);
  534         val &= DMA_MASK;
  535         val |= DMA_TEST_BIT | DMA_6_BITS;
  536         break;
  537     case 7:
  538         val = inw(config);
  539         val &= DMA_MASK;
  540         val |= DMA_TEST_BIT | DMA_7_BITS;
  541         break;
  542     default:
  543         DPRINTF(("pss_testdma: invalid drq (%d)\n", dmaNum));
  544         return 0;
  545     }
  546     outw(config, val);
  547 
  548     /* Check if the DMA channel is in use */
  549     /* Do it a few times in case there is a delay */
  550     ret = 0;
  551     for (i = 0; i < 3; i++) {
  552         val = inw(config);
  553         if (val & DMA_TEST_PASS) {
  554             ret = 1;
  555             break;
  556         }
  557     }
  558 
  559     /* Clear the Test bit and the DMA bits */
  560     val = inw(config);
  561     val &= DMA_TEST_BIT_MASK & DMA_MASK;
  562     outw(config, val);
  563     return(ret);
  564 }
  565 
  566 #ifdef notyet
  567 int
  568 pss_reset_dsp(sc)
  569         struct pss_softc *sc;
  570 {
  571     u_long i;
  572     int pss_base = sc->sc_iobase;
  573 
  574     outw(pss_base+PSS_CONTROL, PSS_RESET);
  575 
  576     for (i = 0; i < 32768; i++)
  577         inw(pss_base+PSS_CONTROL);
  578  
  579     outw(pss_base+PSS_CONTROL, 0);
  580 
  581     return 1;
  582 }
  583 
  584 /*
  585  * This function loads an image into the PSS 
  586  * card.  The function loads the file by
  587  * resetting the dsp and feeding it the boot bytes.
  588  * First you feed the ASIC the first byte of 
  589  * the boot sequence. The ASIC waits until it
  590  * detects a BMS and RD and asserts BR
  591  * and outputs the byte.  The host must poll for
  592  * the BG signal. It then feeds the ASIC another
  593  * byte which removes BR.
  594  */
  595 int
  596 pss_download_dsp(sc, block, size)
  597         struct pss_softc *sc;
  598         u_char *block;
  599         int size;
  600 {
  601     int i, val, count;
  602     int pss_base = sc->sc_iobase;
  603     
  604     DPRINTF(("pss: downloading boot code..."));
  605 
  606     /* Warn DSP software that a boot is coming */
  607     outw(pss_base+PSS_DATA, 0x00fe);
  608 
  609     for (i = 0; i < 32768; i++)
  610         if (inw(pss_base+PSS_DATA) == 0x5500)
  611             break;
  612     outw(pss_base+PSS_DATA, *block++);
  613 
  614     pss_reset_dsp(sc);
  615 
  616     DPRINTF(("start "));
  617 
  618     count = 1;
  619     while(1) {
  620         int j;
  621         for (j=0; j<327670; j++) {
  622             /* Wait for BG to appear */
  623             if (inw(pss_base+PSS_STATUS) & PSS_FLAG3)
  624                 break;
  625         }
  626  
  627         if (j==327670) {
  628             /* It's ok we timed out when the file was empty */
  629             if (count >= size)
  630                 break;
  631             else {
  632                 printf("\npss: DownLoad timeout problems, byte %d=%d\n",
  633                        count, size);
  634                 return 0;
  635             }
  636         }
  637         /* Send the next byte */
  638         outw(pss_base+PSS_DATA, *block++);
  639         count++;
  640     }
  641 
  642     outw(pss_base+PSS_DATA, 0);
  643     for (i = 0; i < 32768; i++)
  644         (void) inw(pss_base+PSS_STATUS);
  645 
  646     DPRINTF(("downloaded\n"));
  647 
  648     for (i = 0; i < 32768; i++) {
  649         val = inw(pss_base+PSS_STATUS);
  650         if (val & PSS_READ_FULL)
  651             break;
  652     }
  653 
  654     /* now read the version */
  655     for (i = 0; i < 32000; i++) {
  656         val = inw(pss_base+PSS_STATUS);
  657         if (val & PSS_READ_FULL)
  658             break;
  659     }
  660     if (i == 32000)
  661         return 0;
  662 
  663     (void) inw(pss_base+PSS_DATA);
  664 
  665     return 1;
  666 }
  667 #endif /* notyet */
  668 
  669 #ifdef AUDIO_DEBUG
  670 void
  671 wss_dump_regs(sc)
  672         struct ad1848_isa_softc *sc;
  673 {
  674 
  675     printf("WSS reg: status=%02x\n",
  676            (u_char)inb(sc->sc_iobase-WSS_CODEC+WSS_STATUS));
  677 }
  678 
  679 void
  680 pss_dump_regs(sc)
  681         struct pss_softc *sc;
  682 {
  683 
  684     printf("PSS regs: status=%04x vers=%04x ",
  685            (u_short)inw(sc->sc_iobase+PSS_STATUS),
  686            (u_short)inw(sc->sc_iobase+PSS_ID_VERS));
  687         
  688     printf("config=%04x wss_config=%04x\n",
  689            (u_short)inw(sc->sc_iobase+PSS_CONFIG),
  690            (u_short)inw(sc->sc_iobase+PSS_WSS_CONFIG));
  691 }
  692 #endif
  693 
  694 /*
  695  * Probe for the PSS hardware.
  696  */
  697 int
  698 pssprobe(parent, match, aux)
  699     struct device *parent;
  700     struct cfdata *match;
  701     void *aux;
  702 {
  703     struct pss_softc probesc, *sc = &probesc;
  704     struct isa_attach_args *ia = aux;
  705 
  706     if (ia->ia_nio < 1)
  707             return (0);
  708     if (ia->ia_nirq < 1)
  709             return (0);
  710     if (ia->ia_ndrq < 1)
  711             return (0);
  712 
  713     if (ISA_DIRECT_CONFIG(ia))
  714         return (0);
  715 
  716     memset(sc, 0, sizeof *sc);
  717     sc->sc_dev.dv_cfdata = match;
  718     strcpy(sc->sc_dev.dv_xname, "pas");
  719     return pssfind(parent, sc, aux);
  720 }
  721 
  722 static int
  723 pssfind(parent, sc, ia)
  724     struct device *parent;
  725     struct pss_softc *sc;
  726     struct isa_attach_args *ia;
  727 {
  728     int iobase = ia->ia_io[0].ir_addr;
  729 
  730     if (!PSS_BASE_VALID(iobase)) {
  731         printf("pss: configured iobase %x invalid\n", iobase);
  732         return 0;
  733     }
  734 
  735     /* Need to probe for iobase when ISACF_PORT_DEFAULT {0x220 0x240} */
  736     if (iobase == ISACF_PORT_DEFAULT) {
  737 
  738         iobase = 0x220;
  739         if ((inw(iobase+PSS_ID_VERS) & 0xff00) == 0x4500)
  740             goto pss_found;
  741 
  742         iobase = 0x240;
  743         if ((inw(iobase+PSS_ID_VERS) & 0xff00) == 0x4500)
  744             goto pss_found;
  745 
  746         DPRINTF(("pss: no PSS found (at 0x220 or 0x240)\n"));
  747         return 0;
  748     }
  749     else if ((inw(iobase+PSS_ID_VERS) & 0xff00) != 0x4500) {
  750         DPRINTF(("pss: not a PSS - %x\n", inw(iobase+PSS_ID_VERS)));
  751         return 0;
  752     }
  753 
  754 pss_found:
  755     sc->sc_iobase = iobase;
  756 
  757     /* Clear WSS config */
  758     pss_setaddr(WSS_BASE_ADDRESS, sc->sc_iobase+PSS_WSS_CONFIG); /* XXX! */
  759     outb(WSS_BASE_ADDRESS+WSS_CONFIG, 0);
  760 
  761     /* Clear config registers (POR reset state) */
  762     outw(sc->sc_iobase+PSS_CONFIG, 0);
  763     outw(sc->sc_iobase+PSS_WSS_CONFIG, 0);
  764     outw(sc->sc_iobase+SB_CONFIG, 0);
  765     outw(sc->sc_iobase+MIDI_CONFIG, 0);
  766     outw(sc->sc_iobase+CD_CONFIG, 0);
  767 
  768     if (ia->ia_irq[0].ir_irq == ISACF_IRQ_DEFAULT) {
  769         int i;
  770         for (i = 0; i < 16; i++) {
  771             if (pss_testirq(sc, i) != 0)
  772                 break;
  773         }
  774         if (i == 16) {
  775             printf("pss: unable to locate free IRQ channel\n");
  776             return 0;
  777         }
  778         else {
  779             ia->ia_irq[0].ir_irq = i;
  780             printf("pss: found IRQ %d free\n", i);
  781         }
  782     }
  783     else {
  784         if (pss_testirq(sc, ia->ia_irq[0].ir_irq) == 0) {
  785             printf("pss: configured IRQ unavailable (%d)\n",
  786                 ia->ia_irq[0].ir_irq);
  787             return 0;
  788         }
  789     }
  790 
  791     /* XXX Need to deal with ISACF_DRQ_DEFAULT */
  792     if (pss_testdma(sc, ia->ia_drq[0].ir_drq) == 0) {
  793         printf("pss: configured DMA channel unavailable (%d)\n",
  794             ia->ia_drq[0].ir_drq);
  795         return 0;
  796     }
  797       
  798     ia->ia_io[0].ir_size = PSS_NPORT;
  799 
  800     /* Initialize PSS irq and DMA */
  801     pss_setint(ia->ia_irq[0].ir_irq, sc->sc_iobase+PSS_CONFIG);
  802     pss_setdma(ia->ia_drq[0].ir_drq, sc->sc_iobase+PSS_CONFIG);
  803 
  804 #ifdef notyet
  805     /* Setup the Game port */
  806 #ifdef PSS_GAMEPORT
  807     DPRINTF(("Turning Game Port On.\n"));
  808     outw(sc->sc_iobase+PSS_STATUS, inw(sc->sc_iobase+PSS_STATUS) | GAME_BIT);
  809 #else
  810     outw(sc->sc_iobase+PSS_STATUS, inw(sc->sc_iobase+PSS_STATUS) & GAME_BIT_MASK);
  811 #endif
  812 
  813     /* Reset DSP */
  814     pss_reset_dsp(sc);
  815 #endif /* notyet */
  816 
  817     return 1;
  818 }
  819 
  820 /*
  821  * Probe for the Soundport (ad1848)
  822  */
  823 int
  824 spprobe(parent, match, aux)
  825     struct device *parent;
  826     struct cfdata *match;
  827     void *aux;
  828 {
  829     struct ad1848_isa_softc probesc, *sc = &probesc;
  830 
  831     memset(sc, 0, sizeof *sc);
  832     sc->sc_ad1848.sc_dev.dv_cfdata = match;
  833     return spfind(parent, sc, aux);
  834 }
  835 
  836 static int
  837 spfind(parent, sc, ia)
  838     struct device *parent;
  839     struct ad1848_isa_softc *sc;
  840     struct isa_attach_args *ia;
  841 {
  842     struct pss_softc *pc = (void *) parent;
  843     struct cfdata *cf = (void *)sc->sc_ad1848.sc_dev.dv_cfdata;
  844     u_char bits;
  845     int i;
  846 
  847     sc->sc_ad1848.sc_iot = ia->ia_iot;
  848     
  849     /* Set WSS io address */
  850     pss_setaddr(cf->cf_iobase, pc->sc_iobase+PSS_WSS_CONFIG);
  851 
  852     /* Is there an ad1848 chip at the WSS iobase ? */
  853     if (ad1848_isa_mapprobe(sc, cf->cf_iobase + WSS_CODEC) == 0) {
  854         DPRINTF(("sp: no ad1848 ? iobase=%x\n", sc->sc_iobase));
  855         return 0;
  856     }
  857         
  858     /* Setup WSS interrupt and DMA if auto */
  859     if (cf->cf_irq == ISACF_IRQ_DEFAULT) {
  860 
  861         /* Find unused IRQ for WSS */
  862         for (i = 0; i < 12; i++) {
  863             if (wss_interrupt_bits[i] != 0xff) {
  864                 if (pss_testirq(pc, i))
  865                     break;
  866             }
  867         }
  868         if (i == 12) {
  869             printf("sp: unable to locate free IRQ for WSS\n");
  870             return 0;
  871         }
  872         else {
  873             cf->cf_irq = i;
  874             sc->sc_irq = i;
  875             DPRINTF(("sp: found IRQ %d free\n", i));
  876         }
  877     }
  878     else {
  879         sc->sc_irq = cf->cf_irq;
  880         if (pss_testirq(pc, sc->sc_irq) == 0) {
  881             printf("sp: configured IRQ unavailable (%d)\n", sc->sc_irq);
  882             return 0;
  883         }
  884     }
  885 
  886     if (cf->cf_drq == ISACF_DRQ_DEFAULT) {
  887         /* Find unused DMA channel for WSS */
  888         for (i = 0; i < 4; i++) {
  889             if (wss_dma_bits[i]) {
  890                 if (pss_testdma(pc, i))
  891                     break;
  892             }
  893         }
  894         if (i == 4) {
  895             printf("sp: unable to locate free DMA channel for WSS\n");
  896             return 0;
  897         }
  898         else {
  899             sc->sc_playdrq = cf->cf_drq = i;
  900             DPRINTF(("sp: found DMA %d free\n", i));
  901         }
  902     }
  903     else {
  904         if (pss_testdma(pc, sc->sc_playdrq) == 0) {
  905             printf("sp: configured DMA channel unavailable (%d)\n",
  906                 sc->sc_playdrq);
  907             return 0;
  908         }
  909         sc->sc_playdrq = cf->cf_drq;
  910     }
  911     sc->sc_recdrq = sc->sc_playdrq;
  912 
  913     /* Set WSS config registers */
  914     if ((bits = wss_interrupt_bits[sc->sc_irq]) == 0xff) {
  915         printf("sp: invalid interrupt configuration (irq=%d)\n", sc->sc_irq);
  916         return 0;
  917     }
  918 
  919     outb(sc->sc_iobase+WSS_CONFIG, (bits | 0x40));
  920     if ((inb(sc->sc_iobase+WSS_STATUS) & 0x40) == 0)    /* XXX What do these bits mean ? */
  921         DPRINTF(("sp: IRQ %x\n", inb(sc->sc_iobase+WSS_STATUS)));
  922     
  923     outb(sc->sc_iobase+WSS_CONFIG, (bits | wss_dma_bits[sc->sc_playdrq]));
  924 
  925     pc->ad1848_sc = (struct ad1848_softc *)sc;
  926     sc->sc_ad1848.parent = pc;
  927     
  928     return 1;
  929 }
  930 
  931 #ifdef notyet
  932 int
  933 mpuprobe(parent, match, aux)
  934     struct device *parent;
  935     struct cfdata *match;
  936     void *aux;
  937 {
  938     return(0);
  939 }
  940 
  941 int
  942 pcdprobe(parent, match, aux)
  943     struct device *parent;
  944     struct cfdata *match;
  945     void *aux;
  946 {
  947     return(0);
  948 }
  949 #endif /* notyet */
  950 
  951 /*
  952  * Attach hardware to driver, attach hardware driver to audio
  953  * pseudo-device driver .
  954  */
  955 void
  956 pssattach(parent, self, aux)
  957     struct device *parent, *self;
  958     void *aux;
  959 {
  960     struct pss_softc *sc = (struct pss_softc *)self;
  961     struct isa_attach_args *ia = (struct isa_attach_args *)aux;
  962     int iobase = ia->ia_io[0].ir_addr;
  963     u_char vers;
  964     struct ad1848_volume vol = {150, 150};
  965     
  966     if (!pssfind(parent, sc, ia)) {
  967         printf("%s: pssfind failed\n", sc->sc_dev.dv_xname);
  968         return;
  969     }
  970 
  971     sc->sc_iobase = iobase;
  972     sc->sc_drq = ia->ia_drq[0].ir_drq;
  973 
  974     /* Setup interrupt handler for PSS */
  975     sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq, IST_EDGE,
  976         IPL_AUDIO, pssintr, sc);
  977 
  978     vers = (inw(sc->sc_iobase+PSS_ID_VERS)&0xff) - 1;
  979     printf(": ESC614%c\n", (vers > 0)?'A'+vers:' ');
  980     
  981     (void)config_found(self, ia, NULL);         /* XXX */
  982 
  983     sc->out_port = PSS_MASTER_VOL;
  984 
  985     (void)pss_set_master_mode(sc, PSS_SPKR_STEREO);
  986     (void)pss_set_master_gain(sc, &vol);
  987     (void)pss_set_treble(sc, AUDIO_MAX_GAIN/2);
  988     (void)pss_set_bass(sc, AUDIO_MAX_GAIN/2);
  989 
  990     audio_attach_mi(&pss_audio_if, sc->ad1848_sc, &sc->ad1848_sc->sc_dev);
  991 }
  992 
  993 void
  994 spattach(parent, self, aux)
  995     struct device *parent, *self;
  996     void *aux;
  997 {
  998     struct ad1848_isa_softc *sc = (struct ad1848_isa_softc *)self;
  999     struct cfdata *cf = (void *)sc->sc_ad1848.sc_dev.dv_cfdata;
 1000     struct isa_attach_args *ia = (struct isa_attach_args *)aux;
 1001     isa_chipset_tag_t ic = ia->ia_ic;
 1002     int iobase = cf->cf_iobase;
 1003 
 1004     if (!spfind(parent, sc, ia)) {
 1005         printf("%s: spfind failed\n", sc->sc_ad1848.sc_dev.dv_xname);
 1006         return;
 1007     }
 1008 
 1009     sc->sc_iobase = iobase;
 1010     sc->sc_playdrq = cf->cf_drq;
 1011 
 1012     sc->sc_ih = isa_intr_establish(ic, cf->cf_irq, IST_EDGE, IPL_AUDIO,
 1013         ad1848_isa_intr, sc);
 1014 
 1015     sc->sc_ic = ic;
 1016 
 1017     ad1848_attach(&sc->sc_ad1848);
 1018 }
 1019 
 1020 #ifdef notyet
 1021 void
 1022 mpuattach(parent, self, aux)
 1023     struct device *parent, *self;
 1024     void *aux;
 1025 {
 1026     struct mpu_softc *sc = (struct mpu_softc *)self;
 1027     struct cfdata *cf = (void *)sc->sc_dev.dv_cfdata;
 1028     isa_chipset_tag_t ic = aux;                         /* XXX */
 1029     int iobase = cf->cf_iobase;
 1030 
 1031     sc->sc_iobase = iobase;
 1032 
 1033     sc->sc_ih = isa_intr_establish(ic, cf->cf_irq, IST_EDGE, IPL_AUDIO,
 1034         mpuintr, sc, sc->sc_dev.dv_xname);
 1035 
 1036     /* XXX might use pssprint func ?? */
 1037     printf(" port 0x%x-0x%x irq %d\n",
 1038            sc->sc_iobase, sc->sc_iobase+MIDI_NPORT,
 1039            cf->cf_irq);
 1040 }
 1041 
 1042 void
 1043 pcdattach(parent, self, aux)
 1044     struct device *parent, *self;
 1045     void *aux;
 1046 {
 1047     struct pcd_softc *sc = (struct pcd_softc *)self;
 1048     struct cfdata *cf = (void *)sc->sc_dev.dv_cfdata;
 1049     int iobase = cf->cf_iobase;
 1050     
 1051     /*
 1052      * The pss driver simply enables the cd interface. The CD
 1053      * appropriate driver - scsi (aic6360) or Sony needs to be
 1054      * used after this to handle the device.
 1055      */
 1056     sc->sc_iobase = iobase;
 1057 
 1058     /* XXX might use pssprint func ?? */
 1059     printf(" port 0x%x-0x%x irq %d\n",
 1060            sc->sc_iobase, sc->sc_iobase+2,
 1061            cf->cf_irq);
 1062 }
 1063 #endif /* notyet */
 1064 
 1065 
 1066 int
 1067 pss_set_master_gain(sc, gp)
 1068     struct pss_softc *sc;
 1069     struct ad1848_volume *gp;
 1070 {
 1071     DPRINTF(("pss_set_master_gain: %d:%d\n", gp->left, gp->right));
 1072         
 1073 #ifdef PSS_DSP
 1074     if (gp->left > PHILLIPS_VOL_MAX)
 1075         gp->left = PHILLIPS_VOL_MAX;
 1076     if (gp->left < PHILLIPS_VOL_MIN)
 1077         gp->left = PHILLIPS_VOL_MIN;
 1078     if (gp->right > PHILLIPS_VOL_MAX)
 1079         gp->right = PHILLIPS_VOL_MAX;
 1080     if (gp->right < PHILLIPS_VOL_MIN)
 1081         gp->right = PHILLIPS_VOL_MIN;
 1082 
 1083     pss_dspwrite(sc, SET_MASTER_COMMAND);
 1084     pss_dspwrite(sc, MASTER_VOLUME_LEFT|(PHILLIPS_VOL_CONSTANT + gp->left / PHILLIPS_VOL_STEP));
 1085     pss_dspwrite(sc, SET_MASTER_COMMAND);
 1086     pss_dspwrite(sc, MASTER_VOLUME_RIGHT|(PHILLIPS_VOL_CONSTANT + gp->right / PHILLIPS_VOL_STEP));
 1087 #endif
 1088 
 1089     sc->master_volume = *gp;
 1090     return(0);
 1091 }
 1092 
 1093 int
 1094 pss_set_master_mode(sc, mode)
 1095     struct pss_softc *sc;
 1096     int mode;
 1097 {
 1098     short phillips_mode;
 1099 
 1100     DPRINTF(("pss_set_master_mode: %d\n", mode));
 1101         
 1102     if (mode == PSS_SPKR_STEREO)
 1103         phillips_mode = PSS_STEREO;
 1104     else if (mode == PSS_SPKR_PSEUDO)
 1105         phillips_mode = PSS_PSEUDO;
 1106     else if (mode == PSS_SPKR_SPATIAL)
 1107         phillips_mode = PSS_SPATIAL;
 1108     else if (mode == PSS_SPKR_MONO)
 1109         phillips_mode = PSS_MONO;
 1110     else
 1111         return (EINVAL);
 1112     
 1113 #ifdef PSS_DSP
 1114     pss_dspwrite(sc, SET_MASTER_COMMAND);
 1115     pss_dspwrite(sc, MASTER_SWITCH | mode);
 1116 #endif
 1117 
 1118     sc->master_mode = mode;
 1119 
 1120     return(0);
 1121 }
 1122 
 1123 int
 1124 pss_set_treble(sc, treb)
 1125     struct pss_softc *sc;
 1126     u_int treb;
 1127 {
 1128     DPRINTF(("pss_set_treble: %d\n", treb));
 1129 
 1130 #ifdef PSS_DSP
 1131     if (treb > PHILLIPS_TREBLE_MAX)
 1132         treb = PHILLIPS_TREBLE_MAX;
 1133     if (treb < PHILLIPS_TREBLE_MIN)
 1134         treb = PHILLIPS_TREBLE_MIN;
 1135     pss_dspwrite(sc, SET_MASTER_COMMAND);
 1136     pss_dspwrite(sc, MASTER_TREBLE|(PHILLIPS_TREBLE_CONSTANT + treb / PHILLIPS_TREBLE_STEP));
 1137 #endif
 1138 
 1139     sc->monitor_treble = treb;
 1140 
 1141     return(0);
 1142 }
 1143 
 1144 int
 1145 pss_set_bass(sc, bass)
 1146     struct pss_softc *sc;
 1147     u_int bass;
 1148 {
 1149     DPRINTF(("pss_set_bass: %d\n", bass));
 1150 
 1151 #ifdef PSS_DSP
 1152     if (bass > PHILLIPS_BASS_MAX)
 1153         bass = PHILLIPS_BASS_MAX;
 1154     if (bass < PHILLIPS_BASS_MIN)
 1155         bass = PHILLIPS_BASS_MIN;
 1156     pss_dspwrite(sc, SET_MASTER_COMMAND);
 1157     pss_dspwrite(sc, MASTER_BASS|(PHILLIPS_BASS_CONSTANT + bass / PHILLIPS_BASS_STEP));
 1158 #endif
 1159 
 1160     sc->monitor_bass = bass;
 1161 
 1162     return(0);
 1163 }
 1164         
 1165 int
 1166 pss_get_master_gain(sc, gp)
 1167     struct pss_softc *sc;
 1168     struct ad1848_volume *gp;
 1169 {
 1170     *gp = sc->master_volume;
 1171     return(0);
 1172 }
 1173 
 1174 int
 1175 pss_get_master_mode(sc, mode)
 1176     struct pss_softc *sc;
 1177     u_int *mode;
 1178 {
 1179     *mode = sc->master_mode;
 1180     return(0);
 1181 }
 1182 
 1183 int
 1184 pss_get_treble(sc, tp)
 1185     struct pss_softc *sc;
 1186     u_char *tp;
 1187 {
 1188     *tp = sc->monitor_treble;
 1189     return(0);
 1190 }
 1191 
 1192 int
 1193 pss_get_bass(sc, bp)
 1194     struct pss_softc *sc;
 1195     u_char *bp;
 1196 {
 1197     *bp = sc->monitor_bass;
 1198     return(0);
 1199 }
 1200 
 1201 int
 1202 pss_speaker_ctl(addr, newstate)
 1203     void *addr;
 1204     int newstate;
 1205 {
 1206     return(0);
 1207 }
 1208 
 1209 int
 1210 pssintr(arg)
 1211         void *arg;
 1212 {
 1213     struct pss_softc *sc = arg;
 1214     u_short sr;
 1215     
 1216     sr = inw(sc->sc_iobase+PSS_STATUS);
 1217     
 1218     DPRINTF(("pssintr: sc=%p st=%x\n", sc, sr));
 1219 
 1220     /* Acknowledge intr */
 1221     outw(sc->sc_iobase+PSS_IRQ_ACK, 0);
 1222     
 1223     /* Is it one of ours ? */
 1224     if (sr & (PSS_WRITE_EMPTY|PSS_READ_FULL|PSS_IRQ|PSS_DMQ_TC)) {
 1225         /* XXX do something */
 1226         return 1;
 1227     }
 1228     
 1229     return 0;
 1230 }
 1231 
 1232 #ifdef notyet
 1233 int
 1234 mpuintr(arg)
 1235         void *arg;
 1236 {
 1237     struct mpu_softc *sc = arg;
 1238     u_char sr;
 1239     
 1240     sr = inb(sc->sc_iobase+MIDI_STATUS_REG);
 1241 
 1242     printf("mpuintr: sc=%p sr=%x\n", sc, sr);
 1243 
 1244     /* XXX Need to clear intr */
 1245     return 1;
 1246 }
 1247 #endif
 1248 
 1249 int
 1250 pss_getdev(addr, retp)
 1251     void *addr;
 1252     struct audio_device *retp;
 1253 {
 1254     DPRINTF(("pss_getdev: retp=%p\n", retp));
 1255 
 1256     *retp = pss_device;
 1257     return 0;
 1258 }
 1259 
 1260 static ad1848_devmap_t mappings[] = {
 1261         { PSS_MIC_IN_LVL, AD1848_KIND_LVL, AD1848_AUX2_CHANNEL },
 1262         { PSS_LINE_IN_LVL, AD1848_KIND_LVL, AD1848_AUX1_CHANNEL },
 1263         { PSS_DAC_LVL, AD1848_KIND_LVL, AD1848_DAC_CHANNEL },
 1264         { PSS_MONITOR_LVL, AD1848_KIND_LVL, AD1848_MONO_CHANNEL },
 1265         { PSS_MIC_IN_MUTE, AD1848_KIND_MUTE, AD1848_AUX2_CHANNEL },
 1266         { PSS_LINE_IN_MUTE, AD1848_KIND_MUTE, AD1848_AUX1_CHANNEL },
 1267         { PSS_DAC_MUTE, AD1848_KIND_MUTE, AD1848_DAC_CHANNEL },
 1268         { PSS_MONITOR_MUTE, AD1848_KIND_MUTE, AD1848_MONO_CHANNEL },
 1269         { PSS_REC_LVL, AD1848_KIND_RECORDGAIN, -1 },
 1270         { PSS_RECORD_SOURCE, AD1848_KIND_RECORDSOURCE, -1}
 1271 };
 1272 
 1273 static int nummap = sizeof(mappings) / sizeof(mappings[0]);
 1274 
 1275 int
 1276 pss_mixer_set_port(addr, cp)
 1277     void *addr;
 1278     mixer_ctrl_t *cp;
 1279 {
 1280     struct ad1848_softc *ac = addr;
 1281     struct pss_softc *sc = ac->parent;
 1282     struct ad1848_volume vol;
 1283     int error = ad1848_mixer_set_port(ac, mappings, nummap, cp);
 1284     
 1285     if (error != ENXIO)
 1286       return (error);
 1287 
 1288     switch (cp->dev) {
 1289     case PSS_MASTER_VOL:        /* master volume */
 1290         if (cp->type == AUDIO_MIXER_VALUE) {
 1291             if (ad1848_to_vol(cp, &vol))
 1292                 error = pss_set_master_gain(sc, &vol);
 1293         }
 1294         break;
 1295 
 1296     case PSS_OUTPUT_MODE:
 1297         if (cp->type == AUDIO_MIXER_ENUM)
 1298             error = pss_set_master_mode(sc, cp->un.ord);
 1299         break;
 1300 
 1301     case PSS_MASTER_TREBLE:     /* master treble */
 1302         if (cp->type == AUDIO_MIXER_VALUE && cp->un.value.num_channels == 1)
 1303             error = pss_set_treble(sc, (u_char)cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
 1304         break;
 1305 
 1306     case PSS_MASTER_BASS:       /* master bass */
 1307         if (cp->type == AUDIO_MIXER_VALUE && cp->un.value.num_channels == 1)
 1308             error = pss_set_bass(sc, (u_char)cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
 1309         break;
 1310 
 1311     default:
 1312             return ENXIO;
 1313             /*NOTREACHED*/
 1314     }
 1315     
 1316     return 0;
 1317 }
 1318 
 1319 int
 1320 pss_mixer_get_port(addr, cp)
 1321     void *addr;
 1322     mixer_ctrl_t *cp;
 1323 {
 1324     struct ad1848_softc *ac = addr;
 1325     struct pss_softc *sc = ac->parent;
 1326     struct ad1848_volume vol;
 1327     u_char eq;
 1328     int error = ad1848_mixer_get_port(ac, mappings, nummap, cp);
 1329 
 1330     if (error != ENXIO)
 1331       return (error);
 1332 
 1333     error = EINVAL;
 1334 
 1335     switch (cp->dev) {
 1336     case PSS_MASTER_VOL:        /* master volume */
 1337         if (cp->type == AUDIO_MIXER_VALUE) {
 1338             error = pss_get_master_gain(sc, &vol);
 1339             if (!error)
 1340                 ad1848_from_vol(cp, &vol);
 1341         }
 1342         break;
 1343 
 1344     case PSS_MASTER_TREBLE:     /* master treble */
 1345         if (cp->type == AUDIO_MIXER_VALUE && cp->un.value.num_channels == 1) {
 1346             error = pss_get_treble(sc, &eq);
 1347             if (!error)
 1348                 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = eq;
 1349         }
 1350         break;
 1351 
 1352     case PSS_MASTER_BASS:       /* master bass */
 1353         if (cp->type == AUDIO_MIXER_VALUE && cp->un.value.num_channels == 1) {
 1354             error = pss_get_bass(sc, &eq);
 1355             if (!error)
 1356                 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = eq;
 1357         }
 1358         break;
 1359 
 1360     case PSS_OUTPUT_MODE:
 1361         if (cp->type == AUDIO_MIXER_ENUM)
 1362             error = pss_get_master_mode(sc, &cp->un.ord);
 1363         break;
 1364 
 1365     default:
 1366         error = ENXIO;
 1367         break;
 1368     }
 1369 
 1370     return(error);
 1371 }
 1372 
 1373 int
 1374 pss_query_devinfo(addr, dip)
 1375     void *addr;
 1376     mixer_devinfo_t *dip;
 1377 {
 1378     DPRINTF(("pss_query_devinfo: index=%d\n", dip->index));
 1379 
 1380     switch(dip->index) {
 1381     case PSS_MIC_IN_LVL:        /* Microphone */
 1382         dip->type = AUDIO_MIXER_VALUE;
 1383         dip->mixer_class = PSS_INPUT_CLASS;
 1384         dip->prev = AUDIO_MIXER_LAST;
 1385         dip->next = PSS_MIC_IN_MUTE;
 1386         strcpy(dip->label.name, AudioNmicrophone);
 1387         dip->un.v.num_channels = 2;
 1388         strcpy(dip->un.v.units.name, AudioNvolume);
 1389         break;
 1390 
 1391     case PSS_LINE_IN_LVL:       /* line/CD */
 1392         dip->type = AUDIO_MIXER_VALUE;
 1393         dip->mixer_class = PSS_INPUT_CLASS;
 1394         dip->prev = AUDIO_MIXER_LAST;
 1395         dip->next = PSS_LINE_IN_MUTE;
 1396         strcpy(dip->label.name, AudioNcd);
 1397         dip->un.v.num_channels = 2;
 1398         strcpy(dip->un.v.units.name, AudioNvolume);
 1399         break;
 1400 
 1401     case PSS_DAC_LVL:           /*  dacout */
 1402         dip->type = AUDIO_MIXER_VALUE;
 1403         dip->mixer_class = PSS_INPUT_CLASS;
 1404         dip->prev = AUDIO_MIXER_LAST;
 1405         dip->next = PSS_DAC_MUTE;
 1406         strcpy(dip->label.name, AudioNdac);
 1407         dip->un.v.num_channels = 2;
 1408         strcpy(dip->un.v.units.name, AudioNvolume);
 1409         break;
 1410 
 1411     case PSS_REC_LVL:   /* record level */
 1412         dip->type = AUDIO_MIXER_VALUE;
 1413         dip->mixer_class = PSS_RECORD_CLASS;
 1414         dip->prev = AUDIO_MIXER_LAST;
 1415         dip->next = PSS_RECORD_SOURCE;
 1416         strcpy(dip->label.name, AudioNrecord);
 1417         dip->un.v.num_channels = 2;
 1418         strcpy(dip->un.v.units.name, AudioNvolume);
 1419         break;
 1420 
 1421     case PSS_MONITOR_LVL:       /* monitor level */
 1422         dip->type = AUDIO_MIXER_VALUE;
 1423         dip->mixer_class = PSS_MONITOR_CLASS;
 1424         dip->prev = AUDIO_MIXER_LAST;
 1425         dip->next = PSS_MONITOR_MUTE;
 1426         strcpy(dip->label.name, AudioNmonitor);
 1427         dip->un.v.num_channels = 1;
 1428         strcpy(dip->un.v.units.name, AudioNvolume);
 1429         break;
 1430 
 1431     case PSS_MASTER_VOL:        /* master volume */
 1432         dip->type = AUDIO_MIXER_VALUE;
 1433         dip->mixer_class = PSS_OUTPUT_CLASS;
 1434         dip->prev = AUDIO_MIXER_LAST;
 1435         dip->next = PSS_OUTPUT_MODE;
 1436         strcpy(dip->label.name, AudioNmaster);
 1437         dip->un.v.num_channels = 2;
 1438         strcpy(dip->un.v.units.name, AudioNvolume);
 1439         break;
 1440 
 1441     case PSS_MASTER_TREBLE:     /* master treble */
 1442         dip->type = AUDIO_MIXER_VALUE;
 1443         dip->mixer_class = PSS_OUTPUT_CLASS;
 1444         dip->next = dip->prev = AUDIO_MIXER_LAST;
 1445         strcpy(dip->label.name, AudioNtreble);
 1446         dip->un.v.num_channels = 1;
 1447         strcpy(dip->un.v.units.name, AudioNtreble);
 1448         break;
 1449 
 1450     case PSS_MASTER_BASS:       /* master bass */
 1451         dip->type = AUDIO_MIXER_VALUE;
 1452         dip->mixer_class = PSS_OUTPUT_CLASS;
 1453         dip->next = dip->prev = AUDIO_MIXER_LAST;
 1454         strcpy(dip->label.name, AudioNbass);
 1455         dip->un.v.num_channels = 1;
 1456         strcpy(dip->un.v.units.name, AudioNbass);
 1457         break;
 1458 
 1459     case PSS_OUTPUT_CLASS:                      /* output class descriptor */
 1460         dip->type = AUDIO_MIXER_CLASS;
 1461         dip->mixer_class = PSS_OUTPUT_CLASS;
 1462         dip->next = dip->prev = AUDIO_MIXER_LAST;
 1463         strcpy(dip->label.name, AudioCoutputs);
 1464         break;
 1465 
 1466     case PSS_INPUT_CLASS:                       /* input class descriptor */
 1467         dip->type = AUDIO_MIXER_CLASS;
 1468         dip->mixer_class = PSS_INPUT_CLASS;
 1469         dip->next = dip->prev = AUDIO_MIXER_LAST;
 1470         strcpy(dip->label.name, AudioCinputs);
 1471         break;
 1472 
 1473     case PSS_MONITOR_CLASS:                     /* monitor class descriptor */
 1474         dip->type = AUDIO_MIXER_CLASS;
 1475         dip->mixer_class = PSS_MONITOR_CLASS;
 1476         dip->next = dip->prev = AUDIO_MIXER_LAST;
 1477         strcpy(dip->label.name, AudioCmonitor);
 1478         break;
 1479             
 1480     case PSS_RECORD_CLASS:                      /* record source class */
 1481         dip->type = AUDIO_MIXER_CLASS;
 1482         dip->mixer_class = PSS_RECORD_CLASS;
 1483         dip->next = dip->prev = AUDIO_MIXER_LAST;
 1484         strcpy(dip->label.name, AudioCrecord);
 1485         break;
 1486         
 1487     case PSS_MIC_IN_MUTE:
 1488         dip->mixer_class = PSS_INPUT_CLASS;
 1489         dip->type = AUDIO_MIXER_ENUM;
 1490         dip->prev = PSS_MIC_IN_LVL;
 1491         dip->next = AUDIO_MIXER_LAST;
 1492         goto mute;
 1493         
 1494     case PSS_LINE_IN_MUTE:
 1495         dip->mixer_class = PSS_INPUT_CLASS;
 1496         dip->type = AUDIO_MIXER_ENUM;
 1497         dip->prev = PSS_LINE_IN_LVL;
 1498         dip->next = AUDIO_MIXER_LAST;
 1499         goto mute;
 1500         
 1501     case PSS_DAC_MUTE:
 1502         dip->mixer_class = PSS_INPUT_CLASS;
 1503         dip->type = AUDIO_MIXER_ENUM;
 1504         dip->prev = PSS_DAC_LVL;
 1505         dip->next = AUDIO_MIXER_LAST;
 1506         goto mute;
 1507 
 1508     case PSS_MONITOR_MUTE:
 1509         dip->mixer_class = PSS_MONITOR_CLASS;
 1510         dip->type = AUDIO_MIXER_ENUM;
 1511         dip->prev = PSS_MONITOR_LVL;
 1512         dip->next = AUDIO_MIXER_LAST;
 1513     mute:
 1514         strcpy(dip->label.name, AudioNmute);
 1515         dip->un.e.num_mem = 2;
 1516         strcpy(dip->un.e.member[0].label.name, AudioNoff);
 1517         dip->un.e.member[0].ord = 0;
 1518         strcpy(dip->un.e.member[1].label.name, AudioNon);
 1519         dip->un.e.member[1].ord = 1;
 1520         break;
 1521 
 1522     case PSS_OUTPUT_MODE:
 1523         dip->mixer_class = PSS_OUTPUT_CLASS;
 1524         dip->type = AUDIO_MIXER_ENUM;
 1525         dip->prev = PSS_MASTER_VOL;
 1526         dip->next = AUDIO_MIXER_LAST;
 1527         strcpy(dip->label.name, AudioNmode);
 1528         dip->un.e.num_mem = 4;
 1529         strcpy(dip->un.e.member[0].label.name, AudioNmono);
 1530         dip->un.e.member[0].ord = PSS_SPKR_MONO;
 1531         strcpy(dip->un.e.member[1].label.name, AudioNstereo);
 1532         dip->un.e.member[1].ord = PSS_SPKR_STEREO;
 1533         strcpy(dip->un.e.member[2].label.name, AudioNpseudo);
 1534         dip->un.e.member[2].ord = PSS_SPKR_PSEUDO;
 1535         strcpy(dip->un.e.member[3].label.name, AudioNspatial);
 1536         dip->un.e.member[3].ord = PSS_SPKR_SPATIAL;
 1537         break;
 1538 
 1539     case PSS_RECORD_SOURCE:
 1540         dip->mixer_class = PSS_RECORD_CLASS;
 1541         dip->type = AUDIO_MIXER_ENUM;
 1542         dip->prev = PSS_REC_LVL;
 1543         dip->next = AUDIO_MIXER_LAST;
 1544         strcpy(dip->label.name, AudioNsource);
 1545         dip->un.e.num_mem = 3;
 1546         strcpy(dip->un.e.member[0].label.name, AudioNmicrophone);
 1547         dip->un.e.member[0].ord = PSS_MIC_IN_LVL;
 1548         strcpy(dip->un.e.member[1].label.name, AudioNcd);
 1549         dip->un.e.member[1].ord = PSS_LINE_IN_LVL;
 1550         strcpy(dip->un.e.member[2].label.name, AudioNdac);
 1551         dip->un.e.member[2].ord = PSS_DAC_LVL;
 1552         break;
 1553 
 1554     default:
 1555         return ENXIO;
 1556         /*NOTREACHED*/
 1557     }
 1558     DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
 1559 
 1560     return 0;
 1561 }

Cache object: 5b8b0f148a278e7395c2ffd19b6db366


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