root/dev/pci/esa.c

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

DEFINITIONS

This source file includes following definitions.
  1. esa_open
  2. esa_close
  3. esa_query_encoding
  4. esa_set_params
  5. esa_commit_settings
  6. esa_round_blocksize
  7. esa_halt_output
  8. esa_halt_input
  9. esa_malloc
  10. esa_free
  11. esa_getdev
  12. esa_set_port
  13. esa_get_port
  14. esa_query_devinfo
  15. esa_round_buffersize
  16. esa_get_props
  17. esa_trigger_output
  18. esa_trigger_input
  19. esa_intr
  20. esa_allocmem
  21. esa_freemem
  22. esa_match
  23. esa_attach
  24. esa_detach
  25. esa_read_assp
  26. esa_write_assp
  27. esa_init_codec
  28. esa_attach_codec
  29. esa_read_codec
  30. esa_write_codec
  31. esa_reset_codec
  32. esa_flags_codec
  33. esa_wait
  34. esa_init
  35. esa_config
  36. esa_assp_halt
  37. esa_codec_reset
  38. esa_amp_enable
  39. esa_enable_interrupts
  40. esa_add_list
  41. esa_remove_list
  42. esa_power
  43. esa_powerhook
  44. esa_suspend
  45. esa_resume
  46. esa_get_pointer
  47. esa_mappage

    1 /*      $OpenBSD: esa.c,v 1.11 2006/01/25 23:54:21 brad Exp $   */
    2 /* $NetBSD: esa.c,v 1.12 2002/03/24 14:17:35 jmcneill Exp $ */
    3 
    4 /*
    5  * Copyright (c) 2001, 2002 Jared D. McNeill <jmcneill@invisible.ca>
    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. The name of the author may not be used to endorse or promote products
   14  *    derived from this software without specific prior written permission.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
   23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   26  * SUCH DAMAGE.
   27  */
   28 
   29 /*
   30  * Shamelessly stolen from NetBSD who based it on FreeBSD's who in turn
   31  * based it on Linux's driver.  What a wonderful world.
   32  *
   33  *
   34  * ESS Allegro-1 / Maestro3 Audio Driver
   35  *
   36  * Based on the FreeBSD maestro3 driver and the NetBSD eap driver.
   37  * Original driver by Don Kim.
   38  *
   39  * The list management code could possibly be written better, but what
   40  * we have right now does the job nicely. Thanks to Zach Brown <zab@zabbo.net>
   41  * and Andrew MacDonald <amac@epsilon.yi.org> for helping me debug the
   42  * problems with the original list management code present in the Linux
   43  * driver.
   44  */
   45 
   46 #include <sys/types.h>
   47 #include <sys/errno.h>
   48 #include <sys/param.h>
   49 #include <sys/systm.h>
   50 #include <sys/malloc.h>
   51 #include <sys/device.h>
   52 #include <sys/conf.h>
   53 #include <sys/exec.h>
   54 #include <sys/selinfo.h>
   55 #include <sys/audioio.h>
   56 
   57 #include <machine/bus.h>
   58 #include <machine/intr.h>
   59 
   60 #include <dev/pci/pcidevs.h>
   61 #include <dev/pci/pcivar.h>
   62 
   63 #include <dev/audio_if.h>
   64 #include <dev/mulaw.h>
   65 #include <dev/auconv.h>
   66 #include <dev/ic/ac97.h>
   67 
   68 #include <dev/pci/esareg.h>
   69 #include <dev/pci/esavar.h>
   70 #include <dev/microcode/esa/esadsp.h>
   71 
   72 #define PCI_CBIO        0x10
   73 
   74 #define ESA_DAC_DATA    0x1100
   75 
   76 enum {
   77         ESS_ALLEGRO1,
   78         ESS_MAESTRO3
   79 };
   80 
   81 static struct esa_card_type {
   82         u_int16_t pci_vendor_id;
   83         u_int16_t pci_product_id;
   84         int type;
   85         int delay1, delay2;
   86 } esa_card_types[] = {
   87         { PCI_VENDOR_ESSTECH, PCI_PRODUCT_ESSTECH_ES1989,
   88           ESS_ALLEGRO1, 50, 800 },
   89         { PCI_VENDOR_ESSTECH, PCI_PRODUCT_ESSTECH_MAESTRO3,
   90           ESS_MAESTRO3, 20, 500 },
   91         { PCI_VENDOR_ESSTECH, PCI_PRODUCT_ESSTECH_MAESTRO3_2,
   92           ESS_MAESTRO3, 20, 500 },
   93         { 0, 0, 0, 0, 0 }
   94 };
   95 
   96 struct audio_device esa_device = {
   97         "ESS Allegro",
   98         "",
   99         "esa"
  100 };
  101 
  102 int             esa_match(struct device *, void *, void *);
  103 void            esa_attach(struct device *, struct device *, void *);
  104 int             esa_detach(struct device *, int);
  105 
  106 /* audio(9) functions */
  107 int             esa_open(void *, int);
  108 void            esa_close(void *);
  109 int             esa_query_encoding(void *, struct audio_encoding *);
  110 int             esa_set_params(void *, int, int, struct audio_params *,
  111                                struct audio_params *);
  112 int             esa_round_blocksize(void *, int);
  113 int             esa_commit_settings(void *);
  114 int             esa_halt_output(void *);
  115 int             esa_halt_input(void *);
  116 int             esa_set_port(void *, mixer_ctrl_t *);
  117 int             esa_get_port(void *, mixer_ctrl_t *);
  118 int             esa_query_devinfo(void *, mixer_devinfo_t *);
  119 void *          esa_malloc(void *, int, size_t, int, int);
  120 void            esa_free(void *, void *, int);
  121 int             esa_getdev(void *, struct audio_device *);
  122 size_t          esa_round_buffersize(void *, int, size_t);
  123 int             esa_get_props(void *);
  124 int             esa_trigger_output(void *, void *, void *, int,
  125                                    void (*)(void *), void *,
  126                                    struct audio_params *);
  127 int             esa_trigger_input(void *, void *, void *, int,
  128                                   void (*)(void *), void *,
  129                                   struct audio_params *);
  130 
  131 int             esa_intr(void *);
  132 int             esa_allocmem(struct esa_softc *, size_t, size_t,
  133                              struct esa_dma *);
  134 int             esa_freemem(struct esa_softc *, struct esa_dma *);
  135 paddr_t         esa_mappage(void *addr, void *mem, off_t off, int prot);
  136 
  137 /* Supporting subroutines */
  138 u_int16_t       esa_read_assp(struct esa_softc *, u_int16_t, u_int16_t);
  139 void            esa_write_assp(struct esa_softc *, u_int16_t, u_int16_t,
  140                                u_int16_t);
  141 int             esa_init_codec(struct esa_softc *);
  142 int             esa_attach_codec(void *, struct ac97_codec_if *);
  143 int             esa_read_codec(void *, u_int8_t, u_int16_t *);
  144 int             esa_write_codec(void *, u_int8_t, u_int16_t);
  145 void            esa_reset_codec(void *);
  146 enum ac97_host_flags    esa_flags_codec(void *);
  147 int             esa_wait(struct esa_softc *);
  148 int             esa_init(struct esa_softc *);
  149 void            esa_config(struct esa_softc *);
  150 u_int8_t        esa_assp_halt(struct esa_softc *);
  151 void            esa_codec_reset(struct esa_softc *);
  152 int             esa_amp_enable(struct esa_softc *);
  153 void            esa_enable_interrupts(struct esa_softc *);
  154 u_int32_t       esa_get_pointer(struct esa_softc *, struct esa_channel *);
  155 
  156 /* list management */
  157 int             esa_add_list(struct esa_voice *, struct esa_list *, u_int16_t,
  158                              int);
  159 void            esa_remove_list(struct esa_voice *, struct esa_list *, int);
  160 
  161 /* power management */
  162 int             esa_power(struct esa_softc *, int);
  163 void            esa_powerhook(int, void *);
  164 int             esa_suspend(struct esa_softc *);
  165 int             esa_resume(struct esa_softc *);
  166 
  167 static audio_encoding_t esa_encoding[] = {
  168         { 0, AudioEulinear, AUDIO_ENCODING_ULINEAR, 8, 0 },
  169         { 1, AudioEmulaw, AUDIO_ENCODING_ULAW, 8,
  170                 AUDIO_ENCODINGFLAG_EMULATED },
  171         { 2, AudioEalaw, AUDIO_ENCODING_ALAW, 8, AUDIO_ENCODINGFLAG_EMULATED },
  172         { 3, AudioEslinear, AUDIO_ENCODING_SLINEAR, 8,
  173                 AUDIO_ENCODINGFLAG_EMULATED }, /* XXX: Are you sure? */
  174         { 4, AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 16, 0 },
  175         { 5, AudioEulinear_le, AUDIO_ENCODING_ULINEAR_LE, 16,
  176                 AUDIO_ENCODINGFLAG_EMULATED },
  177         { 6, AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 16,
  178                 AUDIO_ENCODINGFLAG_EMULATED },
  179         { 7, AudioEulinear_be, AUDIO_ENCODING_ULINEAR_BE, 16,
  180                 AUDIO_ENCODINGFLAG_EMULATED }
  181 };
  182 
  183 #define ESA_NENCODINGS 8
  184 
  185 struct audio_hw_if esa_hw_if = {
  186         esa_open,
  187         esa_close,
  188         NULL,                   /* drain */
  189         esa_query_encoding,
  190         esa_set_params,
  191         esa_round_blocksize,
  192         esa_commit_settings,
  193         NULL,                   /* init_output */
  194         NULL,                   /* init_input */
  195         NULL,                   /* start_output */
  196         NULL,                   /* start_input */
  197         esa_halt_output,
  198         esa_halt_input,
  199         NULL,                   /* speaker_ctl */
  200         esa_getdev,
  201         NULL,                   /* getfd */
  202         esa_set_port,
  203         esa_get_port,
  204         esa_query_devinfo,
  205         esa_malloc,
  206         esa_free,
  207         esa_round_buffersize,
  208         esa_mappage,
  209         esa_get_props,
  210         esa_trigger_output,
  211         esa_trigger_input
  212 };
  213 
  214 struct cfdriver esa_cd = {
  215         NULL, "esa", DV_DULL
  216 };
  217 
  218 struct cfattach esa_ca = {
  219         sizeof(struct esa_softc), esa_match, esa_attach,
  220         esa_detach, /*esa_activate*/ NULL
  221 };
  222 
  223 /*
  224  * audio(9) functions
  225  */
  226 
  227 int
  228 esa_open(void *hdl, int flags)
  229 {
  230 
  231         return (0);
  232 }
  233 
  234 void
  235 esa_close(void *hdl)
  236 {
  237 
  238         return;
  239 }
  240 
  241 int
  242 esa_query_encoding(void *hdl, struct audio_encoding *ae)
  243 {
  244 
  245         if (ae->index < 0 || ae->index >= ESA_NENCODINGS)
  246                 return (EINVAL);
  247         *ae = esa_encoding[ae->index];
  248 
  249         return (0);
  250 }
  251 
  252 int
  253 esa_set_params(void *hdl, int setmode, int usemode, struct audio_params *play,
  254                struct audio_params *rec)
  255 {
  256         struct esa_voice *vc = hdl;
  257         //struct esa_softc *sc = (struct esa_softc *)vc->parent;
  258         struct esa_channel *ch;
  259         struct audio_params *p;
  260         int mode;
  261 
  262         for (mode = AUMODE_RECORD; mode != -1;
  263              mode = (mode == AUMODE_RECORD) ? AUMODE_PLAY : -1) {
  264                 if ((setmode & mode) == 0)
  265                         continue;
  266 
  267                 switch (mode) {
  268                 case AUMODE_PLAY:
  269                         p = play;
  270                         ch = &vc->play;
  271                         break;
  272                 case AUMODE_RECORD:
  273                         p = rec;
  274                         ch = &vc->rec;
  275                         break;
  276                 }
  277 
  278                 if (p->sample_rate < ESA_MINRATE ||
  279                     p->sample_rate > ESA_MAXRATE ||
  280                     (p->precision != 8 && p->precision != 16) ||
  281                     (p->channels < 1 || p->channels > 2))
  282                         return (EINVAL);
  283 
  284                 p->factor = 1;
  285                 p->sw_code = 0;
  286 
  287                 switch(p->encoding) {
  288                 case AUDIO_ENCODING_SLINEAR_BE:
  289                         if (p->precision == 16)
  290                                 p->sw_code = swap_bytes;
  291                         else
  292                                 p->sw_code = change_sign8;
  293                         break;
  294                 case AUDIO_ENCODING_SLINEAR_LE:
  295                         if (p->precision != 16)
  296                                 p->sw_code = change_sign8;
  297                         break;
  298                 case AUDIO_ENCODING_ULINEAR_BE:
  299                         if (p->precision == 16) {
  300                                 if (mode == AUMODE_PLAY)
  301                                         p->sw_code =
  302                                             swap_bytes_change_sign16_le;
  303                                 else
  304                                         p->sw_code =
  305                                             change_sign16_swap_bytes_le;
  306                         }
  307                         break;
  308                 case AUDIO_ENCODING_ULINEAR_LE:
  309                         if (p->precision == 16)
  310                                 p->sw_code = change_sign16_le;
  311                         break;
  312                 case AUDIO_ENCODING_ULAW:
  313                         if (mode == AUMODE_PLAY) {
  314                                 p->factor = 2;
  315                                 p->sw_code = mulaw_to_slinear16_le;
  316                         } else
  317                                 p->sw_code = ulinear8_to_mulaw;
  318                         break;
  319                 case AUDIO_ENCODING_ALAW:
  320                         if (mode == AUMODE_PLAY) {
  321                                 p->factor = 2;
  322                                 p->sw_code = alaw_to_slinear16_le;
  323                         } else
  324                                 p->sw_code = ulinear8_to_alaw;
  325                         break;
  326                 default:
  327                         return (EINVAL);
  328                 }
  329 
  330                 ch->mode = *p;
  331         }
  332 
  333         return (0);
  334 }
  335 
  336 int
  337 esa_commit_settings(void *hdl)
  338 {
  339         struct esa_voice *vc = hdl;
  340         struct esa_softc *sc = (struct esa_softc *)vc->parent;
  341         struct audio_params *p = &vc->play.mode;
  342         struct audio_params *r = &vc->rec.mode;
  343         u_int32_t data;
  344         u_int32_t freq;
  345         int data_bytes = (((ESA_MINISRC_TMP_BUFFER_SIZE & ~1) +
  346                            (ESA_MINISRC_IN_BUFFER_SIZE & ~1) +
  347                            (ESA_MINISRC_OUT_BUFFER_SIZE & ~1) + 4) + 255)
  348                            &~ 255;
  349 
  350         /* playback */
  351         vc->play.data_offset = ESA_DAC_DATA + (data_bytes * vc->index);
  352         if (p->channels == 1)
  353                 data = 1;
  354         else
  355                 data = 0;
  356         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
  357                        vc->play.data_offset + ESA_SRC3_MODE_OFFSET,
  358                        data);
  359         if (p->precision * p->factor == 8)
  360                 data = 1;
  361         else
  362                 data = 0;
  363         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
  364                        vc->play.data_offset + ESA_SRC3_WORD_LENGTH_OFFSET,
  365                        data);
  366         if ((freq = ((p->sample_rate << 15) + 24000) / 48000) != 0) {
  367                 freq--;
  368         }
  369         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
  370                        vc->play.data_offset + ESA_CDATA_FREQUENCY, freq);
  371 
  372         /* recording */
  373         vc->rec.data_offset = ESA_DAC_DATA + (data_bytes * vc->index) +
  374                               (data_bytes / 2);
  375         if (r->channels == 1)
  376                 data = 1;
  377         else
  378                 data = 0;
  379         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
  380                        vc->rec.data_offset + ESA_SRC3_MODE_OFFSET,
  381                        data);
  382         if (r->precision * r->factor == 8)
  383                 data = 1;
  384         else
  385                 data = 0;
  386         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
  387                        vc->rec.data_offset + ESA_SRC3_WORD_LENGTH_OFFSET,
  388                        data);
  389         if ((freq = ((r->sample_rate << 15) + 24000) / 48000) != 0) {
  390                 freq--;
  391         }
  392         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
  393                        vc->rec.data_offset + ESA_CDATA_FREQUENCY, freq);
  394 
  395         return (0);
  396 };
  397 
  398 int
  399 esa_round_blocksize(void *hdl, int bs)
  400 {
  401         struct esa_voice *vc = hdl;
  402 
  403         /*
  404          * Surely there has to be a better solution...
  405          */
  406         vc->play.blksize = vc->rec.blksize = 4096;
  407 
  408         return (vc->play.blksize);
  409 }
  410 
  411 int
  412 esa_halt_output(void *hdl)
  413 {
  414         struct esa_voice *vc = hdl;
  415         struct esa_softc *sc = (struct esa_softc *)vc->parent;
  416         bus_space_tag_t iot = sc->sc_iot;
  417         bus_space_handle_t ioh = sc->sc_ioh;
  418         u_int16_t data;
  419 
  420         if (vc->play.active == 0)
  421                 return (0);
  422 
  423         vc->play.active = 0;
  424 
  425         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
  426                        ESA_CDATA_INSTANCE_READY + vc->play.data_offset, 0);
  427 
  428         sc->sc_ntimers--;
  429         if (sc->sc_ntimers == 0) {
  430                 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
  431                                ESA_KDATA_TIMER_COUNT_RELOAD, 0);
  432                 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
  433                                ESA_KDATA_TIMER_COUNT_CURRENT, 0);
  434                 data = bus_space_read_2(iot, ioh, ESA_HOST_INT_CTRL);
  435                 bus_space_write_2(iot, ioh, ESA_HOST_INT_CTRL,
  436                     data & ~ESA_CLKRUN_GEN_ENABLE);
  437         }
  438 
  439         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
  440                        ESA_KDATA_MIXER_TASK_NUMBER,
  441                        sc->mixer_list.indexmap[vc->index]);
  442         /* remove ourselves from the packed lists */
  443         esa_remove_list(vc, &sc->mixer_list, vc->index);
  444         esa_remove_list(vc, &sc->dma_list, vc->index);
  445         esa_remove_list(vc, &sc->msrc_list, vc->index);
  446 
  447         return (0);
  448 }
  449 
  450 int
  451 esa_halt_input(void *hdl)
  452 {
  453         struct esa_voice *vc = hdl;
  454         struct esa_softc *sc = (struct esa_softc *)vc->parent;
  455         bus_space_tag_t iot = sc->sc_iot;
  456         bus_space_handle_t ioh = sc->sc_ioh;
  457         u_int32_t data;
  458 
  459         if (vc->rec.active == 0)
  460                 return (0);
  461 
  462         vc->rec.active = 0;
  463 
  464         sc->sc_ntimers--;
  465         if (sc->sc_ntimers == 0) {
  466                 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
  467                                ESA_KDATA_TIMER_COUNT_RELOAD, 0);
  468                 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
  469                                ESA_KDATA_TIMER_COUNT_CURRENT, 0);
  470                 data = bus_space_read_2(iot, ioh, ESA_HOST_INT_CTRL);
  471                 bus_space_write_2(iot, ioh, ESA_HOST_INT_CTRL,
  472                                   data & ~ESA_CLKRUN_GEN_ENABLE);
  473         }
  474 
  475         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, vc->rec.data_offset +
  476                        ESA_CDATA_INSTANCE_READY, 0);
  477         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_ADC1_REQUEST,
  478                        0);
  479 
  480         /* remove ourselves from the packed lists */
  481         esa_remove_list(vc, &sc->adc1_list, vc->index + ESA_NUM_VOICES);
  482         esa_remove_list(vc, &sc->dma_list, vc->index + ESA_NUM_VOICES);
  483         esa_remove_list(vc, &sc->msrc_list, vc->index + ESA_NUM_VOICES);
  484 
  485         return (0);
  486 }
  487 
  488 void *
  489 esa_malloc(void *hdl, int direction, size_t size, int type, int flags)
  490 {
  491         struct esa_voice *vc = hdl;
  492         struct esa_softc *sc = (struct esa_softc *)vc->parent;
  493         struct esa_dma *p;
  494         int error;
  495 
  496         p = malloc(sizeof(*p), type, flags);
  497         if (!p)
  498                 return (0);
  499         error = esa_allocmem(sc, size, 16, p);
  500         if (error) {
  501                 free(p, type);
  502                 printf("%s: esa_malloc: not enough memory\n",
  503                     sc->sc_dev.dv_xname);
  504                 return (0);
  505         }
  506         p->next = vc->dma;
  507         vc->dma = p;
  508 
  509         return (KERNADDR(p));
  510 }
  511 
  512 void
  513 esa_free(void *hdl, void *addr, int type)
  514 {
  515         struct esa_voice *vc = hdl;
  516         struct esa_softc *sc = (struct esa_softc *)vc->parent;
  517         struct esa_dma *p;
  518         struct esa_dma **pp;
  519 
  520         for (pp = &vc->dma; (p = *pp) != NULL; pp = &p->next)
  521                 if (KERNADDR(p) == addr) {
  522                         esa_freemem(sc, p);
  523                         *pp = p->next;
  524                         free(p, type);
  525                         return;
  526                 }
  527 }
  528 
  529 int
  530 esa_getdev(void *hdl, struct audio_device *ret)
  531 {
  532 
  533         *ret = esa_device;
  534 
  535         return (0);
  536 }
  537 
  538 int
  539 esa_set_port(void *hdl, mixer_ctrl_t *mc)
  540 {
  541         struct esa_voice *vc = hdl;
  542         struct esa_softc *sc = (struct esa_softc *)vc->parent;
  543 
  544         return (sc->codec_if->vtbl->mixer_set_port(sc->codec_if, mc));
  545 }
  546 
  547 int
  548 esa_get_port(void *hdl, mixer_ctrl_t *mc)
  549 {
  550         struct esa_voice *vc = hdl;
  551         struct esa_softc *sc = (struct esa_softc *)vc->parent;
  552 
  553         return (sc->codec_if->vtbl->mixer_get_port(sc->codec_if, mc));
  554 }
  555 
  556 int
  557 esa_query_devinfo(void *hdl, mixer_devinfo_t *di)
  558 {
  559         struct esa_voice *vc = hdl;
  560         struct esa_softc *sc = (struct esa_softc *)vc->parent;
  561 
  562         return (sc->codec_if->vtbl->query_devinfo(sc->codec_if, di));
  563 }
  564 
  565 size_t
  566 esa_round_buffersize(void *hdl, int direction, size_t bufsize)
  567 {
  568         struct esa_voice *vc = hdl;
  569 
  570         /*
  571          * We must be able to do better than this...
  572          */
  573         vc->play.bufsize = vc->rec.bufsize = 65536;
  574 
  575         return (vc->play.bufsize);
  576 }
  577 
  578 int
  579 esa_get_props(void *hdl)
  580 {
  581 
  582         return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX);
  583 }
  584 
  585 int
  586 esa_trigger_output(void *hdl, void *start, void *end, int blksize,
  587                         void (*intr)(void *), void *intrarg,
  588                         struct audio_params *param)
  589 {
  590         struct esa_voice *vc = hdl;
  591         struct esa_softc *sc = (struct esa_softc *)vc->parent;
  592         struct esa_dma *p;
  593         bus_space_tag_t iot = sc->sc_iot;
  594         bus_space_handle_t ioh = sc->sc_ioh;
  595         u_int32_t data;
  596         u_int32_t bufaddr;
  597         u_int32_t i;
  598         size_t size;
  599 
  600         int data_bytes = (((ESA_MINISRC_TMP_BUFFER_SIZE & ~1) +
  601                            (ESA_MINISRC_IN_BUFFER_SIZE & ~1) +
  602                            (ESA_MINISRC_OUT_BUFFER_SIZE & ~1) + 4) + 255)
  603                            &~ 255;
  604         int dac_data = ESA_DAC_DATA + (data_bytes * vc->index);
  605         int dsp_in_size = ESA_MINISRC_IN_BUFFER_SIZE - (0x20 * 2);
  606         int dsp_out_size = ESA_MINISRC_OUT_BUFFER_SIZE - (0x20 * 2);
  607         int dsp_in_buf = dac_data + (ESA_MINISRC_TMP_BUFFER_SIZE / 2);
  608         int dsp_out_buf = dsp_in_buf + (dsp_in_size / 2) + 1;
  609 
  610         if (vc->play.active)
  611                 return (EINVAL);
  612 
  613         for (p = vc->dma; p && KERNADDR(p) != start; p = p->next)
  614                 ;
  615         if (!p) {
  616                 printf("%s: esa_trigger_output: bad addr %p\n",
  617                     sc->sc_dev.dv_xname, start);
  618                 return (EINVAL);
  619         }
  620 
  621         vc->play.active = 1;
  622         vc->play.intr = intr;
  623         vc->play.arg = intrarg;
  624         vc->play.pos = 0;
  625         vc->play.count = 0;
  626         vc->play.buf = start;
  627         size = (size_t)(((caddr_t)end - (caddr_t)start));
  628         bufaddr = DMAADDR(p);
  629         vc->play.start = bufaddr;
  630 
  631 #define LO(x) ((x) & 0x0000ffff)
  632 #define HI(x) ((x) >> 16)
  633 
  634         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
  635             ESA_CDATA_HOST_SRC_ADDRL, LO(bufaddr));
  636         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
  637             ESA_CDATA_HOST_SRC_ADDRH, HI(bufaddr));
  638         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
  639             ESA_CDATA_HOST_SRC_END_PLUS_1L, LO(bufaddr + size));
  640         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
  641             ESA_CDATA_HOST_SRC_END_PLUS_1H, HI(bufaddr + size));
  642         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
  643             ESA_CDATA_HOST_SRC_CURRENTL, LO(bufaddr));
  644         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
  645             ESA_CDATA_HOST_SRC_CURRENTH, HI(bufaddr));
  646 
  647         /* DSP buffers */
  648         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
  649             ESA_CDATA_IN_BUF_BEGIN, dsp_in_buf);
  650         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
  651             ESA_CDATA_IN_BUF_END_PLUS_1, dsp_in_buf + (dsp_in_size / 2));
  652         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
  653             ESA_CDATA_IN_BUF_HEAD, dsp_in_buf);
  654         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
  655             ESA_CDATA_IN_BUF_TAIL, dsp_in_buf);
  656         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
  657             ESA_CDATA_OUT_BUF_BEGIN, dsp_out_buf);
  658         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
  659             ESA_CDATA_OUT_BUF_END_PLUS_1, dsp_out_buf + (dsp_out_size / 2));
  660         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
  661             ESA_CDATA_OUT_BUF_HEAD, dsp_out_buf);
  662         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
  663             ESA_CDATA_OUT_BUF_TAIL, dsp_out_buf);
  664 
  665         /* Some per-client initializers */
  666         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
  667             ESA_SRC3_DIRECTION_OFFSET + 12, dac_data + 40 + 8);
  668         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
  669             ESA_SRC3_DIRECTION_OFFSET + 19, 0x400 + ESA_MINISRC_COEF_LOC);
  670         /* Enable or disable low-pass filter? (0xff if rate > 45000) */
  671         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
  672             ESA_SRC3_DIRECTION_OFFSET + 22,
  673             vc->play.mode.sample_rate > 45000 ? 0xff : 0);
  674         /* Tell it which way DMA is going */
  675         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
  676             ESA_CDATA_DMA_CONTROL,
  677             ESA_DMACONTROL_AUTOREPEAT + ESA_DMAC_PAGE3_SELECTOR +
  678             ESA_DMAC_BLOCKF_SELECTOR);
  679 
  680         /* Set an armload of static initializers */
  681         for (i = 0; i < (sizeof(esa_playvals) / sizeof(esa_playvals[0])); i++)
  682                 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
  683                     esa_playvals[i].addr, esa_playvals[i].val);
  684 
  685         /* Put us in the packed task lists */
  686         esa_add_list(vc, &sc->msrc_list, dac_data >> ESA_DP_SHIFT_COUNT,
  687                      vc->index);
  688         esa_add_list(vc, &sc->dma_list, dac_data >> ESA_DP_SHIFT_COUNT,
  689                      vc->index);
  690         esa_add_list(vc, &sc->mixer_list, dac_data >> ESA_DP_SHIFT_COUNT,
  691                      vc->index);
  692 #undef LO
  693 #undef HI
  694 
  695         /* XXX */
  696         //esa_commit_settings(vc);
  697 
  698         sc->sc_ntimers++;
  699 
  700         if (sc->sc_ntimers == 1) {
  701                 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
  702                     ESA_KDATA_TIMER_COUNT_RELOAD, 240);
  703                 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
  704                     ESA_KDATA_TIMER_COUNT_CURRENT, 240);
  705                 data = bus_space_read_2(iot, ioh, ESA_HOST_INT_CTRL);
  706                 bus_space_write_2(iot, ioh, ESA_HOST_INT_CTRL,
  707                     data | ESA_CLKRUN_GEN_ENABLE);
  708         }
  709 
  710         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, dac_data +
  711             ESA_CDATA_INSTANCE_READY, 1);
  712         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
  713             ESA_KDATA_MIXER_TASK_NUMBER,
  714             sc->mixer_list.indexmap[vc->index]);
  715 
  716         return (0);
  717 }
  718 
  719 int
  720 esa_trigger_input(void *hdl, void *start, void *end, int blksize,
  721                         void (*intr)(void *), void *intrarg,
  722                         struct audio_params *param)
  723 {
  724         struct esa_voice *vc = hdl;
  725         struct esa_softc *sc = (struct esa_softc *)vc->parent;
  726         struct esa_dma *p;
  727         bus_space_tag_t iot = sc->sc_iot;
  728         bus_space_handle_t ioh = sc->sc_ioh;
  729         u_int32_t data;
  730         u_int32_t bufaddr;
  731         u_int32_t i;
  732         size_t size;
  733         int data_bytes = (((ESA_MINISRC_TMP_BUFFER_SIZE & ~1) +
  734                            (ESA_MINISRC_IN_BUFFER_SIZE & ~1) +
  735                            (ESA_MINISRC_OUT_BUFFER_SIZE & ~1) + 4) + 255)
  736                            &~ 255;
  737         int adc_data = ESA_DAC_DATA + (data_bytes * vc->index) +
  738                        (data_bytes / 2);
  739         int dsp_in_size = ESA_MINISRC_IN_BUFFER_SIZE - (0x10 * 2);
  740         int dsp_out_size = ESA_MINISRC_OUT_BUFFER_SIZE - (0x10 * 2);
  741         int dsp_in_buf = adc_data + (ESA_MINISRC_TMP_BUFFER_SIZE / 2);
  742         int dsp_out_buf = dsp_in_buf + (dsp_in_size / 2) + 1;
  743         vc->rec.data_offset = adc_data;
  744 
  745         /* We only support 1 recording channel */
  746         if (vc->index > 0)
  747                 return (ENODEV);
  748 
  749         if (vc->rec.active)
  750                 return (EINVAL);
  751 
  752         for (p = vc->dma; p && KERNADDR(p) != start; p = p->next)
  753                 ;
  754         if (!p) {
  755                 printf("%s: esa_trigger_input: bad addr %p\n",
  756                     sc->sc_dev.dv_xname, start);
  757                 return (EINVAL);
  758         }
  759 
  760         vc->rec.active = 1;
  761         vc->rec.intr = intr;
  762         vc->rec.arg = intrarg;
  763         vc->rec.pos = 0;
  764         vc->rec.count = 0;
  765         vc->rec.buf = start;
  766         size = (size_t)(((caddr_t)end - (caddr_t)start));
  767         bufaddr = DMAADDR(p);
  768         vc->rec.start = bufaddr;
  769 
  770 #define LO(x) ((x) & 0x0000ffff)
  771 #define HI(x) ((x) >> 16)
  772 
  773         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
  774             ESA_CDATA_HOST_SRC_ADDRL, LO(bufaddr));
  775         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
  776             ESA_CDATA_HOST_SRC_ADDRH, HI(bufaddr));
  777         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
  778             ESA_CDATA_HOST_SRC_END_PLUS_1L, LO(bufaddr + size));
  779         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
  780             ESA_CDATA_HOST_SRC_END_PLUS_1H, HI(bufaddr + size));
  781         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
  782             ESA_CDATA_HOST_SRC_CURRENTL, LO(bufaddr));
  783         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
  784             ESA_CDATA_HOST_SRC_CURRENTH, HI(bufaddr));
  785 
  786         /* DSP buffers */
  787         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
  788             ESA_CDATA_IN_BUF_BEGIN, dsp_in_buf);
  789         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
  790             ESA_CDATA_IN_BUF_END_PLUS_1, dsp_in_buf + (dsp_in_size / 2));
  791         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
  792             ESA_CDATA_IN_BUF_HEAD, dsp_in_buf);
  793         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
  794             ESA_CDATA_IN_BUF_TAIL, dsp_in_buf);
  795         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
  796             ESA_CDATA_OUT_BUF_BEGIN, dsp_out_buf);
  797         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
  798             ESA_CDATA_OUT_BUF_END_PLUS_1, dsp_out_buf + (dsp_out_size / 2));
  799         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
  800             ESA_CDATA_OUT_BUF_HEAD, dsp_out_buf);
  801         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
  802             ESA_CDATA_OUT_BUF_TAIL, dsp_out_buf);
  803 
  804         /* Some per-client initializers */
  805         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
  806             ESA_SRC3_DIRECTION_OFFSET + 12, adc_data + 40 + 8);
  807         /* Tell it which way DMA is going */
  808         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
  809             ESA_CDATA_DMA_CONTROL,
  810             ESA_DMACONTROL_DIRECTION + ESA_DMACONTROL_AUTOREPEAT +
  811             ESA_DMAC_PAGE3_SELECTOR + ESA_DMAC_BLOCKF_SELECTOR);
  812 
  813         /* Set an armload of static initializers */
  814         for (i = 0; i < (sizeof(esa_recvals) / sizeof(esa_recvals[0])); i++)
  815                 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
  816                     esa_recvals[i].addr, esa_recvals[i].val);
  817 
  818         /* Put us in the packed task lists */
  819         esa_add_list(vc, &sc->adc1_list, adc_data >> ESA_DP_SHIFT_COUNT,
  820                      vc->index + ESA_NUM_VOICES);
  821         esa_add_list(vc, &sc->msrc_list, adc_data >> ESA_DP_SHIFT_COUNT,
  822                      vc->index + ESA_NUM_VOICES);
  823         esa_add_list(vc, &sc->dma_list, adc_data >> ESA_DP_SHIFT_COUNT,
  824                      vc->index + ESA_NUM_VOICES);
  825 #undef LO
  826 #undef HI
  827 
  828         /* XXX */
  829         //esa_commit_settings(vc);
  830 
  831         sc->sc_ntimers++;
  832         if (sc->sc_ntimers == 1) {
  833                 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
  834                     ESA_KDATA_TIMER_COUNT_RELOAD, 240);
  835                 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
  836                     ESA_KDATA_TIMER_COUNT_CURRENT, 240);
  837                 data = bus_space_read_2(iot, ioh, ESA_HOST_INT_CTRL);
  838                 bus_space_write_2(iot, ioh, ESA_HOST_INT_CTRL,
  839                     data | ESA_CLKRUN_GEN_ENABLE);
  840         }
  841 
  842         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, adc_data +
  843             ESA_CDATA_INSTANCE_READY, 1);
  844         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_ADC1_REQUEST,
  845             1);
  846 
  847         return (0);
  848 }
  849 
  850 /* Interrupt handler */
  851 
  852 int
  853 esa_intr(void *hdl)
  854 {
  855         struct esa_softc *sc = hdl;
  856         struct esa_voice *vc;
  857         bus_space_tag_t iot = sc->sc_iot;
  858         bus_space_handle_t ioh = sc->sc_ioh;
  859         u_int8_t status, ctl;
  860         u_int32_t pos;
  861         u_int32_t diff;
  862         u_int32_t play_blksize, play_bufsize;
  863         u_int32_t rec_blksize, rec_bufsize;
  864         int i;
  865 
  866         status = bus_space_read_1(iot, ioh, ESA_HOST_INT_STATUS);
  867         if (status == 0xff)
  868                 return (0);
  869 
  870         /* ack the interrupt */
  871         bus_space_write_1(iot, ioh, ESA_HOST_INT_STATUS, status);
  872 
  873         if (status & ESA_HV_INT_PENDING) {
  874                 u_int8_t event;
  875 
  876                 printf("%s: hardware volume interrupt\n", sc->sc_dev.dv_xname);
  877                 event = bus_space_read_1(iot, ioh, ESA_HW_VOL_COUNTER_MASTER);
  878                 switch(event) {
  879                 case 0x99:
  880                 case 0xaa:
  881                 case 0x66:
  882                 case 0x88:
  883                         printf("%s: esa_intr: FIXME\n", sc->sc_dev.dv_xname);
  884                         break;
  885                 default:
  886                         printf("%s: unknown hwvol event 0x%02x\n",
  887                             sc->sc_dev.dv_xname, event);
  888                         break;
  889                 }
  890                 bus_space_write_1(iot, ioh, ESA_HW_VOL_COUNTER_MASTER, 0x88);
  891         }
  892 
  893         if (status & ESA_ASSP_INT_PENDING) {
  894                 ctl = bus_space_read_1(iot, ioh, ESA_ASSP_CONTROL_B);
  895                 if (!(ctl & ESA_STOP_ASSP_CLOCK)) {
  896                         ctl = bus_space_read_1(iot, ioh,
  897                                                ESA_ASSP_HOST_INT_STATUS);
  898                         if (ctl & ESA_DSP2HOST_REQ_TIMER) {
  899                                 bus_space_write_1(iot, ioh,
  900                                     ESA_ASSP_HOST_INT_STATUS,
  901                                     ESA_DSP2HOST_REQ_TIMER);
  902                                 for (i = 0; i < ESA_NUM_VOICES; i++) {
  903                                         vc = &sc->voice[i];
  904                                         if (vc->play.active) {
  905                                                 play_blksize = vc->play.blksize;
  906                                                 play_bufsize = vc->play.bufsize;
  907                                                 pos = esa_get_pointer(sc, &vc->play)
  908                                                     % play_bufsize;
  909                                                 diff = (play_bufsize + pos - vc->play.pos)
  910                                                     % play_bufsize;
  911                                                 vc->play.pos = pos;
  912                                                 vc->play.count += diff;
  913                                                 while(vc->play.count >= play_blksize) {
  914                                                         vc->play.count -= play_blksize;
  915                                                         (*vc->play.intr)(vc->play.arg);
  916                                                 }
  917                                         }
  918                                         if (vc->rec.active) {
  919                                                 rec_blksize = vc->rec.blksize;
  920                                                 rec_bufsize = vc->rec.bufsize;
  921                                                 pos = esa_get_pointer(sc, &vc->rec)
  922                                                     % rec_bufsize;
  923                                                 diff = (rec_bufsize + pos - vc->rec.pos)
  924                                                     % rec_bufsize;
  925                                                 vc->rec.pos = pos;
  926                                                 vc->rec.count += diff;
  927                                                 while(vc->rec.count >= rec_blksize) {
  928                                                         vc->rec.count -= rec_blksize;
  929                                                         (*vc->rec.intr)(vc->rec.arg);
  930                                                 }
  931                                         }
  932                                 }
  933                         }
  934                 }
  935         }
  936 
  937         return (1);
  938 }
  939 
  940 int
  941 esa_allocmem(struct esa_softc *sc, size_t size, size_t align,
  942                 struct esa_dma *p)
  943 {
  944         int error;
  945 
  946         p->size = size;
  947         error = bus_dmamem_alloc(sc->sc_dmat, p->size, align, 0,
  948                                  p->segs, sizeof(p->segs) / sizeof(p->segs[0]),
  949                                  &p->nsegs, BUS_DMA_NOWAIT);
  950         if (error)
  951                 return (error);
  952 
  953         error = bus_dmamem_map(sc->sc_dmat, p->segs, p->nsegs, p->size,
  954                                 &p->addr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
  955         if (error)
  956                 goto free;
  957 
  958         error = bus_dmamap_create(sc->sc_dmat, p->size, 1, p->size, 0,
  959                                   BUS_DMA_NOWAIT, &p->map);
  960         if (error)
  961                 goto unmap;
  962 
  963         error = bus_dmamap_load(sc->sc_dmat, p->map, p->addr, p->size, NULL,
  964                                 BUS_DMA_NOWAIT);
  965         if (error)
  966                 goto destroy;
  967 
  968         return (0);
  969 
  970 destroy:
  971         bus_dmamap_destroy(sc->sc_dmat, p->map);
  972 unmap:
  973         bus_dmamem_unmap(sc->sc_dmat, p->addr, p->size);
  974 free:
  975         bus_dmamem_free(sc->sc_dmat, p->segs, p->nsegs);
  976 
  977         return (error);
  978 }
  979 
  980 int
  981 esa_freemem(struct esa_softc *sc, struct esa_dma *p)
  982 {
  983 
  984         bus_dmamap_unload(sc->sc_dmat, p->map);
  985         bus_dmamap_destroy(sc->sc_dmat, p->map);
  986         bus_dmamem_unmap(sc->sc_dmat, p->addr, p->size);
  987         bus_dmamem_free(sc->sc_dmat, p->segs, p->nsegs);
  988 
  989         return (0);
  990 }
  991 
  992 /*
  993  * Supporting Subroutines
  994  */
  995 const struct pci_matchid esa_devices[] = {
  996         { PCI_VENDOR_ESSTECH, PCI_PRODUCT_ESSTECH_ES1989 },
  997         { PCI_VENDOR_ESSTECH, PCI_PRODUCT_ESSTECH_MAESTRO3 },
  998         { PCI_VENDOR_ESSTECH, PCI_PRODUCT_ESSTECH_MAESTRO3_2 },
  999 };
 1000 
 1001 int
 1002 esa_match(struct device *dev, void *match, void *aux)
 1003 {
 1004         return (pci_matchbyid((struct pci_attach_args *)aux, esa_devices,
 1005             sizeof(esa_devices)/sizeof(esa_devices[0])));
 1006 }
 1007 
 1008 void
 1009 esa_attach(struct device *parent, struct device *self, void *aux)
 1010 {
 1011         struct esa_softc *sc = (struct esa_softc *)self;
 1012         struct pci_attach_args *pa = (struct pci_attach_args *)aux;
 1013         pcitag_t tag = pa->pa_tag;
 1014         pci_chipset_tag_t pc = pa->pa_pc;
 1015         pci_intr_handle_t ih;
 1016         struct esa_card_type *card;
 1017         const char *intrstr;
 1018         int i, len;
 1019 
 1020         for (card = esa_card_types; card->pci_vendor_id; card++)
 1021                 if (PCI_VENDOR(pa->pa_id) == card->pci_vendor_id &&
 1022                     PCI_PRODUCT(pa->pa_id) == card->pci_product_id) {
 1023                         sc->type = card->type;
 1024                         sc->delay1 = card->delay1;
 1025                         sc->delay2 = card->delay2;
 1026                         break;
 1027                 }
 1028 
 1029         /* Map I/O register */
 1030         if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0,
 1031             &sc->sc_iot, &sc->sc_ioh, &sc->sc_iob, &sc->sc_ios, 0)) {
 1032                 printf(": can't map i/o space\n");
 1033                 return;
 1034         }
 1035 
 1036         /* Initialize softc */
 1037         sc->sc_tag = tag;
 1038         sc->sc_pct = pc;
 1039         sc->sc_dmat = pa->pa_dmat;
 1040 
 1041         /* Map and establish an interrupt */
 1042         if (pci_intr_map(pa, &ih)) {
 1043                 printf(": can't map interrupt\n");
 1044                 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
 1045                 return;
 1046         }
 1047         intrstr = pci_intr_string(pc, ih);
 1048         sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO, esa_intr, self,
 1049             sc->sc_dev.dv_xname);
 1050         if (sc->sc_ih == NULL) {
 1051                 printf(": can't establish interrupt");
 1052                 if (intrstr != NULL)
 1053                         printf(" at %s", intrstr);
 1054                 printf("\n");
 1055                 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
 1056                 return;
 1057         }
 1058         printf(": %s\n", intrstr);
 1059 
 1060         /* Power up chip */
 1061         esa_power(sc, PCI_PMCSR_STATE_D0);
 1062 
 1063         /* Init chip */
 1064         if (esa_init(sc) == -1) {
 1065                 printf("%s: esa_attach: unable to initialize the card\n",
 1066                     sc->sc_dev.dv_xname);
 1067                 pci_intr_disestablish(pc, sc->sc_ih);
 1068                 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
 1069                 return;
 1070         }
 1071 
 1072         /* create suspend save area */
 1073         len = sizeof(u_int16_t) * (ESA_REV_B_CODE_MEMORY_LENGTH
 1074             + ESA_REV_B_DATA_MEMORY_LENGTH + 1);
 1075         sc->savemem = (u_int16_t *)malloc(len, M_DEVBUF, M_NOWAIT);
 1076         if (sc->savemem == NULL) {
 1077                 printf("%s: unable to allocate suspend buffer\n",
 1078                     sc->sc_dev.dv_xname);
 1079                 pci_intr_disestablish(pc, sc->sc_ih);
 1080                 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
 1081                 return;
 1082         }
 1083         bzero(sc->savemem, len);
 1084 
 1085         /*
 1086          * Every card I've seen has had their channels swapped with respect
 1087          * to the mixer. Ie:
 1088          *  $ mixerctl -w outputs.master=0,191
 1089          * Would result in the _right_ speaker being turned off.
 1090          *
 1091          * So, we will swap the left and right mixer channels to compensate
 1092          * for this.
 1093          */
 1094         sc->codec_flags |= AC97_HOST_SWAPPED_CHANNELS;
 1095         sc->codec_flags |= AC97_HOST_DONT_READ;
 1096 
 1097         /* Attach AC97 host interface */
 1098         sc->host_if.arg = self;
 1099         sc->host_if.attach = esa_attach_codec;
 1100         sc->host_if.read = esa_read_codec;
 1101         sc->host_if.write = esa_write_codec;
 1102         sc->host_if.reset = esa_reset_codec;
 1103         sc->host_if.flags = esa_flags_codec;
 1104 
 1105         if (ac97_attach(&sc->host_if) != 0) {
 1106                 pci_intr_disestablish(pc, sc->sc_ih);
 1107                 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
 1108                 free(sc->savemem, M_DEVBUF);
 1109                 return;
 1110         }
 1111 
 1112         /* initialize list management structures */
 1113         sc->mixer_list.mem_addr = ESA_KDATA_MIXER_XFER0;
 1114         sc->mixer_list.max = ESA_MAX_VIRTUAL_MIXER_CHANNELS;
 1115         sc->adc1_list.mem_addr = ESA_KDATA_ADC1_XFER0;
 1116         sc->adc1_list.max = ESA_MAX_VIRTUAL_ADC1_CHANNELS;
 1117         sc->dma_list.mem_addr = ESA_KDATA_DMA_XFER0;
 1118         sc->dma_list.max = ESA_MAX_VIRTUAL_DMA_CHANNELS;
 1119         sc->msrc_list.mem_addr = ESA_KDATA_INSTANCE0_MINISRC;
 1120         sc->msrc_list.max = ESA_MAX_INSTANCE_MINISRC;
 1121 
 1122         /* initialize index maps */
 1123         for (i = 0; i < ESA_NUM_VOICES * 2; i++) {
 1124                 sc->mixer_list.indexmap[i] = -1;
 1125                 sc->msrc_list.indexmap[i] = -1;
 1126                 sc->dma_list.indexmap[i] = -1;
 1127                 sc->adc1_list.indexmap[i] = -1;
 1128         }
 1129         for (i = 0; i < ESA_NUM_VOICES; i++) {
 1130                 sc->voice[i].parent = (struct device *)sc;
 1131                 sc->voice[i].index = i;
 1132                 sc->sc_audiodev[i] =
 1133                     audio_attach_mi(&esa_hw_if, &sc->voice[i], &sc->sc_dev);
 1134         }
 1135 
 1136         sc->powerhook = powerhook_establish(esa_powerhook, sc);
 1137         if (sc->powerhook == NULL)
 1138                 printf("%s: WARNING: unable to establish powerhook\n",
 1139                     sc->sc_dev.dv_xname);
 1140 
 1141         return;
 1142 }
 1143 
 1144 int
 1145 esa_detach(struct device *self, int flags)
 1146 {
 1147         struct esa_softc *sc = (struct esa_softc *)self;
 1148         int i;
 1149 
 1150         for (i = 0; i < ESA_NUM_VOICES; i++) {
 1151                 if (sc->sc_audiodev[i] != NULL)
 1152                         config_detach(sc->sc_audiodev[i], flags);
 1153         }
 1154 
 1155         if (sc->sc_ih != NULL)
 1156                 pci_intr_disestablish(sc->sc_pct, sc->sc_ih);
 1157         if (sc->sc_ios)
 1158                 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
 1159 
 1160         free(sc->savemem, M_DEVBUF);
 1161 
 1162         return (0);
 1163 }
 1164 
 1165 u_int16_t
 1166 esa_read_assp(struct esa_softc *sc, u_int16_t region, u_int16_t index)
 1167 {
 1168         u_int16_t data;
 1169         bus_space_tag_t iot = sc->sc_iot;
 1170         bus_space_handle_t ioh = sc->sc_ioh;
 1171 
 1172         bus_space_write_2(iot, ioh, ESA_DSP_PORT_MEMORY_TYPE,
 1173             region & ESA_MEMTYPE_MASK);
 1174         bus_space_write_2(iot, ioh, ESA_DSP_PORT_MEMORY_INDEX, index);
 1175         data = bus_space_read_2(iot, ioh, ESA_DSP_PORT_MEMORY_DATA);
 1176 
 1177         return (data);
 1178 }
 1179 
 1180 void
 1181 esa_write_assp(struct esa_softc *sc, u_int16_t region, u_int16_t index,
 1182                 u_int16_t data)
 1183 {
 1184         bus_space_tag_t iot = sc->sc_iot;
 1185         bus_space_handle_t ioh = sc->sc_ioh;
 1186 
 1187         bus_space_write_2(iot, ioh, ESA_DSP_PORT_MEMORY_TYPE,
 1188             region & ESA_MEMTYPE_MASK);
 1189         bus_space_write_2(iot, ioh, ESA_DSP_PORT_MEMORY_INDEX, index);
 1190         bus_space_write_2(iot, ioh, ESA_DSP_PORT_MEMORY_DATA, data);
 1191 
 1192         return;
 1193 }
 1194 
 1195 int
 1196 esa_init_codec(struct esa_softc *sc)
 1197 {
 1198         bus_space_tag_t iot = sc->sc_iot;
 1199         bus_space_handle_t ioh = sc->sc_ioh;
 1200         u_int32_t data;
 1201 
 1202         data = bus_space_read_1(iot, ioh, ESA_CODEC_COMMAND);
 1203 
 1204         return ((data & 0x1) ? 0 : 1);
 1205 }
 1206 
 1207 int
 1208 esa_attach_codec(void *aux, struct ac97_codec_if *codec_if)
 1209 {
 1210         struct esa_softc *sc = aux;
 1211 
 1212         sc->codec_if = codec_if;
 1213 
 1214         return (0);
 1215 }
 1216 
 1217 int
 1218 esa_read_codec(void *aux, u_int8_t reg, u_int16_t *result)
 1219 {
 1220         struct esa_softc *sc = aux;
 1221         bus_space_tag_t iot = sc->sc_iot;
 1222         bus_space_handle_t ioh = sc->sc_ioh;
 1223 
 1224         if (esa_wait(sc))
 1225                 printf("%s: esa_read_codec: timed out\n", sc->sc_dev.dv_xname);
 1226         bus_space_write_1(iot, ioh, ESA_CODEC_COMMAND, (reg & 0x7f) | 0x80);
 1227         delay(50);
 1228         if (esa_wait(sc))
 1229                 printf("%s: esa_read_codec: timed out\n", sc->sc_dev.dv_xname);
 1230         *result = bus_space_read_2(iot, ioh, ESA_CODEC_DATA);
 1231 
 1232         return (0);
 1233 }
 1234 
 1235 int
 1236 esa_write_codec(void *aux, u_int8_t reg, u_int16_t data)
 1237 {
 1238         struct esa_softc *sc = aux;
 1239         bus_space_tag_t iot = sc->sc_iot;
 1240         bus_space_handle_t ioh = sc->sc_ioh;
 1241 
 1242         if (esa_wait(sc)) {
 1243                 printf("%s: esa_write_codec: timed out\n", sc->sc_dev.dv_xname);
 1244                 return (-1);
 1245         }
 1246         bus_space_write_2(iot, ioh, ESA_CODEC_DATA, data);
 1247         bus_space_write_1(iot, ioh, ESA_CODEC_COMMAND, reg & 0x7f);
 1248         delay(50);
 1249 
 1250         return (0);
 1251 }
 1252 
 1253 void
 1254 esa_reset_codec(void *aux)
 1255 {
 1256 
 1257         return;
 1258 }
 1259 
 1260 enum ac97_host_flags
 1261 esa_flags_codec(void *aux)
 1262 {
 1263         struct esa_softc *sc = aux;
 1264 
 1265         return (sc->codec_flags);
 1266 }
 1267 
 1268 int
 1269 esa_wait(struct esa_softc *sc)
 1270 {
 1271         int i, val;
 1272         bus_space_tag_t iot = sc->sc_iot;
 1273         bus_space_handle_t ioh = sc->sc_ioh;
 1274 
 1275         for (i = 0; i < 20; i++) {
 1276                 val = bus_space_read_1(iot, ioh, ESA_CODEC_STATUS);
 1277                 if ((val & 1) == 0)
 1278                         return (0);
 1279                 delay(2);
 1280         }
 1281 
 1282         return (-1);
 1283 }
 1284 
 1285 int
 1286 esa_init(struct esa_softc *sc)
 1287 {
 1288         struct esa_voice *vc;
 1289         bus_space_tag_t iot = sc->sc_iot;
 1290         bus_space_handle_t ioh = sc->sc_ioh;
 1291         pcitag_t tag = sc->sc_tag;
 1292         pci_chipset_tag_t pc = sc->sc_pct;
 1293         u_int32_t data, i, size;
 1294         u_int8_t reset_state;
 1295         int data_bytes = (((ESA_MINISRC_TMP_BUFFER_SIZE & ~1) +
 1296                            (ESA_MINISRC_IN_BUFFER_SIZE & ~1) +
 1297                            (ESA_MINISRC_OUT_BUFFER_SIZE & ~1) + 4) + 255)
 1298                            &~ 255;
 1299 
 1300         /* Disable legacy emulation */
 1301         data = pci_conf_read(pc, tag, PCI_LEGACY_AUDIO_CTRL);
 1302         data |= DISABLE_LEGACY;
 1303         pci_conf_write(pc, tag, PCI_LEGACY_AUDIO_CTRL, data);
 1304 
 1305         esa_config(sc);
 1306 
 1307         reset_state = esa_assp_halt(sc);
 1308 
 1309         esa_init_codec(sc);
 1310         esa_codec_reset(sc);
 1311 
 1312         /* Zero kernel and mixer data */
 1313         size = ESA_REV_B_DATA_MEMORY_UNIT_LENGTH * ESA_NUM_UNITS_KERNEL_DATA;
 1314         for (i = 0; i < size / 2; i++) {
 1315                 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
 1316                     ESA_KDATA_BASE_ADDR + i, 0);
 1317                 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
 1318                     ESA_KDATA_BASE_ADDR2 + i, 0);
 1319         }
 1320 
 1321         /* Init DMA pointer */
 1322         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_CURRENT_DMA,
 1323             ESA_KDATA_DMA_XFER0);
 1324 
 1325         /* Write kernel code into memory */
 1326         size = sizeof(esa_assp_kernel_image);
 1327         for (i = 0; i < size / 2; i++)
 1328                 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_CODE,
 1329                     ESA_REV_B_CODE_MEMORY_BEGIN + i, esa_assp_kernel_image[i]);
 1330 
 1331         size = sizeof(esa_assp_minisrc_image);
 1332         for (i = 0; i < size / 2; i++)
 1333                 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_CODE, 0x400 + i,
 1334                     esa_assp_minisrc_image[i]);
 1335 
 1336         /* Write the coefficients for the low pass filter */
 1337         size = sizeof(esa_minisrc_lpf_image);
 1338         for (i = 0; i < size / 2; i++)
 1339                 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_CODE,
 1340                     0x400 + ESA_MINISRC_COEF_LOC + i, esa_minisrc_lpf_image[i]);
 1341         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_CODE,
 1342             0x400 + ESA_MINISRC_COEF_LOC + size, 0x8000);
 1343         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_TASK0, 0x400);
 1344         /* Init the mixer number */
 1345         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
 1346              ESA_KDATA_MIXER_TASK_NUMBER, 0);
 1347         /* Extreme kernel master volume */
 1348         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
 1349             ESA_KDATA_DAC_LEFT_VOLUME, ESA_ARB_VOLUME);
 1350         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
 1351             ESA_KDATA_DAC_RIGHT_VOLUME, ESA_ARB_VOLUME);
 1352 
 1353         if (esa_amp_enable(sc))
 1354                 return (-1);
 1355 
 1356         /* Zero entire DAC/ADC area */
 1357         for (i = 0x1100; i < 0x1c00; i++)
 1358                 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, i, 0);
 1359 
 1360         /* set some sane defaults */
 1361         for (i = 0; i < ESA_NUM_VOICES; i++) {
 1362                 vc = &sc->voice[i];
 1363                 vc->play.data_offset = ESA_DAC_DATA + (data_bytes * i);
 1364                 vc->rec.data_offset = ESA_DAC_DATA + (data_bytes * i * 2);
 1365         }
 1366 
 1367         esa_enable_interrupts(sc);
 1368 
 1369         bus_space_write_1(iot, ioh, ESA_DSP_PORT_CONTROL_REG_B,
 1370             reset_state | ESA_REGB_ENABLE_RESET);
 1371 
 1372         return (0);
 1373 }
 1374 
 1375 void
 1376 esa_config(struct esa_softc *sc)
 1377 {
 1378         bus_space_tag_t iot = sc->sc_iot;
 1379         bus_space_handle_t ioh = sc->sc_ioh;
 1380         pcitag_t tag = sc->sc_tag;
 1381         pci_chipset_tag_t pc = sc->sc_pct;
 1382         u_int32_t data;
 1383 
 1384         data = pci_conf_read(pc, tag, ESA_PCI_ALLEGRO_CONFIG);
 1385         data &= ESA_REDUCED_DEBOUNCE;
 1386         data |= ESA_PM_CTRL_ENABLE | ESA_CLK_DIV_BY_49 | ESA_USE_PCI_TIMING;
 1387         pci_conf_write(pc, tag, ESA_PCI_ALLEGRO_CONFIG, data);
 1388 
 1389         bus_space_write_1(iot, ioh, ESA_ASSP_CONTROL_B, ESA_RESET_ASSP);
 1390         data = pci_conf_read(pc, tag, ESA_PCI_ALLEGRO_CONFIG);
 1391         data &= ~ESA_INT_CLK_SELECT;
 1392         if (sc->type == ESS_MAESTRO3) {
 1393                 data &= ~ESA_INT_CLK_MULT_ENABLE;
 1394                 data |= ESA_INT_CLK_SRC_NOT_PCI;
 1395         }
 1396         data &= ~(ESA_CLK_MULT_MODE_SELECT | ESA_CLK_MULT_MODE_SELECT_2);
 1397         pci_conf_write(pc, tag, ESA_PCI_ALLEGRO_CONFIG, data);
 1398 
 1399         if (sc->type == ESS_ALLEGRO1) {
 1400                 data = pci_conf_read(pc, tag, ESA_PCI_USER_CONFIG);
 1401                 data |= ESA_IN_CLK_12MHZ_SELECT;
 1402                 pci_conf_write(pc, tag, ESA_PCI_USER_CONFIG, data);
 1403         }
 1404 
 1405         data = bus_space_read_1(iot, ioh, ESA_ASSP_CONTROL_A);
 1406         data &= ~(ESA_DSP_CLK_36MHZ_SELECT | ESA_ASSP_CLK_49MHZ_SELECT);
 1407         data |= ESA_ASSP_CLK_49MHZ_SELECT;      /* XXX: Assumes 49MHz DSP */
 1408         data |= ESA_ASSP_0_WS_ENABLE;
 1409         bus_space_write_1(iot, ioh, ESA_ASSP_CONTROL_A, data);
 1410 
 1411         bus_space_write_1(iot, ioh, ESA_ASSP_CONTROL_B, ESA_RUN_ASSP);
 1412 
 1413         return;
 1414 }
 1415 
 1416 u_int8_t
 1417 esa_assp_halt(struct esa_softc *sc)
 1418 {
 1419         bus_space_tag_t iot = sc->sc_iot;
 1420         bus_space_handle_t ioh = sc->sc_ioh;
 1421         u_int8_t data, reset_state;
 1422 
 1423         data = bus_space_read_1(iot, ioh, ESA_DSP_PORT_CONTROL_REG_B);
 1424         reset_state = data & ~ESA_REGB_STOP_CLOCK;
 1425         delay(10000);           /* XXX use tsleep */
 1426         bus_space_write_1(iot, ioh, ESA_DSP_PORT_CONTROL_REG_B,
 1427                         reset_state & ~ESA_REGB_ENABLE_RESET);
 1428         delay(10000);           /* XXX use tsleep */
 1429 
 1430         return (reset_state);
 1431 }
 1432 
 1433 void
 1434 esa_codec_reset(struct esa_softc *sc)
 1435 {
 1436         bus_space_tag_t iot = sc->sc_iot;
 1437         bus_space_handle_t ioh = sc->sc_ioh;
 1438         u_int16_t data, dir;
 1439         int retry = 0;
 1440 
 1441         do {
 1442                 data = bus_space_read_2(iot, ioh, ESA_GPIO_DIRECTION);
 1443                 dir = data | 0x10; /* assuming pci bus master? */
 1444 
 1445                 /* remote codec config */
 1446                 data = bus_space_read_2(iot, ioh, ESA_RING_BUS_CTRL_B);
 1447                 bus_space_write_2(iot, ioh, ESA_RING_BUS_CTRL_B,
 1448                     data & ~ESA_SECOND_CODEC_ID_MASK);
 1449                 data = bus_space_read_2(iot, ioh, ESA_SDO_OUT_DEST_CTRL);
 1450                 bus_space_write_2(iot, ioh, ESA_SDO_OUT_DEST_CTRL,
 1451                     data & ~ESA_COMMAND_ADDR_OUT);
 1452                 data = bus_space_read_2(iot, ioh, ESA_SDO_IN_DEST_CTRL);
 1453                 bus_space_write_2(iot, ioh, ESA_SDO_IN_DEST_CTRL,
 1454                     data & ~ESA_STATUS_ADDR_IN);
 1455 
 1456                 bus_space_write_2(iot, ioh, ESA_RING_BUS_CTRL_A,
 1457                                   ESA_IO_SRAM_ENABLE);
 1458                 delay(20);
 1459 
 1460                 bus_space_write_2(iot, ioh, ESA_GPIO_DIRECTION,
 1461                     dir & ~ESA_GPO_PRIMARY_AC97);
 1462                 bus_space_write_2(iot, ioh, ESA_GPIO_MASK,
 1463                                   ~ESA_GPO_PRIMARY_AC97);
 1464                 bus_space_write_2(iot, ioh, ESA_GPIO_DATA, 0);
 1465                 bus_space_write_2(iot, ioh, ESA_GPIO_DIRECTION,
 1466                     dir | ESA_GPO_PRIMARY_AC97);
 1467                 delay(sc->delay1 * 1000);
 1468                 bus_space_write_2(iot, ioh, ESA_GPIO_DATA,
 1469                                   ESA_GPO_PRIMARY_AC97);
 1470                 delay(5);
 1471                 bus_space_write_2(iot, ioh, ESA_RING_BUS_CTRL_A,
 1472                     ESA_IO_SRAM_ENABLE | ESA_SERIAL_AC_LINK_ENABLE);
 1473                 bus_space_write_2(iot, ioh, ESA_GPIO_MASK, ~0);
 1474                 delay(sc->delay2 * 1000);
 1475 
 1476                 esa_read_codec(sc, 0x7c, &data);
 1477                 if ((data == 0) || (data == 0xffff)) {
 1478                         retry++;
 1479                         if (retry > 3) {
 1480                                 printf("%s: esa_codec_reset: failed\n",
 1481                                     sc->sc_dev.dv_xname);
 1482                                 break;
 1483                         }
 1484                         printf("%s: esa_codec_reset: retrying\n",
 1485                             sc->sc_dev.dv_xname);
 1486                 } else
 1487                         retry = 0;
 1488         } while (retry);
 1489 
 1490         return;
 1491 }
 1492 
 1493 int
 1494 esa_amp_enable(struct esa_softc *sc)
 1495 {
 1496         bus_space_tag_t iot = sc->sc_iot;
 1497         bus_space_handle_t ioh = sc->sc_ioh;
 1498         u_int32_t gpo, polarity_port, polarity;
 1499         u_int16_t data;
 1500 
 1501         switch (sc->type) {
 1502         case ESS_ALLEGRO1:
 1503                 polarity_port = 0x1800;
 1504                 break;
 1505         case ESS_MAESTRO3:
 1506                 polarity_port = 0x1100;
 1507                 break;
 1508         default:
 1509                 printf("%s: esa_amp_enable: Unknown chip type!!!\n",
 1510                     sc->sc_dev.dv_xname);
 1511                 return (1);
 1512         }
 1513 
 1514         gpo = (polarity_port >> 8) & 0x0f;
 1515         polarity = polarity_port >> 12;
 1516         polarity = !polarity;   /* Enable */
 1517         polarity = polarity << gpo;
 1518         gpo = 1 << gpo;
 1519         bus_space_write_2(iot, ioh, ESA_GPIO_MASK, ~gpo);
 1520         data = bus_space_read_2(iot, ioh, ESA_GPIO_DIRECTION);
 1521         bus_space_write_2(iot, ioh, ESA_GPIO_DIRECTION, data | gpo);
 1522         data = ESA_GPO_SECONDARY_AC97 | ESA_GPO_PRIMARY_AC97 | polarity;
 1523         bus_space_write_2(iot, ioh, ESA_GPIO_DATA, data);
 1524         bus_space_write_2(iot, ioh, ESA_GPIO_MASK, ~0);
 1525 
 1526         return (0);
 1527 }
 1528 
 1529 void
 1530 esa_enable_interrupts(struct esa_softc *sc)
 1531 {
 1532         bus_space_tag_t iot = sc->sc_iot;
 1533         bus_space_handle_t ioh = sc->sc_ioh;
 1534         u_int8_t data;
 1535 
 1536         bus_space_write_2(iot, ioh, ESA_HOST_INT_CTRL,
 1537             ESA_ASSP_INT_ENABLE | ESA_HV_INT_ENABLE);
 1538         data = bus_space_read_1(iot, ioh, ESA_ASSP_CONTROL_C);
 1539         bus_space_write_1(iot, ioh, ESA_ASSP_CONTROL_C,
 1540             data | ESA_ASSP_HOST_INT_ENABLE);
 1541 }
 1542 
 1543 /*
 1544  * List management
 1545  */
 1546 int
 1547 esa_add_list(struct esa_voice *vc, struct esa_list *el,
 1548              u_int16_t val, int index)
 1549 {
 1550         struct esa_softc *sc = (struct esa_softc *)vc->parent;
 1551 
 1552         el->indexmap[index] = el->currlen;
 1553         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
 1554                        el->mem_addr + el->currlen,
 1555                        val);
 1556 
 1557         return (el->currlen++);
 1558 }
 1559 
 1560 void
 1561 esa_remove_list(struct esa_voice *vc, struct esa_list *el, int index)
 1562 {
 1563         struct esa_softc *sc = (struct esa_softc *)vc->parent;
 1564         u_int16_t val;
 1565         int lastindex = el->currlen - 1;
 1566         int vindex = el->indexmap[index];
 1567         int i;
 1568 
 1569         /* reset our virtual index */
 1570         el->indexmap[index] = -1;
 1571 
 1572         if (vindex != lastindex) {
 1573                 val = esa_read_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
 1574                                     el->mem_addr + lastindex);
 1575                 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
 1576                                el->mem_addr + vindex,
 1577                                val);
 1578                 for (i = 0; i < ESA_NUM_VOICES * 2; i++)
 1579                         if (el->indexmap[i] == lastindex)
 1580                                 break;
 1581                 if (i >= ESA_NUM_VOICES * 2)
 1582                         printf("%s: esa_remove_list: invalid task index\n",
 1583                                sc->sc_dev.dv_xname);
 1584                 else
 1585                         el->indexmap[i] = vindex;
 1586         }
 1587 
 1588         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA,
 1589                        el->mem_addr + lastindex, 0);
 1590         el->currlen--;
 1591 
 1592         return;
 1593 }
 1594 
 1595 int
 1596 esa_power(struct esa_softc *sc, int state)
 1597 {
 1598         pcitag_t tag = sc->sc_tag;
 1599         pci_chipset_tag_t pc = sc->sc_pct;
 1600         pcireg_t data;
 1601         int pmcapreg;
 1602 
 1603         if (pci_get_capability(pc, tag, PCI_CAP_PWRMGMT, &pmcapreg, 0)) {
 1604                 data = pci_conf_read(pc, tag, pmcapreg + PCI_PMCSR);
 1605                 if ((data & PCI_PMCSR_STATE_MASK) != state)
 1606                         pci_conf_write(pc, tag, pmcapreg + PCI_PMCSR, state);
 1607         }
 1608 
 1609         return (0);
 1610 }
 1611 
 1612 void
 1613 esa_powerhook(int why, void *hdl)
 1614 {
 1615         struct esa_softc *sc = (struct esa_softc *)hdl;
 1616 
 1617         switch (why) {
 1618         case PWR_SUSPEND:
 1619         case PWR_STANDBY:
 1620                 esa_suspend(sc);
 1621                 break;
 1622         case PWR_RESUME:
 1623                 esa_resume(sc);
 1624                 (sc->codec_if->vtbl->restore_ports)(sc->codec_if);
 1625                 break;
 1626         }
 1627 }
 1628 
 1629 int
 1630 esa_suspend(struct esa_softc *sc)
 1631 {
 1632         bus_space_tag_t iot = sc->sc_iot;
 1633         bus_space_handle_t ioh = sc->sc_ioh;
 1634         int i, index;
 1635 
 1636         index = 0;
 1637 
 1638         bus_space_write_2(iot, ioh, ESA_HOST_INT_CTRL, 0);
 1639         bus_space_write_1(iot, ioh, ESA_ASSP_CONTROL_C, 0);
 1640 
 1641         esa_assp_halt(sc);
 1642 
 1643         /* Save ASSP state */
 1644         for (i = ESA_REV_B_CODE_MEMORY_BEGIN; i <= ESA_REV_B_CODE_MEMORY_END;
 1645             i++)
 1646                 sc->savemem[index++] = esa_read_assp(sc,
 1647                     ESA_MEMTYPE_INTERNAL_CODE, i);
 1648         for (i = ESA_REV_B_DATA_MEMORY_BEGIN; i <= ESA_REV_B_DATA_MEMORY_END;
 1649             i++)
 1650                 sc->savemem[index++] = esa_read_assp(sc,
 1651                     ESA_MEMTYPE_INTERNAL_DATA, i);
 1652 
 1653         esa_power(sc, PCI_PMCSR_STATE_D3);
 1654 
 1655         return (0);
 1656 }
 1657 
 1658 int
 1659 esa_resume(struct esa_softc *sc) {
 1660         bus_space_tag_t iot = sc->sc_iot;
 1661         bus_space_handle_t ioh = sc->sc_ioh;
 1662         int i, index;
 1663         u_int8_t reset_state;
 1664 
 1665         index = 0;
 1666 
 1667         esa_power(sc, PCI_PMCSR_STATE_D0);
 1668         delay(10000);
 1669 
 1670         esa_config(sc);
 1671 
 1672         reset_state = esa_assp_halt(sc);
 1673 
 1674         esa_codec_reset(sc);
 1675 
 1676         /* restore ASSP */
 1677         for (i = ESA_REV_B_CODE_MEMORY_BEGIN; i <= ESA_REV_B_CODE_MEMORY_END;
 1678             i++)
 1679                 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_CODE, i,
 1680                     sc->savemem[index++]);
 1681         for (i = ESA_REV_B_DATA_MEMORY_BEGIN; i <= ESA_REV_B_DATA_MEMORY_END;
 1682             i++)
 1683                 esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, i,
 1684                     sc->savemem[index++]);
 1685 
 1686         esa_write_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, ESA_KDATA_DMA_ACTIVE, 0);
 1687         bus_space_write_1(iot, ioh, ESA_DSP_PORT_CONTROL_REG_B,
 1688             reset_state | ESA_REGB_ENABLE_RESET);
 1689 
 1690         esa_enable_interrupts(sc);
 1691         esa_amp_enable(sc);
 1692 
 1693         return (0);
 1694 }
 1695 
 1696 u_int32_t
 1697 esa_get_pointer(struct esa_softc *sc, struct esa_channel *ch)
 1698 {
 1699         u_int16_t hi = 0, lo = 0;
 1700         u_int32_t addr;
 1701         int data_offset = ch->data_offset;
 1702 
 1703         hi = esa_read_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, data_offset +
 1704             ESA_CDATA_HOST_SRC_CURRENTH);
 1705         lo = esa_read_assp(sc, ESA_MEMTYPE_INTERNAL_DATA, data_offset +
 1706             ESA_CDATA_HOST_SRC_CURRENTL);
 1707 
 1708         addr = lo | ((u_int32_t)hi << 16);
 1709         return (addr - ch->start);
 1710 }
 1711 
 1712 paddr_t
 1713 esa_mappage(void *addr, void *mem, off_t off, int prot)
 1714 {
 1715         struct esa_voice *vc = addr;
 1716         struct esa_softc *sc = (struct esa_softc *)vc->parent;
 1717         struct esa_dma *p;
 1718 
 1719         if (off < 0)
 1720                 return (-1);
 1721         for (p = vc->dma; p && KERNADDR(p) != mem; p = p->next)
 1722                 ;
 1723         if (!p)
 1724                 return (-1);
 1725         return (bus_dmamem_mmap(sc->sc_dmat, p->segs, p->nsegs,
 1726                                 off, prot, BUS_DMA_WAITOK));
 1727 }

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