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/pci/es1371.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Support Sound Cards based on the Ensoniq/Creative Labs ES1371/1373 
    3  *
    4  * Copyright (c) 1999 by Russell Cattelan. 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  *
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  *
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in
   15  *    the documentation and/or other materials provided with the
   16  *    distribution.
   17  *
   18  * 3. All advertising materials mentioning features or use of this
   19  *    software must display the following acknowledgement:
   20  *      This product includes software developed by Russell Cattelan.
   21  *
   22  * 4. The name of the author may not be used to endorse or promote
   23  *    products derived from this software without specific prior
   24  *    written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
   27  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   28  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   29  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
   30  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   31  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   32  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   34  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   36  * OF THE POSSIBILITY OF SUCH DAMAGE.
   37  *
   38  * $FreeBSD$
   39  */
   40 
   41 
   42 #include <sys/param.h>
   43 #include <machine/bus_pio.h>
   44 #include <machine/bus.h>
   45 
   46 #include <i386/isa/snd/sound.h>
   47 
   48 #include <pci/es1370_reg.h>
   49 
   50 /* -------------------------------------------------------------------- */
   51 /*
   52  * hweightN: returns the hamming weight (i.e. the number
   53  * of bits set) of a N-bit word
   54  */
   55 
   56 unsigned int hweight32(unsigned int w);
   57 
   58 __inline__ unsigned int hweight32(unsigned int w)
   59 {
   60   unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
   61   res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
   62   res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
   63   res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
   64   return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
   65 }
   66 
   67 /* #define ES1371_REG_STATUS                    0x14 */
   68 #define ES1371_REG_CODEC                        0x14 /* this is really for the 1371  */
   69 #define ES1371_CODEC_INDEX_SHIFT                16 /* this is really for the 1371  */
   70 #define ES1371_REG_RECSRC               0x1a
   71 
   72 #define ES1371_REG_LEGACY 0x18  /* W/R: Legacy control/status register */
   73 #define   ES1371_REG_SMPRATE 0x10       /* W/R: Codec rate converter interface register */
   74 #define   ES1371_SRC_RAM_ADDRO(o) (((o)&0x7f)<<25)      /* address of the sample rate converter */
   75 #define   ES1371_SRC_RAM_ADDRM     (0x7f<<25)   /* mask for above */
   76 #define   ES1371_SRC_RAM_ADDRI(i) (((i)>>25)&0x7f)      /* address of the sample rate converter */
   77 #define   ES1371_SRC_RAM_WE        (1<<24)      /* R/W: read/write control for sample rate converter */
   78 #define   ES1371_SRC_RAM_BUSY     (1<<23)       /* R/O: sample rate memory is busy */
   79 #define   ES1371_SRC_DISABLE      (1<<22)       /* sample rate converter disable */
   80 #define   ES1371_DIS_P1    (1<<21)      /* playback channel 1 accumulator update disable */
   81 #define   ES1371_DIS_P2    (1<<20)      /* playback channel 1 accumulator update disable */
   82 #define   ES1371_DIS_R1    (1<<19)      /* record channel accumulator update disable */
   83 #define   ES1371_SRC_RAM_DATAO(o) (((o)&0xffff)<<0)     /* current value of the sample rate converter */
   84 #define   ES1371_SRC_RAM_DATAM     (0xffff<<0)  /* mask for above */
   85 #define   ES1371_SRC_RAM_DATAI(i) (((i)>>0)&0xffff)     /* current value of the sample rate converter */
   86 #define   ES_1371_SYNC_RES      (1<<14)         /* Warm AC97 reset */
   87 #define ES1371_CSTAT      (1<<30)
   88  
   89 #define CODEC_RDY         0x80000000  /* AC97 read data valid */
   90 #define CODEC_WIP         0x40000000  /* AC97 write in progress */
   91 #define CODEC_PORD        0x00800000  /* 0 = write AC97 register */
   92 #define CODEC_POADD_MASK  0x007f0000
   93 #define CODEC_POADD_SHIFT 16
   94 #define CODEC_PODAT_MASK  0x0000ffff
   95 #define CODEC_PODAT_SHIFT 0
   96 
   97 /* codec constants */
   98 
   99 #define CODEC_ID_DEDICATEDMIC    0x001
  100 #define CODEC_ID_MODEMCODEC      0x002
  101 #define CODEC_ID_BASSTREBLE      0x004
  102 #define CODEC_ID_SIMULATEDSTEREO 0x008
  103 #define CODEC_ID_HEADPHONEOUT    0x010
  104 #define CODEC_ID_LOUDNESS        0x020
  105 #define CODEC_ID_18BITDAC        0x040
  106 #define CODEC_ID_20BITDAC        0x080
  107 #define CODEC_ID_18BITADC        0x100
  108 #define CODEC_ID_20BITADC        0x200
  109 
  110 #define CODEC_ID_SESHIFT    10
  111 #define CODEC_ID_SEMASK     0x1f
  112 
  113 /* sample rate converter */
  114 #define SRC_RAMADDR_MASK   0xfe000000
  115 #define SRC_RAMADDR_SHIFT  25
  116 #define SRC_WE             0x01000000  /* read/write control for SRC RAM */
  117 #define SRC_BUSY           0x00800000  /* SRC busy */
  118 #define SRC_DIS            0x00400000  /* 1 = disable SRC */
  119 #define SRC_DDAC1          0x00200000  /* 1 = disable accum update for DAC1 */
  120 #define SRC_DDAC2          0x00100000  /* 1 = disable accum update for DAC2 */
  121 #define SRC_DADC           0x00080000  /* 1 = disable accum update for ADC2 */
  122 #define SRC_RAMDATA_MASK   0x0000ffff
  123 #define SRC_RAMDATA_SHIFT  0
  124 /*
  125  *  Sample rate converter addresses
  126  */
  127 
  128 #define ES_SMPREG_DAC1          0x70
  129 #define ES_SMPREG_DAC2          0x74
  130 #define ES_SMPREG_ADC           0x78
  131 #define ES_SMPREG_VOL_ADC       0x6c
  132 #define ES_SMPREG_VOL_DAC1      0x7c
  133 #define ES_SMPREG_VOL_DAC2      0x7e
  134 #define ES_SMPREG_TRUNC_N       0x00
  135 #define ES_SMPREG_INT_REGS      0x01
  136 #define ES_SMPREG_ACCUM_FRAC    0x02
  137 #define ES_SMPREG_VFREQ_FRAC    0x03
  138 
  139 
  140 #define CODEC_PIRD        0x00800000  /* 0 = write AC97 register */
  141 #define CODEC_PIADD_MASK  0x007f0000
  142 #define CODEC_PIADD_SHIFT 16
  143 #define CODEC_PIDAT_MASK  0x0000ffff
  144 #define CODEC_PIDAT_SHIFT 0
  145 
  146 
  147 struct initvol {
  148         int mixch;
  149         int vol;
  150 };
  151 
  152 struct initvol initvol[] = {
  153         { SOUND_MIXER_WRITE_LINE, 0x4040 },
  154         { SOUND_MIXER_WRITE_CD, 0x4040 },
  155         { MIXER_WRITE(SOUND_MIXER_VIDEO), 0x4040 },
  156         { SOUND_MIXER_WRITE_LINE1, 0x4040 },
  157 /*      { SOUND_MIXER_WRITE_PCM, 0x4040 }, */
  158         { SOUND_MIXER_WRITE_PCM, 0x6464 },
  159         { SOUND_MIXER_WRITE_VOLUME, 0x4040 },
  160         { SOUND_MIXER_WRITE_BASS, 0x1010 },
  161         { SOUND_MIXER_WRITE_TREBLE, 0x1010 },
  162         { MIXER_WRITE(SOUND_MIXER_PHONEOUT), 0x4040 },
  163         { SOUND_MIXER_WRITE_OGAIN, 0x4040 },
  164         { MIXER_WRITE(SOUND_MIXER_PHONEIN), 0x4040 },
  165         { SOUND_MIXER_WRITE_SPEAKER, 0x4040 },
  166         { SOUND_MIXER_WRITE_MIC, 0x4040 },
  167         { SOUND_MIXER_WRITE_RECLEV, 0x4040 },
  168         { SOUND_MIXER_WRITE_IGAIN, 0x4040 }
  169 };
  170 
  171 
  172 static const char *stereo_enhancement[] = 
  173 {
  174         "no 3D stereo enhancement",
  175         "Analog Devices Phat Stereo",
  176         "Creative Stereo Enhancement",
  177         "National Semiconductor 3D Stereo Enhancement",
  178         "YAMAHA Ymersion",
  179         "BBE 3D Stereo Enhancement",
  180         "Crystal Semiconductor 3D Stereo Enhancement",
  181         "Qsound QXpander",
  182         "Spatializer 3D Stereo Enhancement",
  183         "SRS 3D Stereo Enhancement",
  184         "Platform Technologies 3D Stereo Enhancement", 
  185         "AKM 3D Audio",
  186         "Aureal Stereo Enhancement",
  187         "AZTECH  3D Enhancement",
  188         "Binaura 3D Audio Enhancement",
  189         "ESS Technology Stereo Enhancement",
  190         "Harman International VMAx",
  191         "NVidea 3D Stereo Enhancement",
  192         "Philips Incredible Sound",
  193         "Texas Instruments 3D Stereo Enhancement",
  194         "VLSI Technology 3D Stereo Enhancement"
  195 };
  196 
  197 
  198 static const unsigned int recsrc[8] = 
  199 {
  200         SOUND_MASK_MIC,
  201         SOUND_MASK_CD,
  202         SOUND_MASK_VIDEO,
  203         SOUND_MASK_LINE1,
  204         SOUND_MASK_LINE,
  205         SOUND_MASK_VOLUME,
  206         SOUND_MASK_PHONEOUT,
  207         SOUND_MASK_PHONEIN
  208 };
  209 
  210 static const unsigned char volreg[] = 
  211 {
  212         /* 5 bit stereo */
  213         [SOUND_MIXER_LINE] = 0x10,
  214         [SOUND_MIXER_CD] = 0x12,
  215         [SOUND_MIXER_VIDEO] = 0x14,
  216         [SOUND_MIXER_LINE1] = 0x16,
  217         [SOUND_MIXER_PCM] = 0x18,
  218         /* 6 bit stereo */
  219         [SOUND_MIXER_VOLUME] = 0x02,
  220         [SOUND_MIXER_PHONEOUT] = 0x04,
  221         /* 6 bit mono */
  222         [SOUND_MIXER_OGAIN] = 0x06,
  223         [SOUND_MIXER_PHONEIN] = 0x0c,
  224         /* 4 bit mono but shifted by 1 */
  225         [SOUND_MIXER_SPEAKER] = 0x08,
  226         /* 6 bit mono + preamp */
  227         [SOUND_MIXER_MIC] = 0x0e,
  228         /* 4 bit stereo */
  229         [SOUND_MIXER_RECLEV] = 0x1c,
  230         /* 4 bit mono */
  231         [SOUND_MIXER_IGAIN] = 0x1e
  232 };
  233 
  234 
  235 #define swab(x) ((((x) >> 8) & 0xff) | (((x) << 8) & 0xff00))
  236 #define AC97_PESSIMISTIC
  237 #define put_user(a,b)  *b=a
  238 
  239 
  240 int
  241 es_init_1371(snddev_info *d){
  242         struct es_info *es = (struct es_info *)d->device_data;
  243         u_int           i;
  244         int idx;
  245         int val, val2 = 0;
  246         if(es_debug > 0) printf("es_init_1371\n");
  247 
  248         strncpy(d->name,"ES1371",strlen("ES1371"));
  249         es->ctrl = 0;
  250         es->sctrl = 0;
  251         /* initialize the chips */
  252         bus_space_write_4(es->st, es->sh, ES1370_REG_CONTROL, es->ctrl);
  253         bus_space_write_4(es->st, es->sh, ES1370_REG_SERIAL_CONTROL, es->sctrl);
  254         bus_space_write_4(es->st, es->sh, ES1371_REG_LEGACY, 0);
  255         /* AC'97 warm reset to start the bitclk */
  256         bus_space_write_4(es->st, es->sh, ES1371_REG_LEGACY, es->ctrl | ES_1371_SYNC_RES);
  257         DELAY(2000);
  258         bus_space_write_4(es->st, es->sh,  ES1370_REG_SERIAL_CONTROL,es->ctrl);
  259         /* Init the sample rate converter */
  260         bus_space_write_4(es->st, es->sh, ES1371_REG_SMPRATE, ES1371_SRC_DISABLE);
  261         for (idx = 0; idx < 0x80; idx++)
  262           es1371_src_write(d, idx, 0);
  263         es1371_src_write(d, ES_SMPREG_DAC1 + ES_SMPREG_TRUNC_N, 16 << 4);
  264         es1371_src_write(d, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS, 16 << 10);
  265         es1371_src_write(d, ES_SMPREG_DAC2 + ES_SMPREG_TRUNC_N, 16 << 4);
  266         es1371_src_write(d, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS, 16 << 10);
  267         es1371_src_write(d, ES_SMPREG_VOL_ADC, 1 << 12);
  268         es1371_src_write(d, ES_SMPREG_VOL_ADC + 1, 1 << 12);
  269         es1371_src_write(d, ES_SMPREG_VOL_DAC1, 1 << 12);
  270         es1371_src_write(d, ES_SMPREG_VOL_DAC1 + 1, 1 << 12);
  271         es1371_src_write(d, ES_SMPREG_VOL_DAC2, 1 << 12);
  272         es1371_src_write(d, ES_SMPREG_VOL_DAC2 + 1, 1 << 12);
  273         es1371_adc_rate(d, 22050, 1);
  274         es1371_dac1_rate(d, 22050, 1);
  275         es1371_dac2_rate(d, 22050, 1);
  276         /* WARNING:
  277          * enabling the sample rate converter without properly programming
  278          * its parameters causes the chip to lock up (the SRC busy bit will
  279          * be stuck high, and I've found no way to rectify this other than
  280          * power cycle)
  281          */
  282         /*outl(0, s->io+ES1371_REG_SRCONV); */
  283         bus_space_write_4(es->st, es->sh, ES1371_REG_SMPRATE, 0);
  284         /* codec init */
  285         wrcodec(d, 0x00, 0); /* reset codec */
  286         d->bd_id = rdcodec(d, 0x00);  /* get codec ID */
  287         val = rdcodec(d, 0x7c);
  288         val2 = rdcodec(d, 0x7e);
  289         if(es_debug > 0) printf("init: d->bd_id 0x%x val 0x%x val2 0x%x\n",d->bd_id,val,val2);
  290         d->bd_id |=  CODEC_ID_BASSTREBLE;
  291         printf("es1371: codec vendor %c%c%c revision %d\n", 
  292                    (val >> 8) & 0xff, val & 0xff, (val2 >> 8) & 0xff, val2 & 0xff);
  293         printf("es1371: codec features");
  294         if (d->bd_id & CODEC_ID_DEDICATEDMIC)
  295           printf(" dedicated MIC PCM in");
  296         if (d->bd_id & CODEC_ID_MODEMCODEC)
  297           printf(" Modem Line Codec");
  298         if (d->bd_id & CODEC_ID_BASSTREBLE)
  299           printf(" Bass & Treble");
  300         if (d->bd_id & CODEC_ID_SIMULATEDSTEREO)
  301           printf(" Simulated Stereo");
  302         if (d->bd_id & CODEC_ID_HEADPHONEOUT)
  303           printf(" Headphone out");
  304         if (d->bd_id & CODEC_ID_LOUDNESS)
  305           printf(" Loudness");
  306         if (d->bd_id & CODEC_ID_18BITDAC)
  307           printf(" 18bit DAC");
  308         if (d->bd_id & CODEC_ID_20BITDAC)
  309           printf(" 20bit DAC");
  310         if (d->bd_id & CODEC_ID_18BITADC)
  311           printf(" 18bit ADC");
  312         if (d->bd_id & CODEC_ID_20BITADC)
  313           printf(" 20bit ADC");
  314         printf("%s\n", (d->bd_id & 0x3ff) ? "" : " none");
  315         val = (d->bd_id >> CODEC_ID_SESHIFT) & CODEC_ID_SEMASK;
  316         printf("es1371: stereo enhancement: %s\n", (val <= 20) ? stereo_enhancement[val] : "unknown");
  317         val = SOUND_MASK_LINE;
  318         mixer_ioctl_1371(d, SOUND_MIXER_WRITE_RECSRC, (caddr_t)&val, 0,NULL);
  319         for (i = 0; i < sizeof(initvol)/sizeof(initvol[0]); i++) {
  320           val = initvol[i].vol;
  321           if(es_debug > 0) printf("es_init -> mixer_ioctl_1371 0x%x\n",val);
  322           mixer_ioctl_1371(d, initvol[i].mixch, (caddr_t)&val, 0,NULL);
  323         }
  324         return 0;
  325 }
  326 
  327 
  328 int mixer_rdch(snddev_info *s, unsigned int ch, int *arg)
  329 {
  330         int j;
  331         
  332         if(es_debug > 0) printf("mixer_rdch ch 0x%x\n",ch);
  333         switch (ch) {
  334         case SOUND_MIXER_MIC:
  335           j = rdcodec(s, 0x0e);
  336           if (j & 0x8000){
  337                 put_user(0, (int *)arg);
  338                 return (*arg);
  339           }
  340           put_user(0x4949 - 0x202 * (j & 0x1f) + ((j & 0x40) ? 0x1b1b : 0), (int *)arg);
  341           return (*arg);
  342           
  343         case SOUND_MIXER_OGAIN:
  344         case SOUND_MIXER_PHONEIN:
  345           j = rdcodec(s, volreg[ch]);
  346           if (j & 0x8000){
  347                 put_user(0, (int *)arg);
  348                 return (*arg);
  349           }
  350           put_user(0x6464 - 0x303 * (j & 0x1f), (int *)arg);
  351           return (*arg);
  352           
  353         case SOUND_MIXER_PHONEOUT:
  354           if (!(s->bd_id & CODEC_ID_HEADPHONEOUT))
  355                 return EINVAL;
  356           /* fall through */
  357         case SOUND_MIXER_VOLUME:
  358           j = rdcodec(s, volreg[ch]);
  359           if (j & 0x8000){
  360                 put_user(0, (int *)arg);
  361                 return (*arg);
  362           }
  363           put_user(0x6464 - (swab(j) & 0x1f1f) * 3, (int *)arg);
  364           return (*arg);
  365         case SOUND_MIXER_SPEAKER:
  366           j = rdcodec(s, 0x0a);
  367           if (j & 0x8000){
  368                 put_user(0, (int *)arg);
  369                 return (*arg);
  370           }
  371           put_user(0x6464 - ((j >> 1) & 0xf) * 0x606, (int *)arg);
  372           return (*arg);
  373           
  374         case SOUND_MIXER_LINE:
  375         case SOUND_MIXER_CD:
  376         case SOUND_MIXER_VIDEO:
  377         case SOUND_MIXER_LINE1:
  378         case SOUND_MIXER_PCM:
  379           j = rdcodec(s, volreg[ch]);
  380           if (j & 0x8000){
  381                 put_user(0, (int *)arg);
  382                 return (*arg);
  383           }
  384           put_user(0x6464 - (swab(j) & 0x1f1f) * 3, (int *)arg);
  385           return (*arg);
  386           
  387         case SOUND_MIXER_BASS:
  388         case SOUND_MIXER_TREBLE:
  389           if (!(s->bd_id & CODEC_ID_BASSTREBLE))
  390                 return EINVAL;
  391           j = rdcodec(s, 0x08);
  392           if (ch == SOUND_MIXER_BASS)
  393                 j >>= 8;
  394           put_user((((j & 15) * 100) / 15) * 0x101, (int *)arg);
  395           return (*arg);
  396           
  397           /* SOUND_MIXER_RECLEV and SOUND_MIXER_IGAIN specify gain */
  398         case SOUND_MIXER_RECLEV:
  399           j = rdcodec(s, 0x1c);
  400           if (j & 0x8000){
  401                 put_user(0, (int *)arg);
  402                 return (*arg);
  403           }
  404           put_user((swab(j)  & 0xf0f) * 6 + 0xa0a, (int *)arg);
  405           return (*arg);
  406           
  407         case SOUND_MIXER_IGAIN:
  408           if (!(s->bd_id & CODEC_ID_DEDICATEDMIC))
  409                 return EINVAL;
  410           j = rdcodec(s, 0x1e);
  411           if (j & 0x8000){
  412                 put_user(0, (int *)arg);
  413                 return (*arg);
  414           }
  415           put_user((j & 0xf) * 0x606 + 0xa0a, (int *)arg);
  416           return (*arg);
  417           
  418         default:
  419           return EINVAL;
  420         }
  421 }
  422 
  423 int mixer_wrch(snddev_info *s, unsigned int ich, int val) 
  424 {
  425         int i;
  426         unsigned l1, r1;
  427 
  428         u_int ch = (ich & 0xff);
  429         if(es_debug > 0) printf("mixer_wrch ch 0x%x val 0x%x\t",ch,(val & 0xffff));
  430 
  431         l1 = val & 0xff;
  432         r1 = (val >> 8) & 0xff;
  433         if(es_debug > 0) printf ("l1 0x%x r1 0x%x\n",l1,r1);
  434         if (l1 > 100)
  435                 l1 = 100;
  436         if (r1 > 100)
  437                 r1 = 100;
  438         s->mix_levels[ch] = ((u_int) r1 << 8) | l1;
  439         switch (ch)  {
  440         case SOUND_MIXER_LINE:
  441 /*        printf("SOUND_MIXER_LINE\n"); */
  442         case SOUND_MIXER_CD:
  443 /*        printf("SOUND_MIXER_CD\n"); */
  444         case SOUND_MIXER_VIDEO:
  445 /*        printf("SOUND_MIXER_VIDEO\n"); */
  446         case SOUND_MIXER_LINE1:
  447 /*        printf("SOUND_MIXEgR_LINE1\n");*/
  448         case SOUND_MIXER_PCM:
  449           if (es_debug >0 ) printf("SOUND_MIXER_PCM\n");
  450           if (l1 < 7 && r1 < 7) {
  451                 wrcodec(s, volreg[ch], 0x8000);
  452                 return 0;
  453           }
  454           if (l1 < 7)
  455                 l1 = 7;
  456           if (r1 < 7)
  457                 r1 = 7;
  458           wrcodec(s, volreg[ch], (((100 - l1) / 3) << 8) | ((100 - r1) / 3));
  459           return 0;
  460           
  461         case SOUND_MIXER_PHONEOUT:
  462           if(es_debug > 0) printf("SOUND_MIXER_PHONEOUT\n");
  463           if (!(s->bd_id & CODEC_ID_HEADPHONEOUT))
  464                 return EINVAL;
  465           /* fall through */
  466         case SOUND_MIXER_VOLUME:
  467           if(es_debug > 0) printf("SOUND_MIXER_VOLUME\n");
  468 #ifdef AC97_PESSIMISTIC
  469           if (l1 < 7 && r1 < 7) {
  470                 wrcodec(s, volreg[ch], 0x8000);
  471                 return 0;
  472           }
  473           if (l1 < 7)
  474                 l1 = 7;
  475           if (r1 < 7)
  476                 r1 = 7;
  477           wrcodec(s, volreg[ch], (((100 - l1) / 3) << 8) | ((100 - r1) / 3));
  478           /*      es1371_src_write(s, volreg[ch], (((100 - l1) / 3) << 8) | ((100 - r1) / 3)); */
  479           return 0;
  480 #else /* AC97_PESSIMISTIC */
  481           if (l1 < 4 && r1 < 4) {
  482                 wrcodec(s, volreg[ch], 0x8000);
  483                 return 0;
  484           }
  485           if (l1 < 4)
  486                 l1 = 4;
  487           if (r1 < 4)
  488                 r1 = 4;
  489           wrcodec(s, volreg[ch], ((2 * (100 - l1) / 3) << 8) | (2 * (100 - r1) / 3));
  490           return 0;
  491 #endif /* AC97_PESSIMISTIC */
  492           
  493         case SOUND_MIXER_OGAIN:
  494           if(es_debug > 0) printf("SOUND_MIXER_OGAIN\n");
  495         case SOUND_MIXER_PHONEIN:
  496           if(es_debug > 0) printf("SOUND_MIXER_PHONEIN\n");
  497 #ifdef AC97_PESSIMISTIC
  498           wrcodec(s, volreg[ch], (l1 < 7) ? 0x8000 : (100 - l1) / 3);
  499           return 0;
  500 #else /* AC97_PESSIMISTIC */
  501           wrcodec(s, volreg[ch], (l1 < 4) ? 0x8000 : (2 * (100 - l1) / 3));
  502           return 0;
  503 #endif /* AC97_PESSIMISTIC */
  504           
  505         case SOUND_MIXER_SPEAKER:
  506           wrcodec(s, 0x0a, (l1 < 10) ? 0x8000 : ((100 - l1) / 6) << 1);
  507           return 0;
  508           
  509         case SOUND_MIXER_MIC:
  510           if(es_debug > 0) printf("SOUND_MIXER_MIC\n");
  511 #ifdef AC97_PESSIMISTIC
  512           if (l1 < 11) {
  513                 wrcodec(s, 0x0e, 0x8000);
  514                 return 0;
  515           }
  516           i = 0;
  517           if (l1 >= 27) {
  518                 l1 -= 27;
  519                 i = 0x40;
  520           }
  521           if (l1 < 11) 
  522                 l1 = 11;
  523           wrcodec(s, 0x0e, ((73 - l1) / 2) | i);
  524           return 0;
  525 #else /* AC97_PESSIMISTIC */
  526           if (l1 < 9) {
  527                 wrcodec(s, 0x0e, 0x8000);
  528                 return 0;
  529           }
  530           i = 0;
  531           if (l1 >= 13) {
  532                 l1 -= 13;
  533                 i = 0x40;
  534           }
  535           if (l1 < 9) 
  536                 l1 = 9;
  537           wrcodec(s, 0x0e, (((87 - l1) * 4) / 5) | i);
  538           return 0;
  539 #endif /* AC97_PESSIMISTIC */
  540           
  541         case SOUND_MIXER_BASS:
  542           if(es_debug > 0) printf("SOUND_MIXER_BASS\n");
  543           val = ((l1 * 15) / 100) & 0xf;
  544           wrcodec(s, 0x08, (rdcodec(s, 0x08) & 0x00ff) | (val << 8));
  545           return 0;
  546           
  547         case SOUND_MIXER_TREBLE:
  548           if(es_debug > 0) printf("SOUND_MIXER_TREBLE\n");
  549           val = ((l1 * 15) / 100) & 0xf;
  550           wrcodec(s, 0x08, (rdcodec(s, 0x08) & 0xff00) | val);
  551           return 0;
  552           
  553           /* SOUND_MIXER_RECLEV and SOUND_MIXER_IGAIN specify gain */
  554         case SOUND_MIXER_RECLEV:
  555           if(es_debug > 0) printf("SOUND_MIXER_RECLEV\n");
  556           if (l1 < 10 || r1 < 10) {
  557                 wrcodec(s, 0x1c, 0x8000);
  558                 return 0;
  559           }
  560           if (l1 < 10)
  561                 l1 = 10;
  562           if (r1 < 10)
  563                 r1 = 10;
  564           wrcodec(s, 0x1c, (((l1 - 10) / 6) << 8) | ((r1 - 10) / 6));
  565           return 0;
  566           
  567         case SOUND_MIXER_IGAIN:
  568           if(es_debug > 0) printf("SOUND_MIXER_IGAIN\n");
  569           if (!(s->bd_id & CODEC_ID_DEDICATEDMIC))
  570                 return EINVAL;
  571           wrcodec(s, 0x1e, (l1 < 10) ? 0x8000 : ((l1 - 10) / 6) & 0xf);
  572           return 0;
  573           
  574         default:
  575           return EINVAL;
  576         }
  577 }
  578 
  579 
  580 /* --------------------------------------------------------------------- */
  581 
  582 #if 0
  583 /* hmm for some reason I changed this in the es1370 code ... should wrcodec handle this */
  584 /* make sure to find out where this is called from */
  585 static int
  586 write_codec_1371(snddev_info *d, u_char i, u_char data)
  587 {
  588         struct es_info *es = (struct es_info *)d->device_data;
  589         int             wait = 100;     /* 100 msec timeout */
  590         u_int32_t ret;
  591         do {
  592                 if ((ret = bus_space_read_4(es->st, es->sh, ES1371_REG_STATUS) &
  593                       ES1371_CSTAT) == 0) {
  594                         bus_space_write_2(es->st, es->sh, ES1371_REG_CODEC,
  595                                 ((u_short)i << ES1371_CODEC_INDEX_SHIFT) | data);
  596                         return (0);
  597                 }
  598                 if(es_debug > 0) printf("write_codec ret 0x%x ret & ES1371_CSTAT 0x%x\n",ret,ret & STAT_CSTAT);
  599                 DELAY(1000);
  600                 /* tsleep(&wait, PZERO, "sndaw", hz / 1000); */
  601         } while (--wait);
  602         printf("pcm: write_codec timed out\n");
  603         return (-1);
  604 }
  605 #endif
  606 
  607 
  608 void wrcodec(snddev_info *s, unsigned addr, unsigned data)
  609 {
  610   /*    unsigned long flags; */
  611   int sl;
  612     unsigned t, x;
  613         struct es_info *es = (struct es_info *)s->device_data;
  614 
  615         if(es_debug > 0) printf("wrcodec addr 0x%x data 0x%x\n",addr,data);
  616 
  617         for (t = 0; t < 0x1000; t++)
  618           if(!(bus_space_read_4(es->st, es->sh,ES1371_REG_CODEC) & CODEC_WIP))
  619                         break;
  620         /*      spin_lock_irqsave(&s->lock, flags); */
  621         sl = spltty();
  622         /* save the current state for later */
  623         x =  bus_space_read_4(es->st, es->sh, ES1371_REG_SMPRATE);
  624         /* enable SRC state data in SRC mux */
  625         bus_space_write_4(es->st, es->sh, ES1371_REG_SMPRATE,
  626                                           (es1371_wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DDAC2 | SRC_DADC)));     
  627         /* wait for a SAFE time to write addr/data and then do it, dammit */
  628         for (t = 0; t < 0x1000; t++)
  629           if (( bus_space_read_4(es->st, es->sh, ES1371_REG_SMPRATE) & 0x00070000) == 0x00010000) 
  630                 break;
  631         
  632         if(es_debug > 2) printf("one b_s_w: 0x%x 0x%x 0x%x\n",es->sh,ES1371_REG_CODEC,
  633                                                  ((addr << CODEC_POADD_SHIFT) & CODEC_POADD_MASK) |
  634                                                  ((data << CODEC_PODAT_SHIFT) & CODEC_PODAT_MASK));
  635         
  636         bus_space_write_4(es->st, es->sh,ES1371_REG_CODEC,
  637                                           ((addr << CODEC_POADD_SHIFT) & CODEC_POADD_MASK) |
  638                                           ((data << CODEC_PODAT_SHIFT) & CODEC_PODAT_MASK));
  639         /* restore SRC reg */
  640         es1371_wait_src_ready(s);
  641         if(es_debug > 2) printf("two b_s_w: 0x%x 0x%x 0x%x\n",es->sh,ES1371_REG_SMPRATE,x);
  642         bus_space_write_4(es->st, es->sh,ES1371_REG_SMPRATE,x);
  643         /*      spin_unlock_irqrestore(&s->lock, flags); */
  644         splx(sl);
  645 }
  646 
  647 unsigned rdcodec(snddev_info *s, unsigned addr)
  648 {
  649   /*  unsigned long flags; */
  650   int sl;
  651   unsigned t, x;
  652 
  653   struct es_info *es = (struct es_info *)s->device_data;
  654   if(es_debug > 5) printf("rdcodec ");
  655   
  656   for (t = 0; t < 0x1000; t++)
  657         if (!(x = bus_space_read_4(es->st,es->sh,ES1371_REG_CODEC) & CODEC_WIP))
  658           break;
  659   sl = spltty();
  660   /* save the current state for later */
  661   x =  bus_space_read_4(es->st, es->sh, ES1371_REG_SMPRATE);
  662   /* enable SRC state data in SRC mux */
  663   bus_space_write_4(es->st, es->sh, ES1371_REG_SMPRATE,
  664                                         (es1371_wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DDAC2 | SRC_DADC)));     
  665   /* wait for a SAFE time to write addr/data and then do it, dammit */
  666   for (t = 0; t < 0x1000; t++)
  667         if (( bus_space_read_4(es->st, es->sh, ES1371_REG_SMPRATE) & 0x00070000) == 0x00010000) 
  668           break;
  669 
  670   bus_space_write_4(es->st, es->sh,ES1371_REG_CODEC,
  671                                         ((addr << CODEC_POADD_SHIFT) & CODEC_POADD_MASK) | CODEC_PORD);
  672 
  673   /* restore SRC reg */
  674   es1371_wait_src_ready(s);
  675   bus_space_write_4(es->st,es->sh,ES1371_REG_SMPRATE,x);
  676   splx(sl);
  677   /* now wait for the stinkin' data (RDY) */
  678   for (t = 0; t < 0x1000; t++)
  679         if ((x = bus_space_read_4(es->st,es->sh,ES1371_REG_CODEC)) & CODEC_RDY)
  680           break;
  681   if(es_debug > 5) printf("0x%x ret 0x%x\n",x,((x & CODEC_PIDAT_MASK) >> CODEC_PIDAT_SHIFT));
  682   return ((x & CODEC_PIDAT_MASK) >> CODEC_PIDAT_SHIFT);
  683 }
  684 
  685 
  686 
  687 int 
  688 mixer_ioctl_1371(snddev_info *s, u_long cmd, caddr_t data, int fflag, struct proc *p)
  689 {
  690   int cmdi;
  691   int val;      
  692   int *arg = (int *)data;
  693   
  694   val = *(int *)data;
  695   cmdi = cmd & 0xff;
  696 
  697   if(es_debug > 0) printf("mixer_ioctl_1371 cmd 0x%x cmdi 0x%x write %s read %s ",(u_int)cmd,cmdi,
  698                                            (((cmd & MIXER_WRITE(0)) == MIXER_WRITE(0))?"yes":"no"),
  699                                            (((cmd & MIXER_READ(0)) == MIXER_READ(0))?"yes":"no"));
  700 
  701   if (cmdi == OSS_GETVERSION){
  702         put_user(SOUND_VERSION, (int *)arg);
  703         return (0);
  704   }
  705 
  706   if ((cmd & MIXER_READ(0)) == MIXER_READ(0)){
  707         switch (cmdi)  {
  708         case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
  709           if (es_debug > 4) printf("mixer_ioctl_1371: SOUND_MIXER_RECSRC\n");
  710                 put_user(recsrc[rdcodec(s, ES1371_REG_RECSRC) & 7], (int *)arg);
  711                 break;
  712         case SOUND_MIXER_DEVMASK: /* Arg contains a bit for each supported device */
  713           put_user(SOUND_MASK_LINE | SOUND_MASK_CD | SOUND_MASK_VIDEO |
  714                            SOUND_MASK_LINE1 | SOUND_MASK_PCM | SOUND_MASK_VOLUME |
  715                            SOUND_MASK_OGAIN | SOUND_MASK_PHONEIN | SOUND_MASK_SPEAKER |
  716                            SOUND_MASK_MIC | SOUND_MASK_RECLEV |
  717                            ((s->bd_id & CODEC_ID_BASSTREBLE) ? (SOUND_MASK_BASS | SOUND_MASK_TREBLE) : 0) |
  718                            ((s->bd_id & CODEC_ID_HEADPHONEOUT) ? SOUND_MASK_PHONEOUT : 0) |
  719                            ((s->bd_id & CODEC_ID_DEDICATEDMIC) ? SOUND_MASK_IGAIN : 0), (int *)arg);
  720           if (es_debug > 4) printf("mixer_ioctl_1371: SOUND_MIXER_DEVMASK s->bd_id 0x%x arg 0x%x\n",s->bd_id,*arg);
  721           break;
  722         case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
  723           if (es_debug > 4) printf("mixer_ioctl_1371: SOUND_MIXER_RECMASK\n");
  724           put_user(SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_VIDEO | SOUND_MASK_LINE1 |
  725                            SOUND_MASK_LINE | SOUND_MASK_VOLUME | SOUND_MASK_PHONEOUT |
  726                            SOUND_MASK_PHONEIN, (int *)arg);
  727           break;
  728         case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
  729           if (es_debug > 4) printf("mixer_ioctl_1371: SOUND_MIXER_STEREODEVS\n");
  730           put_user(SOUND_MASK_LINE | SOUND_MASK_CD | SOUND_MASK_VIDEO |
  731                            SOUND_MASK_LINE1 | SOUND_MASK_PCM | SOUND_MASK_VOLUME |
  732                            SOUND_MASK_PHONEOUT | SOUND_MASK_RECLEV, (int *)arg);
  733           break;
  734         case SOUND_MIXER_CAPS:
  735           if (es_debug > 4) printf("mixer_ioctl_1371: SOUND_MIXER_CAPS\n");
  736           put_user(SOUND_CAP_EXCL_INPUT, (int *)arg);
  737           break;
  738         default:
  739           if (es_debug > 4) printf("mixer_ioctl_1371: default\n");
  740           cmdi = cmd & 0xff;
  741           if (cmdi >= SOUND_MIXER_NRDEVICES)
  742                 return EINVAL;
  743           { int ret;
  744            ret = mixer_rdch(s, cmdi, arg);
  745            if(es_debug > 0) printf("READ done ret 0x%x arg 0x%x\n",ret,*arg);
  746           }
  747         }
  748   } 
  749   if  ((cmd & MIXER_WRITE(0)) == MIXER_WRITE(0)){
  750         if(es_debug > 0) printf("WRITE cmdi 0x%x data 0x%x val 0x%x sizeof(val) %d\n",cmdi,*data,val,sizeof(val));
  751         switch (cmdi)  {
  752           int i;
  753         case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
  754           /*      get_user_ret(val, (int *)arg, EFAULT); */
  755           i = hweight32(val);
  756           if (es_debug > 0) printf("SOUND_MIXER_RECSRC i: %d\n",i);
  757           if (i == 0)
  758                 return 0; /*val = mixer_recmask(s);*/
  759           else if (i > 1) 
  760                 val &= ~recsrc[rdcodec(s, ES1371_REG_RECSRC) & 7];
  761           for (i = 0; i < 8; i++) {
  762                 if (val & recsrc[i]) {
  763                   wrcodec(s, ES1371_REG_RECSRC, 0x101 * i);
  764                   return 0;
  765                 }
  766           }
  767           return 0;
  768         default:
  769           if (es_debug > 0) printf("mixer_ioctl_1371 default cmdi: %d\n",cmdi);
  770           if (cmdi >= SOUND_MIXER_NRDEVICES)
  771                 return EINVAL;
  772           /*      get_user_ret(val, (int *)arg, EFAULT); */
  773           if (mixer_wrch(s, cmdi, val))
  774                 return EINVAL;
  775           { int ret;
  776           ret = mixer_rdch(s, cmdi, (int *)arg);
  777           if(es_debug > 0) printf("WRITE done ret 0x%x arg 0x%x\n",ret,*arg);
  778           }
  779         }
  780   }
  781   return (0);
  782 }
  783 
  784 u_int es1371_wait_src_ready(snddev_info *d){
  785   struct es_info *es = (struct es_info *)d->device_data;
  786   u_int t, r;
  787   
  788   for (t = 0; t < 500; t++) {
  789         if (!((r = bus_space_read_4(es->st, es->sh,ES1371_REG_SMPRATE)) & ES1371_SRC_RAM_BUSY)){
  790           return r;
  791         }
  792         /*      snd_delay(1); */
  793         DELAY(1000);
  794   }
  795   printf("es1371: wait source ready timeout 0x%x [0x%x]\n", ES1371_REG_SMPRATE, r);
  796   return 0;
  797 }
  798 
  799 static u_int es1371_src_read(snddev_info *d, 
  800                                                          u_short reg){
  801   struct es_info *es = (struct es_info *)d->device_data;
  802   unsigned int r;
  803   
  804   r = es1371_wait_src_ready(d) &
  805         (ES1371_SRC_DISABLE |
  806          ES1371_DIS_P1 |
  807          ES1371_DIS_P2 |
  808          ES1371_DIS_R1);
  809   r |= ES1371_SRC_RAM_ADDRO(reg);
  810   bus_space_write_4(es->st, es->sh,ES1371_REG_SMPRATE,r);
  811   return ES1371_SRC_RAM_DATAI(es1371_wait_src_ready(d));
  812 }
  813 
  814 void es1371_src_write(snddev_info *d,
  815                                                                  u_short reg, 
  816                                                                  u_short data){
  817         struct es_info *es = (struct es_info *)d->device_data;
  818         u_int r;
  819 
  820         r = es1371_wait_src_ready(d) &
  821             (ES1371_SRC_DISABLE | 
  822                  ES1371_DIS_P1 |
  823              ES1371_DIS_P2 |
  824                  ES1371_DIS_R1);
  825         r |= ES1371_SRC_RAM_ADDRO(reg) |  ES1371_SRC_RAM_DATAO(data);
  826         if(es_debug > 1 ) printf("es1371_src_write 0x%x 0x%x\n",ES1371_REG_SMPRATE,r | ES1371_SRC_RAM_WE); 
  827         bus_space_write_4(es->st, es->sh,ES1371_REG_SMPRATE,r | ES1371_SRC_RAM_WE);
  828 }
  829 
  830 u_int 
  831 es1371_adc_rate(snddev_info *d,
  832                                 u_int rate, 
  833                                 int set){
  834   u_int n, truncm, freq, result;
  835   
  836   if (rate > 48000)
  837         rate = 48000;
  838   if (rate < 4000)
  839         rate = 4000;
  840   n = rate / 3000;
  841   if ((1 << n) & ((1 << 15) | (1 << 13) | (1 << 11) | (1 << 9)))
  842         n--;
  843   truncm = (21 * n - 1) | 1;
  844   freq = ((48000UL << 15) / rate) * n;
  845   result = (48000UL << 15) / (freq / n);
  846   if (set) {
  847         if (rate >= 24000) {
  848           if (truncm > 239)
  849                 truncm = 239;
  850           es1371_src_write(d, ES_SMPREG_ADC + ES_SMPREG_TRUNC_N,
  851                                            (((239 - truncm) >> 1) << 9) | (n << 4));
  852         } else {
  853           if (truncm > 119)
  854                 truncm = 119;
  855           es1371_src_write(d, ES_SMPREG_ADC + ES_SMPREG_TRUNC_N,
  856                                                    0x8000 | (((119 - truncm) >> 1) << 9) | (n << 4));
  857         }
  858         es1371_src_write(d, ES_SMPREG_ADC + ES_SMPREG_INT_REGS,
  859                                                  (es1371_src_read(d, 
  860                                                                                   ES_SMPREG_ADC +
  861                                                                                   ES_SMPREG_INT_REGS) &
  862                                                   0x00ff) | ((freq >> 5) & 0xfc00));
  863         es1371_src_write(d, ES_SMPREG_ADC + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff);
  864         es1371_src_write(d, ES_SMPREG_VOL_ADC, n << 8);
  865         es1371_src_write(d, ES_SMPREG_VOL_ADC + 1, n << 8);
  866         }
  867         return result;
  868 }
  869 
  870 u_int
  871 es1371_dac1_rate(snddev_info *d,
  872                                  u_int rate,
  873                                  int set){
  874   struct es_info *es = (struct es_info *)d->device_data;
  875   u_int freq, r, result;
  876   
  877   
  878   if (rate > 48000)
  879         rate = 48000;
  880   if (rate < 4000)
  881         rate = 4000;
  882   freq = (rate << 15) / 3000;
  883   result = (freq * 3000) >> 15;
  884   if (set) {
  885         r = (es1371_wait_src_ready(d) & (ES1371_SRC_DISABLE | ES1371_DIS_P2 | ES1371_DIS_R1)) | ES1371_DIS_P1;
  886         bus_space_write_4(es->st, es->sh,ES1371_REG_SMPRATE,r);
  887         if(es_debug > 0) printf("dac1_rate 0x%x\n",bus_space_read_4(es->st, es->sh,ES1371_REG_SMPRATE));
  888         es1371_src_write(d, ES_SMPREG_DAC1 + 
  889                                          ES_SMPREG_INT_REGS,
  890                                          (es1371_src_read(d, 
  891                                                                           ES_SMPREG_DAC1 +
  892                                                                           ES_SMPREG_INT_REGS) &
  893                                           0x00ff) | ((freq >> 5) & 0xfc00));
  894         es1371_src_write(d, ES_SMPREG_DAC1 + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff);
  895         r = (es1371_wait_src_ready(d) & (ES1371_SRC_DISABLE | ES1371_DIS_P2 | ES1371_DIS_R1));
  896         bus_space_write_4(es->st, es->sh,ES1371_REG_SMPRATE,r);
  897         if(es_debug > 0) printf("dac1_rate 0x%x\n",bus_space_read_4(es->st, es->sh,ES1371_REG_SMPRATE));
  898   }
  899   return result;
  900 }
  901 
  902 u_int
  903 es1371_dac2_rate(snddev_info *d,
  904                                  u_int rate, 
  905                                  int set){
  906   u_int freq, r, result;
  907   struct es_info *es = (struct es_info *)d->device_data;
  908   
  909   if (rate > 48000)
  910         rate = 48000;
  911   if (rate < 4000)
  912         rate = 4000;
  913   freq = (rate << 15) / 3000;
  914   result = (freq * 3000) >> 15;
  915   if (set) {
  916         r = (es1371_wait_src_ready(d) & (ES1371_SRC_DISABLE | ES1371_DIS_P1 | ES1371_DIS_R1)) | ES1371_DIS_P2;
  917         bus_space_write_4(es->st, es->sh,ES1371_REG_SMPRATE,r);
  918         if(es_debug > 0) printf("dac2_rate 0x%x\n",bus_space_read_4(es->st, es->sh,ES1371_REG_SMPRATE));
  919         es1371_src_write(d, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS,
  920                                          (es1371_src_read(d, ES_SMPREG_DAC2 +
  921                                                                           ES_SMPREG_INT_REGS) & 
  922                                           0x00ff) | ((freq >> 5) & 0xfc00));
  923         es1371_src_write(d, ES_SMPREG_DAC2 + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff);
  924         r = (es1371_wait_src_ready(d) & (ES1371_SRC_DISABLE | ES1371_DIS_P1 | ES1371_DIS_R1));
  925         bus_space_write_4(es->st, es->sh,ES1371_REG_SMPRATE,r);
  926         if(es_debug > 0) printf("dac2_rate 0x%x\n",bus_space_read_4(es->st, es->sh,ES1371_REG_SMPRATE));
  927   }
  928   return result;
  929 }

Cache object: 28a2f12ef2964157dcf11ed420f20a94


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