root/dev/pci/yds.c

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

DEFINITIONS

This source file includes following definitions.
  1. YREAD2
  2. YREAD4
  3. YWRITE1
  4. YWRITE2
  5. YWRITE4
  6. yds_dump_play_slot
  7. yds_get_dstype
  8. nswaph
  9. yds_download_mcode
  10. yds_allocate_slots
  11. yds_enable_dsp
  12. yds_disable_dsp
  13. yds_match
  14. yds_configure_legacy
  15. yds_attach
  16. yds_attachhook
  17. yds_attach_codec
  18. yds_ready_codec
  19. yds_read_codec
  20. yds_write_codec
  21. yds_reset_codec
  22. yds_intr
  23. yds_allocmem
  24. yds_freemem
  25. yds_open
  26. yds_close
  27. yds_query_encoding
  28. yds_set_params
  29. yds_round_blocksize
  30. yds_get_lpfq
  31. yds_get_lpfk
  32. yds_trigger_output
  33. yds_trigger_input
  34. yds_halt
  35. yds_halt_output
  36. yds_halt_input
  37. yds_getdev
  38. yds_mixer_set_port
  39. yds_mixer_get_port
  40. yds_query_devinfo
  41. yds_get_portnum_by_name
  42. yds_malloc
  43. yds_free
  44. yds_find_dma
  45. yds_round_buffersize
  46. yds_mappage
  47. yds_get_props
  48. yds_powerhook
  49. yds_init

    1 /*      $OpenBSD: yds.c,v 1.28 2007/01/06 02:48:40 deraadt Exp $        */
    2 /*      $NetBSD: yds.c,v 1.5 2001/05/21 23:55:04 minoura Exp $  */
    3 
    4 /*
    5  * Copyright (c) 2000, 2001 Kazuki Sakamoto and Minoura Makoto.
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   27  */
   28 
   29 /* 
   30  * Yamaha YMF724[B-F]/740[B-C]/744/754
   31  *
   32  * Documentation links:
   33  * - ftp://ftp.alsa-project.org/pub/manuals/yamaha/
   34  * - ftp://ftp.alsa-project.org/pub/manuals/yamaha/pci/
   35  *
   36  * TODO:
   37  * - FM synth volume (difficult: mixed before ac97)
   38  * - Digital in/out (SPDIF) support
   39  * - Effect??
   40  */
   41 
   42 #include <sys/param.h>
   43 #include <sys/systm.h>
   44 #include <sys/kernel.h>
   45 #include <sys/fcntl.h>
   46 #include <sys/malloc.h>
   47 #include <sys/device.h>
   48 #include <sys/proc.h>
   49 #include <sys/queue.h>
   50 #include <sys/fcntl.h>
   51 
   52 #include <dev/pci/pcidevs.h>
   53 #include <dev/pci/pcireg.h>
   54 #include <dev/pci/pcivar.h>
   55 
   56 #include <sys/audioio.h>
   57 #include <dev/audio_if.h>
   58 #include <dev/midi_if.h>
   59 #include <dev/mulaw.h>
   60 #include <dev/auconv.h>
   61 #include <dev/ic/ac97.h>
   62 #include <dev/ic/mpuvar.h>
   63 
   64 #include <machine/bus.h>
   65 #include <machine/intr.h>
   66 
   67 #include <dev/pci/ydsreg.h>
   68 #include <dev/pci/ydsvar.h>
   69 
   70 /* Debug */
   71 #undef YDS_USE_REC_SLOT
   72 #define YDS_USE_P44
   73 
   74 #ifdef AUDIO_DEBUG
   75 # define DPRINTF(x)     if (ydsdebug) printf x
   76 # define DPRINTFN(n,x)  if (ydsdebug>(n)) printf x
   77 int     ydsdebug = 0;
   78 #else
   79 # define DPRINTF(x)
   80 # define DPRINTFN(n,x)
   81 #endif
   82 #ifdef YDS_USE_REC_SLOT
   83 # define YDS_INPUT_SLOT 0       /* REC slot = ADC + loopbacks */
   84 #else
   85 # define YDS_INPUT_SLOT 1       /* ADC slot */
   86 #endif
   87 
   88 static  int ac97_id2;
   89 
   90 int     yds_match(struct device *, void *, void *);
   91 void    yds_attach(struct device *, struct device *, void *);
   92 int     yds_intr(void *);
   93 
   94 static void nswaph(u_int32_t *p, int wcount);
   95 
   96 #define DMAADDR(p) ((p)->map->dm_segs[0].ds_addr)
   97 #define KERNADDR(p) ((void *)((p)->addr))
   98 
   99 int     yds_allocmem(struct yds_softc *, size_t, size_t,
  100             struct yds_dma *);
  101 int     yds_freemem(struct yds_softc *, struct yds_dma *);
  102 
  103 #ifndef AUDIO_DEBUG
  104 #define YWRITE1(sc, r, x) bus_space_write_1((sc)->memt, (sc)->memh, (r), (x))
  105 #define YWRITE2(sc, r, x) bus_space_write_2((sc)->memt, (sc)->memh, (r), (x))
  106 #define YWRITE4(sc, r, x) bus_space_write_4((sc)->memt, (sc)->memh, (r), (x))
  107 #define YREAD1(sc, r) bus_space_read_1((sc)->memt, (sc)->memh, (r))
  108 #define YREAD2(sc, r) bus_space_read_2((sc)->memt, (sc)->memh, (r))
  109 #define YREAD4(sc, r) bus_space_read_4((sc)->memt, (sc)->memh, (r))
  110 #else
  111 
  112 u_int16_t YREAD2(struct yds_softc *sc,bus_size_t r);
  113 u_int32_t YREAD4(struct yds_softc *sc,bus_size_t r);
  114 void YWRITE1(struct yds_softc *sc,bus_size_t r,u_int8_t x);
  115 void YWRITE2(struct yds_softc *sc,bus_size_t r,u_int16_t x);
  116 void YWRITE4(struct yds_softc *sc,bus_size_t r,u_int32_t x);
  117 
  118 u_int16_t YREAD2(struct yds_softc *sc,bus_size_t r)
  119 {
  120   DPRINTFN(5, (" YREAD2(0x%lX)\n",(unsigned long)r));
  121   return bus_space_read_2(sc->memt,sc->memh,r);
  122 }
  123 u_int32_t YREAD4(struct yds_softc *sc,bus_size_t r)
  124 {
  125   DPRINTFN(5, (" YREAD4(0x%lX)\n",(unsigned long)r));
  126   return bus_space_read_4(sc->memt,sc->memh,r);
  127 }
  128 void YWRITE1(struct yds_softc *sc,bus_size_t r,u_int8_t x)
  129 {
  130   DPRINTFN(5, (" YWRITE1(0x%lX,0x%lX)\n",(unsigned long)r,(unsigned long)x));
  131   bus_space_write_1(sc->memt,sc->memh,r,x);
  132 }
  133 void YWRITE2(struct yds_softc *sc,bus_size_t r,u_int16_t x)
  134 {
  135   DPRINTFN(5, (" YWRITE2(0x%lX,0x%lX)\n",(unsigned long)r,(unsigned long)x));
  136   bus_space_write_2(sc->memt,sc->memh,r,x);
  137 }
  138 void YWRITE4(struct yds_softc *sc,bus_size_t r,u_int32_t x)
  139 {
  140   DPRINTFN(5, (" YWRITE4(0x%lX,0x%lX)\n",(unsigned long)r,(unsigned long)x));
  141   bus_space_write_4(sc->memt,sc->memh,r,x);
  142 }
  143 #endif
  144 
  145 #define YWRITEREGION4(sc, r, x, c)      \
  146         bus_space_write_region_4((sc)->memt, (sc)->memh, (r), (x), (c) / 4)
  147 
  148 struct cfattach yds_ca = {
  149         sizeof(struct yds_softc), yds_match, yds_attach
  150 };
  151 
  152 struct cfdriver yds_cd = {
  153         NULL, "yds", DV_DULL
  154 };
  155 
  156 int     yds_open(void *, int);
  157 void    yds_close(void *);
  158 int     yds_query_encoding(void *, struct audio_encoding *);
  159 int     yds_set_params(void *, int, int,
  160             struct audio_params *, struct audio_params *);
  161 int     yds_round_blocksize(void *, int);
  162 int     yds_trigger_output(void *, void *, void *, int, void (*)(void *),
  163             void *, struct audio_params *);
  164 int     yds_trigger_input(void *, void *, void *, int, void (*)(void *),
  165             void *, struct audio_params *);
  166 int     yds_halt_output(void *);
  167 int     yds_halt_input(void *);
  168 int     yds_getdev(void *, struct audio_device *);
  169 int     yds_mixer_set_port(void *, mixer_ctrl_t *);
  170 int     yds_mixer_get_port(void *, mixer_ctrl_t *);
  171 void   *yds_malloc(void *, int, size_t, int, int);
  172 void    yds_free(void *, void *, int);
  173 size_t  yds_round_buffersize(void *, int, size_t);
  174 paddr_t yds_mappage(void *, void *, off_t, int);
  175 int     yds_get_props(void *);
  176 int     yds_query_devinfo(void *addr, mixer_devinfo_t *dip);
  177 
  178 int     yds_attach_codec(void *sc, struct ac97_codec_if *);
  179 int     yds_read_codec(void *sc, u_int8_t a, u_int16_t *d);
  180 int     yds_write_codec(void *sc, u_int8_t a, u_int16_t d);
  181 void    yds_reset_codec(void *sc);
  182 int     yds_get_portnum_by_name(struct yds_softc *, char *, char *,
  183             char *);
  184 
  185 static u_int yds_get_dstype(int);
  186 static int yds_download_mcode(struct yds_softc *);
  187 static int yds_allocate_slots(struct yds_softc *);
  188 static void yds_configure_legacy(struct yds_softc *arg);
  189 static void yds_enable_dsp(struct yds_softc *);
  190 static int yds_disable_dsp(struct yds_softc *);
  191 static int yds_ready_codec(struct yds_codec_softc *);
  192 static int yds_halt(struct yds_softc *);
  193 static u_int32_t yds_get_lpfq(u_int);
  194 static u_int32_t yds_get_lpfk(u_int);
  195 static struct yds_dma *yds_find_dma(struct yds_softc *, void *);
  196 
  197 void yds_powerhook(int, void *);
  198 int     yds_init(void *sc);
  199 void    yds_attachhook(void *);
  200 
  201 #ifdef AUDIO_DEBUG
  202 static void yds_dump_play_slot(struct yds_softc *, int);
  203 #define YDS_DUMP_PLAY_SLOT(n,sc,bank) \
  204         if (ydsdebug > (n)) yds_dump_play_slot(sc, bank)
  205 #else
  206 #define YDS_DUMP_PLAY_SLOT(n,sc,bank)
  207 #endif /* AUDIO_DEBUG */
  208 
  209 static struct audio_hw_if yds_hw_if = {
  210         yds_open,
  211         yds_close,
  212         NULL,
  213         yds_query_encoding,
  214         yds_set_params,
  215         yds_round_blocksize,
  216         NULL,
  217         NULL,
  218         NULL,
  219         NULL,
  220         NULL,
  221         yds_halt_output,
  222         yds_halt_input,
  223         NULL,
  224         yds_getdev,
  225         NULL,
  226         yds_mixer_set_port,
  227         yds_mixer_get_port,
  228         yds_query_devinfo,
  229         yds_malloc,
  230         yds_free,
  231         yds_round_buffersize,
  232         yds_mappage,
  233         yds_get_props,
  234         yds_trigger_output,
  235         yds_trigger_input
  236 };
  237 
  238 struct audio_device yds_device = {
  239         "Yamaha DS-1",
  240         "",
  241         "yds"
  242 };
  243 
  244 const static struct {
  245         u_int   id;
  246         u_int   flags;
  247 #define YDS_CAP_MCODE_1                 0x0001
  248 #define YDS_CAP_MCODE_1E                0x0002
  249 #define YDS_CAP_LEGACY_SELECTABLE       0x0004
  250 #define YDS_CAP_LEGACY_FLEXIBLE         0x0008
  251 #define YDS_CAP_HAS_P44                 0x0010
  252 #define YDS_CAP_LEGACY_SMOD_DISABLE     0x1000
  253 } yds_chip_capability_list[] = {
  254         { PCI_PRODUCT_YAMAHA_YMF724,
  255           YDS_CAP_MCODE_1|YDS_CAP_LEGACY_SELECTABLE },
  256         /* 740[C] has only 32 slots.  But anyway we use only 2 */
  257         { PCI_PRODUCT_YAMAHA_YMF740,
  258           YDS_CAP_MCODE_1|YDS_CAP_LEGACY_SELECTABLE },  /* XXX NOT TESTED */
  259         { PCI_PRODUCT_YAMAHA_YMF740C,
  260           YDS_CAP_MCODE_1E|YDS_CAP_LEGACY_SELECTABLE },
  261         { PCI_PRODUCT_YAMAHA_YMF724F,
  262           YDS_CAP_MCODE_1E|YDS_CAP_LEGACY_SELECTABLE },
  263         { PCI_PRODUCT_YAMAHA_YMF744, 
  264           YDS_CAP_MCODE_1E|YDS_CAP_LEGACY_FLEXIBLE },
  265         { PCI_PRODUCT_YAMAHA_YMF754,
  266           YDS_CAP_MCODE_1E|YDS_CAP_LEGACY_FLEXIBLE|YDS_CAP_HAS_P44 },
  267         /* How about 734/737/738?? */
  268         { 0, 0 }
  269 };
  270 #ifdef AUDIO_DEBUG
  271 #define YDS_CAP_BITS    "\020\005P44\004LEGFLEX\003LEGSEL\002MCODE1E\001MCODE1"
  272 #endif
  273 
  274 #ifdef AUDIO_DEBUG
  275 static void
  276 yds_dump_play_slot(sc, bank)
  277         struct yds_softc *sc;
  278         int bank;
  279 {
  280         int i, j;
  281         u_int32_t *p;
  282         u_int32_t num;
  283         struct yds_dma *dma;
  284 
  285         for (i = 0; i < N_PLAY_SLOTS; i++) {
  286                 printf("pbankp[%d] = %p,", i*2, sc->pbankp[i*2]);
  287                 printf("pbankp[%d] = %p\n", i*2+1, sc->pbankp[i*2+1]);
  288         }
  289 
  290         p = (u_int32_t*)sc->ptbl;
  291         for (i = 0; i < N_PLAY_SLOTS+1; i++) {
  292                 printf("ptbl + %d:0x%x\n", i, *p);
  293                 p++;
  294         }
  295 
  296         num = *(u_int32_t*)sc->ptbl;
  297         printf("num = %d\n", num);
  298 
  299         for (i = 0; i < num; i++) {
  300 
  301                 p = (u_int32_t *)sc->pbankp[i];
  302 
  303                 dma = yds_find_dma(sc,(void *)p);
  304 
  305                 for (j = 0; j < sizeof(struct play_slot_ctrl_bank) /
  306                     sizeof(u_int32_t); j++) {
  307                         printf("    0x%02x: 0x%08x\n",
  308                                (unsigned) (j * sizeof(u_int32_t)),
  309                                (unsigned) *p++);
  310                 }
  311                 /*
  312                 p = (u_int32_t *)sc->pbankp[i*2 + 1];
  313                 printf("  pbankp[%d] : %p\n", i*2 + 1, p);
  314                 for (j = 0; j < sizeof(struct play_slot_ctrl_bank) /
  315                     sizeof(u_int32_t); j++) {
  316                         printf("    0x%02x: 0x%08x\n",
  317                                 j * sizeof(u_int32_t), *p++);
  318                                 delay(1);
  319                 }       
  320                 */
  321         }
  322 }
  323 #endif /* AUDIO_DEBUG */
  324 
  325 static u_int
  326 yds_get_dstype(id)
  327         int id;
  328 {
  329         int i;
  330 
  331         for (i = 0; yds_chip_capability_list[i].id; i++) {
  332                 if (PCI_PRODUCT(id) == yds_chip_capability_list[i].id)
  333                         return yds_chip_capability_list[i].flags;
  334         }
  335 
  336         return -1;
  337 }
  338 
  339 static void
  340 nswaph(u_int32_t *p, int wcount)
  341 {
  342         for (; wcount; wcount -=4) {
  343                 *p = ntohl(*p);
  344                 p++;
  345         }
  346 }
  347 
  348 static int
  349 yds_download_mcode(sc)
  350         struct yds_softc *sc;
  351 {
  352         u_int ctrl;
  353         const u_int32_t *p;
  354         size_t size;
  355         u_char *buf;
  356         size_t buflen;
  357         int error;
  358         struct yds_firmware *yf;
  359 
  360         error = loadfirmware("yds", &buf, &buflen);
  361         if (error)
  362                 return 1;
  363         yf = (struct yds_firmware *)buf;
  364 
  365         if (sc->sc_flags & YDS_CAP_MCODE_1) {
  366                 p = (u_int32_t *)&yf->data[ntohl(yf->dsplen)];
  367                 size = ntohl(yf->ds1len);
  368         } else if (sc->sc_flags & YDS_CAP_MCODE_1E) {
  369                 p = (u_int32_t *)&yf->data[ntohl(yf->dsplen) + ntohl(yf->ds1len)];
  370                 size = ntohl(yf->ds1elen);
  371         } else {
  372                 free(buf, M_DEVBUF);
  373                 return 1;       /* unknown */
  374         }
  375 
  376         if (size > buflen) {
  377                 printf("%s: old firmware file, update please\n",
  378                     sc->sc_dev.dv_xname);
  379                 free(buf, M_DEVBUF);
  380                 return 1;
  381         }
  382 
  383         if (yds_disable_dsp(sc)) {
  384                 free(buf, M_DEVBUF);
  385                 return 1;
  386         }
  387 
  388         /* Software reset */
  389         YWRITE4(sc, YDS_MODE, YDS_MODE_RESET);
  390         YWRITE4(sc, YDS_MODE, 0);
  391 
  392         YWRITE4(sc, YDS_MAPOF_REC, 0);
  393         YWRITE4(sc, YDS_MAPOF_EFFECT, 0);
  394         YWRITE4(sc, YDS_PLAY_CTRLBASE, 0);
  395         YWRITE4(sc, YDS_REC_CTRLBASE, 0);
  396         YWRITE4(sc, YDS_EFFECT_CTRLBASE, 0);
  397         YWRITE4(sc, YDS_WORK_BASE, 0);
  398 
  399         ctrl = YREAD2(sc, YDS_GLOBAL_CONTROL);
  400         YWRITE2(sc, YDS_GLOBAL_CONTROL, ctrl & ~0x0007);
  401 
  402         /* Download DSP microcode. */
  403         nswaph((u_int32_t *)&yf->data[0], ntohl(yf->dsplen));
  404         YWRITEREGION4(sc, YDS_DSP_INSTRAM, (u_int32_t *)&yf->data[0],
  405             ntohl(yf->dsplen));
  406 
  407         /* Download CONTROL microcode. */
  408         nswaph((u_int32_t *)p, size);
  409         YWRITEREGION4(sc, YDS_CTRL_INSTRAM, p, size);
  410 
  411         yds_enable_dsp(sc);
  412         delay(10*1000);         /* neccesary on my 724F (??) */
  413 
  414         free(buf, M_DEVBUF);
  415         return 0;
  416 }
  417 
  418 static int
  419 yds_allocate_slots(sc)
  420         struct yds_softc *sc;
  421 {
  422         size_t pcs, rcs, ecs, ws, memsize;
  423         void *mp;
  424         u_int32_t da;           /* DMA address */
  425         char *va;               /* KVA */
  426         off_t cb;
  427         int i;
  428         struct yds_dma *p;
  429 
  430         /* Alloc DSP Control Data */
  431         pcs = YREAD4(sc, YDS_PLAY_CTRLSIZE) * sizeof(u_int32_t);
  432         rcs = YREAD4(sc, YDS_REC_CTRLSIZE) * sizeof(u_int32_t);
  433         ecs = YREAD4(sc, YDS_EFFECT_CTRLSIZE) * sizeof(u_int32_t);
  434         ws = WORK_SIZE;
  435         YWRITE4(sc, YDS_WORK_SIZE, ws / sizeof(u_int32_t));
  436 
  437         DPRINTF(("play control size : %d\n", (unsigned int)pcs));
  438         DPRINTF(("rec control size : %d\n", (unsigned int)rcs));
  439         DPRINTF(("eff control size : %d\n", (unsigned int)ecs));
  440         DPRINTF(("work size : %d\n", (unsigned int)ws));
  441 #ifdef DIAGNOSTIC
  442         if (pcs != sizeof(struct play_slot_ctrl_bank)) {
  443                 printf("%s: invalid play slot ctrldata %d != %d\n",
  444                        sc->sc_dev.dv_xname, (unsigned int)pcs,
  445                        (unsigned int)sizeof(struct play_slot_ctrl_bank));
  446         }
  447         if (rcs != sizeof(struct rec_slot_ctrl_bank)) {
  448                 printf("%s: invalid rec slot ctrldata %d != %d\n",
  449                        sc->sc_dev.dv_xname, (unsigned int)rcs,
  450                        (unsigned int)sizeof(struct rec_slot_ctrl_bank));
  451         }
  452 #endif
  453 
  454         memsize = N_PLAY_SLOTS*N_PLAY_SLOT_CTRL_BANK*pcs +
  455                   N_REC_SLOT_CTRL*N_REC_SLOT_CTRL_BANK*rcs + ws;
  456         memsize += (N_PLAY_SLOTS+1)*sizeof(u_int32_t);
  457 
  458         p = &sc->sc_ctrldata;
  459         i = yds_allocmem(sc, memsize, 16, p);
  460         if (i) {
  461                 printf("%s: couldn't alloc/map DSP DMA buffer, reason %d\n",
  462                        sc->sc_dev.dv_xname, i);
  463                 free(p, M_DEVBUF);
  464                 return 1;
  465         }
  466         mp = KERNADDR(p);
  467         da = DMAADDR(p);
  468 
  469         DPRINTF(("mp:%p, DMA addr:%p\n",
  470                  mp, (void *) sc->sc_ctrldata.map->dm_segs[0].ds_addr));
  471 
  472         bzero(mp, memsize);
  473 
  474         /* Work space */
  475         cb = 0;
  476         va = (u_int8_t*)mp;
  477         YWRITE4(sc, YDS_WORK_BASE, da + cb);
  478         cb += ws;
  479 
  480         /* Play control data table */
  481         sc->ptbl = (u_int32_t *)(va + cb);
  482         sc->ptbloff = cb;
  483         YWRITE4(sc, YDS_PLAY_CTRLBASE, da + cb);
  484         cb += (N_PLAY_SLOT_CTRL + 1) * sizeof(u_int32_t);
  485 
  486         /* Record slot control data */
  487         sc->rbank = (struct rec_slot_ctrl_bank *)(va + cb);
  488         YWRITE4(sc, YDS_REC_CTRLBASE, da + cb);
  489         sc->rbankoff = cb;
  490         cb += N_REC_SLOT_CTRL * N_REC_SLOT_CTRL_BANK * rcs;
  491 
  492 #if 0
  493         /* Effect slot control data -- unused */
  494         YWRITE4(sc, YDS_EFFECT_CTRLBASE, da + cb);
  495         cb += N_EFFECT_SLOT_CTRL * N_EFFECT_SLOT_CTRL_BANK * ecs;
  496 #endif
  497 
  498         /* Play slot control data */
  499         sc->pbankoff = da + cb;
  500         for (i=0; i<N_PLAY_SLOT_CTRL; i++) {
  501                 sc->pbankp[i*2] = (struct play_slot_ctrl_bank *)(va + cb);
  502                 *(sc->ptbl + i+1) = da + cb;
  503                 cb += pcs;
  504 
  505                 sc->pbankp[i*2+1] = (struct play_slot_ctrl_bank *)(va + cb);
  506                 cb += pcs;
  507         }
  508         /* Sync play control data table */
  509         bus_dmamap_sync(sc->sc_dmatag, p->map,
  510                         sc->ptbloff, (N_PLAY_SLOT_CTRL+1) * sizeof(u_int32_t),
  511                         BUS_DMASYNC_PREWRITE);
  512 
  513         return 0;
  514 }
  515 
  516 static void
  517 yds_enable_dsp(sc)
  518         struct yds_softc *sc;
  519 {
  520         YWRITE4(sc, YDS_CONFIG, YDS_DSP_SETUP);
  521 }
  522 
  523 static int
  524 yds_disable_dsp(sc)
  525         struct yds_softc *sc;
  526 {
  527         int to;
  528         u_int32_t data;
  529 
  530         data = YREAD4(sc, YDS_CONFIG);
  531         if (data)
  532                 YWRITE4(sc, YDS_CONFIG, YDS_DSP_DISABLE);
  533 
  534         for (to = 0; to < YDS_WORK_TIMEOUT; to++) {
  535                 if ((YREAD4(sc, YDS_STATUS) & YDS_STAT_WORK) == 0)
  536                         return 0;
  537                 delay(1);
  538         }
  539 
  540         return 1;
  541 }
  542 
  543 int
  544 yds_match(parent, match, aux)
  545         struct device *parent;
  546         void *match;
  547         void *aux;
  548 {
  549         struct pci_attach_args *pa = (struct pci_attach_args *) aux;
  550 
  551         switch (PCI_VENDOR(pa->pa_id)) {
  552         case PCI_VENDOR_YAMAHA:
  553                 switch (PCI_PRODUCT(pa->pa_id)) {
  554                 case PCI_PRODUCT_YAMAHA_YMF724:
  555                 case PCI_PRODUCT_YAMAHA_YMF740:
  556                 case PCI_PRODUCT_YAMAHA_YMF740C:
  557                 case PCI_PRODUCT_YAMAHA_YMF724F:
  558                 case PCI_PRODUCT_YAMAHA_YMF744:
  559                 case PCI_PRODUCT_YAMAHA_YMF754:
  560                 /* 734, 737, 738?? */
  561                         return (1);
  562                 }
  563                 break;
  564         }
  565 
  566         return (0);
  567 }
  568 
  569 /*
  570  * This routine is called after all the ISA devices are configured,
  571  * to avoid conflict.
  572  */
  573 static void
  574 yds_configure_legacy (sc)
  575         struct yds_softc *sc;
  576 #define FLEXIBLE        (sc->sc_flags & YDS_CAP_LEGACY_FLEXIBLE)
  577 #define SELECTABLE      (sc->sc_flags & YDS_CAP_LEGACY_SELECTABLE)
  578 {
  579         pcireg_t reg;
  580         struct device *dev;
  581         int i;
  582         bus_addr_t opl_addrs[] = {0x388, 0x398, 0x3A0, 0x3A8};
  583         bus_addr_t mpu_addrs[] = {0x330, 0x300, 0x332, 0x334};
  584 
  585         if (!FLEXIBLE && !SELECTABLE)
  586                 return;
  587 
  588         reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, YDS_PCI_LEGACY);
  589         reg &= ~0x8133c03f;     /* these bits are out of interest */
  590         reg |= (YDS_PCI_EX_LEGACY_IMOD | YDS_PCI_LEGACY_FMEN |
  591                 YDS_PCI_LEGACY_MEN /*| YDS_PCI_LEGACY_MIEN*/);
  592         if (sc->sc_flags & YDS_CAP_LEGACY_SMOD_DISABLE)
  593                 reg |= YDS_PCI_EX_LEGACY_SMOD_DISABLE;
  594         if (FLEXIBLE) {
  595                 pci_conf_write(sc->sc_pc, sc->sc_pcitag, YDS_PCI_LEGACY, reg);
  596                 delay(100*1000);
  597         }
  598 
  599         /* Look for OPL */
  600         dev = 0;
  601         for (i = 0; i < sizeof(opl_addrs) / sizeof (bus_addr_t); i++) {
  602                 if (SELECTABLE) {
  603                         pci_conf_write(sc->sc_pc, sc->sc_pcitag,
  604                                        YDS_PCI_LEGACY, reg | (i << (0+16)));
  605                         delay(100*1000);        /* wait 100ms */
  606                 } else
  607                         pci_conf_write(sc->sc_pc, sc->sc_pcitag,
  608                                        YDS_PCI_FM_BA, opl_addrs[i]);
  609                 if (bus_space_map(sc->sc_opl_iot,
  610                                   opl_addrs[i], 4, 0, &sc->sc_opl_ioh) == 0) {
  611                         struct audio_attach_args aa; 
  612 
  613                         aa.type = AUDIODEV_TYPE_OPL;
  614                         aa.hwif = aa.hdl = NULL;
  615                         dev = config_found(&sc->sc_dev, &aa, audioprint);
  616                         if (dev == 0)
  617                                 bus_space_unmap(sc->sc_opl_iot,
  618                                                 sc->sc_opl_ioh, 4);
  619                         else {
  620                                 if (SELECTABLE)
  621                                         reg |= (i << (0+16));
  622                                 break;
  623                         }
  624                 } 
  625         }
  626         if (dev == 0) {
  627                 reg &= ~YDS_PCI_LEGACY_FMEN;
  628                 pci_conf_write(sc->sc_pc, sc->sc_pcitag,
  629                                YDS_PCI_LEGACY, reg);
  630         } else {
  631                 /* Max. volume */
  632                 YWRITE4(sc, YDS_LEGACY_OUT_VOLUME, 0x3fff3fff);
  633                 YWRITE4(sc, YDS_LEGACY_REC_VOLUME, 0x3fff3fff);
  634         }
  635 
  636         /* Look for MPU */
  637         dev = 0;
  638         for (i = 0; i < sizeof(mpu_addrs) / sizeof (bus_addr_t); i++) {
  639                 if (SELECTABLE)
  640                         pci_conf_write(sc->sc_pc, sc->sc_pcitag,
  641                                        YDS_PCI_LEGACY, reg | (i << (4+16)));
  642                 else
  643                         pci_conf_write(sc->sc_pc, sc->sc_pcitag,
  644                                        YDS_PCI_MPU_BA, mpu_addrs[i]);
  645                 if (bus_space_map(sc->sc_mpu_iot,
  646                                   mpu_addrs[i], 2, 0, &sc->sc_mpu_ioh) == 0) {
  647                         struct audio_attach_args aa; 
  648 
  649                         aa.type = AUDIODEV_TYPE_MPU;
  650                         aa.hwif = aa.hdl = NULL;
  651                         dev = config_found(&sc->sc_dev, &aa, audioprint);
  652                         if (dev == 0)
  653                                 bus_space_unmap(sc->sc_mpu_iot,
  654                                                 sc->sc_mpu_ioh, 2);
  655                         else {
  656                                 if (SELECTABLE)
  657                                         reg |= (i << (4+16));
  658                                 break;
  659                         }
  660                 }
  661         }
  662         if (dev == 0) {
  663                 reg &= ~(YDS_PCI_LEGACY_MEN | YDS_PCI_LEGACY_MIEN);
  664                 pci_conf_write(sc->sc_pc, sc->sc_pcitag,
  665                                YDS_PCI_LEGACY, reg);
  666         }
  667         sc->sc_mpu = dev;
  668 } 
  669 #undef FLEXIBLE
  670 #undef SELECTABLE
  671 
  672 void
  673 yds_attach(parent, self, aux)
  674         struct device *parent;
  675         struct device *self;
  676         void *aux;
  677 {
  678         struct yds_softc *sc = (struct yds_softc *)self;
  679         struct pci_attach_args *pa = (struct pci_attach_args *)aux;
  680         pci_chipset_tag_t pc = pa->pa_pc;
  681         char const *intrstr;
  682         pci_intr_handle_t ih;
  683         bus_size_t size;
  684         pcireg_t reg;
  685         int i;
  686 
  687         /* Map register to memory */
  688         if (pci_mapreg_map(pa, YDS_PCI_MBA, PCI_MAPREG_TYPE_MEM, 0,
  689             &sc->memt, &sc->memh, NULL, &size, 0)) {
  690                 printf("%s: can't map memory space\n", sc->sc_dev.dv_xname);
  691                 return;
  692         }
  693 
  694         /* Map and establish the interrupt. */
  695         if (pci_intr_map(pa, &ih)) {
  696                 printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname);
  697                 bus_space_unmap(sc->memt, sc->memh, size);
  698                 return;
  699         }
  700         intrstr = pci_intr_string(pc, ih);
  701         sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO, yds_intr, sc,
  702             self->dv_xname);
  703         if (sc->sc_ih == NULL) {
  704                 printf("%s: couldn't establish interrupt",
  705                     sc->sc_dev.dv_xname);
  706                 if (intrstr != NULL)
  707                         printf(" at %s", intrstr);
  708                 printf("\n");
  709                 bus_space_unmap(sc->memt, sc->memh, size);
  710                 return;
  711         }
  712         printf(": %s\n", intrstr);
  713 
  714         sc->sc_dmatag = pa->pa_dmat;
  715         sc->sc_pc = pc;
  716         sc->sc_pcitag = pa->pa_tag;
  717         sc->sc_id = pa->pa_id;
  718         sc->sc_revision = PCI_REVISION(pa->pa_class);
  719         sc->sc_flags = yds_get_dstype(sc->sc_id);
  720         if (sc->sc_dev.dv_cfdata->cf_flags & YDS_CAP_LEGACY_SMOD_DISABLE)
  721                 sc->sc_flags |= YDS_CAP_LEGACY_SMOD_DISABLE;
  722 #ifdef AUDIO_DEBUG
  723         if (ydsdebug)
  724                 printf("%s: chip has %b\n", sc->sc_dev.dv_xname,
  725                         YDS_CAP_BITS, sc->sc_flags);
  726 #endif
  727 
  728         /* Disable legacy mode */
  729         reg = pci_conf_read(pc, pa->pa_tag, YDS_PCI_LEGACY);
  730         pci_conf_write(pc, pa->pa_tag, YDS_PCI_LEGACY,
  731                        reg & YDS_PCI_LEGACY_LAD);
  732 
  733         /* Mute all volumes */
  734         for (i = 0x80; i < 0xc0; i += 2)
  735                 YWRITE2(sc, i, 0);
  736 
  737         sc->sc_legacy_iot = pa->pa_iot;
  738         mountroothook_establish(yds_attachhook, sc);
  739 }
  740 
  741 void
  742 yds_attachhook(void *xsc)
  743 {
  744         struct yds_softc *sc = xsc;
  745         struct yds_codec_softc *codec;
  746         mixer_ctrl_t ctl;
  747         int r, i;
  748         
  749         /* Initialize the device */
  750         if (yds_init(sc) == -1)
  751                 return;
  752 
  753         /*
  754          * Attach ac97 codec
  755          */
  756         for (i = 0; i < 2; i++) {
  757                 static struct {
  758                         int data;
  759                         int addr;
  760                 } statregs[] = {
  761                         {AC97_STAT_DATA1, AC97_STAT_ADDR1},
  762                         {AC97_STAT_DATA2, AC97_STAT_ADDR2},
  763                 };
  764 
  765                 if (i == 1 && ac97_id2 == -1)
  766                         break;          /* secondary ac97 not available */
  767 
  768                 codec = &sc->sc_codec[i];
  769                 memcpy(&codec->sc_dev, &sc->sc_dev, sizeof(codec->sc_dev));
  770                 codec->sc = sc;
  771                 codec->id = i == 1 ? ac97_id2 : 0;
  772                 codec->status_data = statregs[i].data;
  773                 codec->status_addr = statregs[i].addr;
  774                 codec->host_if.arg = codec;
  775                 codec->host_if.attach = yds_attach_codec;
  776                 codec->host_if.read = yds_read_codec;
  777                 codec->host_if.write = yds_write_codec;
  778                 codec->host_if.reset = yds_reset_codec;
  779 
  780                 if ((r = ac97_attach(&codec->host_if)) != 0) {
  781                         printf("%s: can't attach codec (error 0x%X)\n",
  782                                 sc->sc_dev.dv_xname, r);
  783                         return;
  784                 }
  785         }
  786 
  787         /* Just enable the DAC and master volumes by default */
  788         ctl.type = AUDIO_MIXER_ENUM;
  789         ctl.un.ord = 0;  /* off */
  790         ctl.dev = yds_get_portnum_by_name(sc, AudioCoutputs,
  791                AudioNmaster, AudioNmute);
  792         yds_mixer_set_port(sc, &ctl);
  793         ctl.dev = yds_get_portnum_by_name(sc, AudioCinputs,
  794                AudioNdac, AudioNmute);
  795         yds_mixer_set_port(sc, &ctl);
  796         ctl.dev = yds_get_portnum_by_name(sc, AudioCinputs,
  797                AudioNcd, AudioNmute);
  798         yds_mixer_set_port(sc, &ctl);
  799         ctl.dev = yds_get_portnum_by_name(sc, AudioCrecord,
  800                AudioNvolume, AudioNmute);
  801         yds_mixer_set_port(sc, &ctl);
  802         
  803         ctl.dev = yds_get_portnum_by_name(sc, AudioCrecord,
  804                AudioNsource, NULL);
  805         ctl.type = AUDIO_MIXER_ENUM;
  806         ctl.un.ord = 0;
  807         yds_mixer_set_port(sc, &ctl);
  808 
  809         /* Set a reasonable default volume */
  810         ctl.type = AUDIO_MIXER_VALUE;
  811         ctl.un.value.num_channels = 2;
  812         ctl.un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
  813         ctl.un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 127;
  814 
  815         ctl.dev = sc->sc_codec[0].codec_if->vtbl->get_portnum_by_name(
  816                 sc->sc_codec[0].codec_if, AudioCoutputs, AudioNmaster, NULL);
  817         yds_mixer_set_port(sc, &ctl);
  818 
  819         audio_attach_mi(&yds_hw_if, sc, &sc->sc_dev);
  820 
  821         /* Watch for power changes */
  822         sc->suspend = PWR_RESUME;
  823         sc->powerhook = powerhook_establish(yds_powerhook, sc);
  824 
  825         yds_configure_legacy(sc);
  826 }
  827 
  828 int
  829 yds_attach_codec(sc_, codec_if)
  830         void *sc_;
  831         struct ac97_codec_if *codec_if;
  832 {
  833         struct yds_codec_softc *sc = sc_;
  834 
  835         sc->codec_if = codec_if;
  836         return 0;
  837 }
  838 
  839 static int
  840 yds_ready_codec(sc)
  841         struct yds_codec_softc *sc;
  842 {
  843         int to;
  844 
  845         for (to = 0; to < AC97_TIMEOUT; to++) {
  846                 if ((YREAD2(sc->sc, sc->status_addr) & AC97_BUSY) == 0)
  847                         return 0;
  848                 delay(1);
  849         }
  850 
  851         return 1;
  852 }
  853 
  854 int
  855 yds_read_codec(sc_, reg, data)
  856         void *sc_;
  857         u_int8_t reg;
  858         u_int16_t *data;
  859 {
  860         struct yds_codec_softc *sc = sc_;
  861 
  862         YWRITE2(sc->sc, AC97_CMD_ADDR, AC97_CMD_READ | AC97_ID(sc->id) | reg);
  863 
  864         if (yds_ready_codec(sc)) {
  865                 printf("%s: yds_read_codec timeout\n",
  866                        sc->sc->sc_dev.dv_xname);
  867                 return EIO;
  868         }
  869 
  870         if (PCI_PRODUCT(sc->sc->sc_id) == PCI_PRODUCT_YAMAHA_YMF744 &&
  871             sc->sc->sc_revision < 2) {
  872                 int i;
  873 
  874                 for (i = 0; i < 600; i++)
  875                         YREAD2(sc->sc, sc->status_data);
  876         }
  877         *data = YREAD2(sc->sc, sc->status_data);
  878 
  879         return 0;
  880 }
  881 
  882 int
  883 yds_write_codec(sc_, reg, data)
  884         void *sc_;
  885         u_int8_t reg;
  886         u_int16_t data;
  887 {
  888         struct yds_codec_softc *sc = sc_;
  889 
  890         YWRITE2(sc->sc, AC97_CMD_ADDR, AC97_CMD_WRITE | AC97_ID(sc->id) | reg);
  891         YWRITE2(sc->sc, AC97_CMD_DATA, data);
  892 
  893         if (yds_ready_codec(sc)) {
  894                 printf("%s: yds_write_codec timeout\n",
  895                         sc->sc->sc_dev.dv_xname);
  896                 return EIO;
  897         }
  898 
  899         return 0;
  900 }
  901 
  902 /*
  903  * XXX: Must handle the secondary differntly!!
  904  */
  905 void
  906 yds_reset_codec(sc_)
  907         void *sc_;
  908 {
  909         struct yds_codec_softc *codec = sc_;
  910         struct yds_softc *sc = codec->sc;
  911         pcireg_t reg;
  912 
  913         /* reset AC97 codec */
  914         reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, YDS_PCI_DSCTRL);
  915         if (reg & 0x03) {
  916                 pci_conf_write(sc->sc_pc, sc->sc_pcitag,
  917                                YDS_PCI_DSCTRL, reg & ~0x03);
  918                 pci_conf_write(sc->sc_pc, sc->sc_pcitag,
  919                                YDS_PCI_DSCTRL, reg | 0x03);
  920                 pci_conf_write(sc->sc_pc, sc->sc_pcitag,
  921                                YDS_PCI_DSCTRL, reg & ~0x03);
  922                 delay(50000);
  923         }
  924 
  925         yds_ready_codec(sc_);
  926 }
  927 
  928 int
  929 yds_intr(p)
  930         void *p;
  931 {
  932         struct yds_softc *sc = p;
  933         u_int status;
  934 
  935         status = YREAD4(sc, YDS_STATUS);
  936         DPRINTFN(1, ("yds_intr: status=%08x\n", status));
  937         if ((status & (YDS_STAT_INT|YDS_STAT_TINT)) == 0) {
  938 #if 0
  939                 if (sc->sc_mpu)
  940                         return mpu_intr(sc->sc_mpu);
  941 #endif
  942                 return 0;
  943         }
  944 
  945         if (status & YDS_STAT_TINT) {
  946                 YWRITE4(sc, YDS_STATUS, YDS_STAT_TINT);
  947                 printf ("yds_intr: timeout!\n");
  948         }
  949 
  950         if (status & YDS_STAT_INT) {
  951                 int nbank = (YREAD4(sc, YDS_CONTROL_SELECT) == 0);
  952 
  953                 /* Clear interrupt flag */
  954                 YWRITE4(sc, YDS_STATUS, YDS_STAT_INT);
  955 
  956                 /* Buffer for the next frame is always ready. */
  957                 YWRITE4(sc, YDS_MODE, YREAD4(sc, YDS_MODE) | YDS_MODE_ACTV2);
  958 
  959                 if (sc->sc_play.intr) {
  960                         u_int dma, cpu, blk, len;
  961 
  962                         /* Sync play slot control data */
  963                         bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map,
  964                                         sc->pbankoff,
  965                                         sizeof(struct play_slot_ctrl_bank)*
  966                                             (*sc->ptbl)*
  967                                             N_PLAY_SLOT_CTRL_BANK,
  968                                         BUS_DMASYNC_POSTWRITE|
  969                                         BUS_DMASYNC_POSTREAD);
  970                         dma = sc->pbankp[nbank]->pgstart * sc->sc_play.factor;
  971                         cpu = sc->sc_play.offset;
  972                         blk = sc->sc_play.blksize;
  973                         len = sc->sc_play.length;
  974 
  975                         if (((dma > cpu) && (dma - cpu > blk * 2)) ||
  976                             ((cpu > dma) && (dma + len - cpu > blk * 2))) {
  977                                 /* We can fill the next block */
  978                                 /* Sync ring buffer for previous write */
  979                                 bus_dmamap_sync(sc->sc_dmatag,
  980                                                 sc->sc_play.dma->map,
  981                                                 cpu, blk,
  982                                                 BUS_DMASYNC_POSTWRITE);
  983                                 sc->sc_play.intr(sc->sc_play.intr_arg);
  984                                 sc->sc_play.offset += blk;
  985                                 if (sc->sc_play.offset >= len) {
  986                                         sc->sc_play.offset -= len;
  987 #ifdef DIAGNOSTIC
  988                                         if (sc->sc_play.offset != 0)
  989                                                 printf ("Audio ringbuffer botch\n");
  990 #endif
  991                                 }
  992                                 /* Sync ring buffer for next write */
  993                                 bus_dmamap_sync(sc->sc_dmatag,
  994                                                 sc->sc_play.dma->map,
  995                                                 cpu, blk,
  996                                                 BUS_DMASYNC_PREWRITE);
  997                         }
  998                 }
  999                 if (sc->sc_rec.intr) {
 1000                         u_int dma, cpu, blk, len;
 1001 
 1002                         /* Sync rec slot control data */
 1003                         bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map,
 1004                                         sc->rbankoff,
 1005                                         sizeof(struct rec_slot_ctrl_bank)*
 1006                                             N_REC_SLOT_CTRL*
 1007                                             N_REC_SLOT_CTRL_BANK,
 1008                                         BUS_DMASYNC_POSTWRITE|
 1009                                         BUS_DMASYNC_POSTREAD);
 1010                         dma = sc->rbank[YDS_INPUT_SLOT*2 + nbank].pgstartadr;
 1011                         cpu = sc->sc_rec.offset;
 1012                         blk = sc->sc_rec.blksize;
 1013                         len = sc->sc_rec.length;
 1014 
 1015                         if (((dma > cpu) && (dma - cpu > blk * 2)) ||
 1016                             ((cpu > dma) && (dma + len - cpu > blk * 2))) {
 1017                                 /* We can drain the current block */
 1018                                 /* Sync ring buffer first */
 1019                                 bus_dmamap_sync(sc->sc_dmatag,
 1020                                                 sc->sc_rec.dma->map,
 1021                                                 cpu, blk,
 1022                                                 BUS_DMASYNC_POSTREAD);
 1023                                 sc->sc_rec.intr(sc->sc_rec.intr_arg);
 1024                                 sc->sc_rec.offset += blk;
 1025                                 if (sc->sc_rec.offset >= len) {
 1026                                         sc->sc_rec.offset -= len;
 1027 #ifdef DIAGNOSTIC
 1028                                         if (sc->sc_rec.offset != 0)
 1029                                                 printf ("Audio ringbuffer botch\n");
 1030 #endif
 1031                                 }
 1032                                 /* Sync ring buffer for next read */
 1033                                 bus_dmamap_sync(sc->sc_dmatag,
 1034                                                 sc->sc_rec.dma->map,
 1035                                                 cpu, blk,
 1036                                                 BUS_DMASYNC_PREREAD);
 1037                         }
 1038                 }
 1039         }
 1040 
 1041         return 1;
 1042 }
 1043 
 1044 int
 1045 yds_allocmem(sc, size, align, p)
 1046         struct yds_softc *sc;
 1047         size_t size;
 1048         size_t align;
 1049         struct yds_dma *p;
 1050 {
 1051         int error;
 1052 
 1053         p->size = size;
 1054         error = bus_dmamem_alloc(sc->sc_dmatag, p->size, align, 0,
 1055                                  p->segs, sizeof(p->segs)/sizeof(p->segs[0]),
 1056                                  &p->nsegs, BUS_DMA_NOWAIT);
 1057         if (error)
 1058                 return (error);
 1059 
 1060         error = bus_dmamem_map(sc->sc_dmatag, p->segs, p->nsegs, p->size, 
 1061                                &p->addr, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
 1062         if (error)
 1063                 goto free;
 1064 
 1065         error = bus_dmamap_create(sc->sc_dmatag, p->size, 1, p->size,
 1066                                   0, BUS_DMA_NOWAIT, &p->map);
 1067         if (error)
 1068                 goto unmap;
 1069 
 1070         error = bus_dmamap_load(sc->sc_dmatag, p->map, p->addr, p->size, NULL, 
 1071                                 BUS_DMA_NOWAIT);
 1072         if (error)
 1073                 goto destroy;
 1074         return (0);
 1075 
 1076 destroy:
 1077         bus_dmamap_destroy(sc->sc_dmatag, p->map);
 1078 unmap:
 1079         bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size);
 1080 free:
 1081         bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs);
 1082         return (error);
 1083 }
 1084 
 1085 int
 1086 yds_freemem(sc, p)
 1087         struct yds_softc *sc;
 1088         struct yds_dma *p;
 1089 {
 1090         bus_dmamap_unload(sc->sc_dmatag, p->map);
 1091         bus_dmamap_destroy(sc->sc_dmatag, p->map);
 1092         bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size);
 1093         bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs);
 1094         return 0;
 1095 }
 1096 
 1097 int
 1098 yds_open(addr, flags)
 1099         void *addr;
 1100         int flags;
 1101 {
 1102         struct yds_softc *sc = addr;
 1103         int mode;
 1104 
 1105         /* Select bank 0. */
 1106         YWRITE4(sc, YDS_CONTROL_SELECT, 0);
 1107 
 1108         /* Start the DSP operation. */
 1109         mode = YREAD4(sc, YDS_MODE);
 1110         mode |= YDS_MODE_ACTV;
 1111         mode &= ~YDS_MODE_ACTV2;
 1112         YWRITE4(sc, YDS_MODE, mode);
 1113 
 1114         return 0;
 1115 }
 1116 
 1117 /*
 1118  * Close function is called at splaudio().
 1119  */
 1120 void
 1121 yds_close(addr)
 1122         void *addr;
 1123 {
 1124         struct yds_softc *sc = addr;
 1125 
 1126         yds_halt_output(sc);
 1127         yds_halt_input(sc);
 1128         yds_halt(sc);
 1129 }
 1130 
 1131 int
 1132 yds_query_encoding(addr, fp)
 1133         void *addr;
 1134         struct audio_encoding *fp;
 1135 {
 1136         switch (fp->index) {
 1137         case 0:
 1138                 strlcpy(fp->name, AudioEulinear, sizeof fp->name);
 1139                 fp->encoding = AUDIO_ENCODING_ULINEAR;
 1140                 fp->precision = 8;
 1141                 fp->flags = 0;
 1142                 return (0);
 1143         case 1:
 1144                 strlcpy(fp->name, AudioEmulaw, sizeof fp->name);
 1145                 fp->encoding = AUDIO_ENCODING_ULAW;
 1146                 fp->precision = 8;
 1147                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
 1148                 return (0);
 1149         case 2:
 1150                 strlcpy(fp->name, AudioEalaw, sizeof fp->name);
 1151                 fp->encoding = AUDIO_ENCODING_ALAW;
 1152                 fp->precision = 8;
 1153                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
 1154                 return (0);
 1155         case 3:
 1156                 strlcpy(fp->name, AudioEslinear, sizeof fp->name);
 1157                 fp->encoding = AUDIO_ENCODING_SLINEAR;
 1158                 fp->precision = 8;
 1159                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
 1160                 return (0);
 1161         case 4:
 1162                 strlcpy(fp->name, AudioEslinear_le, sizeof fp->name);
 1163                 fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
 1164                 fp->precision = 16;
 1165                 fp->flags = 0;
 1166                 return (0);
 1167         case 5:
 1168                 strlcpy(fp->name, AudioEulinear_le, sizeof fp->name);
 1169                 fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
 1170                 fp->precision = 16;
 1171                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
 1172                 return (0);
 1173         case 6:
 1174                 strlcpy(fp->name, AudioEslinear_be, sizeof fp->name);
 1175                 fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
 1176                 fp->precision = 16;
 1177                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
 1178                 return (0);
 1179         case 7:
 1180                 strlcpy(fp->name, AudioEulinear_be, sizeof fp->name);
 1181                 fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
 1182                 fp->precision = 16;
 1183                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
 1184                 return (0);
 1185         default:
 1186                 return (EINVAL);
 1187         }
 1188 }
 1189 
 1190 int
 1191 yds_set_params(addr, setmode, usemode, play, rec)
 1192         void *addr;
 1193         int setmode, usemode;
 1194         struct audio_params *play, *rec;
 1195 {
 1196         struct audio_params *p;
 1197         int mode;
 1198 
 1199         for (mode = AUMODE_RECORD; mode != -1; 
 1200              mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
 1201                 if ((setmode & mode) == 0)
 1202                         continue;
 1203 
 1204                 p = mode == AUMODE_PLAY ? play : rec;
 1205 
 1206                 if (p->sample_rate < 4000 || p->sample_rate > 48000 ||
 1207                     (p->precision != 8 && p->precision != 16) ||
 1208                     (p->channels != 1 && p->channels != 2))
 1209                         return (EINVAL);
 1210 
 1211                 p->factor = 1;
 1212                 p->sw_code = 0;
 1213                 switch (p->encoding) {
 1214                 case AUDIO_ENCODING_SLINEAR_BE:
 1215                         if (p->precision == 16)
 1216                                 p->sw_code = swap_bytes;
 1217                         else
 1218                                 p->sw_code = change_sign8;
 1219                         break;
 1220                 case AUDIO_ENCODING_SLINEAR_LE:
 1221                         if (p->precision != 16)
 1222                                 p->sw_code = change_sign8;
 1223                         break;
 1224                 case AUDIO_ENCODING_ULINEAR_BE:
 1225                         if (p->precision == 16) {
 1226                                 if (mode == AUMODE_PLAY)
 1227                                         p->sw_code = swap_bytes_change_sign16_le;
 1228                                 else
 1229                                         p->sw_code = change_sign16_swap_bytes_le;
 1230                         }
 1231                         break;
 1232                 case AUDIO_ENCODING_ULINEAR_LE:
 1233                         if (p->precision == 16)
 1234                                 p->sw_code = change_sign16_le;
 1235                         break;
 1236                 case AUDIO_ENCODING_ULAW:
 1237                         if (mode == AUMODE_PLAY) {
 1238                                 p->factor = 2;
 1239                                 p->precision = 16;
 1240                                 p->sw_code = mulaw_to_slinear16_le;
 1241                         } else
 1242                                 p->sw_code = ulinear8_to_mulaw;
 1243                         break;
 1244                 case AUDIO_ENCODING_ALAW:
 1245                         if (mode == AUMODE_PLAY) {
 1246                                 p->factor = 2;
 1247                                 p->precision = 16;
 1248                                 p->sw_code = alaw_to_slinear16_le;
 1249                         } else
 1250                                 p->sw_code = ulinear8_to_alaw;
 1251                         break;
 1252                 default:
 1253                         return (EINVAL);
 1254                 }
 1255         }
 1256 
 1257         return 0;
 1258 }
 1259 
 1260 int
 1261 yds_round_blocksize(addr, blk)
 1262         void *addr;
 1263         int blk;
 1264 {
 1265         /*
 1266          * Block size must be bigger than a frame.
 1267          * That is 1024bytes at most, i.e. for 48000Hz, 16bit, 2ch.
 1268          */
 1269         if (blk < 1024)
 1270                 blk = 1024;
 1271 
 1272         return blk & ~4;
 1273 }
 1274 
 1275 static u_int32_t
 1276 yds_get_lpfq(sample_rate)
 1277         u_int sample_rate;
 1278 {
 1279         int i;
 1280         static struct lpfqt {
 1281                 u_int rate;
 1282                 u_int32_t lpfq;
 1283         } lpfqt[] = {
 1284                 {8000,  0x32020000},
 1285                 {11025, 0x31770000},
 1286                 {16000, 0x31390000},
 1287                 {22050, 0x31c90000},
 1288                 {32000, 0x33d00000},
 1289                 {48000, 0x40000000},
 1290                 {0, 0}
 1291         };
 1292 
 1293         if (sample_rate == 44100)               /* for P44 slot? */
 1294                 return 0x370A0000;
 1295 
 1296         for (i = 0; lpfqt[i].rate != 0; i++)
 1297                 if (sample_rate <= lpfqt[i].rate)
 1298                         break;
 1299 
 1300         return lpfqt[i].lpfq;
 1301 }
 1302 
 1303 static u_int32_t
 1304 yds_get_lpfk(sample_rate)
 1305         u_int sample_rate;
 1306 {
 1307         int i;
 1308         static struct lpfkt {
 1309                 u_int rate;
 1310                 u_int32_t lpfk;
 1311         } lpfkt[] = {
 1312                 {8000,  0x18b20000},
 1313                 {11025, 0x20930000},
 1314                 {16000, 0x2b9a0000},
 1315                 {22050, 0x35a10000},
 1316                 {32000, 0x3eaa0000},
 1317                 {48000, 0x40000000},
 1318                 {0, 0}
 1319         };
 1320 
 1321         if (sample_rate == 44100)               /* for P44 slot? */
 1322                 return 0x46460000;
 1323 
 1324         for (i = 0; lpfkt[i].rate != 0; i++)
 1325                 if (sample_rate <= lpfkt[i].rate)
 1326                         break;
 1327 
 1328         return lpfkt[i].lpfk;
 1329 }
 1330 
 1331 int
 1332 yds_trigger_output(addr, start, end, blksize, intr, arg, param)
 1333         void *addr;
 1334         void *start, *end;
 1335         int blksize;
 1336         void (*intr)(void *);
 1337         void *arg;
 1338         struct audio_params *param;
 1339 #define P44             (sc->sc_flags & YDS_CAP_HAS_P44)
 1340 {
 1341         struct yds_softc *sc = addr;
 1342         struct yds_dma *p;
 1343         struct play_slot_ctrl_bank *psb;
 1344         const u_int gain = 0x40000000;
 1345         bus_addr_t s;
 1346         size_t l;
 1347         int i;
 1348         int p44, channels;
 1349 
 1350 #ifdef DIAGNOSTIC
 1351         if (sc->sc_play.intr)
 1352                 panic("yds_trigger_output: already running");
 1353 #endif
 1354 
 1355         sc->sc_play.intr = intr;
 1356         sc->sc_play.intr_arg = arg;
 1357         sc->sc_play.offset = 0;
 1358         sc->sc_play.blksize = blksize;
 1359 
 1360         DPRINTFN(1, ("yds_trigger_output: sc=%p start=%p end=%p "
 1361             "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));
 1362 
 1363         p = yds_find_dma(sc, start);
 1364         if (!p) {
 1365                 printf("yds_trigger_output: bad addr %p\n", start);
 1366                 return (EINVAL);
 1367         }
 1368         sc->sc_play.dma = p;
 1369 
 1370 #ifdef DIAGNOSTIC
 1371         {
 1372                 u_int32_t ctrlsize;
 1373                 if ((ctrlsize = YREAD4(sc, YDS_PLAY_CTRLSIZE)) !=
 1374                     sizeof(struct play_slot_ctrl_bank) / sizeof(u_int32_t))
 1375                         panic("%s: invalid play slot ctrldata %d %d",
 1376                               sc->sc_dev.dv_xname, ctrlsize,
 1377                               sizeof(struct play_slot_ctrl_bank));
 1378         }
 1379 #endif
 1380 
 1381 #ifdef YDS_USE_P44
 1382         /* The document says the P44 SRC supports only stereo, 16bit PCM. */
 1383         if (P44)
 1384                 p44 = ((param->sample_rate == 44100) &&
 1385                        (param->channels == 2) &&
 1386                        (param->precision == 16));
 1387         else
 1388 #endif
 1389                 p44 = 0;
 1390         channels = p44 ? 1 : param->channels;
 1391 
 1392         s = DMAADDR(p);
 1393         l = ((char *)end - (char *)start);
 1394         sc->sc_play.length = l;
 1395 
 1396         *sc->ptbl = channels;   /* Num of play */
 1397 
 1398         sc->sc_play.factor = 1;
 1399         if (param->channels == 2)
 1400                 sc->sc_play.factor *= 2;
 1401         if (param->precision != 8)
 1402                 sc->sc_play.factor *= 2;
 1403         l /= sc->sc_play.factor;
 1404 
 1405         psb = sc->pbankp[0];
 1406         memset(psb, 0, sizeof(*psb));
 1407         psb->format = ((channels == 2 ? PSLT_FORMAT_STEREO : 0) |
 1408                        (param->precision == 8 ? PSLT_FORMAT_8BIT : 0) |
 1409                        (p44 ? PSLT_FORMAT_SRC441 : 0));
 1410         psb->pgbase = s;
 1411         psb->pgloopend = l;
 1412         if (!p44) {
 1413                 psb->pgdeltaend = (param->sample_rate * 65536 / 48000) << 12;
 1414                 psb->lpfkend = yds_get_lpfk(param->sample_rate);
 1415                 psb->eggainend = gain;
 1416                 psb->lpfq = yds_get_lpfq(param->sample_rate);
 1417                 psb->pgdelta = psb->pgdeltaend;
 1418                 psb->lpfk = yds_get_lpfk(param->sample_rate);
 1419                 psb->eggain = gain;
 1420         }
 1421 
 1422         for (i = 0; i < channels; i++) {
 1423                 /* i == 0: left or mono, i == 1: right */
 1424                 psb = sc->pbankp[i*2];
 1425                 if (i)
 1426                         /* copy from left */
 1427                         *psb = *(sc->pbankp[0]);
 1428                 if (channels == 2) {
 1429                         /* stereo */
 1430                         if (i == 0) {
 1431                                 psb->lchgain = psb->lchgainend = gain;
 1432                         } else {
 1433                                 psb->lchgain = psb->lchgainend = 0;
 1434                                 psb->rchgain = psb->rchgainend = gain;
 1435                                 psb->format |= PSLT_FORMAT_RCH;
 1436                         }
 1437                 } else if (!p44) {
 1438                         /* mono */
 1439                         psb->lchgain = psb->rchgain = gain;
 1440                         psb->lchgainend = psb->rchgainend = gain;
 1441                 }
 1442                 /* copy to the other bank */
 1443                 *(sc->pbankp[i*2+1]) = *psb;
 1444         }
 1445 
 1446         YDS_DUMP_PLAY_SLOT(5, sc, 0);
 1447         YDS_DUMP_PLAY_SLOT(5, sc, 1);
 1448 
 1449         if (p44)
 1450                 YWRITE4(sc, YDS_P44_OUT_VOLUME, 0x3fff3fff);
 1451         else
 1452                 YWRITE4(sc, YDS_DAC_OUT_VOLUME, 0x3fff3fff);
 1453 
 1454         /* Now the play slot for the next frame is set up!! */
 1455         /* Sync play slot control data for both directions */
 1456         bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map,
 1457                         sc->ptbloff,
 1458                         sizeof(struct play_slot_ctrl_bank) *
 1459                             channels * N_PLAY_SLOT_CTRL_BANK,
 1460                         BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
 1461         /* Sync ring buffer */
 1462         bus_dmamap_sync(sc->sc_dmatag, p->map, 0, blksize,
 1463                         BUS_DMASYNC_PREWRITE);
 1464         /* HERE WE GO!! */
 1465         YWRITE4(sc, YDS_MODE,
 1466                 YREAD4(sc, YDS_MODE) | YDS_MODE_ACTV | YDS_MODE_ACTV2);
 1467 
 1468         return 0;
 1469 }
 1470 #undef P44
 1471 
 1472 int
 1473 yds_trigger_input(addr, start, end, blksize, intr, arg, param)
 1474         void *addr;
 1475         void *start, *end;
 1476         int blksize;
 1477         void (*intr)(void *);
 1478         void *arg;
 1479         struct audio_params *param;
 1480 {
 1481         struct yds_softc *sc = addr;
 1482         struct yds_dma *p;
 1483         u_int srate, format;
 1484         struct rec_slot_ctrl_bank *rsb;
 1485         bus_addr_t s;
 1486         size_t l;
 1487 
 1488 #ifdef DIAGNOSTIC
 1489         if (sc->sc_rec.intr)
 1490                 panic("yds_trigger_input: already running");
 1491 #endif
 1492         sc->sc_rec.intr = intr;
 1493         sc->sc_rec.intr_arg = arg;
 1494         sc->sc_rec.offset = 0;
 1495         sc->sc_rec.blksize = blksize;
 1496 
 1497         DPRINTFN(1, ("yds_trigger_input: "
 1498             "sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n", 
 1499             addr, start, end, blksize, intr, arg));
 1500         DPRINTFN(1, (" parameters: rate=%lu, precision=%u, channels=%u\n",
 1501             param->sample_rate, param->precision, param->channels));
 1502 
 1503         p = yds_find_dma(sc, start);
 1504         if (!p) {
 1505                 printf("yds_trigger_input: bad addr %p\n", start);
 1506                 return (EINVAL);
 1507         }
 1508         sc->sc_rec.dma = p;
 1509 
 1510         s = DMAADDR(p);
 1511         l = ((char *)end - (char *)start);
 1512         sc->sc_rec.length = l;
 1513 
 1514         sc->sc_rec.factor = 1;
 1515         if (param->channels == 2)
 1516                 sc->sc_rec.factor *= 2;
 1517         if (param->precision != 8)
 1518                 sc->sc_rec.factor *= 2;
 1519 
 1520         rsb = &sc->rbank[0];
 1521         memset(rsb, 0, sizeof(*rsb));
 1522         rsb->pgbase = s;
 1523         rsb->pgloopendadr = l;
 1524         /* Seems all 4 banks must be set up... */
 1525         sc->rbank[1] = *rsb;
 1526         sc->rbank[2] = *rsb;
 1527         sc->rbank[3] = *rsb;
 1528 
 1529         YWRITE4(sc, YDS_ADC_IN_VOLUME, 0x3fff3fff);
 1530         YWRITE4(sc, YDS_REC_IN_VOLUME, 0x3fff3fff);
 1531         srate = 48000 * 4096 / param->sample_rate - 1;
 1532         format = ((param->precision == 8 ? YDS_FORMAT_8BIT : 0) |
 1533                   (param->channels == 2 ? YDS_FORMAT_STEREO : 0));
 1534         DPRINTF(("srate=%d, format=%08x\n", srate, format));
 1535 #ifdef YDS_USE_REC_SLOT
 1536         YWRITE4(sc, YDS_DAC_REC_VOLUME, 0x3fff3fff);
 1537         YWRITE4(sc, YDS_P44_REC_VOLUME, 0x3fff3fff);
 1538         YWRITE4(sc, YDS_MAPOF_REC, YDS_RECSLOT_VALID);
 1539         YWRITE4(sc, YDS_REC_SAMPLE_RATE, srate);
 1540         YWRITE4(sc, YDS_REC_FORMAT, format);
 1541 #else
 1542         YWRITE4(sc, YDS_MAPOF_REC, YDS_ADCSLOT_VALID);
 1543         YWRITE4(sc, YDS_ADC_SAMPLE_RATE, srate);
 1544         YWRITE4(sc, YDS_ADC_FORMAT, format);
 1545 #endif
 1546         /* Now the rec slot for the next frame is set up!! */
 1547         /* Sync record slot control data */
 1548         bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map,
 1549                         sc->rbankoff,
 1550                         sizeof(struct rec_slot_ctrl_bank)*
 1551                             N_REC_SLOT_CTRL*
 1552                             N_REC_SLOT_CTRL_BANK,
 1553                         BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
 1554         /* Sync ring buffer */
 1555         bus_dmamap_sync(sc->sc_dmatag, p->map, 0, blksize,
 1556                         BUS_DMASYNC_PREREAD);
 1557         /* HERE WE GO!! */
 1558         YWRITE4(sc, YDS_MODE,
 1559                 YREAD4(sc, YDS_MODE) | YDS_MODE_ACTV | YDS_MODE_ACTV2);
 1560 
 1561         return 0;
 1562 }
 1563 
 1564 static int
 1565 yds_halt(sc)
 1566         struct yds_softc *sc;
 1567 {
 1568         u_int32_t mode;
 1569 
 1570         /* Stop the DSP operation. */
 1571         mode = YREAD4(sc, YDS_MODE);
 1572         YWRITE4(sc, YDS_MODE, mode & ~(YDS_MODE_ACTV|YDS_MODE_ACTV2));
 1573 
 1574         /* Paranoia...  mute all */
 1575         YWRITE4(sc, YDS_P44_OUT_VOLUME, 0);
 1576         YWRITE4(sc, YDS_DAC_OUT_VOLUME, 0);
 1577         YWRITE4(sc, YDS_ADC_IN_VOLUME, 0);
 1578         YWRITE4(sc, YDS_REC_IN_VOLUME, 0);
 1579         YWRITE4(sc, YDS_DAC_REC_VOLUME, 0);
 1580         YWRITE4(sc, YDS_P44_REC_VOLUME, 0);
 1581 
 1582         return 0;
 1583 }
 1584 
 1585 int
 1586 yds_halt_output(addr)
 1587         void *addr;
 1588 {
 1589         struct yds_softc *sc = addr;
 1590 
 1591         DPRINTF(("yds: yds_halt_output\n"));
 1592         if (sc->sc_play.intr) {
 1593                 sc->sc_play.intr = 0;
 1594                 /* Sync play slot control data */
 1595                 bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map,
 1596                                 sc->pbankoff,
 1597                                 sizeof(struct play_slot_ctrl_bank)*
 1598                                     (*sc->ptbl)*N_PLAY_SLOT_CTRL_BANK,
 1599                                 BUS_DMASYNC_POSTWRITE|BUS_DMASYNC_POSTREAD);
 1600                 /* Stop the play slot operation */
 1601                 sc->pbankp[0]->status =
 1602                 sc->pbankp[1]->status =
 1603                 sc->pbankp[2]->status =
 1604                 sc->pbankp[3]->status = 1;
 1605                 /* Sync ring buffer */
 1606                 bus_dmamap_sync(sc->sc_dmatag, sc->sc_play.dma->map,
 1607                                 0, sc->sc_play.length, BUS_DMASYNC_POSTWRITE);
 1608         }
 1609 
 1610         return 0;
 1611 }
 1612 
 1613 int
 1614 yds_halt_input(addr)
 1615         void *addr;
 1616 {
 1617         struct yds_softc *sc = addr;
 1618 
 1619         DPRINTF(("yds: yds_halt_input\n"));
 1620         if (sc->sc_rec.intr) {
 1621                 /* Stop the rec slot operation */
 1622                 YWRITE4(sc, YDS_MAPOF_REC, 0);
 1623                 sc->sc_rec.intr = 0;
 1624                 /* Sync rec slot control data */
 1625                 bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map,
 1626                                 sc->rbankoff,
 1627                                 sizeof(struct rec_slot_ctrl_bank)*
 1628                                     N_REC_SLOT_CTRL*N_REC_SLOT_CTRL_BANK,
 1629                                 BUS_DMASYNC_POSTWRITE|BUS_DMASYNC_POSTREAD);
 1630                 /* Sync ring buffer */
 1631                 bus_dmamap_sync(sc->sc_dmatag, sc->sc_rec.dma->map,
 1632                                 0, sc->sc_rec.length, BUS_DMASYNC_POSTREAD);
 1633         }
 1634         sc->sc_rec.intr = NULL;
 1635 
 1636         return 0;
 1637 }
 1638 
 1639 int
 1640 yds_getdev(addr, retp)
 1641         void *addr;
 1642         struct audio_device *retp;
 1643 {
 1644         *retp = yds_device;
 1645 
 1646         return 0;
 1647 }
 1648 
 1649 int
 1650 yds_mixer_set_port(addr, cp)
 1651         void *addr;
 1652         mixer_ctrl_t *cp;
 1653 {
 1654         struct yds_softc *sc = addr;
 1655 
 1656         return (sc->sc_codec[0].codec_if->vtbl->mixer_set_port(
 1657             sc->sc_codec[0].codec_if, cp));
 1658 }
 1659 
 1660 int
 1661 yds_mixer_get_port(addr, cp)
 1662         void *addr;
 1663         mixer_ctrl_t *cp;
 1664 {
 1665         struct yds_softc *sc = addr;
 1666 
 1667         return (sc->sc_codec[0].codec_if->vtbl->mixer_get_port(
 1668             sc->sc_codec[0].codec_if, cp));
 1669 }
 1670 
 1671 int
 1672 yds_query_devinfo(addr, dip)
 1673         void *addr;
 1674         mixer_devinfo_t *dip;
 1675 {
 1676         struct yds_softc *sc = addr;
 1677 
 1678         return (sc->sc_codec[0].codec_if->vtbl->query_devinfo(
 1679             sc->sc_codec[0].codec_if, dip));
 1680 }
 1681 
 1682 int
 1683 yds_get_portnum_by_name(sc, class, device, qualifier)
 1684         struct yds_softc *sc;
 1685         char *class, *device, *qualifier;
 1686 {
 1687         return (sc->sc_codec[0].codec_if->vtbl->get_portnum_by_name(
 1688             sc->sc_codec[0].codec_if, class, device, qualifier));
 1689 }
 1690 
 1691 void *
 1692 yds_malloc(addr, direction, size, pool, flags)
 1693         void *addr;
 1694         int direction;
 1695         size_t size;
 1696         int pool, flags;
 1697 {
 1698         struct yds_softc *sc = addr;
 1699         struct yds_dma *p;
 1700         int error;
 1701 
 1702         p = malloc(sizeof(*p), pool, flags);
 1703         if (!p)
 1704                 return (0);
 1705         error = yds_allocmem(sc, size, 16, p);
 1706         if (error) {
 1707                 free(p, pool);
 1708                 return (0);
 1709         }
 1710         p->next = sc->sc_dmas;
 1711         sc->sc_dmas = p;
 1712         return (KERNADDR(p));
 1713 }
 1714 
 1715 void
 1716 yds_free(addr, ptr, pool)
 1717         void *addr;
 1718         void *ptr;
 1719         int pool;
 1720 {
 1721         struct yds_softc *sc = addr;
 1722         struct yds_dma **pp, *p;
 1723 
 1724         for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &p->next) {
 1725                 if (KERNADDR(p) == ptr) {
 1726                         yds_freemem(sc, p);
 1727                         *pp = p->next;
 1728                         free(p, pool);
 1729                         return;
 1730                 }
 1731         }
 1732 }
 1733 
 1734 static struct yds_dma *
 1735 yds_find_dma(sc, addr)
 1736         struct yds_softc *sc;
 1737         void *addr;
 1738 {
 1739         struct yds_dma *p;
 1740 
 1741         for (p = sc->sc_dmas; p && KERNADDR(p) != addr; p = p->next)
 1742                 ;
 1743 
 1744         return p;
 1745 }
 1746 
 1747 size_t
 1748 yds_round_buffersize(addr, direction, size)
 1749         void *addr;
 1750         int direction;
 1751         size_t size;
 1752 {
 1753         /*
 1754          * Buffer size should be at least twice as bigger as a frame.
 1755          */
 1756         if (size < 1024 * 3)
 1757                 size = 1024 * 3;
 1758         return (size);
 1759 }
 1760 
 1761 paddr_t
 1762 yds_mappage(addr, mem, off, prot)
 1763         void *addr;
 1764         void *mem;
 1765         off_t off;
 1766         int prot;
 1767 {
 1768         struct yds_softc *sc = addr;
 1769         struct yds_dma *p;
 1770 
 1771         if (off < 0)
 1772                 return (-1);
 1773         p = yds_find_dma(sc, mem);
 1774         if (!p)
 1775                 return (-1);
 1776         return (bus_dmamem_mmap(sc->sc_dmatag, p->segs, p->nsegs, 
 1777                                 off, prot, BUS_DMA_WAITOK));
 1778 }
 1779 
 1780 int
 1781 yds_get_props(addr)
 1782         void *addr;
 1783 {
 1784         return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | 
 1785                 AUDIO_PROP_FULLDUPLEX);
 1786 }
 1787 
 1788 void
 1789 yds_powerhook(why, self)
 1790         int why;
 1791         void *self;
 1792 {
 1793         struct yds_softc *sc = (struct yds_softc *)self;
 1794 
 1795         if (why != PWR_RESUME) {
 1796                 /* Power down */
 1797                 DPRINTF(("yds: power down\n"));
 1798                 sc->suspend = why;
 1799 
 1800         } else {
 1801                 /* Wake up */
 1802                 DPRINTF(("yds: power resume\n"));
 1803                 if (sc->suspend == PWR_RESUME) {
 1804                         printf("%s: resume without suspend?\n",
 1805                                 sc->sc_dev.dv_xname);
 1806                         sc->suspend = why;
 1807                         return;
 1808                 }
 1809                 sc->suspend = why;
 1810                 yds_init(sc);
 1811                 (sc->sc_codec[0].codec_if->vtbl->restore_ports)(sc->sc_codec[0].codec_if);
 1812         }
 1813 }
 1814 
 1815 int
 1816 yds_init(sc_)
 1817         void *sc_;
 1818 {
 1819         struct yds_softc *sc = sc_;
 1820         u_int32_t reg;
 1821 
 1822         pci_chipset_tag_t pc = sc->sc_pc;
 1823 
 1824         int to;
 1825 
 1826         DPRINTF(("in yds_init()\n"));
 1827 
 1828         /* Download microcode */
 1829         if (yds_download_mcode(sc)) {
 1830                 printf("%s: download microcode failed\n", sc->sc_dev.dv_xname);
 1831                 return -1;
 1832         }
 1833         /* Allocate DMA buffers */
 1834         if (yds_allocate_slots(sc)) {
 1835                 printf("%s: could not allocate slots\n", sc->sc_dev.dv_xname);
 1836                 return -1;
 1837         }
 1838 
 1839         /* Warm reset */
 1840         reg = pci_conf_read(pc, sc->sc_pcitag, YDS_PCI_DSCTRL);
 1841         pci_conf_write(pc, sc->sc_pcitag, YDS_PCI_DSCTRL, reg | YDS_DSCTRL_WRST);
 1842         delay(50000);
 1843 
 1844         /*
 1845          * Detect primary/secondary AC97
 1846          *      YMF754 Hardware Specification Rev 1.01 page 24
 1847          */
 1848         reg = pci_conf_read(pc, sc->sc_pcitag, YDS_PCI_DSCTRL);
 1849         pci_conf_write(pc, sc->sc_pcitag, YDS_PCI_DSCTRL,
 1850                 reg & ~YDS_DSCTRL_CRST);
 1851         delay(400000);          /* Needed for 740C. */
 1852 
 1853         /* Primary */
 1854         for (to = 0; to < AC97_TIMEOUT; to++) {
 1855                 if ((YREAD2(sc, AC97_STAT_ADDR1) & AC97_BUSY) == 0)
 1856                         break;
 1857                 delay(1);
 1858         }
 1859         if (to == AC97_TIMEOUT) {
 1860                 printf("%s: no AC97 available\n", sc->sc_dev.dv_xname);
 1861                 return -1;
 1862         }
 1863 
 1864         /* Secondary */
 1865         /* Secondary AC97 is used for 4ch audio. Currently unused. */
 1866         ac97_id2 = -1;
 1867         if ((YREAD2(sc, YDS_ACTIVITY) & YDS_ACTIVITY_DOCKA) == 0)
 1868                 goto detected;
 1869 #if 0                           /* reset secondary... */
 1870         YWRITE2(sc, YDS_GPIO_OCTRL,
 1871                 YREAD2(sc, YDS_GPIO_OCTRL) & ~YDS_GPIO_GPO2);
 1872         YWRITE2(sc, YDS_GPIO_FUNCE,
 1873                 (YREAD2(sc, YDS_GPIO_FUNCE)&(~YDS_GPIO_GPC2))|YDS_GPIO_GPE2);
 1874 #endif
 1875         for (to = 0; to < AC97_TIMEOUT; to++) {
 1876                 if ((YREAD2(sc, AC97_STAT_ADDR2) & AC97_BUSY) == 0)
 1877                         break;
 1878                 delay(1);
 1879         }
 1880         if (to < AC97_TIMEOUT) {
 1881                 /* detect id */
 1882                 for (ac97_id2 = 1; ac97_id2 < 4; ac97_id2++) {
 1883                         YWRITE2(sc, AC97_CMD_ADDR,
 1884                                 AC97_CMD_READ | AC97_ID(ac97_id2) | 0x28);
 1885 
 1886                         for (to = 0; to < AC97_TIMEOUT; to++) {
 1887                                 if ((YREAD2(sc, AC97_STAT_ADDR2) & AC97_BUSY)
 1888                                     == 0)
 1889                                         goto detected;
 1890                                 delay(1);
 1891                         }
 1892                 }
 1893                 if (ac97_id2 == 4)
 1894                         ac97_id2 = -1;
 1895 detected:
 1896                 ;
 1897         }
 1898 
 1899         pci_conf_write(pc, sc->sc_pcitag, YDS_PCI_DSCTRL,
 1900                 reg | YDS_DSCTRL_CRST);
 1901         delay (20);
 1902         pci_conf_write(pc, sc->sc_pcitag, YDS_PCI_DSCTRL,
 1903                 reg & ~YDS_DSCTRL_CRST);
 1904         delay (400000);
 1905         for (to = 0; to < AC97_TIMEOUT; to++) {
 1906                 if ((YREAD2(sc, AC97_STAT_ADDR1) & AC97_BUSY) == 0)
 1907                         break;
 1908                 delay(1);
 1909         }
 1910 
 1911         DPRINTF(("out of yds_init()\n"));
 1912 
 1913         return 0;
 1914 }

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