root/dev/pci/cs4280.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cs4280_match
  2. cs4280_read_codec
  3. cs4280_write_codec
  4. cs4280_src_wait
  5. cs4280_set_adc_rate
  6. cs4280_set_dac_rate
  7. cs4280_attachhook
  8. cs4280_attach
  9. cs4280_intr
  10. cs4280_download
  11. cs4280_download_image
  12. cs4280_checkimage
  13. cs4280_check_images
  14. cs4280_attach_codec
  15. cs4280_reset_codec
  16. cs4280_reset
  17. cs4280_open
  18. cs4280_close
  19. cs4280_query_encoding
  20. cs4280_set_params
  21. cs4280_round_blocksize
  22. cs4280_round_buffersize
  23. cs4280_get_props
  24. cs4280_mixer_get_port
  25. cs4280_mappage
  26. cs4280_query_devinfo
  27. cs4280_get_portnum_by_name
  28. cs4280_halt_output
  29. cs4280_halt_input
  30. cs4280_getdev
  31. cs4280_mixer_set_port
  32. cs4280_freemem
  33. cs4280_allocmem
  34. cs4280_malloc
  35. cs4280_free
  36. cs4280_trigger_output
  37. cs4280_trigger_input
  38. cs4280_init
  39. cs4280_init2
  40. cs4280_power
  41. cs4280_clear_fifos
  42. cs4280_midi_open
  43. cs4280_midi_close
  44. cs4280_midi_output
  45. cs4280_midi_getinfo

    1 /*      $OpenBSD: cs4280.c,v 1.26 2007/08/01 21:37:21 miod Exp $        */
    2 /*      $NetBSD: cs4280.c,v 1.5 2000/06/26 04:56:23 simonb Exp $        */
    3 
    4 /*
    5  * Copyright (c) 1999, 2000 Tatoku Ogaito.  All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. All advertising materials mentioning features or use of this software
   16  *    must display the following acknowledgement:
   17  *      This product includes software developed by Tatoku Ogaito
   18  *      for the NetBSD Project.
   19  * 4. The name of the author may not be used to endorse or promote products
   20  *    derived from this software without specific prior written permission
   21  *
   22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   32  */
   33 
   34 /*
   35  * Cirrus Logic CS4280 (and maybe CS461x) driver.
   36  * Data sheets can be found
   37  * http://www.cirrus.com/ftp/pubs/4280.pdf
   38  * http://www.cirrus.com/ftp/pubs/4297.pdf
   39  * ftp://ftp.alsa-project.org/pub/manuals/cirrus/embedded_audio_spec.pdf
   40  * ftp://ftp.alsa-project.org/pub/manuals/cirrus/embedded_audio_spec.doc
   41  */
   42 
   43 /*
   44  * TODO
   45  * Implement MIDI
   46  * Joystick support
   47  */
   48 
   49 #ifdef CS4280_DEBUG
   50 #ifndef MIDI_READY
   51 #define MIDI_READY
   52 #endif /* ! MIDI_READY */
   53 #endif
   54 
   55 #ifdef MIDI_READY
   56 #include "midi.h"
   57 #endif
   58 
   59 #if defined(CS4280_DEBUG)
   60 #define DPRINTF(x)          if (cs4280debug) printf x
   61 #define DPRINTFN(n,x)       if (cs4280debug>(n)) printf x
   62 int cs4280debug = 0;
   63 #else
   64 #define DPRINTF(x)
   65 #define DPRINTFN(n,x)
   66 #endif
   67 
   68 #include <sys/param.h>
   69 #include <sys/systm.h>
   70 #include <sys/kernel.h>
   71 #include <sys/fcntl.h>
   72 #include <sys/malloc.h>
   73 #include <sys/device.h>
   74 
   75 #include <dev/pci/pcidevs.h>
   76 #include <dev/pci/pcivar.h>
   77 #include <dev/pci/cs4280reg.h>
   78 
   79 #include <sys/audioio.h>
   80 #include <dev/audio_if.h>
   81 #include <dev/midi_if.h>
   82 #include <dev/mulaw.h>
   83 #include <dev/auconv.h>
   84 
   85 #include <dev/ic/ac97.h>
   86 
   87 #include <machine/bus.h>
   88 
   89 #define CSCC_PCI_BA0 0x10
   90 #define CSCC_PCI_BA1 0x14
   91 
   92 struct cs4280_dma {
   93         bus_dmamap_t map;
   94         caddr_t addr;           /* real dma buffer */
   95         caddr_t dum;            /* dummy buffer for audio driver */
   96         bus_dma_segment_t segs[1];
   97         int nsegs;
   98         size_t size;
   99         struct cs4280_dma *next;
  100 };
  101 #define DMAADDR(p) ((p)->map->dm_segs[0].ds_addr)
  102 #define BUFADDR(p)  ((void *)((p)->dum))
  103 #define KERNADDR(p) ((void *)((p)->addr))
  104 
  105 /*
  106  * Software state
  107  */
  108 struct cs4280_softc {
  109         struct device         sc_dev;
  110 
  111         pci_intr_handle_t *   sc_ih;
  112 
  113         /* I/O (BA0) */
  114         bus_space_tag_t       ba0t;
  115         bus_space_handle_t    ba0h;
  116         
  117         /* BA1 */
  118         bus_space_tag_t       ba1t;
  119         bus_space_handle_t    ba1h;
  120         
  121         /* DMA */
  122         bus_dma_tag_t    sc_dmatag;
  123         struct cs4280_dma *sc_dmas;
  124 
  125         void    (*sc_pintr)(void *);    /* dma completion intr handler */
  126         void    *sc_parg;               /* arg for sc_intr() */
  127         char    *sc_ps, *sc_pe, *sc_pn;
  128         int     sc_pcount;
  129         int     sc_pi;
  130         struct  cs4280_dma *sc_pdma;
  131         char    *sc_pbuf;
  132 #ifdef DIAGNOSTIC
  133         char    sc_prun;
  134 #endif
  135 
  136         void    (*sc_rintr)(void *);    /* dma completion intr handler */
  137         void    *sc_rarg;               /* arg for sc_intr() */
  138         char    *sc_rs, *sc_re, *sc_rn;
  139         int     sc_rcount;
  140         int     sc_ri;
  141         struct  cs4280_dma *sc_rdma;
  142         char    *sc_rbuf;
  143         int     sc_rparam;              /* record format */
  144 #ifdef DIAGNOSTIC
  145         char    sc_rrun;
  146 #endif
  147 
  148 #if NMIDI > 0
  149         void    (*sc_iintr)(void *, int); /* midi input ready handler */
  150         void    (*sc_ointr)(void *);      /* midi output ready handler */
  151         void    *sc_arg;
  152 #endif
  153 
  154         u_int32_t pctl;
  155         u_int32_t cctl;
  156 
  157         struct ac97_codec_if *codec_if;
  158         struct ac97_host_if host_if;    
  159 
  160         char    sc_suspend;
  161         void   *sc_powerhook;           /* Power Hook */
  162         u_int16_t  ac97_reg[CS4280_SAVE_REG_MAX + 1];   /* Save ac97 registers */
  163 };
  164 
  165 #define BA0READ4(sc, r) bus_space_read_4((sc)->ba0t, (sc)->ba0h, (r))
  166 #define BA0WRITE4(sc, r, x) bus_space_write_4((sc)->ba0t, (sc)->ba0h, (r), (x))
  167 #define BA1READ4(sc, r) bus_space_read_4((sc)->ba1t, (sc)->ba1h, (r))
  168 #define BA1WRITE4(sc, r, x) bus_space_write_4((sc)->ba1t, (sc)->ba1h, (r), (x))
  169 
  170 int     cs4280_match(struct device *, void *, void *);
  171 void    cs4280_attach(struct device *, struct device *, void *);
  172 void    cs4280_attachhook(void *xsc);
  173 int     cs4280_intr(void *);
  174 void    cs4280_reset(void *);
  175 int     cs4280_download_image(struct cs4280_softc *);
  176 
  177 int cs4280_download(struct cs4280_softc *, const u_int32_t *, u_int32_t, u_int32_t);
  178 int cs4280_allocmem(struct cs4280_softc *, size_t, size_t,
  179                          struct cs4280_dma *);
  180 int cs4280_freemem(struct cs4280_softc *, struct cs4280_dma *);
  181 
  182 #ifdef CS4280_DEBUG
  183 int     cs4280_check_images(struct cs4280_softc *);
  184 int     cs4280_checkimage(struct cs4280_softc *, u_int32_t *, u_int32_t,
  185                           u_int32_t);
  186 #endif
  187 
  188 struct  cfdriver clcs_cd = {
  189         NULL, "clcs", DV_DULL
  190 };
  191 
  192 struct cfattach clcs_ca = {
  193         sizeof(struct cs4280_softc), cs4280_match, cs4280_attach
  194 };
  195 
  196 int     cs4280_init(struct cs4280_softc *, int);
  197 int     cs4280_init2(struct cs4280_softc *, int);
  198 int     cs4280_open(void *, int);
  199 void    cs4280_close(void *);
  200 
  201 int     cs4280_query_encoding(void *, struct audio_encoding *);
  202 int     cs4280_set_params(void *, int, int, struct audio_params *, struct audio_params *);
  203 int     cs4280_round_blocksize(void *, int);
  204 
  205 int     cs4280_halt_output(void *);
  206 int     cs4280_halt_input(void *);
  207 
  208 int     cs4280_getdev(void *, struct audio_device *);
  209 
  210 int     cs4280_mixer_set_port(void *, mixer_ctrl_t *);
  211 int     cs4280_mixer_get_port(void *, mixer_ctrl_t *);
  212 int     cs4280_query_devinfo(void *addr, mixer_devinfo_t *dip);
  213 void   *cs4280_malloc(void *, int, size_t, int, int);
  214 void    cs4280_free(void *, void *, int);
  215 size_t  cs4280_round_buffersize(void *, int, size_t);
  216 paddr_t cs4280_mappage(void *, void *, off_t, int);
  217 int     cs4280_get_props(void *);
  218 int     cs4280_trigger_output(void *, void *, void *, int, void (*)(void *),
  219             void *, struct audio_params *);
  220 int     cs4280_trigger_input(void *, void *, void *, int, void (*)(void *),
  221             void *, struct audio_params *);
  222 
  223 
  224 void    cs4280_set_dac_rate(struct cs4280_softc *, int );
  225 void    cs4280_set_adc_rate(struct cs4280_softc *, int );
  226 int     cs4280_get_portnum_by_name(struct cs4280_softc *, char *, char *,
  227                                          char *);
  228 int     cs4280_src_wait(struct cs4280_softc *);
  229 int     cs4280_attach_codec(void *sc, struct ac97_codec_if *);
  230 int     cs4280_read_codec(void *sc, u_int8_t a, u_int16_t *d);
  231 int     cs4280_write_codec(void *sc, u_int8_t a, u_int16_t d);
  232 void    cs4280_reset_codec(void *sc);
  233 
  234 void    cs4280_power(int, void *);
  235 
  236 void    cs4280_clear_fifos(struct cs4280_softc *);
  237 
  238 #if NMIDI > 0
  239 void    cs4280_midi_close(void *);
  240 void    cs4280_midi_getinfo(void *, struct midi_info *);
  241 int     cs4280_midi_open(void *, int, void (*)(void *, int),
  242             void (*)(void *), void *);
  243 int     cs4280_midi_output(void *, int);
  244 #endif
  245 
  246 struct audio_hw_if cs4280_hw_if = {
  247         cs4280_open,
  248         cs4280_close,
  249         NULL,
  250         cs4280_query_encoding,
  251         cs4280_set_params,
  252         cs4280_round_blocksize,
  253         NULL,
  254         NULL,
  255         NULL,
  256         NULL,
  257         NULL,
  258         cs4280_halt_output,
  259         cs4280_halt_input,
  260         NULL,
  261         cs4280_getdev,
  262         NULL,
  263         cs4280_mixer_set_port,
  264         cs4280_mixer_get_port,
  265         cs4280_query_devinfo,
  266         cs4280_malloc,
  267         cs4280_free,
  268         cs4280_round_buffersize,
  269         0, /* cs4280_mappage, */
  270         cs4280_get_props,
  271         cs4280_trigger_output,
  272         cs4280_trigger_input,
  273 };
  274 
  275 #if NMIDI > 0
  276 struct midi_hw_if cs4280_midi_hw_if = {
  277         cs4280_midi_open,
  278         cs4280_midi_close,
  279         cs4280_midi_output,
  280         0,                      /* flush */
  281         cs4280_midi_getinfo,
  282         0,                      /* ioctl */
  283 };
  284 #endif
  285 
  286         
  287 
  288 struct audio_device cs4280_device = {
  289         "CS4280",
  290         "",
  291         "cs4280"
  292 };
  293 
  294 const struct pci_matchid cs4280_devices[] = {
  295         { PCI_VENDOR_CIRRUS, PCI_PRODUCT_CIRRUS_CS4280 },
  296         { PCI_VENDOR_CIRRUS, PCI_PRODUCT_CIRRUS_CS4610 },
  297         { PCI_VENDOR_CIRRUS, PCI_PRODUCT_CIRRUS_CS4615 },
  298 };
  299 
  300 int
  301 cs4280_match(parent, ma, aux) 
  302         struct device *parent;
  303         void *ma;
  304         void *aux;
  305 {
  306         return (pci_matchbyid((struct pci_attach_args *)aux, cs4280_devices,
  307             sizeof(cs4280_devices)/sizeof(cs4280_devices[0])));
  308 }
  309 
  310 int
  311 cs4280_read_codec(sc_, add, data)
  312         void *sc_;
  313         u_int8_t add;
  314         u_int16_t *data;
  315 {
  316         struct cs4280_softc *sc = sc_;
  317         int n;
  318         
  319         DPRINTFN(5,("read_codec: add=0x%02x ", add));
  320         /* 
  321          * Make sure that there is not data sitting around from a preivous
  322          * uncompleted access.
  323          */
  324         BA0READ4(sc, CS4280_ACSDA);
  325 
  326         /* Set up AC97 control registers. */
  327         BA0WRITE4(sc, CS4280_ACCAD, add);
  328         BA0WRITE4(sc, CS4280_ACCDA, 0);
  329         BA0WRITE4(sc, CS4280_ACCTL, 
  330             ACCTL_RSTN | ACCTL_ESYN | ACCTL_VFRM | ACCTL_CRW  | ACCTL_DCV );
  331 
  332         if (cs4280_src_wait(sc) < 0) {
  333                 printf("%s: AC97 read prob. (DCV!=0) for add=0x%02x\n",
  334                        sc->sc_dev.dv_xname, add);
  335                 return (1);
  336         }
  337 
  338         /* wait for valid status bit is active */
  339         n = 0;
  340         while (!(BA0READ4(sc, CS4280_ACSTS) & ACSTS_VSTS)) {
  341                 delay(1);
  342                 while (++n > 1000) {
  343                         printf("%s: AC97 read fail (VSTS==0) for add=0x%02x\n", 
  344                                sc->sc_dev.dv_xname, add);
  345                         return (1);
  346                 }
  347         }
  348         *data = BA0READ4(sc, CS4280_ACSDA);
  349         DPRINTFN(5,("data=0x%04x\n", *data));
  350         return (0);
  351 }
  352 
  353 int
  354 cs4280_write_codec(sc_, add, data)
  355         void *sc_;
  356         u_int8_t add;
  357         u_int16_t data;
  358 {
  359         struct cs4280_softc *sc = sc_;
  360 
  361         DPRINTFN(5,("write_codec: add=0x%02x  data=0x%04x\n", add, data));
  362         BA0WRITE4(sc, CS4280_ACCAD, add);
  363         BA0WRITE4(sc, CS4280_ACCDA, data);
  364         BA0WRITE4(sc, CS4280_ACCTL, 
  365             ACCTL_RSTN | ACCTL_ESYN | ACCTL_VFRM | ACCTL_DCV );
  366 
  367         if (cs4280_src_wait(sc) < 0) {
  368                 printf("%s: AC97 write fail (DCV!=0) for add=0x%02x data="
  369                        "0x%04x\n", sc->sc_dev.dv_xname, add, data);
  370                 return (1);
  371         }
  372         return (0);
  373 }
  374 
  375 int
  376 cs4280_src_wait(sc)
  377         struct cs4280_softc *sc;
  378 {
  379         int n;
  380 
  381         n = 0;
  382         while ((BA0READ4(sc, CS4280_ACCTL) & ACCTL_DCV)) {
  383                 delay(1000);
  384                 if (++n > 1000)
  385                         return (-1);
  386         }
  387         return (0);
  388 }
  389 
  390 
  391 void
  392 cs4280_set_adc_rate(sc, rate)
  393         struct cs4280_softc *sc;
  394         int rate;
  395 {
  396         /* calculate capture rate:
  397          *
  398          * capture_coefficient_increment = -round(rate*128*65536/48000;
  399          * capture_phase_increment       = floor(48000*65536*1024/rate);
  400          * cx = round(48000*65536*1024 - capture_phase_increment*rate);
  401          * cy = floor(cx/200);
  402          * capture_sample_rate_correction = cx - 200*cy;
  403          * capture_delay = ceil(24*48000/rate);
  404          * capture_num_triplets = floor(65536*rate/24000);
  405          * capture_group_length = 24000/GCD(rate, 24000);
  406          * where GCD means "Greatest Common Divisor".
  407          *
  408          * capture_coefficient_increment, capture_phase_increment and
  409          * capture_num_triplets are 32-bit signed quantities.
  410          * capture_sample_rate_correction and capture_group_length are
  411          * 16-bit signed quantities.
  412          * capture_delay is a 14-bit unsigned quantity.
  413          */
  414         u_int32_t cci,cpi,cnt,cx,cy,  tmp1;
  415         u_int16_t csrc, cgl, cdlay;
  416         
  417         /* XXX
  418          * Even though, embedded_audio_spec says capture rate range 11025 to
  419          * 48000, dhwiface.cpp says,
  420          *
  421          * "We can only decimate by up to a factor of 1/9th the hardware rate.
  422          *  Return an error if an attempt is made to stray outside that limit."
  423          *
  424          * so assume range as 48000/9 to 48000
  425          */ 
  426 
  427         if (rate < 8000)
  428                 rate = 8000;
  429         if (rate > 48000)
  430                 rate = 48000;
  431 
  432         cx = rate << 16;
  433         cci = cx / 48000;
  434         cx -= cci * 48000;
  435         cx <<= 7;
  436         cci <<= 7;
  437         cci += cx / 48000;
  438         cci = - cci;
  439 
  440         cx = 48000 << 16;
  441         cpi = cx / rate;
  442         cx -= cpi * rate;
  443         cx <<= 10;
  444         cpi <<= 10;
  445         cy = cx / rate;
  446         cpi += cy;
  447         cx -= cy * rate;
  448 
  449         cy   = cx / 200;
  450         csrc = cx - 200*cy;
  451 
  452         cdlay = ((48000 * 24) + rate - 1) / rate;
  453 #if 0
  454         cdlay &= 0x3fff; /* make sure cdlay is 14-bit */
  455 #endif
  456 
  457         cnt  = rate << 16;
  458         cnt  /= 24000;
  459 
  460         cgl = 1;
  461         for (tmp1 = 2; tmp1 <= 64; tmp1 *= 2) {
  462                 if (((rate / tmp1) * tmp1) != rate)
  463                         cgl *= 2;
  464         }
  465         if (((rate / 3) * 3) != rate)
  466                 cgl *= 3;
  467         for (tmp1 = 5; tmp1 <= 125; tmp1 *= 5) {
  468                 if (((rate / tmp1) * tmp1) != rate) 
  469                         cgl *= 5;
  470         }
  471 #if 0
  472         /* XXX what manual says */
  473         tmp1 = BA1READ4(sc, CS4280_CSRC) & ~CSRC_MASK;
  474         tmp1 |= csrc<<16;
  475         BA1WRITE4(sc, CS4280_CSRC, tmp1);
  476 #else
  477         /* suggested by cs461x.c (ALSA driver) */
  478         BA1WRITE4(sc, CS4280_CSRC, CS4280_MK_CSRC(csrc, cy));
  479 #endif
  480 
  481 #if 0
  482         /* I am confused.  The sample rate calculation section says
  483          * cci *is* 32-bit signed quantity but in the parameter description
  484          * section, CCI only assigned 16bit.
  485          * I believe size of the variable.
  486          */
  487         tmp1 = BA1READ4(sc, CS4280_CCI) & ~CCI_MASK;
  488         tmp1 |= cci<<16;
  489         BA1WRITE4(sc, CS4280_CCI, tmp1);
  490 #else
  491         BA1WRITE4(sc, CS4280_CCI, cci);
  492 #endif
  493 
  494         tmp1 = BA1READ4(sc, CS4280_CD) & ~CD_MASK;
  495         tmp1 |= cdlay <<18;
  496         BA1WRITE4(sc, CS4280_CD, tmp1);
  497         
  498         BA1WRITE4(sc, CS4280_CPI, cpi);
  499         
  500         tmp1 = BA1READ4(sc, CS4280_CGL) & ~CGL_MASK;
  501         tmp1 |= cgl;
  502         BA1WRITE4(sc, CS4280_CGL, tmp1);
  503 
  504         BA1WRITE4(sc, CS4280_CNT, cnt);
  505         
  506         tmp1 = BA1READ4(sc, CS4280_CGC) & ~CGC_MASK;
  507         tmp1 |= cgl;
  508         BA1WRITE4(sc, CS4280_CGC, tmp1);
  509 }
  510 
  511 void
  512 cs4280_set_dac_rate(sc, rate)
  513         struct cs4280_softc *sc;
  514         int rate;
  515 {
  516         /*
  517          * playback rate may range from 8000Hz to 48000Hz
  518          *
  519          * play_phase_increment = floor(rate*65536*1024/48000)
  520          * px = round(rate*65536*1024 - play_phase_incremnt*48000)
  521          * py=floor(px/200)
  522          * play_sample_rate_correction = px - 200*py
  523          *
  524          * play_phase_increment is a 32bit signed quantity.
  525          * play_sample_rate_correction is a 16bit signed quantity.
  526          */
  527         int32_t ppi;
  528         int16_t psrc;
  529         u_int32_t px, py;
  530         
  531         if (rate < 8000)
  532                 rate = 8000;
  533         if (rate > 48000)
  534                 rate = 48000;
  535         px = rate << 16;
  536         ppi = px/48000;
  537         px -= ppi*48000;
  538         ppi <<= 10;
  539         px  <<= 10;
  540         py  = px / 48000;
  541         ppi += py;
  542         px -= py*48000;
  543         py  = px/200;
  544         px -= py*200;
  545         psrc = px;
  546 #if 0
  547         /* what manual says */
  548         px = BA1READ4(sc, CS4280_PSRC) & ~PSRC_MASK;
  549         BA1WRITE4(sc, CS4280_PSRC,
  550                           ( ((psrc<<16) & PSRC_MASK) | px ));
  551 #else   
  552         /* suggested by cs461x.c (ALSA driver) */
  553         BA1WRITE4(sc, CS4280_PSRC, CS4280_MK_PSRC(psrc,py));
  554 #endif
  555         BA1WRITE4(sc, CS4280_PPI, ppi);
  556 }
  557 
  558 void
  559 cs4280_attachhook(void *xsc)
  560 {
  561         struct cs4280_softc *sc = xsc;
  562         mixer_ctrl_t ctl;
  563 
  564         /* Initialization */
  565         if (cs4280_init2(sc, 1) != 0)
  566                 return;
  567 
  568         printf("%s: firmware loaded\n", sc->sc_dev.dv_xname);
  569 
  570         /* Turn mute off of DAC, CD and master volumes by default */
  571         ctl.type = AUDIO_MIXER_ENUM;
  572         ctl.un.ord = 0;  /* off */
  573 
  574         ctl.dev = cs4280_get_portnum_by_name(sc, AudioCoutputs,
  575                                              AudioNmaster, AudioNmute);
  576         cs4280_mixer_set_port(sc, &ctl);
  577 
  578         ctl.dev = cs4280_get_portnum_by_name(sc, AudioCinputs,
  579                                              AudioNdac, AudioNmute);
  580         cs4280_mixer_set_port(sc, &ctl);
  581 
  582         ctl.dev = cs4280_get_portnum_by_name(sc, AudioCinputs,
  583                                              AudioNcd, AudioNmute);
  584         cs4280_mixer_set_port(sc, &ctl);
  585         
  586         audio_attach_mi(&cs4280_hw_if, sc, &sc->sc_dev);
  587 
  588 #if NMIDI > 0
  589         midi_attach_mi(&cs4280_midi_hw_if, sc, &sc->sc_dev);
  590 #endif
  591         sc->sc_suspend = PWR_RESUME;
  592         sc->sc_powerhook = powerhook_establish(cs4280_power, sc);
  593 }
  594 
  595 void
  596 cs4280_attach(parent, self, aux)
  597         struct device *parent;
  598         struct device *self;
  599         void *aux;
  600 {
  601         struct cs4280_softc *sc = (struct cs4280_softc *) self;
  602         struct pci_attach_args *pa = (struct pci_attach_args *) aux;
  603         pci_chipset_tag_t pc = pa->pa_pc;
  604         char const *intrstr;
  605         pci_intr_handle_t ih;
  606         u_int32_t mem;
  607     
  608         /* Map I/O register */
  609         if (pci_mapreg_map(pa, CSCC_PCI_BA0, 
  610             PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0,
  611             &sc->ba0t, &sc->ba0h, NULL, NULL, 0)) {
  612                 printf(": can't map BA0 space\n");
  613                 return;
  614         }
  615         if (pci_mapreg_map(pa, CSCC_PCI_BA1,
  616             PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0,
  617             &sc->ba1t, &sc->ba1h, NULL, NULL, 0)) {
  618                 printf(": can't map BA1 space\n");
  619                 return;
  620         }
  621 
  622         sc->sc_dmatag = pa->pa_dmat;
  623 
  624         /* LATENCY_TIMER setting */
  625         mem = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG);
  626         if ( PCI_LATTIMER(mem) < 32 ) {
  627                 mem &= 0xffff00ff;
  628                 mem |= 0x00002000;
  629                 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG, mem);
  630         }
  631         
  632         /* Map and establish the interrupt. */
  633         if (pci_intr_map(pa, &ih)) {
  634                 printf(": couldn't map interrupt\n");
  635                 return;
  636         }
  637         intrstr = pci_intr_string(pc, ih);
  638 
  639         sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO, cs4280_intr, sc,
  640                                        sc->sc_dev.dv_xname);
  641         if (sc->sc_ih == NULL) {
  642                 printf(": couldn't establish interrupt");
  643                 if (intrstr != NULL)
  644                         printf(" at %s", intrstr);
  645                 printf("\n");
  646                 return;
  647         }
  648         printf(": %s\n", intrstr);
  649 
  650         /* Initialization */
  651         if (cs4280_init(sc, 1) != 0)
  652                 return;
  653 
  654         mountroothook_establish(cs4280_attachhook, sc);
  655 
  656         /* AC 97 attachement */
  657         sc->host_if.arg = sc;
  658         sc->host_if.attach = cs4280_attach_codec;
  659         sc->host_if.read   = cs4280_read_codec;
  660         sc->host_if.write  = cs4280_write_codec;
  661         sc->host_if.reset  = cs4280_reset_codec;
  662 
  663         if (ac97_attach(&sc->host_if) != 0) {
  664                 printf("%s: ac97_attach failed\n", sc->sc_dev.dv_xname);
  665                 return;
  666         }
  667 }
  668 
  669 int
  670 cs4280_intr(p)
  671         void *p;
  672 {
  673         /*
  674          * XXX
  675          *
  676          * Since CS4280 has only 4kB dma buffer and
  677          * interrupt occurs every 2kB block, I create dummy buffer
  678          * which returns to audio driver and actual dma buffer
  679          * using in DMA transfer.
  680          *
  681          *
  682          *  ring buffer in audio.c is pointed by BUFADDR
  683          *       <------ ring buffer size == 64kB ------>
  684          *       <-----> blksize == 2048*(sc->sc_[pr]count) kB 
  685          *      |= = = =|= = = =|= = = =|= = = =|= = = =|
  686          *      |       |       |       |       |       | <- call audio_intp every
  687          *                                                   sc->sc_[pr]_count time.
  688          *
  689          *  actual dma buffer is pointed by KERNADDR
  690          *       <-> dma buffer size = 4kB
  691          *      |= =|
  692          *
  693          *
  694          */
  695         struct cs4280_softc *sc = p;
  696         u_int32_t intr, mem;
  697         char * empty_dma;
  698         int handled = 0;
  699 
  700         /* grab interrupt register then clear it */
  701         intr = BA0READ4(sc, CS4280_HISR);
  702         BA0WRITE4(sc, CS4280_HICR, HICR_CHGM | HICR_IEV);
  703 
  704         /* Playback Interrupt */
  705         if (intr & HISR_PINT) {
  706                 handled = 1;
  707                 mem = BA1READ4(sc, CS4280_PFIE);
  708                 BA1WRITE4(sc, CS4280_PFIE, (mem & ~PFIE_PI_MASK) | PFIE_PI_DISABLE);
  709                 if (sc->sc_pintr) {
  710                         if ((sc->sc_pi%sc->sc_pcount) == 0)
  711                                 sc->sc_pintr(sc->sc_parg);
  712                 } else {
  713                         printf("unexpected play intr\n");
  714                 }
  715                 /* copy buffer */
  716                 ++sc->sc_pi;
  717                 empty_dma = sc->sc_pdma->addr;
  718                 if (sc->sc_pi&1)
  719                         empty_dma += CS4280_ICHUNK;
  720                 memcpy(empty_dma, sc->sc_pn, CS4280_ICHUNK);
  721                 sc->sc_pn += CS4280_ICHUNK;
  722                 if (sc->sc_pn >= sc->sc_pe)
  723                         sc->sc_pn = sc->sc_ps;
  724                 BA1WRITE4(sc, CS4280_PFIE, mem);
  725         }
  726         /* Capture Interrupt */
  727         if (intr & HISR_CINT) {
  728                 int  i;
  729                 int16_t rdata;
  730 
  731                 handled = 1;
  732                 mem = BA1READ4(sc, CS4280_CIE);
  733                 BA1WRITE4(sc, CS4280_CIE, (mem & ~CIE_CI_MASK) | CIE_CI_DISABLE);
  734                 ++sc->sc_ri;
  735                 empty_dma = sc->sc_rdma->addr;
  736                 if ((sc->sc_ri&1) == 0)
  737                         empty_dma += CS4280_ICHUNK;
  738 
  739                 /*
  740                  * XXX
  741                  * I think this audio data conversion should be
  742                  * happend in upper layer, but I put this here
  743                  * since there is no conversion function available.
  744                  */
  745                 switch(sc->sc_rparam) {
  746                 case CF_16BIT_STEREO:
  747                         /* just copy it */
  748                         memcpy(sc->sc_rn, empty_dma, CS4280_ICHUNK);
  749                         sc->sc_rn += CS4280_ICHUNK;
  750                         break;
  751                 case CF_16BIT_MONO:
  752                         for (i = 0; i < 512; i++) {
  753                                 rdata  = *((int16_t *)empty_dma)++>>1;
  754                                 rdata += *((int16_t *)empty_dma)++>>1;
  755                                 *((int16_t *)sc->sc_rn)++ = rdata;
  756                         }
  757                         break;
  758                 case CF_8BIT_STEREO:
  759                         for (i = 0; i < 512; i++) {
  760                                 rdata = *((int16_t*)empty_dma)++;
  761                                 *sc->sc_rn++ = rdata >> 8;
  762                                 rdata = *((int16_t*)empty_dma)++;
  763                                 *sc->sc_rn++ = rdata >> 8;
  764                         }
  765                         break;
  766                 case CF_8BIT_MONO:
  767                         for (i = 0; i < 512; i++) {
  768                                 rdata =  *((int16_t*)empty_dma)++ >>1;
  769                                 rdata += *((int16_t*)empty_dma)++ >>1;
  770                                 *sc->sc_rn++ = rdata >>8;
  771                         }
  772                         break;
  773                 default:
  774                         /* Should not reach here */
  775                         printf("unknown sc->sc_rparam: %d\n", sc->sc_rparam);
  776                 }
  777                 if (sc->sc_rn >= sc->sc_re)
  778                         sc->sc_rn = sc->sc_rs;
  779                 BA1WRITE4(sc, CS4280_CIE, mem);
  780                 if (sc->sc_rintr) {
  781                         if ((sc->sc_ri%(sc->sc_rcount)) == 0)
  782                                 sc->sc_rintr(sc->sc_rarg);
  783                 } else {
  784                         printf("unexpected record intr\n");
  785                 }
  786         }
  787 
  788 #if NMIDI > 0
  789         /* Midi port Interrupt */
  790         if (intr & HISR_MIDI) {
  791                 int data;
  792 
  793                 handled = 1;
  794                 DPRINTF(("i: %d: ", 
  795                          BA0READ4(sc, CS4280_MIDSR)));
  796                 /* Read the received data */
  797                 while ((sc->sc_iintr != NULL) &&
  798                        ((BA0READ4(sc, CS4280_MIDSR) & MIDSR_RBE) == 0)) {
  799                         data = BA0READ4(sc, CS4280_MIDRP) & MIDRP_MASK;
  800                         DPRINTF(("r:%x\n",data));
  801                         sc->sc_iintr(sc->sc_arg, data);
  802                 }
  803                 
  804                 /* Write the data */
  805 #if 1
  806                 /* XXX:
  807                  * It seems "Transmit Buffer Full" never activate until EOI
  808                  * is delivered.  Shall I throw EOI top of this routine ?
  809                  */
  810                 if ((BA0READ4(sc, CS4280_MIDSR) & MIDSR_TBF) == 0) {
  811                         DPRINTF(("w: "));
  812                         if (sc->sc_ointr != NULL)
  813                                 sc->sc_ointr(sc->sc_arg);
  814                 }
  815 #else
  816                 while ((sc->sc_ointr != NULL) && 
  817                        ((BA0READ4(sc, CS4280_MIDSR) & MIDSR_TBF) == 0)) {
  818                         DPRINTF(("w: "));
  819                         sc->sc_ointr(sc->sc_arg);
  820                 }
  821 #endif
  822                 DPRINTF(("\n"));
  823         }
  824 #endif
  825 
  826         return handled;
  827 }
  828 
  829 
  830 /* Download Proceessor Code and Data image */
  831 
  832 int
  833 cs4280_download(sc, src, offset, len)
  834         struct cs4280_softc *sc;
  835         const u_int32_t *src;
  836         u_int32_t offset, len;
  837 {
  838         u_int32_t ctr;
  839 
  840 #ifdef CS4280_DEBUG
  841         u_int32_t con, data;
  842         u_int8_t c0,c1,c2,c3;
  843 #endif
  844         if ((offset&3) || (len&3))
  845                 return (-1);
  846 
  847         len /= sizeof(u_int32_t);
  848         for (ctr = 0; ctr < len; ctr++) {
  849                 /* XXX:
  850                  * I cannot confirm this is the right thing or not
  851                  * on BIG-ENDIAN machines.
  852                  */
  853                 BA1WRITE4(sc, offset+ctr*4, htole32(*(src+ctr)));
  854 #ifdef CS4280_DEBUG
  855                 data = htole32(*(src+ctr));
  856                 c0 = bus_space_read_1(sc->ba1t, sc->ba1h, offset+ctr*4+0);
  857                 c1 = bus_space_read_1(sc->ba1t, sc->ba1h, offset+ctr*4+1);
  858                 c2 = bus_space_read_1(sc->ba1t, sc->ba1h, offset+ctr*4+2);
  859                 c3 = bus_space_read_1(sc->ba1t, sc->ba1h, offset+ctr*4+3);
  860                 con = ( (c3<<24) | (c2<<16) | (c1<<8) | c0 );
  861                 if (data != con ) {
  862                         printf("0x%06x: write=0x%08x read=0x%08x\n",
  863                                offset+ctr*4, data, con);
  864                         return (-1);
  865                 }
  866 #endif
  867         }
  868         return (0);
  869 }
  870 
  871 struct BA1struct *BA1Struct;
  872 
  873 int
  874 cs4280_download_image(sc)
  875         struct cs4280_softc *sc;
  876 {
  877         int idx, err = 0;
  878         u_int32_t offset = 0;
  879         static u_char *cs4280_firmware;
  880         static size_t cs4280_firmwarelen;
  881 
  882         if (cs4280_firmware == NULL) {
  883                 err = loadfirmware("cs4280", &cs4280_firmware,
  884                     &cs4280_firmwarelen);
  885                 if (err)
  886                         return (err);
  887         }
  888 
  889         BA1Struct = (struct BA1struct *)cs4280_firmware;
  890 
  891         for (idx = 0; idx < BA1_MEMORY_COUNT; ++idx) {
  892                 err = cs4280_download(sc, &BA1Struct->map[offset],
  893                     BA1Struct->memory[idx].offset, BA1Struct->memory[idx].size);
  894                 if (err != 0) {
  895                         printf("%s: load_image failed at %d\n",
  896                                sc->sc_dev.dv_xname, idx);
  897                         return (-1);
  898                 }
  899                 offset += BA1Struct->memory[idx].size / sizeof(u_int32_t);
  900         }
  901         return (err);
  902 }
  903 
  904 #ifdef CS4280_DEBUG
  905 int
  906 cs4280_checkimage(sc, src, offset, len)
  907         struct cs4280_softc *sc;
  908         u_int32_t *src;
  909         u_int32_t offset, len;
  910 {
  911         u_int32_t ctr, data;
  912         int err = 0;
  913 
  914         if ((offset&3) || (len&3))
  915                 return -1;
  916 
  917         len /= sizeof(u_int32_t);
  918         for (ctr = 0; ctr < len; ctr++) {
  919                 /* I cannot confirm this is the right thing
  920                  * on BIG-ENDIAN machines
  921                  */
  922                 data = BA1READ4(sc, offset+ctr*4);
  923                 if (data != htole32(*(src+ctr))) {
  924                         printf("0x%06x: 0x%08x(0x%08x)\n",
  925                                offset+ctr*4, data, *(src+ctr));
  926                         *(src+ctr) = data;
  927                         ++err;
  928                 }
  929         }
  930         return (err);
  931 }
  932 
  933 int
  934 cs4280_check_images(sc)
  935         struct cs4280_softc *sc;
  936 {
  937         int idx, err;
  938         u_int32_t offset = 0;
  939 
  940         err = 0;
  941         /*for (idx=0; idx < BA1_MEMORY_COUNT; ++idx) { */
  942         for (idx = 0; idx < 1; ++idx) {
  943                 err = cs4280_checkimage(sc, &BA1Struct->map[offset],
  944                     BA1Struct->memory[idx].offset,
  945                     BA1Struct->memory[idx].size);
  946                 if (err != 0) {
  947                         printf("%s: check_image failed at %d\n",
  948                                sc->sc_dev.dv_xname, idx);
  949                 }
  950                 offset += BA1Struct->memory[idx].size / sizeof(u_int32_t);
  951         }
  952         return (err);
  953 }
  954 
  955 #endif
  956 
  957 int
  958 cs4280_attach_codec(sc_, codec_if)
  959         void *sc_;
  960         struct ac97_codec_if *codec_if;
  961 {
  962         struct cs4280_softc *sc = sc_;
  963 
  964         sc->codec_if = codec_if;
  965         return (0);
  966 }
  967 
  968 void
  969 cs4280_reset_codec(sc_)
  970         void *sc_;
  971 {
  972         struct cs4280_softc *sc = sc_;
  973         int n;
  974 
  975         /* Reset codec */
  976         BA0WRITE4(sc, CS4280_ACCTL, 0);
  977         delay(100);    /* delay 100us */
  978         BA0WRITE4(sc, CS4280_ACCTL, ACCTL_RSTN);
  979 
  980         /* 
  981          * It looks like we do the following procedure, too
  982          */
  983 
  984         /* Enable AC-link sync generation */
  985         BA0WRITE4(sc, CS4280_ACCTL, ACCTL_ESYN | ACCTL_RSTN);
  986         delay(50*1000); /* XXX delay 50ms */
  987         
  988         /* Assert valid frame signal */
  989         BA0WRITE4(sc, CS4280_ACCTL, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN);
  990 
  991         /* Wait for valid AC97 input slot */
  992         n = 0;
  993         while (BA0READ4(sc, CS4280_ACISV) != (ACISV_ISV3 | ACISV_ISV4)) {
  994                 delay(1000);
  995                 if (++n > 1000) {
  996                         printf("reset_codec: AC97 inputs slot ready timeout\n");
  997                         return;
  998                 }
  999         }
 1000 }
 1001 
 1002 
 1003 /* Processor Soft Reset */
 1004 void
 1005 cs4280_reset(sc_)
 1006         void *sc_;
 1007 {
 1008         struct cs4280_softc *sc = sc_;
 1009 
 1010         /* Set RSTSP bit in SPCR (also clear RUN, RUNFR, and DRQEN) */
 1011         BA1WRITE4(sc, CS4280_SPCR, SPCR_RSTSP);
 1012         delay(100);
 1013         /* Clear RSTSP bit in SPCR */
 1014         BA1WRITE4(sc, CS4280_SPCR, 0);
 1015         /* enable DMA reqest */
 1016         BA1WRITE4(sc, CS4280_SPCR, SPCR_DRQEN);
 1017 }
 1018 
 1019 int
 1020 cs4280_open(addr, flags)
 1021         void *addr;
 1022         int flags;
 1023 {
 1024         return (0);
 1025 }
 1026 
 1027 void
 1028 cs4280_close(addr)
 1029         void *addr;
 1030 {
 1031         struct cs4280_softc *sc = addr;
 1032         
 1033         cs4280_halt_output(sc);
 1034         cs4280_halt_input(sc);
 1035         
 1036         sc->sc_pintr = 0;
 1037         sc->sc_rintr = 0;
 1038 }
 1039 
 1040 int
 1041 cs4280_query_encoding(addr, fp)
 1042         void *addr;
 1043         struct audio_encoding *fp;
 1044 {
 1045         switch (fp->index) {
 1046         case 0:
 1047                 strlcpy(fp->name, AudioEulinear, sizeof fp->name);
 1048                 fp->encoding = AUDIO_ENCODING_ULINEAR;
 1049                 fp->precision = 8;
 1050                 fp->flags = 0;
 1051                 break;
 1052         case 1:
 1053                 strlcpy(fp->name, AudioEmulaw, sizeof fp->name);
 1054                 fp->encoding = AUDIO_ENCODING_ULAW;
 1055                 fp->precision = 8;
 1056                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
 1057                 break;
 1058         case 2:
 1059                 strlcpy(fp->name, AudioEalaw, sizeof fp->name);
 1060                 fp->encoding = AUDIO_ENCODING_ALAW;
 1061                 fp->precision = 8;
 1062                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
 1063                 break;
 1064         case 3:
 1065                 strlcpy(fp->name, AudioEslinear, sizeof fp->name);
 1066                 fp->encoding = AUDIO_ENCODING_SLINEAR;
 1067                 fp->precision = 8;
 1068                 fp->flags = 0;
 1069                 break;
 1070         case 4:
 1071                 strlcpy(fp->name, AudioEslinear_le, sizeof fp->name);
 1072                 fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
 1073                 fp->precision = 16;
 1074                 fp->flags = 0;
 1075                 break;
 1076         case 5:
 1077                 strlcpy(fp->name, AudioEulinear_le, sizeof fp->name);
 1078                 fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
 1079                 fp->precision = 16;
 1080                 fp->flags = 0;
 1081                 break;
 1082         case 6:
 1083                 strlcpy(fp->name, AudioEslinear_be, sizeof fp->name);
 1084                 fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
 1085                 fp->precision = 16;
 1086                 fp->flags = 0;
 1087                 break;
 1088         case 7:
 1089                 strlcpy(fp->name, AudioEulinear_be, sizeof fp->name);
 1090                 fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
 1091                 fp->precision = 16;
 1092                 fp->flags = 0;
 1093                 break;
 1094         default:
 1095                 return (EINVAL);
 1096         }
 1097         return (0);
 1098 }
 1099 
 1100 int
 1101 cs4280_set_params(addr, setmode, usemode, play, rec)
 1102         void *addr;
 1103         int setmode, usemode;
 1104         struct audio_params *play, *rec;
 1105 {
 1106         struct cs4280_softc *sc = addr;
 1107         struct audio_params *p;
 1108         int mode;
 1109 
 1110         for (mode = AUMODE_RECORD; mode != -1;
 1111             mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1 ) {
 1112                 if ((setmode & mode) == 0)
 1113                         continue;
 1114                 
 1115                 p = mode == AUMODE_PLAY ? play : rec;
 1116                 
 1117                 if (p == play) {
 1118                         DPRINTFN(5,("play: sample=%ld precision=%d channels=%d\n",
 1119                                 p->sample_rate, p->precision, p->channels));
 1120                         /* play back data format may be 8- or 16-bit and
 1121                          * either stereo or mono.
 1122                          * playback rate may range from 8000Hz to 48000Hz 
 1123                          */
 1124                         if (p->sample_rate < 8000 || p->sample_rate > 48000 ||
 1125                             (p->precision != 8 && p->precision != 16) ||
 1126                             (p->channels != 1  && p->channels != 2) ) {
 1127                                 return (EINVAL);
 1128                         }
 1129                 } else {
 1130                         DPRINTFN(5,("rec: sample=%ld precision=%d channels=%d\n",
 1131                                 p->sample_rate, p->precision, p->channels));
 1132                         /* capture data format must be 16bit stereo
 1133                          * and sample rate range from 11025Hz to 48000Hz.
 1134                          *
 1135                          * XXX: it looks like to work with 8000Hz,
 1136                          *      although data sheets say lower limit is
 1137                          *      11025 Hz.
 1138                          */
 1139 
 1140                         if (p->sample_rate < 8000 || p->sample_rate > 48000 ||
 1141                             (p->precision != 8 && p->precision != 16) ||
 1142                             (p->channels  != 1 && p->channels  != 2) ) {
 1143                                 return (EINVAL);
 1144                         }
 1145                 }
 1146                 p->factor  = 1;
 1147                 p->sw_code = 0;
 1148 
 1149                 /* capturing data is slinear */
 1150                 switch (p->encoding) {
 1151                 case AUDIO_ENCODING_SLINEAR_BE:
 1152                         if (mode == AUMODE_RECORD) {
 1153                                 if (p->precision == 16)
 1154                                         p->sw_code = swap_bytes;
 1155                         }
 1156                         break;
 1157                 case AUDIO_ENCODING_SLINEAR_LE:
 1158                         break;
 1159                 case AUDIO_ENCODING_ULINEAR_BE:
 1160                         if (mode == AUMODE_RECORD) {
 1161                                 if (p->precision == 16)
 1162                                         p->sw_code = change_sign16_swap_bytes;
 1163                                 else
 1164                                         p->sw_code = change_sign8;
 1165                         }
 1166                         break;
 1167                 case AUDIO_ENCODING_ULINEAR_LE:
 1168                         if (mode == AUMODE_RECORD) {
 1169                                 if (p->precision == 16)
 1170                                         p->sw_code = change_sign16;
 1171                                 else
 1172                                         p->sw_code = change_sign8;
 1173                         }
 1174                         break;
 1175                 case AUDIO_ENCODING_ULAW:
 1176                         if (mode == AUMODE_PLAY) {
 1177                                 p->factor = 2;
 1178                                 p->sw_code = mulaw_to_slinear16;
 1179                         } else {
 1180                                 p->sw_code = slinear8_to_mulaw;
 1181                         }
 1182                         break;
 1183                 case AUDIO_ENCODING_ALAW:
 1184                         if (mode == AUMODE_PLAY) {
 1185                                 p->factor = 2;
 1186                                 p->sw_code = alaw_to_slinear16;
 1187                         } else {
 1188                                 p->sw_code = slinear8_to_alaw;
 1189                         }
 1190                         break;
 1191                 default:
 1192                         return (EINVAL);
 1193                 }
 1194         }
 1195 
 1196         /* set sample rate */
 1197         cs4280_set_dac_rate(sc, play->sample_rate);
 1198         cs4280_set_adc_rate(sc, rec->sample_rate);
 1199         return (0);
 1200 }
 1201 
 1202 int
 1203 cs4280_round_blocksize(hdl, blk)
 1204         void *hdl;
 1205         int blk;
 1206 {
 1207         return (blk < CS4280_ICHUNK ? CS4280_ICHUNK : blk & -CS4280_ICHUNK);
 1208 }
 1209 
 1210 size_t
 1211 cs4280_round_buffersize(addr, direction, size)
 1212         void *addr;
 1213         int direction;
 1214         size_t size;
 1215 {
 1216         /* although real dma buffer size is 4KB, 
 1217          * let the audio.c driver use a larger buffer.
 1218          * ( suggested by Lennart Augustsson. )
 1219          */
 1220         return (size);
 1221 }
 1222 
 1223 int
 1224 cs4280_get_props(hdl)
 1225         void *hdl;
 1226 {
 1227         return (AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX); 
 1228 #ifdef notyet
 1229         /* XXX 
 1230          * How can I mmap ?
 1231          */
 1232                 AUDIO_PROP_MMAP 
 1233 #endif
 1234             
 1235 }
 1236 
 1237 int
 1238 cs4280_mixer_get_port(addr, cp)
 1239         void *addr;
 1240         mixer_ctrl_t *cp;
 1241 {
 1242         struct cs4280_softc *sc = addr;
 1243 
 1244         return (sc->codec_if->vtbl->mixer_get_port(sc->codec_if, cp));
 1245 }
 1246 
 1247 paddr_t
 1248 cs4280_mappage(addr, mem, off, prot)
 1249         void *addr;
 1250         void *mem;
 1251         off_t off;
 1252         int prot;
 1253 {
 1254         struct cs4280_softc *sc = addr;
 1255         struct cs4280_dma *p;
 1256 
 1257         if (off < 0)
 1258                 return (-1);
 1259         for (p = sc->sc_dmas; p && BUFADDR(p) != mem; p = p->next)
 1260                 ;
 1261         if (!p) {
 1262                 DPRINTF(("cs4280_mappage: bad buffer address\n"));
 1263                 return (-1);
 1264         }
 1265         return (bus_dmamem_mmap(sc->sc_dmatag, p->segs, p->nsegs, 
 1266                                 off, prot, BUS_DMA_WAITOK));
 1267 }
 1268 
 1269 
 1270 int
 1271 cs4280_query_devinfo(addr, dip)
 1272         void *addr;
 1273         mixer_devinfo_t *dip;
 1274 {
 1275         struct cs4280_softc *sc = addr;
 1276 
 1277         return (sc->codec_if->vtbl->query_devinfo(sc->codec_if, dip));
 1278 }
 1279 
 1280 int
 1281 cs4280_get_portnum_by_name(sc, class, device, qualifier)
 1282         struct cs4280_softc *sc;
 1283         char *class, *device, *qualifier;
 1284 {
 1285         return (sc->codec_if->vtbl->get_portnum_by_name(sc->codec_if, class,
 1286              device, qualifier));
 1287 }
 1288 
 1289 int
 1290 cs4280_halt_output(addr)
 1291         void *addr;
 1292 {
 1293         struct cs4280_softc *sc = addr;
 1294         u_int32_t mem;
 1295         
 1296         mem = BA1READ4(sc, CS4280_PCTL);
 1297         BA1WRITE4(sc, CS4280_PCTL, mem & ~PCTL_MASK);
 1298 #ifdef DIAGNOSTIC
 1299         sc->sc_prun = 0;
 1300 #endif
 1301         return (0);
 1302 }
 1303 
 1304 int
 1305 cs4280_halt_input(addr)
 1306         void *addr;
 1307 {
 1308         struct cs4280_softc *sc = addr;
 1309         u_int32_t mem;
 1310 
 1311         mem = BA1READ4(sc, CS4280_CCTL);
 1312         BA1WRITE4(sc, CS4280_CCTL, mem & ~CCTL_MASK);
 1313 #ifdef DIAGNOSTIC
 1314         sc->sc_rrun = 0;
 1315 #endif
 1316         return (0);
 1317 }
 1318 
 1319 int
 1320 cs4280_getdev(addr, retp)
 1321         void *addr;
 1322         struct audio_device *retp;
 1323 {
 1324         *retp = cs4280_device;
 1325         return (0);
 1326 }
 1327 
 1328 int
 1329 cs4280_mixer_set_port(addr, cp)
 1330         void *addr;
 1331         mixer_ctrl_t *cp;
 1332 {
 1333         struct cs4280_softc *sc = addr;
 1334         int val;
 1335 
 1336         val = sc->codec_if->vtbl->mixer_set_port(sc->codec_if, cp);
 1337         DPRINTFN(3,("mixer_set_port: val=%d\n", val));
 1338         return (val);
 1339 }
 1340 
 1341 
 1342 int
 1343 cs4280_freemem(sc, p)
 1344         struct cs4280_softc *sc;
 1345         struct cs4280_dma *p;
 1346 {
 1347         bus_dmamap_unload(sc->sc_dmatag, p->map);
 1348         bus_dmamap_destroy(sc->sc_dmatag, p->map);
 1349         bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size);
 1350         bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs);
 1351         return (0);
 1352 }
 1353 
 1354 int
 1355 cs4280_allocmem(sc, size, align, p)
 1356         struct cs4280_softc *sc;
 1357         size_t size;
 1358         size_t align;
 1359         struct cs4280_dma *p;
 1360 {
 1361         int error;
 1362 
 1363         /* XXX */
 1364         p->size = size;
 1365         error = bus_dmamem_alloc(sc->sc_dmatag, p->size, align, 0,
 1366                                  p->segs, sizeof(p->segs)/sizeof(p->segs[0]),
 1367                                  &p->nsegs, BUS_DMA_NOWAIT);
 1368         if (error) {
 1369                 printf("%s: unable to allocate dma, error=%d\n",
 1370                        sc->sc_dev.dv_xname, error);
 1371                 return (error);
 1372         }
 1373         
 1374         error = bus_dmamem_map(sc->sc_dmatag, p->segs, p->nsegs, p->size, 
 1375                                &p->addr, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
 1376         if (error) {
 1377                 printf("%s: unable to map dma, error=%d\n",
 1378                        sc->sc_dev.dv_xname, error);
 1379                 goto free;
 1380         }
 1381 
 1382         error = bus_dmamap_create(sc->sc_dmatag, p->size, 1, p->size,
 1383                                   0, BUS_DMA_NOWAIT, &p->map);
 1384         if (error) {
 1385                 printf("%s: unable to create dma map, error=%d\n",
 1386                        sc->sc_dev.dv_xname, error);
 1387                 goto unmap;
 1388         }
 1389 
 1390         error = bus_dmamap_load(sc->sc_dmatag, p->map, p->addr, p->size, NULL, 
 1391                                 BUS_DMA_NOWAIT);
 1392         if (error) {
 1393                 printf("%s: unable to load dma map, error=%d\n",
 1394                        sc->sc_dev.dv_xname, error);
 1395                 goto destroy;
 1396         }
 1397         return (0);
 1398 
 1399 destroy:
 1400         bus_dmamap_destroy(sc->sc_dmatag, p->map);
 1401 unmap:
 1402         bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size);
 1403 free:
 1404         bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs);
 1405         return (error);
 1406 }
 1407 
 1408 
 1409 void *
 1410 cs4280_malloc(addr, direction, size, pool, flags)
 1411         void *addr;
 1412         int direction;
 1413         size_t size;
 1414         int pool, flags;
 1415 {
 1416         struct cs4280_softc *sc = addr;
 1417         struct cs4280_dma *p;
 1418         caddr_t q;
 1419         int error;
 1420         
 1421         DPRINTFN(5,("cs4280_malloc: size=%d pool=%d flags=%d\n", size, pool, flags));
 1422         q = malloc(size, pool, flags);
 1423         if (!q) 
 1424                 return (0);
 1425         p = malloc(sizeof(*p), pool, flags);
 1426         if (!p) {
 1427                 free(q,pool);
 1428                 return (0);
 1429         }
 1430         /* 
 1431          * cs4280 has fixed 4kB buffer
 1432          */
 1433         error = cs4280_allocmem(sc, CS4280_DCHUNK, CS4280_DALIGN, p);
 1434 
 1435         if (error) {
 1436                 free(q, pool);
 1437                 free(p, pool);
 1438                 return (0);
 1439         }
 1440 
 1441         p->next = sc->sc_dmas;
 1442         sc->sc_dmas = p;
 1443         p->dum = q; /* return to audio driver */
 1444 
 1445         return (p->dum);
 1446 }
 1447 
 1448 void
 1449 cs4280_free(addr, ptr, pool)
 1450         void *addr;
 1451         void *ptr;
 1452         int pool;
 1453 {
 1454         struct cs4280_softc *sc = addr;
 1455         struct cs4280_dma **pp, *p;
 1456         
 1457         for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &p->next) {
 1458                 if (BUFADDR(p) == ptr) {
 1459                         cs4280_freemem(sc, p);
 1460                         *pp = p->next;
 1461                         free(p->dum, pool);
 1462                         free(p, pool);
 1463                         return;
 1464                 }
 1465         }
 1466 }
 1467 
 1468 int
 1469 cs4280_trigger_output(addr, start, end, blksize, intr, arg, param)
 1470         void *addr;
 1471         void *start, *end;
 1472         int blksize;
 1473         void (*intr)(void *);
 1474         void *arg;
 1475         struct audio_params *param;
 1476 {
 1477         struct cs4280_softc *sc = addr;
 1478         u_int32_t pfie, pctl, mem, pdtc;
 1479         struct cs4280_dma *p;
 1480         
 1481 #ifdef DIAGNOSTIC
 1482         if (sc->sc_prun)
 1483                 printf("cs4280_trigger_output: already running\n");
 1484         sc->sc_prun = 1;
 1485 #endif
 1486 
 1487         DPRINTF(("cs4280_trigger_output: sc=%p start=%p end=%p "
 1488             "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));
 1489         sc->sc_pintr = intr;
 1490         sc->sc_parg  = arg;
 1491 
 1492         /* stop playback DMA */
 1493         mem = BA1READ4(sc, CS4280_PCTL);
 1494         BA1WRITE4(sc, CS4280_PCTL, mem & ~PCTL_MASK);
 1495 
 1496         /* setup PDTC */
 1497         pdtc = BA1READ4(sc, CS4280_PDTC);
 1498         pdtc &= ~PDTC_MASK;
 1499         pdtc |= CS4280_MK_PDTC(param->precision * param->channels);
 1500         BA1WRITE4(sc, CS4280_PDTC, pdtc);
 1501         
 1502         DPRINTF(("param: precision=%d  factor=%d channels=%d encoding=%d\n",
 1503                param->precision, param->factor, param->channels,
 1504                param->encoding));
 1505         for (p = sc->sc_dmas; p != NULL && BUFADDR(p) != start; p = p->next)
 1506                 ;
 1507         if (p == NULL) {
 1508                 printf("cs4280_trigger_output: bad addr %p\n", start);
 1509                 return (EINVAL);
 1510         }
 1511         if (DMAADDR(p) % CS4280_DALIGN != 0 ) {
 1512                 printf("cs4280_trigger_output: DMAADDR(p)=0x%lx does not start"
 1513                        "4kB align\n", DMAADDR(p));
 1514                 return (EINVAL);
 1515         }
 1516 
 1517         sc->sc_pcount = blksize / CS4280_ICHUNK; /* CS4280_ICHUNK is fixed hardware blksize*/
 1518         sc->sc_ps = (char *)start;
 1519         sc->sc_pe = (char *)end;
 1520         sc->sc_pdma = p;
 1521         sc->sc_pbuf = KERNADDR(p);
 1522         sc->sc_pi = 0;
 1523         sc->sc_pn = sc->sc_ps;
 1524         if (blksize >= CS4280_DCHUNK) {
 1525                 sc->sc_pn = sc->sc_ps + CS4280_DCHUNK;
 1526                 memcpy(sc->sc_pbuf, start, CS4280_DCHUNK);
 1527                 ++sc->sc_pi;
 1528         } else {
 1529                 sc->sc_pn = sc->sc_ps + CS4280_ICHUNK;
 1530                 memcpy(sc->sc_pbuf, start, CS4280_ICHUNK);
 1531         }
 1532 
 1533         /* initiate playback dma */
 1534         BA1WRITE4(sc, CS4280_PBA, DMAADDR(p));
 1535 
 1536         /* set PFIE */
 1537         pfie = BA1READ4(sc, CS4280_PFIE) & ~PFIE_MASK;
 1538 
 1539         if (param->precision * param->factor == 8)
 1540                 pfie |= PFIE_8BIT;
 1541         if (param->channels == 1)
 1542                 pfie |= PFIE_MONO;
 1543 
 1544         if (param->encoding == AUDIO_ENCODING_ULINEAR_BE ||
 1545             param->encoding == AUDIO_ENCODING_SLINEAR_BE)
 1546                 pfie |= PFIE_SWAPPED;
 1547         if (param->encoding == AUDIO_ENCODING_ULINEAR_BE ||
 1548             param->encoding == AUDIO_ENCODING_ULINEAR_LE)
 1549                 pfie |= PFIE_UNSIGNED;
 1550 
 1551         BA1WRITE4(sc, CS4280_PFIE, pfie | PFIE_PI_ENABLE);
 1552 
 1553         cs4280_set_dac_rate(sc, param->sample_rate);
 1554 
 1555         pctl = BA1READ4(sc, CS4280_PCTL) & ~PCTL_MASK;
 1556         pctl |= sc->pctl;
 1557         BA1WRITE4(sc, CS4280_PCTL, pctl);
 1558         return (0);
 1559 }
 1560 
 1561 int
 1562 cs4280_trigger_input(addr, start, end, blksize, intr, arg, param)
 1563         void *addr;
 1564         void *start, *end;
 1565         int blksize;
 1566         void (*intr)(void *);
 1567         void *arg;
 1568         struct audio_params *param;
 1569 {
 1570         struct cs4280_softc *sc = addr;
 1571         u_int32_t cctl, cie;
 1572         struct cs4280_dma *p;
 1573         
 1574 #ifdef DIAGNOSTIC
 1575         if (sc->sc_rrun)
 1576                 printf("cs4280_trigger_input: already running\n");
 1577         sc->sc_rrun = 1;
 1578 #endif
 1579         DPRINTF(("cs4280_trigger_input: sc=%p start=%p end=%p "
 1580             "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));
 1581         sc->sc_rintr = intr;
 1582         sc->sc_rarg  = arg;
 1583 
 1584         sc->sc_ri = 0;
 1585         sc->sc_rcount = blksize / CS4280_ICHUNK; /* CS4280_ICHUNK is fixed hardware blksize*/
 1586         sc->sc_rs = (char *)start;
 1587         sc->sc_re = (char *)end;
 1588         sc->sc_rn = sc->sc_rs;
 1589 
 1590         /* setup format information for internal converter */
 1591         sc->sc_rparam = 0;
 1592         if (param->precision == 8) {
 1593                 sc->sc_rparam += CF_8BIT;
 1594                 sc->sc_rcount <<= 1;
 1595         }
 1596         if (param->channels  == 1) {
 1597                 sc->sc_rparam += CF_MONO;
 1598                 sc->sc_rcount <<= 1;
 1599         }
 1600 
 1601         /* stop capture DMA */
 1602         cctl = BA1READ4(sc, CS4280_CCTL) & ~CCTL_MASK;
 1603         BA1WRITE4(sc, CS4280_CCTL, cctl);
 1604         
 1605         for (p = sc->sc_dmas; p && BUFADDR(p) != start; p = p->next)
 1606                 ;
 1607         if (!p) {
 1608                 printf("cs4280_trigger_input: bad addr %p\n", start);
 1609                 return (EINVAL);
 1610         }
 1611         if (DMAADDR(p) % CS4280_DALIGN != 0) {
 1612                 printf("cs4280_trigger_input: DMAADDR(p)=0x%lx does not start"
 1613                        "4kB align\n", DMAADDR(p));
 1614                 return (EINVAL);
 1615         }
 1616         sc->sc_rdma = p;
 1617         sc->sc_rbuf = KERNADDR(p);
 1618         
 1619         /* initiate capture dma */
 1620         BA1WRITE4(sc, CS4280_CBA, DMAADDR(p));
 1621 
 1622         /* set CIE */
 1623         cie = BA1READ4(sc, CS4280_CIE) & ~CIE_CI_MASK;
 1624         BA1WRITE4(sc, CS4280_CIE, cie | CIE_CI_ENABLE);
 1625 
 1626         cs4280_set_adc_rate(sc, param->sample_rate);
 1627 
 1628         cctl = BA1READ4(sc, CS4280_CCTL) & ~CCTL_MASK;
 1629         cctl |= sc->cctl;
 1630         BA1WRITE4(sc, CS4280_CCTL, cctl);
 1631         return (0);
 1632 }
 1633 
 1634 
 1635 int
 1636 cs4280_init(sc, init)
 1637         struct cs4280_softc *sc;
 1638         int init;
 1639 {
 1640         int n;
 1641         u_int32_t mem;
 1642 
 1643         /* Start PLL out in known state */
 1644         BA0WRITE4(sc, CS4280_CLKCR1, 0);
 1645         /* Start serial ports out in known state */
 1646         BA0WRITE4(sc, CS4280_SERMC1, 0);
 1647 
 1648         /* Specify type of CODEC */
 1649 /* XXX should no be here */
 1650 #define SERACC_CODEC_TYPE_1_03
 1651 #ifdef  SERACC_CODEC_TYPE_1_03
 1652         BA0WRITE4(sc, CS4280_SERACC, SERACC_HSP | SERACC_CTYPE_1_03); /* AC 97 1.03 */
 1653 #else
 1654         BA0WRITE4(sc, CS4280_SERACC, SERACC_HSP | SERACC_CTYPE_2_0);  /* AC 97 2.0 */
 1655 #endif
 1656 
 1657         /* Reset codec */
 1658         BA0WRITE4(sc, CS4280_ACCTL, 0);
 1659         delay(100);    /* delay 100us */
 1660         BA0WRITE4(sc, CS4280_ACCTL, ACCTL_RSTN);
 1661         
 1662         /* Enable AC-link sync generation */
 1663         BA0WRITE4(sc, CS4280_ACCTL, ACCTL_ESYN | ACCTL_RSTN);
 1664         delay(50*1000); /* delay 50ms */
 1665 
 1666         /* Set the serial port timing configuration */
 1667         BA0WRITE4(sc, CS4280_SERMC1, SERMC1_PTC_AC97);
 1668         
 1669         /* Setup clock control */
 1670         BA0WRITE4(sc, CS4280_PLLCC, PLLCC_CDR_STATE|PLLCC_LPF_STATE);
 1671         BA0WRITE4(sc, CS4280_PLLM, PLLM_STATE);
 1672         BA0WRITE4(sc, CS4280_CLKCR2, CLKCR2_PDIVS_8);
 1673         
 1674         /* Power up the PLL */
 1675         BA0WRITE4(sc, CS4280_CLKCR1, CLKCR1_PLLP);
 1676         delay(50*1000); /* delay 50ms */
 1677         
 1678         /* Turn on clock */
 1679         mem = BA0READ4(sc, CS4280_CLKCR1) | CLKCR1_SWCE;
 1680         BA0WRITE4(sc, CS4280_CLKCR1, mem);
 1681         
 1682         /* Set the serial port FIFO pointer to the
 1683          * first sample in FIFO. (not documented) */
 1684         cs4280_clear_fifos(sc);
 1685 
 1686 #if 0
 1687         /* Set the serial port FIFO pointer to the first sample in the FIFO */
 1688         BA0WRITE4(sc, CS4280_SERBSP, 0);
 1689 #endif
 1690         
 1691         /* Configure the serial port */
 1692         BA0WRITE4(sc, CS4280_SERC1,  SERC1_SO1EN | SERC1_SO1F_AC97);
 1693         BA0WRITE4(sc, CS4280_SERC2,  SERC2_SI1EN | SERC2_SI1F_AC97);
 1694         BA0WRITE4(sc, CS4280_SERMC1, SERMC1_MSPE | SERMC1_PTC_AC97);
 1695         
 1696         /* Wait for CODEC ready */
 1697         n = 0;
 1698         while ((BA0READ4(sc, CS4280_ACSTS) & ACSTS_CRDY) == 0) {
 1699                 delay(125);
 1700                 if (++n > 1000) {
 1701                         printf("%s: codec ready timeout\n",
 1702                                sc->sc_dev.dv_xname);
 1703                         return(1);
 1704                 }
 1705         }
 1706 
 1707         /* Assert valid frame signal */
 1708         BA0WRITE4(sc, CS4280_ACCTL, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN);
 1709 
 1710         /* Wait for valid AC97 input slot */
 1711         n = 0;
 1712         while ((BA0READ4(sc, CS4280_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) !=
 1713                (ACISV_ISV3 | ACISV_ISV4)) {
 1714                 delay(1000);
 1715                 if (++n > 1000) {
 1716                         printf("AC97 inputs slot ready timeout\n");
 1717                         return(1);
 1718                 }
 1719         }
 1720         
 1721         /* Set AC97 output slot valid signals */
 1722         BA0WRITE4(sc, CS4280_ACOSV, ACOSV_SLV3 | ACOSV_SLV4);
 1723 
 1724         /* reset the processor */
 1725         cs4280_reset(sc);
 1726         return (0);
 1727 }
 1728 
 1729 int
 1730 cs4280_init2(sc, init)
 1731         struct cs4280_softc *sc;
 1732         int init;
 1733 {
 1734         int n;
 1735         u_int32_t mem;
 1736 
 1737         /* Download the image to the processor */
 1738         if (cs4280_download_image(sc) != 0) {
 1739                 printf("%s: image download error\n", sc->sc_dev.dv_xname);
 1740                 return(1);
 1741         }
 1742 
 1743         /* Save playback parameter and then write zero.
 1744          * this ensures that DMA doesn't immediately occur upon
 1745          * starting the processor core 
 1746          */
 1747         mem = BA1READ4(sc, CS4280_PCTL);
 1748         sc->pctl = mem & PCTL_MASK; /* save startup value */
 1749         cs4280_halt_output(sc);
 1750         
 1751         /* Save capture parameter and then write zero.
 1752          * this ensures that DMA doesn't immediately occur upon
 1753          * starting the processor core 
 1754          */
 1755         mem = BA1READ4(sc, CS4280_CCTL);
 1756         sc->cctl = mem & CCTL_MASK; /* save startup value */
 1757         cs4280_halt_input(sc);
 1758 
 1759         /* MSH: need to power up ADC and DAC? */
 1760 
 1761         /* Processor Startup Procedure */
 1762         BA1WRITE4(sc, CS4280_FRMT, FRMT_FTV);
 1763         BA1WRITE4(sc, CS4280_SPCR, SPCR_RUN | SPCR_RUNFR | SPCR_DRQEN);
 1764 
 1765         /* Monitor RUNFR bit in SPCR for 1 to 0 transition */
 1766         n = 0;
 1767         while (BA1READ4(sc, CS4280_SPCR) & SPCR_RUNFR) {
 1768                 delay(10);
 1769                 if (++n > 1000) {
 1770                         printf("SPCR 1->0 transition timeout\n");
 1771                         return(1);
 1772                 }
 1773         }
 1774         
 1775         n = 0;
 1776         while (!(BA1READ4(sc, CS4280_SPCS) & SPCS_SPRUN)) {
 1777                 delay(10);
 1778                 if (++n > 1000) {
 1779                         printf("SPCS 0->1 transition timeout\n");
 1780                         return(1);
 1781                 }
 1782         }
 1783         /* Processor is now running !!! */
 1784 
 1785         /* Setup  volume */
 1786         BA1WRITE4(sc, CS4280_PVOL, 0x80008000);
 1787         BA1WRITE4(sc, CS4280_CVOL, 0x80008000);
 1788 
 1789         /* Interrupt enable */
 1790         BA0WRITE4(sc, CS4280_HICR, HICR_IEV|HICR_CHGM);
 1791 
 1792         /* playback interrupt enable */
 1793         mem = BA1READ4(sc, CS4280_PFIE) & ~PFIE_PI_MASK;
 1794         mem |= PFIE_PI_ENABLE;
 1795         BA1WRITE4(sc, CS4280_PFIE, mem);
 1796         /* capture interrupt enable */
 1797         mem = BA1READ4(sc, CS4280_CIE) & ~CIE_CI_MASK;
 1798         mem |= CIE_CI_ENABLE;
 1799         BA1WRITE4(sc, CS4280_CIE, mem);
 1800 
 1801 #if NMIDI > 0
 1802         /* Reset midi port */
 1803         mem = BA0READ4(sc, CS4280_MIDCR) & ~MIDCR_MASK;
 1804         BA0WRITE4(sc, CS4280_MIDCR, mem | MIDCR_MRST);
 1805         DPRINTF(("midi reset: 0x%x\n", BA0READ4(sc, CS4280_MIDCR)));
 1806         /* midi interrupt enable */
 1807         mem |= MIDCR_TXE | MIDCR_RXE | MIDCR_RIE | MIDCR_TIE;
 1808         BA0WRITE4(sc, CS4280_MIDCR, mem);
 1809 #endif
 1810         return(0);
 1811 }
 1812 
 1813 void
 1814 cs4280_power(why, v)
 1815         int why;
 1816         void *v;
 1817 {
 1818         struct cs4280_softc *sc = (struct cs4280_softc *)v;
 1819         int i;
 1820 
 1821         DPRINTF(("%s: cs4280_power why=%d\n",
 1822                sc->sc_dev.dv_xname, why));
 1823         if (why != PWR_RESUME) {
 1824                 sc->sc_suspend = why;
 1825 
 1826                 cs4280_halt_output(sc);
 1827                 cs4280_halt_input(sc);
 1828                 /* Save AC97 registers */
 1829                 for(i = 1; i <= CS4280_SAVE_REG_MAX; i++) {
 1830                         if(i == 0x04) /* AC97_REG_MASTER_TONE */
 1831                                 continue;
 1832                         cs4280_read_codec(sc, 2*i, &sc->ac97_reg[i]);
 1833                 }
 1834                 /* should I powerdown here ? */
 1835                 cs4280_write_codec(sc, AC97_REG_POWER, CS4280_POWER_DOWN_ALL);
 1836         } else {
 1837                 if (sc->sc_suspend == PWR_RESUME) {
 1838                         printf("cs4280_power: odd, resume without suspend.\n");
 1839                         sc->sc_suspend = why;
 1840                         return;
 1841                 }
 1842                 sc->sc_suspend = why;
 1843                 cs4280_init(sc, 0);
 1844                 cs4280_init2(sc, 0);
 1845                 cs4280_reset_codec(sc);
 1846 
 1847                 /* restore ac97 registers */
 1848                 for(i = 1; i <= CS4280_SAVE_REG_MAX; i++) {
 1849                         if(i == 0x04) /* AC97_REG_MASTER_TONE */
 1850                                 continue;
 1851                         cs4280_write_codec(sc, 2*i, sc->ac97_reg[i]);
 1852                 }
 1853         }
 1854 }
 1855 
 1856 void
 1857 cs4280_clear_fifos(sc)
 1858         struct cs4280_softc *sc;
 1859 {
 1860         int pd = 0, cnt, n;
 1861         u_int32_t mem;
 1862         
 1863         /* 
 1864          * If device power down, power up the device and keep power down
 1865          * state.
 1866          */
 1867         mem = BA0READ4(sc, CS4280_CLKCR1);
 1868         if (!(mem & CLKCR1_SWCE)) {
 1869                 printf("cs4280_clear_fifo: power down found.\n");
 1870                 BA0WRITE4(sc, CS4280_CLKCR1, mem | CLKCR1_SWCE);
 1871                 pd = 1;
 1872         }
 1873         BA0WRITE4(sc, CS4280_SERBWP, 0);
 1874         for (cnt = 0; cnt < 256; cnt++) {
 1875                 n = 0;
 1876                 while (BA0READ4(sc, CS4280_SERBST) & SERBST_WBSY) {
 1877                         delay(1000);
 1878                         if (++n > 1000) {
 1879                                 printf("clear_fifo: fist timeout cnt=%d\n", cnt);
 1880                                 break;
 1881                         }
 1882                 }
 1883                 BA0WRITE4(sc, CS4280_SERBAD, cnt);
 1884                 BA0WRITE4(sc, CS4280_SERBCM, SERBCM_WRC);
 1885         }
 1886         if (pd)
 1887                 BA0WRITE4(sc, CS4280_CLKCR1, mem);
 1888 }
 1889 
 1890 #if NMIDI > 0
 1891 int
 1892 cs4280_midi_open(addr, flags, iintr, ointr, arg)
 1893         void *addr;
 1894         int flags;
 1895         void (*iintr)(void *, int);
 1896         void (*ointr)(void *);
 1897         void *arg;
 1898 {
 1899         struct cs4280_softc *sc = addr;
 1900         u_int32_t mem;
 1901 
 1902         DPRINTF(("midi_open\n"));
 1903         sc->sc_iintr = iintr;
 1904         sc->sc_ointr = ointr;
 1905         sc->sc_arg = arg;
 1906 
 1907         /* midi interrupt enable */
 1908         mem = BA0READ4(sc, CS4280_MIDCR) & ~MIDCR_MASK;
 1909         mem |= MIDCR_TXE | MIDCR_RXE | MIDCR_RIE | MIDCR_TIE | MIDCR_MLB;
 1910         BA0WRITE4(sc, CS4280_MIDCR, mem);
 1911 #ifdef CS4280_DEBUG
 1912         if (mem != BA0READ4(sc, CS4280_MIDCR)) {
 1913                 DPRINTF(("midi_open: MIDCR=%d\n", BA0READ4(sc, CS4280_MIDCR)));
 1914                 return(EINVAL);
 1915         }
 1916         DPRINTF(("MIDCR=0x%x\n", BA0READ4(sc, CS4280_MIDCR)));
 1917 #endif
 1918         return (0);
 1919 }
 1920 
 1921 void
 1922 cs4280_midi_close(addr)
 1923         void *addr;
 1924 {
 1925         struct cs4280_softc *sc = addr;
 1926         u_int32_t mem;
 1927         
 1928         DPRINTF(("midi_close\n"));
 1929         mem = BA0READ4(sc, CS4280_MIDCR);
 1930         mem &= ~MIDCR_MASK;
 1931         BA0WRITE4(sc, CS4280_MIDCR, mem);
 1932 
 1933         sc->sc_iintr = 0;
 1934         sc->sc_ointr = 0;
 1935 }
 1936 
 1937 int
 1938 cs4280_midi_output(addr, d)
 1939         void *addr;
 1940         int d;
 1941 {
 1942         struct cs4280_softc *sc = addr;
 1943         u_int32_t mem;
 1944         int x;
 1945 
 1946         for (x = 0; x != MIDI_BUSY_WAIT; x++) {
 1947                 if ((BA0READ4(sc, CS4280_MIDSR) & MIDSR_TBF) == 0) {
 1948                         mem = BA0READ4(sc, CS4280_MIDWP) & ~MIDWP_MASK;
 1949                         mem |= d & MIDWP_MASK;
 1950                         DPRINTFN(5,("midi_output d=0x%08x",d));
 1951                         BA0WRITE4(sc, CS4280_MIDWP, mem);
 1952                         if (mem != BA0READ4(sc, CS4280_MIDWP)) {
 1953                                 DPRINTF(("Bad write data: %d %d",
 1954                                          mem, BA0READ4(sc, CS4280_MIDWP)));
 1955                                 return(EIO);
 1956                         }
 1957                         return (0);
 1958                 }
 1959                 delay(MIDI_BUSY_DELAY);
 1960         }
 1961         return (EIO);
 1962 }
 1963 
 1964 void
 1965 cs4280_midi_getinfo(addr, mi)
 1966         void *addr;
 1967         struct midi_info *mi;
 1968 {
 1969         mi->name = "CS4280 MIDI UART";
 1970         mi->props = MIDI_PROP_CAN_INPUT | MIDI_PROP_OUT_INTR;
 1971 }
 1972 
 1973 #endif

/* [<][>][^][v][top][bottom][index][help] */