root/dev/pci/auixp.c

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

DEFINITIONS

This source file includes following definitions.
  1. auixp_open
  2. auixp_close
  3. auixp_query_encoding
  4. auixp_commit_settings
  5. auixp_set_params
  6. auixp_round_blocksize
  7. auixp_malloc
  8. auixp_free
  9. auixp_getdev
  10. auixp_set_port
  11. auixp_get_port
  12. auixp_query_devinfo
  13. auixp_round_buffersize
  14. auixp_get_props
  15. auixp_link_daisychain
  16. auixp_allocate_dma_chain
  17. auixp_program_dma_chain
  18. auixp_dma_update
  19. auixp_update_busbusy
  20. auixp_trigger_output
  21. auixp_halt_output
  22. auixp_trigger_input
  23. auixp_halt_input
  24. auixp_intr
  25. auixp_allocmem
  26. auixp_freemem
  27. auixp_mappage
  28. auixp_match
  29. auixp_attach
  30. auixp_post_config
  31. auixp_enable_interrupts
  32. auixp_disable_interrupts
  33. auixp_detach
  34. auixp_attach_codec
  35. auixp_read_codec
  36. auixp_write_codec
  37. auixp_reset_codec
  38. auixp_flags_codec
  39. auixp_wait_for_codecs
  40. auixp_autodetect_codecs
  41. auixp_disable_dma
  42. auixp_enable_dma
  43. auixp_reset_aclink
  44. auixp_init
  45. auixp_power
  46. auixp_powerhook
  47. auixp_suspend
  48. auixp_resume

    1 /* $OpenBSD: auixp.c,v 1.10 2007/05/26 00:36:03 krw Exp $ */
    2 /* $NetBSD: auixp.c,v 1.9 2005/06/27 21:13:09 thorpej Exp $ */
    3 
    4 /*
    5  * Copyright (c) 2004, 2005 Reinoud Zandijk <reinoud@netbsd.org>
    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  * 3. All advertising materials mentioning features or use of this software
   16  *    must display the following acknowledgement:
   17  *      This product includes software developed by the NetBSD
   18  *      Foundation, Inc. and its contributors.
   19  * 4. Neither the name of The NetBSD Foundation nor the names of its
   20  *    contributors may be used to endorse or promote products derived
   21  *    from this software without specific prior written permission.
   22  *
   23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   26  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
   30  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   31  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   33  * SUCH DAMAGE.
   34  */
   35 /*
   36  * Audio driver for ATI IXP-{150,200,...} audio driver hardware.
   37  *
   38  * Recording and playback has been tested OK on various sample rates and
   39  * encodings.
   40  *
   41  * Known problems and issues :
   42  * - SPDIF is untested and needs some work still (LED stays off)
   43  * - 32 bit audio playback failed last time i tried but that might an AC'97
   44  *   codec support problem.
   45  * - 32 bit recording works but can't try out playing: see above.
   46  * - no suspend/resume support yet.
   47  * - multiple codecs are `supported' but not tested; the implemetation needs
   48  *   some cleaning up.
   49  */
   50 
   51 /*#define DEBUG_AUIXP*/
   52 
   53 #include <sys/types.h>
   54 #include <sys/errno.h>
   55 #include <sys/param.h>
   56 #include <sys/systm.h>
   57 #include <sys/malloc.h>
   58 #include <sys/device.h>
   59 #include <sys/conf.h>
   60 #include <sys/exec.h>
   61 #include <sys/selinfo.h>
   62 #include <sys/audioio.h>
   63 #include <sys/queue.h>
   64 
   65 #include <machine/bus.h>
   66 #include <machine/intr.h>
   67 
   68 #include <dev/pci/pcidevs.h>
   69 #include <dev/pci/pcivar.h>
   70 
   71 #include <dev/audio_if.h>
   72 #include <dev/mulaw.h>
   73 #include <dev/auconv.h>
   74 #include <dev/ic/ac97.h>
   75 
   76 #include <dev/pci/auixpreg.h>
   77 #include <dev/pci/auixpvar.h>
   78 
   79 /* codec detection constant indicating the interrupt flags */
   80 #define ALL_CODECS_NOT_READY \
   81     (ATI_REG_ISR_CODEC0_NOT_READY | ATI_REG_ISR_CODEC1_NOT_READY |\
   82      ATI_REG_ISR_CODEC2_NOT_READY)
   83 #define CODEC_CHECK_BITS (ALL_CODECS_NOT_READY|ATI_REG_ISR_NEW_FRAME)
   84 
   85 /* why isn't this base address register not in the headerfile? */
   86 #define PCI_CBIO 0x10
   87 
   88 /* macro's used */
   89 #define KERNADDR(p)     ((void *)((p)->addr))
   90 #define DMAADDR(p)      ((p)->map->dm_segs[0].ds_addr)
   91 
   92 const struct pci_matchid auixp_pci_devices[] = {
   93         { PCI_VENDOR_ATI, PCI_PRODUCT_ATI_IXP_AUDIO_200 },
   94         { PCI_VENDOR_ATI, PCI_PRODUCT_ATI_IXP_AUDIO_300 },
   95         { PCI_VENDOR_ATI, PCI_PRODUCT_ATI_IXP_AUDIO_400 },
   96 };
   97 
   98 struct cfdriver auixp_cd = {
   99         NULL, "auixp", DV_DULL
  100 };
  101 
  102 int     auixp_match( struct device *, void *, void *);
  103 void    auixp_attach(struct device *, struct device *, void *);
  104 int     auixp_detach(struct device *, int);
  105 
  106 struct cfattach auixp_ca = {
  107         sizeof(struct auixp_softc), auixp_match, auixp_attach
  108 };
  109 
  110 int     auixp_open(void *v, int flags);
  111 void    auixp_close(void *v);
  112 int     auixp_query_encoding(void *, struct audio_encoding *);
  113 int     auixp_set_params(void *, int, int, struct audio_params *,
  114     struct audio_params *);
  115 int     auixp_commit_settings(void *);
  116 int     auixp_round_blocksize(void *, int);
  117 int     auixp_trigger_output(void *, void *, void *, int,
  118     void (*)(void *), void *, struct audio_params *);
  119 int     auixp_trigger_input(void *, void *, void *, int,
  120     void (*)(void *), void *, struct audio_params *);
  121 int     auixp_halt_output(void *);
  122 int     auixp_halt_input(void *);
  123 int     auixp_set_port(void *, mixer_ctrl_t *);
  124 int     auixp_get_port(void *, mixer_ctrl_t *);
  125 int     auixp_query_devinfo(void *, mixer_devinfo_t *);
  126 void *  auixp_malloc(void *, int, size_t, int, int);
  127 void    auixp_free(void *, void *, int);
  128 int     auixp_getdev(void *, struct audio_device *);
  129 size_t  auixp_round_buffersize(void *, int, size_t);
  130 int     auixp_get_props(void *);
  131 int     auixp_intr(void *);
  132 int     auixp_allocmem(struct auixp_softc *, size_t, size_t,
  133     struct auixp_dma *);
  134 int     auixp_freemem(struct auixp_softc *, struct auixp_dma *);
  135 paddr_t auixp_mappage(void *, void *, off_t, int);
  136 
  137 
  138 /* power management (do we support that already?) */
  139 int     auixp_power(struct auixp_softc *, int);
  140 #if 0
  141 void    auixp_powerhook(int, void *);
  142 int     auixp_suspend(struct auixp_softc *);
  143 int     auixp_resume(struct auixp_softc *);
  144 #endif
  145 
  146 
  147 /* Supporting subroutines */
  148 int     auixp_init(struct auixp_softc *);
  149 void    auixp_autodetect_codecs(struct auixp_softc *);
  150 void    auixp_post_config(void *);
  151 
  152 void    auixp_reset_aclink(struct auixp_softc *);
  153 int     auixp_attach_codec(void *, struct ac97_codec_if *);
  154 int     auixp_read_codec(void *, u_int8_t, u_int16_t *);
  155 int     auixp_write_codec(void *, u_int8_t, u_int16_t);
  156 int     auixp_wait_for_codecs(struct auixp_softc *, const char *);
  157 void    auixp_reset_codec(void *);
  158 enum ac97_host_flags    auixp_flags_codec(void *);
  159 
  160 void    auixp_enable_dma(struct auixp_softc *, struct auixp_dma *);
  161 void    auixp_disable_dma(struct auixp_softc *, struct auixp_dma *);
  162 void    auixp_enable_interrupts(struct auixp_softc *);
  163 void    auixp_disable_interrupts(struct auixp_softc *);
  164 
  165 void    auixp_link_daisychain(struct auixp_softc *,
  166     struct auixp_dma *, struct auixp_dma *, int, int);
  167 int     auixp_allocate_dma_chain(struct auixp_softc *, struct auixp_dma **);
  168 void    auixp_program_dma_chain(struct auixp_softc *, struct auixp_dma *);
  169 void    auixp_dma_update(struct auixp_softc *, struct auixp_dma *);
  170 void    auixp_update_busbusy(struct auixp_softc *);
  171 
  172 #ifdef DEBUG_AUIXP
  173 #define DPRINTF(x)      printf x;
  174 #else
  175 #define DPRINTF(x)
  176 #endif
  177 
  178 struct audio_hw_if auixp_hw_if = {
  179         auixp_open,
  180         auixp_close,
  181         NULL,                   /* drain */
  182         auixp_query_encoding,
  183         auixp_set_params,
  184         auixp_round_blocksize,
  185         auixp_commit_settings,
  186         NULL,                   /* init_output  */
  187         NULL,                   /* init_input   */
  188         NULL,                   /* start_output */
  189         NULL,                   /* start_input  */
  190         auixp_halt_output,
  191         auixp_halt_input,
  192         NULL,                   /* speaker_ctl */
  193         auixp_getdev,
  194         NULL,                   /* getfd */
  195         auixp_set_port,
  196         auixp_get_port,
  197         auixp_query_devinfo,
  198         auixp_malloc,
  199         auixp_free,
  200         auixp_round_buffersize,
  201         auixp_mappage,
  202         auixp_get_props,
  203         auixp_trigger_output,
  204         auixp_trigger_input
  205 };
  206 
  207 int
  208 auixp_open(void *v, int flags)
  209 {
  210 
  211         return 0;
  212 }
  213 
  214 void
  215 auixp_close(void *v)
  216 {
  217 }
  218 
  219 int
  220 auixp_query_encoding(void *hdl, struct audio_encoding *aep)
  221 {
  222         switch (aep->index) {
  223         case 0:
  224                 strlcpy(aep->name, AudioEulinear, sizeof aep->name);
  225                 aep->encoding = AUDIO_ENCODING_ULINEAR;
  226                 aep->precision = 8;
  227                 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
  228                 return (0);
  229         case 1:
  230                 strlcpy(aep->name, AudioEmulaw, sizeof aep->name);
  231                 aep->encoding = AUDIO_ENCODING_ULAW;
  232                 aep->precision = 8;
  233                 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
  234                 return (0);
  235         case 2:
  236                 strlcpy(aep->name, AudioEalaw, sizeof aep->name);
  237                 aep->encoding = AUDIO_ENCODING_ALAW;
  238                 aep->precision = 8;
  239                 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
  240                 return (0);
  241         case 3:
  242                 strlcpy(aep->name, AudioEslinear, sizeof aep->name);
  243                 aep->encoding = AUDIO_ENCODING_SLINEAR;
  244                 aep->precision = 8;
  245                 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
  246                 return (0);
  247         case 4:
  248                 strlcpy(aep->name, AudioEslinear_le, sizeof aep->name);
  249                 aep->encoding = AUDIO_ENCODING_SLINEAR_LE;
  250                 aep->precision = 16;
  251                 aep->flags = 0;
  252                 return (0);
  253         case 5:
  254                 strlcpy(aep->name, AudioEulinear_le, sizeof aep->name);
  255                 aep->encoding = AUDIO_ENCODING_ULINEAR_LE;
  256                 aep->precision = 16;
  257                 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
  258                 return (0);
  259         case 6:
  260                 strlcpy(aep->name, AudioEslinear_be, sizeof aep->name);
  261                 aep->encoding = AUDIO_ENCODING_SLINEAR_BE;
  262                 aep->precision = 16;
  263                 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
  264                 return (0);
  265         case 7:
  266                 strlcpy(aep->name, AudioEulinear_be, sizeof aep->name);
  267                 aep->encoding = AUDIO_ENCODING_ULINEAR_BE;
  268                 aep->precision = 16;
  269                 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
  270                 return (0);
  271         default:
  272                 return (EINVAL);
  273         }
  274 }
  275 
  276 
  277 /* commit setting and program ATI IXP chip */
  278 int
  279 auixp_commit_settings(void *hdl)
  280 {
  281         struct auixp_codec *co;
  282         struct auixp_softc *sc;
  283         bus_space_tag_t    iot;
  284         bus_space_handle_t ioh;
  285         struct audio_params *params;
  286         u_int32_t value;
  287 
  288         /* XXX would it be better to stop interrupts first? XXX */
  289         co = (struct auixp_codec *) hdl;
  290         sc = co->sc;
  291         iot = sc->sc_iot;
  292         ioh = sc->sc_ioh;
  293 
  294         /* process input settings */
  295         params = &sc->sc_play_params;
  296 
  297         /* set input interleaving (precision) */
  298         value  =  bus_space_read_4(iot, ioh, ATI_REG_CMD);
  299         value &= ~ATI_REG_CMD_INTERLEAVE_IN;
  300         if (params->precision <= 16)
  301                 value |= ATI_REG_CMD_INTERLEAVE_IN;
  302         bus_space_write_4(iot, ioh, ATI_REG_CMD, value);
  303 
  304         /* process output settings */
  305         params = &sc->sc_play_params;
  306 
  307         value  =  bus_space_read_4(iot, ioh, ATI_REG_OUT_DMA_SLOT);
  308         value &= ~ATI_REG_OUT_DMA_SLOT_MASK;
  309 
  310         /* TODO SPDIF case for 8 channels */
  311         switch (params->channels) {
  312         case 6:
  313                 value |= ATI_REG_OUT_DMA_SLOT_BIT(7) |
  314                          ATI_REG_OUT_DMA_SLOT_BIT(8);
  315                 /* FALLTHROUGH */
  316         case 4:
  317                 value |= ATI_REG_OUT_DMA_SLOT_BIT(6) |
  318                          ATI_REG_OUT_DMA_SLOT_BIT(9);
  319                 /* FALLTHROUGH */
  320         default:
  321                 value |= ATI_REG_OUT_DMA_SLOT_BIT(3) |
  322                          ATI_REG_OUT_DMA_SLOT_BIT(4);
  323                 break;
  324         }
  325         /* set output threshold */
  326         value |= 0x04 << ATI_REG_OUT_DMA_THRESHOLD_SHIFT;
  327         bus_space_write_4(iot, ioh, ATI_REG_OUT_DMA_SLOT, value);
  328 
  329         /* set output interleaving (precision) */
  330         value  =  bus_space_read_4(iot, ioh, ATI_REG_CMD);
  331         value &= ~ATI_REG_CMD_INTERLEAVE_OUT;
  332         if (params->precision <= 16)
  333                 value |= ATI_REG_CMD_INTERLEAVE_OUT;
  334         bus_space_write_4(iot, ioh, ATI_REG_CMD, value);
  335 
  336         /* enable 6 channel reordering */
  337         value  =  bus_space_read_4(iot, ioh, ATI_REG_6CH_REORDER);
  338         value &= ~ATI_REG_6CH_REORDER_EN;
  339         if (params->channels == 6)
  340                 value |= ATI_REG_6CH_REORDER_EN;
  341         bus_space_write_4(iot, ioh, ATI_REG_6CH_REORDER, value);
  342 
  343         if (sc->has_spdif) {
  344                 /* set SPDIF (if present) */
  345                 value  =  bus_space_read_4(iot, ioh, ATI_REG_CMD);
  346                 value &= ~ATI_REG_CMD_SPDF_CONFIG_MASK;
  347                 value |=  ATI_REG_CMD_SPDF_CONFIG_34; /* NetBSD AC'97 default */
  348 
  349                 /* XXX this is probably not necessary unless splitted XXX */
  350                 value &= ~ATI_REG_CMD_INTERLEAVE_SPDF;
  351                 if (params->precision <= 16)
  352                         value |= ATI_REG_CMD_INTERLEAVE_SPDF;
  353                 bus_space_write_4(iot, ioh, ATI_REG_CMD, value);
  354         }
  355 
  356         return 0;
  357 }
  358 
  359 
  360 /* set audio properties in desired setting */
  361 int
  362 auixp_set_params(void *hdl, int setmode, int usemode,
  363     struct audio_params *play, struct audio_params *rec)
  364 {
  365         struct auixp_codec *co;
  366         struct auixp_softc *sc;
  367         int error;
  368 
  369         co = (struct auixp_codec *) hdl;
  370         sc = co->sc;
  371         if (setmode & AUMODE_PLAY) {
  372                 play->factor = 1;
  373                 play->sw_code = NULL;
  374                 switch(play->encoding) {
  375                 case AUDIO_ENCODING_ULAW:
  376                         switch (play->channels) {
  377                         case 1:
  378                                 play->factor = 4;
  379                                 play->sw_code = mulaw_to_slinear16_mts;
  380                                 break;
  381                         case 2:
  382                                 play->factor = 2;
  383                                 play->sw_code = mulaw_to_slinear16;
  384                                 break;
  385                         default:
  386                                 return (EINVAL);
  387                         }
  388                         break;
  389                 case AUDIO_ENCODING_SLINEAR_LE:
  390                         switch (play->precision) {
  391                         case 8:
  392                                 switch (play->channels) {
  393                                 case 1:
  394                                         play->factor = 4;
  395                                         play->sw_code = linear8_to_linear16_mts;
  396                                         break;
  397                                 case 2:
  398                                         play->factor = 2;
  399                                         play->sw_code = linear8_to_linear16;
  400                                         break;
  401                                 default:
  402                                         return (EINVAL);
  403                                 }
  404                                 break;
  405                         case 16:
  406                                 switch (play->channels) {
  407                                 case 1:
  408                                         play->factor = 2;
  409                                         play->sw_code = noswap_bytes_mts;
  410                                         break;
  411                                 case 2:
  412                                         break;
  413                                 default:
  414                                         return (EINVAL);
  415                                 }
  416                                 break;
  417                         default:
  418                                 return (EINVAL);
  419                         }
  420                         break;
  421                 case AUDIO_ENCODING_ULINEAR_LE:
  422                         switch (play->precision) {
  423                         case 8:
  424                                 switch (play->channels) {
  425                                 case 1:
  426                                         play->factor = 4;
  427                                         play->sw_code = ulinear8_to_linear16_mts;
  428                                         break;
  429                                 case 2:
  430                                         play->factor = 2;
  431                                         play->sw_code = ulinear8_to_linear16;
  432                                         break;
  433                                 default:
  434                                         return (EINVAL);
  435                                 }
  436                                 break;
  437                         case 16:
  438                                 switch (play->channels) {
  439                                 case 1:
  440                                         play->factor = 2;
  441                                         play->sw_code = change_sign16_mts;
  442                                         break;
  443                                 case 2:
  444                                         play->sw_code = change_sign16;
  445                                         break;
  446                                 default:
  447                                         return (EINVAL);
  448                                 }
  449                                 break;
  450                         default:
  451                                 return (EINVAL);
  452                         }
  453                         break;
  454                 case AUDIO_ENCODING_ALAW:
  455                         switch (play->channels) {
  456                         case 1:
  457                                 play->factor = 4;
  458                                 play->sw_code = alaw_to_slinear16_mts;
  459                                 break;
  460                         case 2:
  461                                 play->factor = 2;
  462                                 play->sw_code = alaw_to_slinear16;
  463                                 break;
  464                         default:
  465                                 return (EINVAL);
  466                         }
  467                         break;
  468                 case AUDIO_ENCODING_SLINEAR_BE:
  469                         switch (play->precision) {
  470                         case 8:
  471                                 switch (play->channels) {
  472                                 case 1:
  473                                         play->factor = 4;
  474                                         play->sw_code = linear8_to_linear16_mts;
  475                                         break;
  476                                 case 2:
  477                                         play->factor = 2;
  478                                         play->sw_code = linear8_to_linear16;
  479                                         break;
  480                                 default:
  481                                         return (EINVAL);
  482                                 }
  483                                 break;
  484                         case 16:
  485                                 switch (play->channels) {
  486                                 case 1:
  487                                         play->factor = 2;
  488                                         play->sw_code = swap_bytes_mts;
  489                                         break;
  490                                 case 2:
  491                                         play->sw_code = swap_bytes;
  492                                         break;
  493                                 default:
  494                                         return (EINVAL);
  495                                 }
  496                                 break;
  497                         default:
  498                                 return (EINVAL);
  499                         }
  500                         break;
  501                 case AUDIO_ENCODING_ULINEAR_BE:
  502                         switch (play->precision) {
  503                         case 8:
  504                                 switch (play->channels) {
  505                                 case 1:
  506                                         play->factor = 4;
  507                                         play->sw_code = ulinear8_to_linear16_mts;
  508                                         break;
  509                                 case 2:
  510                                         play->factor = 2;
  511                                         play->sw_code = ulinear8_to_linear16;
  512                                         break;
  513                                 default:
  514                                         return (EINVAL);
  515                                 }
  516                                 break;
  517                         case 16:
  518                                 switch (play->channels) {
  519                                 case 1:
  520                                         play->factor = 2;
  521                                         play->sw_code = change_sign16_swap_bytes_mts;
  522                                         break;
  523                                 case 2:
  524                                         play->sw_code = change_sign16_swap_bytes;
  525                                         break;
  526                                 default:
  527                                         return (EINVAL);
  528                                 }
  529                                 break;
  530                         default:
  531                                 return (EINVAL);
  532                         }
  533                         break;
  534                 default:
  535                         return (EINVAL);
  536                 }
  537 
  538                 error = ac97_set_rate(co->codec_if, play, AUMODE_PLAY);
  539                 if (error)
  540                         return (error);
  541         }
  542 
  543         if (setmode & AUMODE_RECORD) {
  544                 rec->factor = 1;
  545                 rec->sw_code = 0;
  546                 switch(rec->encoding) {
  547                 case AUDIO_ENCODING_ULAW:
  548                         rec->sw_code = ulinear8_to_mulaw;
  549                         break;
  550                 case AUDIO_ENCODING_SLINEAR_LE:
  551                         if (rec->precision == 8)
  552                                 rec->sw_code = change_sign8;
  553                         break;
  554                 case AUDIO_ENCODING_ULINEAR_LE:
  555                         if (rec->precision == 16)
  556                                 rec->sw_code = change_sign16;
  557                         break;
  558                 case AUDIO_ENCODING_ALAW:
  559                         rec->sw_code = ulinear8_to_alaw;
  560                         break;
  561                 case AUDIO_ENCODING_SLINEAR_BE:
  562                         if (rec->precision == 16)
  563                                 rec->sw_code = swap_bytes;
  564                         else
  565                                 rec->sw_code = change_sign8;
  566                         break;
  567                 case AUDIO_ENCODING_ULINEAR_BE:
  568                         if (rec->precision == 16)
  569                                 rec->sw_code = swap_bytes_change_sign16;
  570                         break;
  571                 default:
  572                         return (EINVAL);
  573                 }
  574 
  575                 error = ac97_set_rate(co->codec_if, rec, AUMODE_RECORD);
  576                 if (error)
  577                         return (error);
  578         }
  579 
  580         return (0);
  581 }
  582 
  583 
  584 /* called to translate a requested blocksize to a hw-possible one */
  585 int
  586 auixp_round_blocksize(void *v, int blk)
  587 {
  588 
  589         blk = (blk + 0x1f) & ~0x1f;
  590         /* Be conservative; align to 32 bytes and maximise it to 64 kb */
  591         if (blk > 0x10000)
  592                 blk = 0x10000;
  593 
  594         return blk;
  595 }
  596 
  597 
  598 /*
  599  * allocate dma capable memory and record its information for later retrieval
  600  * when we program the dma chain itself. The trigger routines passes on the
  601  * kernel virtual address we return here as a reference to the mapping.
  602  */
  603 void *
  604 auixp_malloc(void *hdl, int direction, size_t size, int pool, int flags)
  605 {
  606         struct auixp_codec *co;
  607         struct auixp_softc *sc;
  608         struct auixp_dma *dma;
  609         int error;
  610 
  611         co = (struct auixp_codec *) hdl;
  612         sc = co->sc;
  613         /* get us a auixp_dma structure */
  614         dma = malloc(sizeof(*dma), pool, flags);
  615         if (!dma)
  616                 return NULL;
  617 
  618         /* get us a dma buffer itself */
  619         error = auixp_allocmem(sc, size, 16, dma);
  620         if (error) {
  621                 free(dma, pool);
  622                 printf("%s: auixp_malloc: not enough memory\n",
  623                     sc->sc_dev.dv_xname);
  624                 return NULL;
  625         }
  626         SLIST_INSERT_HEAD(&sc->sc_dma_list, dma, dma_chain);
  627 
  628         DPRINTF(("auixp_malloc: returning kern %p,   hw 0x%08x for %d bytes "
  629             "in %d segs\n", KERNADDR(dma), (u_int32_t) DMAADDR(dma), dma->size,
  630             dma->nsegs)
  631         );
  632 
  633         return KERNADDR(dma);
  634 }
  635 
  636 /*
  637  * free and release dma capable memory we allocated before and remove its
  638  * recording
  639  */
  640 void
  641 auixp_free(void *hdl, void *addr, int pool)
  642 {
  643         struct auixp_codec *co;
  644         struct auixp_softc *sc;
  645         struct auixp_dma *dma;
  646 
  647         co = (struct auixp_codec *) hdl;
  648         sc = co->sc;
  649         SLIST_FOREACH(dma, &sc->sc_dma_list, dma_chain) {
  650                 if (KERNADDR(dma) == addr) {
  651                         SLIST_REMOVE(&sc->sc_dma_list, dma, auixp_dma,
  652                             dma_chain);
  653                         auixp_freemem(sc, dma);
  654                         free(dma, pool);
  655                         return;
  656                 }
  657         }
  658 }
  659 
  660 int
  661 auixp_getdev(void *v, struct audio_device *adp)
  662 {
  663         struct auixp_softc *sc = v;
  664         *adp = sc->sc_audev;
  665         return 0;
  666 }
  667 
  668 /* pass request to AC'97 codec code */
  669 int
  670 auixp_set_port(void *hdl, mixer_ctrl_t *mc)
  671 {
  672         struct auixp_codec *co;
  673 
  674         co = (struct auixp_codec *) hdl;
  675         return co->codec_if->vtbl->mixer_set_port(co->codec_if, mc);
  676 }
  677 
  678 
  679 /* pass request to AC'97 codec code */
  680 int
  681 auixp_get_port(void *hdl, mixer_ctrl_t *mc)
  682 {
  683         struct auixp_codec *co;
  684 
  685         co = (struct auixp_codec *) hdl;
  686         return co->codec_if->vtbl->mixer_get_port(co->codec_if, mc);
  687 }
  688 
  689 /* pass request to AC'97 codec code */
  690 int
  691 auixp_query_devinfo(void *hdl, mixer_devinfo_t *di)
  692 {
  693         struct auixp_codec *co;
  694 
  695         co = (struct auixp_codec *) hdl;
  696         return co->codec_if->vtbl->query_devinfo(co->codec_if, di);
  697 }
  698 
  699 
  700 size_t
  701 auixp_round_buffersize(void *hdl, int direction, size_t bufsize)
  702 {
  703 
  704         /* XXX force maximum? i.e. 256 kb? */
  705         return bufsize;
  706 }
  707 
  708 
  709 int
  710 auixp_get_props(void *hdl)
  711 {
  712 
  713         return AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX;
  714 }
  715 
  716 
  717 /*
  718  * A dma descriptor has dma->nsegs segments defined in dma->segs set up when
  719  * we claimed the memory.
  720  *
  721  * Due to our demand for one contiguous DMA area, we only have one segment. A
  722  * c_dma structure is about 3 kb for the 256 entries we maximally program
  723  * -arbitrary limit AFAIK- so all is most likely to be in one segment/page
  724  * anyway.
  725  *
  726  * XXX ought to implement fragmented dma area XXX
  727  *
  728  * Note that _v variables depict kernel virtual addresses, _p variables depict
  729  * physical addresses.
  730  */
  731 void
  732 auixp_link_daisychain(struct auixp_softc *sc,
  733                 struct auixp_dma *c_dma, struct auixp_dma *s_dma,
  734                 int blksize, int blocks)
  735 {
  736         atiixp_dma_desc_t *caddr_v, *next_caddr_v;
  737         u_int32_t caddr_p, next_caddr_p, saddr_p;
  738         int i;
  739 
  740         /* just make sure we are not changing when its running */
  741         auixp_disable_dma(sc, c_dma);
  742 
  743         /* setup dma chain start addresses */
  744         caddr_v = KERNADDR(c_dma);
  745         caddr_p = DMAADDR(c_dma);
  746         saddr_p = DMAADDR(s_dma);
  747 
  748         /* program the requested number of blocks */
  749         for (i = 0; i < blocks; i++) {
  750                 /* clear the block just in case */
  751                 bzero(caddr_v, sizeof(atiixp_dma_desc_t));
  752 
  753                 /* round robin the chain dma addresses for its successor */
  754                 next_caddr_v = caddr_v + 1;
  755                 next_caddr_p = caddr_p + sizeof(atiixp_dma_desc_t);
  756 
  757                 if (i == blocks-1) {
  758                         next_caddr_v = KERNADDR(c_dma);
  759                         next_caddr_p = DMAADDR(c_dma);
  760                 }
  761 
  762                 /* fill in the hardware dma chain descriptor in little-endian */
  763                 caddr_v->addr   = htole32(saddr_p);
  764                 caddr_v->status = htole16(0);
  765                 caddr_v->size   = htole16((blksize >> 2)); /* in dwords (!!!) */
  766                 caddr_v->next   = htole32(next_caddr_p);
  767 
  768                 /* advance slot */
  769                 saddr_p += blksize;     /* XXX assuming contiguous XXX */
  770                 caddr_v  = next_caddr_v;
  771                 caddr_p  = next_caddr_p;
  772         }
  773 }
  774 
  775 
  776 int
  777 auixp_allocate_dma_chain(struct auixp_softc *sc, struct auixp_dma **dmap)
  778 {
  779         struct auixp_dma *dma;
  780         int error;
  781 
  782         /* allocate keeper of dma area */
  783         *dmap = NULL;
  784         dma = malloc(sizeof(*dma), M_DEVBUF, M_NOWAIT);
  785         if (!dma)
  786                 return ENOMEM;
  787         bzero(dma, sizeof(*dma));
  788 
  789         /* allocate for daisychain of IXP hardware-dma descriptors */
  790         error = auixp_allocmem(sc, DMA_DESC_CHAIN * sizeof(atiixp_dma_desc_t),
  791             16, dma);
  792         if (error) {
  793                 printf("%s: can't malloc dma descriptor chain\n",
  794                     sc->sc_dev.dv_xname);
  795                 free(dma, M_DEVBUF);
  796                 return ENOMEM;
  797         }
  798 
  799         /* return info and initialise structure */
  800         dma->intr    = NULL;
  801         dma->intrarg = NULL;
  802 
  803         *dmap = dma;
  804         return 0;
  805 }
  806 
  807 
  808 /* program dma chain in its link address descriptor */
  809 void
  810 auixp_program_dma_chain(struct auixp_softc *sc, struct auixp_dma *dma)
  811 {
  812         bus_space_tag_t    iot;
  813         bus_space_handle_t ioh;
  814         u_int32_t value;
  815 
  816         iot = sc->sc_iot;
  817         ioh = sc->sc_ioh;
  818         /* get hardware start address of DMA chain and set valid-flag in it */
  819         /* XXX always at start? XXX */
  820         value = DMAADDR(dma);
  821         value = value | ATI_REG_LINKPTR_EN;
  822 
  823         /* reset linkpointer */
  824         bus_space_write_4(iot, ioh, dma->linkptr, 0);
  825 
  826         /* reset this DMA engine */
  827         auixp_disable_dma(sc, dma);
  828         auixp_enable_dma(sc, dma);
  829 
  830         /* program new DMA linkpointer */
  831         bus_space_write_4(iot, ioh, dma->linkptr, value);
  832 }
  833 
  834 
  835 /* called from interrupt code to signal end of one dma-slot */
  836 void
  837 auixp_dma_update(struct auixp_softc *sc, struct auixp_dma *dma)
  838 {
  839 
  840         /* be very paranoid */
  841         if (!dma)
  842                 panic("auixp: update: dma = NULL");
  843         if (!dma->intr)
  844                 panic("auixp: update: dma->intr = NULL");
  845 
  846         /* request more input from upper layer */
  847         (*dma->intr)(dma->intrarg);
  848 }
  849 
  850 
  851 /*
  852  * The magic `busbusy' bit that needs to be set when dma is active; allowing
  853  * busmastering?
  854  */
  855 void
  856 auixp_update_busbusy(struct auixp_softc *sc)
  857 {
  858         bus_space_tag_t    iot;
  859         bus_space_handle_t ioh;
  860         u_int32_t value;
  861         int running;
  862 
  863         iot = sc->sc_iot;
  864         ioh = sc->sc_ioh;
  865         /* set bus-busy flag when either recording or playing is performed */
  866         value  = bus_space_read_4(iot, ioh, ATI_REG_IER);
  867         value &= ~ATI_REG_IER_SET_BUS_BUSY;
  868 
  869         running = ((sc->sc_output_dma->running) || (sc->sc_input_dma->running));
  870         if (running)
  871                 value |= ATI_REG_IER_SET_BUS_BUSY;
  872 
  873         bus_space_write_4(iot, ioh, ATI_REG_IER, value);
  874 
  875 }
  876 
  877 
  878 /*
  879  * Called from upper audio layer to request playing audio, only called once;
  880  * audio is refilled by calling the intr() function when space is available
  881  * again.
  882  */
  883 /* XXX almost literally a copy of trigger-input; could be factorised XXX */
  884 int
  885 auixp_trigger_output(void *hdl, void *start, void *end, int blksize,
  886     void (*intr)(void *), void *intrarg, struct audio_params *param)
  887 {
  888         struct auixp_codec *co;
  889         struct auixp_softc *sc;
  890         struct auixp_dma   *chain_dma;
  891         struct auixp_dma   *sound_dma;
  892         u_int32_t blocks;
  893 
  894         co = (struct auixp_codec *) hdl;
  895         sc = co->sc;
  896         chain_dma = sc->sc_output_dma;
  897         /* add functions to call back */
  898         chain_dma->intr    = intr;
  899         chain_dma->intrarg = intrarg;
  900 
  901         /*
  902          * Program output DMA chain with blocks from [start...end] with
  903          * blksize fragments.
  904          *
  905          * NOTE, we can assume its in one block since we asked for it to be in
  906          * one contiguous blob; XXX change this? XXX
  907          */
  908         blocks = (size_t) (((caddr_t) end) - ((caddr_t) start)) / blksize;
  909 
  910         /* lookup `start' address in our list of DMA area's */
  911         SLIST_FOREACH(sound_dma, &sc->sc_dma_list, dma_chain) {
  912                 if (KERNADDR(sound_dma) == start)
  913                         break;
  914         }
  915 
  916         /* not ours ? then bail out */
  917         if (!sound_dma) {
  918                 printf("%s: auixp_trigger_output: bad sound addr %p\n",
  919                     sc->sc_dev.dv_xname, start);
  920                 return EINVAL;
  921         }
  922 
  923         /* link round-robin daisychain and program hardware */
  924         auixp_link_daisychain(sc, chain_dma, sound_dma, blksize, blocks);
  925         auixp_program_dma_chain(sc, chain_dma);
  926 
  927         /* mark we are now able to run now */
  928         chain_dma->running = 1;
  929 
  930         /* update bus-flags; XXX programs more flags XXX */
  931         auixp_update_busbusy(sc);
  932 
  933         /* callbacks happen in interrupt routine */
  934         return 0;
  935 }
  936 
  937 
  938 /* halt output of audio, just disable its dma and update bus state */
  939 int
  940 auixp_halt_output(void *hdl)
  941 {
  942         struct auixp_codec *co;
  943         struct auixp_softc *sc;
  944         struct auixp_dma   *dma;
  945 
  946         co  = (struct auixp_codec *) hdl;
  947         sc  = co->sc;
  948         dma = sc->sc_output_dma;
  949         auixp_disable_dma(sc, dma);
  950 
  951         dma->running = 0;
  952         auixp_update_busbusy(sc);
  953 
  954         return 0;
  955 }
  956 
  957 
  958 /* XXX almost literally a copy of trigger-output; could be factorised XXX */
  959 int
  960 auixp_trigger_input(void *hdl, void *start, void *end, int blksize,
  961     void (*intr)(void *), void *intrarg, struct audio_params *param)
  962 {
  963         struct auixp_codec *co;
  964         struct auixp_softc *sc;
  965         struct auixp_dma   *chain_dma;
  966         struct auixp_dma   *sound_dma;
  967         u_int32_t blocks;
  968 
  969         co = (struct auixp_codec *) hdl;
  970         sc = co->sc;
  971         chain_dma = sc->sc_input_dma;
  972         /* add functions to call back */
  973         chain_dma->intr    = intr;
  974         chain_dma->intrarg = intrarg;
  975 
  976         /*
  977          * Program output DMA chain with blocks from [start...end] with
  978          * blksize fragments.
  979          *
  980          * NOTE, we can assume its in one block since we asked for it to be in
  981          * one contiguous blob; XXX change this? XXX
  982          */
  983         blocks = (size_t) (((caddr_t) end) - ((caddr_t) start)) / blksize;
  984 
  985         /* lookup `start' address in our list of DMA area's */
  986         SLIST_FOREACH(sound_dma, &sc->sc_dma_list, dma_chain) {
  987                 if (KERNADDR(sound_dma) == start)
  988                         break;
  989         }
  990 
  991         /* not ours ? then bail out */
  992         if (!sound_dma) {
  993                 printf("%s: auixp_trigger_input: bad sound addr %p\n",
  994                     sc->sc_dev.dv_xname, start);
  995                 return EINVAL;
  996         }
  997 
  998         /* link round-robin daisychain and program hardware */
  999         auixp_link_daisychain(sc, chain_dma, sound_dma, blksize, blocks);
 1000         auixp_program_dma_chain(sc, chain_dma);
 1001 
 1002         /* mark we are now able to run now */
 1003         chain_dma->running = 1;
 1004 
 1005         /* update bus-flags; XXX programs more flags XXX */
 1006         auixp_update_busbusy(sc);
 1007 
 1008         /* callbacks happen in interrupt routine */
 1009         return 0;
 1010 }
 1011 
 1012 
 1013 /* halt sampling audio, just disable its dma and update bus state */
 1014 int
 1015 auixp_halt_input(void *hdl)
 1016 {
 1017         struct auixp_codec *co;
 1018         struct auixp_softc *sc;
 1019         struct auixp_dma   *dma;
 1020 
 1021         co = (struct auixp_codec *) hdl;
 1022         sc = co->sc;
 1023         dma = sc->sc_input_dma;
 1024         auixp_disable_dma(sc, dma);
 1025 
 1026         dma->running = 0;
 1027         auixp_update_busbusy(sc);
 1028 
 1029         return 0;
 1030 }
 1031 
 1032 
 1033 /*
 1034  * IXP audio interrupt handler
 1035  *
 1036  * note that we return the number of bits handled; the return value is not
 1037  * documented but I saw it implemented in other drivers. Probably returning a
 1038  * value > 0 means "I've dealt with it"
 1039  *
 1040  */
 1041 int
 1042 auixp_intr(void *softc)
 1043 {
 1044         struct auixp_softc *sc;
 1045         bus_space_tag_t    iot;
 1046         bus_space_handle_t ioh;
 1047         u_int32_t status, enable, detected_codecs;
 1048         int ret;
 1049 
 1050         sc = softc;
 1051         iot = sc->sc_iot;
 1052         ioh = sc->sc_ioh;
 1053         ret = 0;
 1054         /* get status from the interrupt status register */
 1055         status = bus_space_read_4(iot, ioh, ATI_REG_ISR);
 1056 
 1057         if (status == 0)
 1058                 return 0;
 1059 
 1060         DPRINTF(("%s: (status = %x)\n", sc->sc_dev.dv_xname, status));
 1061 
 1062         /* check DMA UPDATE flags for input & output */
 1063         if (status & ATI_REG_ISR_IN_STATUS) {
 1064                 ret++; DPRINTF(("IN_STATUS\n"));
 1065                 auixp_dma_update(sc, sc->sc_input_dma);
 1066         }
 1067         if (status & ATI_REG_ISR_OUT_STATUS) {
 1068                 ret++; DPRINTF(("OUT_STATUS\n"));
 1069                 auixp_dma_update(sc, sc->sc_output_dma);
 1070         }
 1071 
 1072         /* XXX XRUN flags not used/needed yet; should i implement it? XXX */
 1073         /* acknowledge the interrupts nevertheless */
 1074         if (status & ATI_REG_ISR_IN_XRUN) {
 1075                 ret++; DPRINTF(("IN_XRUN\n"));
 1076                 /* auixp_dma_xrun(sc, sc->sc_input_dma);  */
 1077         }
 1078         if (status & ATI_REG_ISR_OUT_XRUN) {
 1079                 ret++; DPRINTF(("OUT_XRUN\n"));
 1080                 /* auixp_dma_xrun(sc, sc->sc_output_dma); */
 1081         }
 1082 
 1083         /* check if we are looking for codec detection */
 1084         if (status & CODEC_CHECK_BITS) {
 1085                 ret++;
 1086                 /* mark missing codecs as not ready */
 1087                 detected_codecs = status & CODEC_CHECK_BITS;
 1088                 sc->sc_codec_not_ready_bits |= detected_codecs;
 1089 
 1090                 /* disable detected interrupt sources */
 1091                 enable  = bus_space_read_4(iot, ioh, ATI_REG_IER);
 1092                 enable &= ~detected_codecs;
 1093                 bus_space_write_4(iot, ioh, ATI_REG_IER, enable);
 1094         }
 1095 
 1096         /* acknowledge interrupt sources */
 1097         bus_space_write_4(iot, ioh, ATI_REG_ISR, status);
 1098 
 1099         return ret;
 1100 }
 1101 
 1102 
 1103 /* allocate memory for dma purposes; on failure of any of the steps, roll back */
 1104 int
 1105 auixp_allocmem(struct auixp_softc *sc, size_t size,
 1106                size_t align, struct auixp_dma *dma)
 1107 {
 1108         int error;
 1109 
 1110         /* remember size */
 1111         dma->size = size;
 1112 
 1113         /* allocate DMA safe memory but in just one segment for now :( */
 1114         error = bus_dmamem_alloc(sc->sc_dmat, dma->size, align, 0,
 1115             dma->segs, sizeof(dma->segs) / sizeof(dma->segs[0]), &dma->nsegs,
 1116             BUS_DMA_NOWAIT);
 1117         if (error)
 1118                 return error;
 1119 
 1120         /*
 1121          * map allocated memory into kernel virtual address space and keep it
 1122          * coherent with the CPU.
 1123          */
 1124         error = bus_dmamem_map(sc->sc_dmat, dma->segs, dma->nsegs, dma->size,
 1125                                 &dma->addr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
 1126         if (error)
 1127                 goto free;
 1128 
 1129         /* allocate associated dma handle and initialize it. */
 1130         error = bus_dmamap_create(sc->sc_dmat, dma->size, 1, dma->size, 0,
 1131                                   BUS_DMA_NOWAIT, &dma->map);
 1132         if (error)
 1133                 goto unmap;
 1134 
 1135         /*
 1136          * load the dma handle with mappings for a dma transfer; all pages
 1137          * need to be wired.
 1138          */
 1139         error = bus_dmamap_load(sc->sc_dmat, dma->map, dma->addr, dma->size, NULL,
 1140                                 BUS_DMA_NOWAIT);
 1141         if (error)
 1142                 goto destroy;
 1143 
 1144         return 0;
 1145 
 1146 destroy:
 1147         bus_dmamap_destroy(sc->sc_dmat, dma->map);
 1148 unmap:
 1149         bus_dmamem_unmap(sc->sc_dmat, dma->addr, dma->size);
 1150 free:
 1151         bus_dmamem_free(sc->sc_dmat, dma->segs, dma->nsegs);
 1152 
 1153         return error;
 1154 }
 1155 
 1156 
 1157 /* undo dma mapping and release memory allocated */
 1158 int
 1159 auixp_freemem(struct auixp_softc *sc, struct auixp_dma *p)
 1160 {
 1161 
 1162         bus_dmamap_unload(sc->sc_dmat, p->map);
 1163         bus_dmamap_destroy(sc->sc_dmat, p->map);
 1164         bus_dmamem_unmap(sc->sc_dmat, p->addr, p->size);
 1165         bus_dmamem_free(sc->sc_dmat, p->segs, p->nsegs);
 1166 
 1167         return 0;
 1168 }
 1169 
 1170 
 1171 /* memory map dma memory */
 1172 paddr_t
 1173 auixp_mappage(void *hdl, void *mem, off_t off, int prot)
 1174 {
 1175         struct auixp_codec *co;
 1176         struct auixp_softc *sc;
 1177         struct auixp_dma *p;
 1178 
 1179         co = (struct auixp_codec *) hdl;
 1180         sc  = co->sc;
 1181         /* for sanity */
 1182         if (off < 0)
 1183                 return -1;
 1184 
 1185         /* look up allocated DMA area */
 1186         SLIST_FOREACH(p, &sc->sc_dma_list, dma_chain) {
 1187                 if (KERNADDR(p) == mem)
 1188                         break;
 1189         }
 1190 
 1191         /* have we found it ? */
 1192         if (!p)
 1193                 return -1;
 1194 
 1195         /* return mmap'd region */
 1196         return bus_dmamem_mmap(sc->sc_dmat, p->segs, p->nsegs,
 1197             off, prot, BUS_DMA_WAITOK);
 1198 }
 1199 
 1200 int
 1201 auixp_match(struct device *dev, void *match, void *aux)
 1202 {
 1203         return (pci_matchbyid((struct pci_attach_args *)aux, auixp_pci_devices,
 1204             sizeof(auixp_pci_devices)/sizeof(auixp_pci_devices[0])));
 1205 }
 1206 
 1207 void
 1208 auixp_attach(struct device *parent, struct device *self, void *aux)
 1209 {
 1210         struct auixp_softc *sc;
 1211         struct pci_attach_args *pa;
 1212         pcitag_t tag;
 1213         pci_chipset_tag_t pc;
 1214         pci_intr_handle_t ih;
 1215         const char *intrstr;
 1216         int len;
 1217 
 1218         sc = (struct auixp_softc *)self;
 1219         pa = (struct pci_attach_args *)aux;
 1220         tag = pa->pa_tag;
 1221         pc = pa->pa_pc;
 1222 
 1223         /* map memory; its not sized -> what is the size? max PCI slot size? */
 1224         if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_MEM, 0,
 1225             &sc->sc_iot, &sc->sc_ioh, &sc->sc_iob, &sc->sc_ios, 0)) {
 1226                 printf(": can't map memory space\n");
 1227                 return;
 1228         }
 1229 
 1230         /* Initialize softc */
 1231         sc->sc_tag = tag;
 1232         sc->sc_pct = pc;
 1233         sc->sc_dmat = pa->pa_dmat;
 1234         SLIST_INIT(&sc->sc_dma_list);
 1235 
 1236         /* get us the auixp_dma structures */
 1237         auixp_allocate_dma_chain(sc, &sc->sc_output_dma);
 1238         auixp_allocate_dma_chain(sc, &sc->sc_input_dma);
 1239 
 1240         /* when that fails we are dead in the water */
 1241         if (!sc->sc_output_dma || !sc->sc_input_dma)
 1242                 return;
 1243 
 1244         /* fill in the missing details about the dma channels. */
 1245 
 1246         /* for output */
 1247         sc->sc_output_dma->linkptr        = ATI_REG_OUT_DMA_LINKPTR;
 1248         sc->sc_output_dma->dma_enable_bit = ATI_REG_CMD_OUT_DMA_EN |
 1249                                             ATI_REG_CMD_SEND_EN;
 1250         /* have spdif? then this too! XXX not seeing LED yet! XXX */
 1251         if (sc->has_spdif)
 1252                 sc->sc_output_dma->dma_enable_bit |= ATI_REG_CMD_SPDF_OUT_EN;
 1253 
 1254         /* and for input */
 1255         sc->sc_input_dma->linkptr         = ATI_REG_IN_DMA_LINKPTR;
 1256         sc->sc_input_dma->dma_enable_bit  = ATI_REG_CMD_IN_DMA_EN  |
 1257                                             ATI_REG_CMD_RECEIVE_EN;
 1258 
 1259 #if 0
 1260         /* could preliminary program DMA chain */
 1261         auixp_program_dma_chain(sc, sc->sc_output_dma);
 1262         auixp_program_dma_chain(sc, sc->sc_input_dma);
 1263 #endif
 1264 
 1265         if (pci_intr_map(pa, &ih)) {
 1266                 printf(": can't map interrupt\n");
 1267                 return;
 1268         }
 1269         intrstr = pci_intr_string(pc, ih);
 1270         sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO, auixp_intr, sc,
 1271             sc->sc_dev.dv_xname);
 1272         if (sc->sc_ih == NULL) {
 1273                 printf(": can't establish interrupt");
 1274                 if (intrstr != NULL)
 1275                         printf(" at %s", intrstr);
 1276                 printf("\n");
 1277                 return;
 1278         }
 1279         printf(": %s\n", intrstr);
 1280 
 1281         strlcpy(sc->sc_audev.name, "ATI IXP AC97", sizeof sc->sc_audev.name);
 1282         snprintf(sc->sc_audev.version, sizeof sc->sc_audev.version, "0x%02x",
 1283             PCI_REVISION(pa->pa_class));
 1284         strlcpy(sc->sc_audev.config, sc->sc_dev.dv_xname,
 1285             sizeof sc->sc_audev.config);
 1286 
 1287         /* power up chip */
 1288         auixp_power(sc, PCI_PMCSR_STATE_D0);
 1289 
 1290         /* init chip */
 1291         if (auixp_init(sc) == -1) {
 1292                 printf("%s: auixp_attach: unable to initialize the card\n",
 1293                     sc->sc_dev.dv_xname);
 1294                 return;
 1295         }
 1296 
 1297         /* XXX set up power hooks; not implemented yet XXX */
 1298 
 1299         len = 1;        /* shut up gcc */
 1300 #ifdef notyet
 1301         /* create suspend save area */
 1302         len = sizeof(u_int16_t) * (ESA_REV_B_CODE_MEMORY_LENGTH
 1303             + ESA_REV_B_DATA_MEMORY_LENGTH + 1);
 1304         sc->savemem = (u_int16_t *)malloc(len, M_DEVBUF, M_NOWAIT | M_ZERO);
 1305         if (sc->savemem == NULL) {
 1306                 printf("%s: unable to allocate suspend buffer\n",
 1307                     sc->sc_dev.dv_xname);
 1308                 return;
 1309         }
 1310 
 1311         sc->powerhook = powerhook_establish(auixp_powerhook, sc);
 1312         if (sc->powerhook == NULL)
 1313                 printf("%s: WARNING: unable to establish powerhook\n",
 1314                     sc->sc_dev.dv_xname);
 1315 
 1316 #endif
 1317 
 1318         /*
 1319          * delay further configuration of codecs and audio after interrupts
 1320          * are enabled.
 1321          */
 1322         mountroothook_establish(auixp_post_config, self);
 1323 }
 1324 
 1325 /* called from autoconfigure system when interrupts are enabled */
 1326 void
 1327 auixp_post_config(void *self)
 1328 {
 1329         struct auixp_softc *sc;
 1330         struct auixp_codec *codec;
 1331         int codec_nr;
 1332 
 1333         sc = (struct auixp_softc *)self;
 1334         /* detect the AC97 codecs */
 1335         auixp_autodetect_codecs(sc);
 1336 
 1337 #if notyet
 1338         /* copy formats and invalidate entries not suitable for codec0 */
 1339         sc->has_4ch   = AC97_IS_4CH(codec->codec_if);
 1340         sc->has_6ch   = AC97_IS_6CH(codec->codec_if);
 1341         sc->is_fixed  = AC97_IS_FIXED_RATE(codec->codec_if);
 1342         sc->has_spdif = AC97_HAS_SPDIF(codec->codec_if);
 1343 #endif
 1344 
 1345         /* attach audio devices for all detected codecs */
 1346         for (codec_nr = 0; codec_nr < ATI_IXP_CODECS; codec_nr++) {
 1347                 codec = &sc->sc_codec[codec_nr];
 1348                 if (codec->present)
 1349                         audio_attach_mi(&auixp_hw_if, codec, &sc->sc_dev);
 1350         }
 1351 
 1352         /* done! now enable all interrupts we can service */
 1353         auixp_enable_interrupts(sc);
 1354 }
 1355 
 1356 void
 1357 auixp_enable_interrupts(struct auixp_softc *sc)
 1358 {
 1359         bus_space_tag_t     iot;
 1360         bus_space_handle_t  ioh;
 1361         u_int32_t value;
 1362 
 1363         iot = sc->sc_iot;
 1364         ioh = sc->sc_ioh;
 1365         /* clear all pending */
 1366         bus_space_write_4(iot, ioh, ATI_REG_ISR, 0xffffffff);
 1367 
 1368         /* enable all relevant interrupt sources we can handle */
 1369         value = bus_space_read_4(iot, ioh, ATI_REG_IER);
 1370 
 1371         value |= ATI_REG_IER_IO_STATUS_EN;
 1372 #ifdef notyet
 1373         value |= ATI_REG_IER_IN_XRUN_EN;
 1374         value |= ATI_REG_IER_OUT_XRUN_EN;
 1375 
 1376         value |= ATI_REG_IER_SPDIF_XRUN_EN;
 1377         value |= ATI_REG_IER_SPDF_STATUS_EN;
 1378 #endif
 1379 
 1380         bus_space_write_4(iot, ioh, ATI_REG_IER, value);
 1381 }
 1382 
 1383 void
 1384 auixp_disable_interrupts(struct auixp_softc *sc)
 1385 {
 1386         bus_space_tag_t     iot;
 1387         bus_space_handle_t  ioh;
 1388 
 1389         iot = sc->sc_iot;
 1390         ioh = sc->sc_ioh;
 1391         /* disable all interrupt sources */
 1392         bus_space_write_4(iot, ioh, ATI_REG_IER, 0);
 1393 
 1394         /* clear all pending */
 1395         bus_space_write_4(iot, ioh, ATI_REG_ISR, 0xffffffff);
 1396 }
 1397 
 1398 /* dismantle what we've set up by undoing setup */
 1399 int
 1400 auixp_detach(struct device *self, int flags)
 1401 {
 1402         struct auixp_softc *sc;
 1403 
 1404         sc = (struct auixp_softc *)self;
 1405         /* XXX shouldn't we just reset the chip? XXX */
 1406         /*
 1407          * should we explicitly disable interrupt generation and acknowledge
 1408          * what's left on? better be safe than sorry.
 1409          */
 1410         auixp_disable_interrupts(sc);
 1411 
 1412         /* tear down .... */
 1413         config_detach(&sc->sc_dev, flags);      /* XXX OK? XXX */
 1414 
 1415         if (sc->sc_ih != NULL)
 1416                 pci_intr_disestablish(sc->sc_pct, sc->sc_ih);
 1417         if (sc->sc_ios)
 1418                 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
 1419 
 1420         if (sc->savemem)
 1421                 free(sc->savemem, M_DEVBUF);
 1422 
 1423         return 0;
 1424 }
 1425 
 1426 
 1427 /*
 1428  * codec handling
 1429  *
 1430  * IXP audio support can have upto 3 codecs! are they chained ? or
 1431  * alternative outlets with the same audio feed i.e. with different mixer
 1432  * settings? XXX does NetBSD support more than one audio codec? XXX
 1433  */
 1434 
 1435 
 1436 int
 1437 auixp_attach_codec(void *aux, struct ac97_codec_if *codec_if)
 1438 {
 1439         struct auixp_codec *ixp_codec;
 1440 
 1441         ixp_codec = aux;
 1442         ixp_codec->codec_if = codec_if;
 1443         ixp_codec->present  = 1;
 1444 
 1445         return 0;
 1446 }
 1447 
 1448 int
 1449 auixp_read_codec(void *aux, u_int8_t reg, u_int16_t *result)
 1450 {
 1451         struct auixp_codec *co;
 1452         struct auixp_softc *sc;
 1453         bus_space_tag_t     iot;
 1454         bus_space_handle_t  ioh;
 1455         u_int32_t data;
 1456         int timeout;
 1457 
 1458         co  = aux;
 1459         sc  = co->sc;
 1460         iot = sc->sc_iot;
 1461         ioh = sc->sc_ioh;
 1462         if (auixp_wait_for_codecs(sc, "read_codec"))
 1463                 return 0xffff;
 1464 
 1465         /* build up command for reading codec register */
 1466         data = (reg << ATI_REG_PHYS_OUT_ADDR_SHIFT) |
 1467                 ATI_REG_PHYS_OUT_ADDR_EN |
 1468                 ATI_REG_PHYS_OUT_RW |
 1469                 co->codec_nr;
 1470 
 1471         bus_space_write_4(iot, ioh, ATI_REG_PHYS_OUT_ADDR, data);
 1472 
 1473         if (auixp_wait_for_codecs(sc, "read_codec"))
 1474                 return 0xffff;
 1475 
 1476         /* wait until codec info is clocked in */
 1477         timeout = 500;          /* 500*2 usec -> 0.001 sec */
 1478         do {
 1479                 data = bus_space_read_4(iot, ioh, ATI_REG_PHYS_IN_ADDR);
 1480                 if (data & ATI_REG_PHYS_IN_READ_FLAG) {
 1481                         DPRINTF(("read ac'97 codec reg 0x%x = 0x%08x\n",
 1482                                 reg, data >> ATI_REG_PHYS_IN_DATA_SHIFT));
 1483                         *result = data >> ATI_REG_PHYS_IN_DATA_SHIFT;
 1484                         return 0;
 1485                 }
 1486                 DELAY(2);
 1487                 timeout--;
 1488         } while (timeout > 0);
 1489 
 1490         if (reg < 0x7c)
 1491                 printf("%s: codec read timeout! (reg %x)\n",
 1492                     sc->sc_dev.dv_xname, reg);
 1493 
 1494         return 0xffff;
 1495 }
 1496 
 1497 int
 1498 auixp_write_codec(void *aux, u_int8_t reg, u_int16_t data)
 1499 {
 1500         struct auixp_codec *co;
 1501         struct auixp_softc *sc;
 1502         bus_space_tag_t     iot;
 1503         bus_space_handle_t  ioh;
 1504         u_int32_t value;
 1505 
 1506         DPRINTF(("write ac'97 codec reg 0x%x = 0x%08x\n", reg, data));
 1507         co  = aux;
 1508         sc  = co->sc;
 1509         iot = sc->sc_iot;
 1510         ioh = sc->sc_ioh;
 1511         if (auixp_wait_for_codecs(sc, "write_codec"))
 1512                 return -1;
 1513 
 1514         /* build up command for writing codec register */
 1515         value = (((u_int32_t) data) << ATI_REG_PHYS_OUT_DATA_SHIFT) |
 1516                 (((u_int32_t)  reg) << ATI_REG_PHYS_OUT_ADDR_SHIFT) |
 1517                 ATI_REG_PHYS_OUT_ADDR_EN |
 1518                 co->codec_nr;
 1519 
 1520         bus_space_write_4(iot, ioh, ATI_REG_PHYS_OUT_ADDR, value);
 1521 
 1522         return 0;
 1523 }
 1524 
 1525 void
 1526 auixp_reset_codec(void *aux)
 1527 {
 1528 
 1529         /* nothing to be done? */
 1530 }
 1531 
 1532 enum ac97_host_flags
 1533 auixp_flags_codec(void *aux)
 1534 {
 1535         struct auixp_codec *ixp_codec;
 1536 
 1537         ixp_codec = aux;
 1538         return ixp_codec->codec_flags;
 1539 }
 1540 
 1541 int
 1542 auixp_wait_for_codecs(struct auixp_softc *sc, const char *func)
 1543 {
 1544         bus_space_tag_t      iot;
 1545         bus_space_handle_t   ioh;
 1546         u_int32_t value;
 1547         int timeout;
 1548 
 1549         iot = sc->sc_iot;
 1550         ioh = sc->sc_ioh;
 1551         /* wait until all codec transfers are done */
 1552         timeout = 500;          /* 500*2 usec -> 0.001 sec */
 1553         do {
 1554                 value = bus_space_read_4(iot, ioh, ATI_REG_PHYS_OUT_ADDR);
 1555                 if ((value & ATI_REG_PHYS_OUT_ADDR_EN) == 0)
 1556                         return 0;
 1557 
 1558                 DELAY(2);
 1559                 timeout--;
 1560         } while (timeout > 0);
 1561 
 1562         printf("%s: %s: timed out\n", func, sc->sc_dev.dv_xname);
 1563         return -1;
 1564 }
 1565 
 1566 void
 1567 auixp_autodetect_codecs(struct auixp_softc *sc)
 1568 {
 1569         bus_space_tag_t      iot;
 1570         bus_space_handle_t   ioh;
 1571         pcireg_t subdev;
 1572         struct auixp_codec  *codec;
 1573         int timeout, codec_nr;
 1574 
 1575         iot = sc->sc_iot;
 1576         ioh = sc->sc_ioh;
 1577         subdev = pci_conf_read(sc->sc_pct, sc->sc_tag, PCI_SUBSYS_ID_REG);
 1578 
 1579         /* ATI IXP can have upto 3 codecs; mark all codecs as not existing */
 1580         sc->sc_codec_not_ready_bits = 0;
 1581         sc->sc_num_codecs = 0;
 1582 
 1583         /* enable all codecs to interrupt as well as the new frame interrupt */
 1584         bus_space_write_4(iot, ioh, ATI_REG_IER, CODEC_CHECK_BITS);
 1585 
 1586         /* wait for the interrupts to happen */
 1587         timeout = 100;          /* 100.000 usec -> 0.1 sec */
 1588 
 1589         while (timeout > 0) {
 1590                 DELAY(1000);
 1591                 if (sc->sc_codec_not_ready_bits)
 1592                         break;
 1593                 timeout--;
 1594         }
 1595 
 1596         if (timeout == 0)
 1597                 printf("%s: WARNING: timeout during codec detection; "
 1598                         "codecs might be present but haven't interrupted\n",
 1599                         sc->sc_dev.dv_xname);
 1600 
 1601         /* disable all interrupts for now */
 1602         auixp_disable_interrupts(sc);
 1603 
 1604         /* Attach AC97 host interfaces */
 1605         for (codec_nr = 0; codec_nr < ATI_IXP_CODECS; codec_nr++) {
 1606                 codec = &sc->sc_codec[codec_nr];
 1607                 bzero(codec, sizeof(struct auixp_codec));
 1608 
 1609                 codec->sc       = sc;
 1610                 codec->codec_nr = codec_nr;
 1611                 codec->present  = 0;
 1612 
 1613                 codec->host_if.arg    = codec;
 1614                 codec->host_if.attach = auixp_attach_codec;
 1615                 codec->host_if.read   = auixp_read_codec;
 1616                 codec->host_if.write  = auixp_write_codec;
 1617                 codec->host_if.reset  = auixp_reset_codec;
 1618                 codec->host_if.flags  = auixp_flags_codec;
 1619                 switch (subdev) {
 1620                 case 0x1311462: /* MSI S270 */
 1621                         codec->codec_flags = AC97_HOST_DONT_ENABLE_SPDIF;
 1622                         break;
 1623                 }
 1624         }
 1625 
 1626         if (!(sc->sc_codec_not_ready_bits & ATI_REG_ISR_CODEC0_NOT_READY)) {
 1627                 /* codec 0 present */
 1628                 DPRINTF(("auixp : YAY! codec 0 present!\n"));
 1629                 if (ac97_attach(&sc->sc_codec[0].host_if) == 0)
 1630                         sc->sc_num_codecs++;
 1631         }
 1632 
 1633 #ifdef notyet
 1634         if (!(sc->sc_codec_not_ready_bits & ATI_REG_ISR_CODEC1_NOT_READY)) {
 1635                 /* codec 1 present */
 1636                 DPRINTF(("auixp : YAY! codec 1 present!\n"));
 1637                 if (ac97_attach(&sc->sc_codec[1].host_if, &sc->sc_dev) == 0)
 1638                         sc->sc_num_codecs++;
 1639         }
 1640 
 1641         if (!(sc->sc_codec_not_ready_bits & ATI_REG_ISR_CODEC2_NOT_READY)) {
 1642                 /* codec 2 present */
 1643                 DPRINTF(("auixp : YAY! codec 2 present!\n"));
 1644                 if (ac97_attach(&sc->sc_codec[2].host_if, &sc->sc_dev) == 0)
 1645                         sc->sc_num_codecs++;
 1646         }
 1647 #endif
 1648 
 1649         if (sc->sc_num_codecs == 0) {
 1650                 printf("%s: no codecs detected or initialised\n",
 1651                     sc->sc_dev.dv_xname);
 1652                 return;
 1653         }
 1654 }
 1655 
 1656 void
 1657 auixp_disable_dma(struct auixp_softc *sc, struct auixp_dma *dma)
 1658 {
 1659         bus_space_tag_t      iot;
 1660         bus_space_handle_t   ioh;
 1661         u_int32_t value;
 1662 
 1663         iot = sc->sc_iot;
 1664         ioh = sc->sc_ioh;
 1665         /* lets not stress the DMA engine more than necessary */
 1666         value = bus_space_read_4(iot, ioh, ATI_REG_CMD);
 1667         if (value & dma->dma_enable_bit) {
 1668                 value &= ~dma->dma_enable_bit;
 1669                 bus_space_write_4(iot, ioh, ATI_REG_CMD, value);
 1670         }
 1671 }
 1672 
 1673 void
 1674 auixp_enable_dma(struct auixp_softc *sc, struct auixp_dma *dma)
 1675 {
 1676         bus_space_tag_t      iot;
 1677         bus_space_handle_t   ioh;
 1678         u_int32_t value;
 1679 
 1680         iot = sc->sc_iot;
 1681         ioh = sc->sc_ioh;
 1682         /* lets not stress the DMA engine more than necesssary */
 1683         value = bus_space_read_4(iot, ioh, ATI_REG_CMD);
 1684         if (!(value & dma->dma_enable_bit)) {
 1685                 value |= dma->dma_enable_bit;
 1686                 bus_space_write_4(iot, ioh, ATI_REG_CMD, value);
 1687         }
 1688 }
 1689 
 1690 void
 1691 auixp_reset_aclink(struct auixp_softc *sc)
 1692 {
 1693         bus_space_tag_t      iot;
 1694         bus_space_handle_t   ioh;
 1695         u_int32_t value, timeout;
 1696 
 1697         iot = sc->sc_iot;
 1698         ioh = sc->sc_ioh;
 1699 
 1700         /* if power is down, power it up */
 1701         value = bus_space_read_4(iot, ioh, ATI_REG_CMD);
 1702         if (value & ATI_REG_CMD_POWERDOWN) {
 1703                 printf("%s: powering up\n", sc->sc_dev.dv_xname);
 1704 
 1705                 /* explicitly enable power */
 1706                 value &= ~ATI_REG_CMD_POWERDOWN;
 1707                 bus_space_write_4(iot, ioh, ATI_REG_CMD, value);
 1708 
 1709                 /* have to wait at least 10 usec for it to initialise */
 1710                 DELAY(20);
 1711         };
 1712 
 1713         printf("%s: soft resetting aclink\n", sc->sc_dev.dv_xname);
 1714 
 1715         /* perform a soft reset */
 1716         value  = bus_space_read_4(iot, ioh, ATI_REG_CMD);
 1717         value |= ATI_REG_CMD_AC_SOFT_RESET;
 1718         bus_space_write_4(iot, ioh, ATI_REG_CMD, value);
 1719 
 1720         /* need to read the CMD reg and wait aprox. 10 usec to init */
 1721         value  = bus_space_read_4(iot, ioh, ATI_REG_CMD);
 1722         DELAY(20);
 1723 
 1724         /* clear soft reset flag again */
 1725         value  = bus_space_read_4(iot, ioh, ATI_REG_CMD);
 1726         value &= ~ATI_REG_CMD_AC_SOFT_RESET;
 1727         bus_space_write_4(iot, ioh, ATI_REG_CMD, value);
 1728 
 1729         /* check if the ac-link is working; reset device otherwise */
 1730         timeout = 10;
 1731         value = bus_space_read_4(iot, ioh, ATI_REG_CMD);
 1732         while (!(value & ATI_REG_CMD_ACLINK_ACTIVE)) {
 1733                 printf("%s: not up; resetting aclink hardware\n",
 1734                                 sc->sc_dev.dv_xname);
 1735 
 1736                 /* dip aclink reset but keep the acsync */
 1737                 value &= ~ATI_REG_CMD_AC_RESET;
 1738                 value |=  ATI_REG_CMD_AC_SYNC;
 1739                 bus_space_write_4(iot, ioh, ATI_REG_CMD, value);
 1740 
 1741                 /* need to read CMD again and wait again (clocking in issue?) */
 1742                 value = bus_space_read_4(iot, ioh, ATI_REG_CMD);
 1743                 DELAY(20);
 1744 
 1745                 /* assert aclink reset again */
 1746                 value = bus_space_read_4(iot, ioh, ATI_REG_CMD);
 1747                 value |=  ATI_REG_CMD_AC_RESET;
 1748                 bus_space_write_4(iot, ioh, ATI_REG_CMD, value);
 1749 
 1750                 /* check if its active now */
 1751                 value = bus_space_read_4(iot, ioh, ATI_REG_CMD);
 1752 
 1753                 timeout--;
 1754                 if (timeout == 0) break;
 1755         };
 1756 
 1757         if (timeout == 0) {
 1758                 printf("%s: giving up aclink reset\n", sc->sc_dev.dv_xname);
 1759         };
 1760         if (timeout != 10) {
 1761                 printf("%s: aclink hardware reset successful\n",
 1762                         sc->sc_dev.dv_xname);
 1763         };
 1764 
 1765         /* assert reset and sync for safety */
 1766         value  = bus_space_read_4(iot, ioh, ATI_REG_CMD);
 1767         value |= ATI_REG_CMD_AC_SYNC | ATI_REG_CMD_AC_RESET;
 1768         bus_space_write_4(iot, ioh, ATI_REG_CMD, value);
 1769 }
 1770 
 1771 /* chip hard init */
 1772 int
 1773 auixp_init(struct auixp_softc *sc)
 1774 {
 1775         bus_space_tag_t      iot;
 1776         bus_space_handle_t   ioh;
 1777         u_int32_t value;
 1778 
 1779         iot = sc->sc_iot;
 1780         ioh = sc->sc_ioh;
 1781         /* disable all interrupts and clear all sources */
 1782         auixp_disable_interrupts(sc);
 1783 
 1784         /* clear all DMA enables (preserving rest of settings) */
 1785         value = bus_space_read_4(iot, ioh, ATI_REG_CMD);
 1786         value &= ~( ATI_REG_CMD_IN_DMA_EN  |
 1787                     ATI_REG_CMD_OUT_DMA_EN |
 1788                     ATI_REG_CMD_SPDF_OUT_EN );
 1789         bus_space_write_4(iot, ioh, ATI_REG_CMD, value);
 1790 
 1791         /* Reset AC-link */
 1792         auixp_reset_aclink(sc);
 1793 
 1794         /*
 1795          * codecs get auto-detected later
 1796          *
 1797          * note: we are NOT enabling interrupts yet, no codecs have been
 1798          * detected yet nor is anything else set up
 1799          */
 1800 
 1801         return 0;
 1802 }
 1803 
 1804 /*
 1805  * TODO power saving and suspend / resume support
 1806  */
 1807 int
 1808 auixp_power(struct auixp_softc *sc, int state)
 1809 {
 1810         pcitag_t tag;
 1811         pci_chipset_tag_t pc;
 1812         pcireg_t data;
 1813         int pmcapreg;
 1814 
 1815         tag = sc->sc_tag;
 1816         pc = sc->sc_pct;
 1817         if (pci_get_capability(pc, tag, PCI_CAP_PWRMGMT, &pmcapreg, 0)) {
 1818                 data = pci_conf_read(pc, tag, pmcapreg + PCI_PMCSR);
 1819                 if ((data & PCI_PMCSR_STATE_MASK) != state)
 1820                         pci_conf_write(pc, tag, pmcapreg + PCI_PMCSR, state);
 1821         }
 1822 
 1823         return 0;
 1824 }
 1825 
 1826 #if 0
 1827 void
 1828 auixp_powerhook(int why, void *hdl)
 1829 {
 1830         struct auixp_softc *sc;
 1831 
 1832         sc = (struct auixp_softc *)hdl;
 1833         switch (why) {
 1834         case PWR_SUSPEND:
 1835         case PWR_STANDBY:
 1836                 auixp_suspend(sc);
 1837                 break;
 1838         case PWR_RESUME:
 1839                 auixp_resume(sc);
 1840 /* XXX fix me XXX */
 1841                 (sc->codec_if->vtbl->restore_ports)(sc->codec_if);
 1842                 break;
 1843         }
 1844 }
 1845 
 1846 int
 1847 auixp_suspend(struct auixp_softc *sc)
 1848 {
 1849 
 1850         /* XXX no power functions yet XXX */
 1851         return 0;
 1852 }
 1853 
 1854 int
 1855 auixp_resume(struct auixp_softc *sc)
 1856 {
 1857 
 1858         /* XXX no power functions yet XXX */
 1859         return 0;
 1860 }
 1861 #endif /* 0 */

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