root/dev/pci/azalia.c

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

DEFINITIONS

This source file includes following definitions.
  1. azalia_dma_t
  2. stream_t
  3. azalia_t
  4. azalia_pci_match
  5. azalia_pci_attach
  6. azalia_pci_activate
  7. azalia_pci_detach
  8. azalia_intr
  9. azalia_attach
  10. azalia_attach_intr
  11. azalia_init_corb
  12. azalia_delete_corb
  13. azalia_init_rirb
  14. azalia_delete_rirb
  15. azalia_set_command
  16. azalia_get_response
  17. azalia_rirb_kick_unsol_events
  18. azalia_rirb_intr
  19. azalia_alloc_dmamem
  20. azalia_free_dmamem
  21. azalia_codec_init
  22. azalia_codec_delete
  23. azalia_codec_construct_format
  24. azalia_codec_add_bits
  25. azalia_codec_add_format
  26. azalia_codec_comresp
  27. azalia_codec_connect_stream
  28. azalia_widget_init
  29. azalia_widget_init_audio
  30. azalia_widget_print_audio
  31. azalia_widget_init_pin
  32. azalia_widget_print_pin
  33. azalia_widget_init_connection
  34. azalia_stream_init
  35. azalia_stream_delete
  36. azalia_stream_reset
  37. azalia_stream_start
  38. azalia_stream_halt
  39. azalia_stream_intr
  40. azalia_open
  41. azalia_close
  42. azalia_query_encoding
  43. azalia_set_params
  44. azalia_round_blocksize
  45. azalia_halt_output
  46. azalia_halt_input
  47. azalia_getdev
  48. azalia_set_port
  49. azalia_get_port
  50. azalia_query_devinfo
  51. azalia_allocm
  52. azalia_freem
  53. azalia_round_buffersize
  54. azalia_get_props
  55. azalia_trigger_output
  56. azalia_trigger_input
  57. azalia_params2fmt
  58. azalia_create_encodings

    1 /*      $OpenBSD: azalia.c,v 1.29 2007/08/02 17:13:31 reyk Exp $        */
    2 /*      $NetBSD: azalia.c,v 1.20 2006/05/07 08:31:44 kent Exp $ */
    3 
    4 /*-
    5  * Copyright (c) 2005 The NetBSD Foundation, Inc.
    6  * All rights reserved.
    7  *
    8  * This code is derived from software contributed to The NetBSD Foundation
    9  * by TAMURA Kent
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  * 3. All advertising materials mentioning features or use of this software
   20  *    must display the following acknowledgement:
   21  *        This product includes software developed by the NetBSD
   22  *        Foundation, Inc. and its contributors.
   23  * 4. Neither the name of The NetBSD Foundation nor the names of its
   24  *    contributors may be used to endorse or promote products derived
   25  *    from this software without specific prior written permission.
   26  *
   27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   37  * POSSIBILITY OF SUCH DAMAGE.
   38  */
   39 
   40 /*
   41  * High Definition Audio Specification
   42  *      ftp://download.intel.com/standards/hdaudio/pdf/HDAudio_03.pdf
   43  *
   44  *
   45  * TO DO:
   46  *  - S/PDIF
   47  *  - power hook
   48  *  - multiple codecs (needed?)
   49  *  - multiple streams (needed?)
   50  */
   51 
   52 #include <sys/cdefs.h>
   53 #ifdef NETBSD_GOOP
   54 __KERNEL_RCSID(0, "$NetBSD: azalia.c,v 1.15 2005/09/29 04:14:03 kent Exp $");
   55 #endif
   56 
   57 #include <sys/param.h>
   58 #include <sys/device.h>
   59 #include <sys/malloc.h>
   60 #include <sys/systm.h>
   61 #include <uvm/uvm_param.h>
   62 #include <dev/audio_if.h>
   63 #include <dev/auconv.h>
   64 #include <dev/pci/pcidevs.h>
   65 #include <dev/pci/pcivar.h>
   66 
   67 #include <dev/pci/azalia.h>
   68 
   69 typedef struct audio_params audio_params_t;
   70 #ifndef BUS_DMA_NOCACHE
   71 #define BUS_DMA_NOCACHE 0
   72 #endif
   73 #define auconv_delete_encodings(x...)
   74 #define auconv_query_encoding(x...)     (EINVAL)
   75 #define auconv_create_encodings(x...)   (0)
   76 
   77 struct audio_format {
   78         void *driver_data;
   79         int32_t mode;
   80         u_int encoding;
   81         u_int validbits;
   82         u_int precision;
   83         u_int channels;
   84         u_int channel_mask;
   85 #define AUFMT_UNKNOWN_POSITION          0U
   86 #define AUFMT_FRONT_LEFT                0x00001U /* USB audio compatible */
   87 #define AUFMT_FRONT_RIGHT               0x00002U /* USB audio compatible */
   88 #define AUFMT_FRONT_CENTER              0x00004U /* USB audio compatible */
   89 #define AUFMT_LOW_FREQUENCY             0x00008U /* USB audio compatible */
   90 #define AUFMT_BACK_LEFT                 0x00010U /* USB audio compatible */
   91 #define AUFMT_BACK_RIGHT                0x00020U /* USB audio compatible */
   92 #define AUFMT_FRONT_LEFT_OF_CENTER      0x00040U /* USB audio compatible */
   93 #define AUFMT_FRONT_RIGHT_OF_CENTER     0x00080U /* USB audio compatible */
   94 #define AUFMT_BACK_CENTER               0x00100U /* USB audio compatible */
   95 #define AUFMT_SIDE_LEFT                 0x00200U /* USB audio compatible */
   96 #define AUFMT_SIDE_RIGHT                0x00400U /* USB audio compatible */
   97 #define AUFMT_TOP_CENTER                0x00800U /* USB audio compatible */
   98 #define AUFMT_TOP_FRONT_LEFT            0x01000U
   99 #define AUFMT_TOP_FRONT_CENTER          0x02000U
  100 #define AUFMT_TOP_FRONT_RIGHT           0x04000U
  101 #define AUFMT_TOP_BACK_LEFT             0x08000U
  102 #define AUFMT_TOP_BACK_CENTER           0x10000U
  103 #define AUFMT_TOP_BACK_RIGHT            0x20000U
  104 
  105 #define AUFMT_MONAURAL          AUFMT_FRONT_CENTER
  106 #define AUFMT_STEREO            (AUFMT_FRONT_LEFT | AUFMT_FRONT_RIGHT)
  107 #define AUFMT_SURROUND4         (AUFMT_STEREO | AUFMT_BACK_LEFT \
  108                                 | AUFMT_BACK_RIGHT)
  109 #define AUFMT_DOLBY_5_1         (AUFMT_SURROUND4 | AUFMT_FRONT_CENTER \
  110                                 | AUFMT_LOW_FREQUENCY)
  111 
  112         /**
  113          * 0: frequency[0] is lower limit, and frequency[1] is higher limit.
  114          * 1-16: frequency[0] to frequency[frequency_type-1] are valid.
  115          */
  116         u_int frequency_type;
  117 
  118 #define AUFMT_MAX_FREQUENCIES   16
  119         /**
  120          * sampling rates
  121          */
  122         u_int frequency[AUFMT_MAX_FREQUENCIES];
  123 };
  124 
  125 #define AUFMT_INVALIDATE(fmt)   (fmt)->mode |= 0x80000000
  126 #define AUFMT_VALIDATE(fmt)     (fmt)->mode &= 0x7fffffff
  127 #define AUFMT_IS_VALID(fmt)     (((fmt)->mode & 0x80000000) == 0)
  128 
  129 /* ----------------------------------------------------------------
  130  * ICH6/ICH7 constant values
  131  * ---------------------------------------------------------------- */
  132 
  133 /* PCI registers */
  134 #define ICH_PCI_HDBARL  0x10
  135 #define ICH_PCI_HDBARU  0x14
  136 #define ICH_PCI_HDCTL   0x40
  137 #define         ICH_PCI_HDCTL_CLKDETCLR         0x08
  138 #define         ICH_PCI_HDCTL_CLKDETEN          0x04
  139 #define         ICH_PCI_HDCTL_CLKDETINV         0x02
  140 #define         ICH_PCI_HDCTL_SIGNALMODE        0x01
  141 
  142 /* internal types */
  143 
  144 typedef struct {
  145         bus_dmamap_t map;
  146         caddr_t addr;           /* kernel virtual address */
  147         bus_dma_segment_t segments[1];
  148         size_t size;
  149 } azalia_dma_t;
  150 #define AZALIA_DMA_DMAADDR(p)   ((p)->map->dm_segs[0].ds_addr)
  151 
  152 typedef struct {
  153         struct azalia_t *az;
  154         int regbase;
  155         int number;
  156         int dir;                /* AUMODE_PLAY or AUMODE_RECORD */
  157         uint32_t intr_bit;
  158         azalia_dma_t bdlist;
  159         azalia_dma_t buffer;
  160         void (*intr)(void*);
  161         void *intr_arg;
  162 } stream_t;
  163 #define STR_READ_1(s, r)        \
  164         bus_space_read_1((s)->az->iot, (s)->az->ioh, (s)->regbase + HDA_SD_##r)
  165 #define STR_READ_2(s, r)        \
  166         bus_space_read_2((s)->az->iot, (s)->az->ioh, (s)->regbase + HDA_SD_##r)
  167 #define STR_READ_4(s, r)        \
  168         bus_space_read_4((s)->az->iot, (s)->az->ioh, (s)->regbase + HDA_SD_##r)
  169 #define STR_WRITE_1(s, r, v)    \
  170         bus_space_write_1((s)->az->iot, (s)->az->ioh, (s)->regbase + HDA_SD_##r, v)
  171 #define STR_WRITE_2(s, r, v)    \
  172         bus_space_write_2((s)->az->iot, (s)->az->ioh, (s)->regbase + HDA_SD_##r, v)
  173 #define STR_WRITE_4(s, r, v)    \
  174         bus_space_write_4((s)->az->iot, (s)->az->ioh, (s)->regbase + HDA_SD_##r, v)
  175 
  176 typedef struct azalia_t {
  177         struct device dev;
  178         struct device *audiodev;
  179 
  180         pci_chipset_tag_t pc;
  181         void *ih;
  182         bus_space_tag_t iot;
  183         bus_space_handle_t ioh;
  184         bus_size_t map_size;
  185         bus_dma_tag_t dmat;
  186         pcireg_t pciid;
  187         uint32_t subid;
  188 
  189         codec_t codecs[15];
  190         int ncodecs;            /* number of codecs */
  191         int codecno;            /* index of the using codec */
  192 
  193         azalia_dma_t corb_dma;
  194         int corb_size;
  195         azalia_dma_t rirb_dma;
  196         int rirb_size;
  197         int rirb_rp;
  198 #define UNSOLQ_SIZE     256
  199         rirb_entry_t *unsolq;
  200         int unsolq_wp;
  201         int unsolq_rp;
  202         boolean_t unsolq_kick;
  203 
  204         boolean_t ok64;
  205         int nistreams, nostreams, nbstreams;
  206         stream_t pstream;
  207         stream_t rstream;
  208 } azalia_t;
  209 #define XNAME(sc)               ((sc)->dev.dv_xname)
  210 #define AZ_READ_1(z, r)         bus_space_read_1((z)->iot, (z)->ioh, HDA_##r)
  211 #define AZ_READ_2(z, r)         bus_space_read_2((z)->iot, (z)->ioh, HDA_##r)
  212 #define AZ_READ_4(z, r)         bus_space_read_4((z)->iot, (z)->ioh, HDA_##r)
  213 #define AZ_WRITE_1(z, r, v)     bus_space_write_1((z)->iot, (z)->ioh, HDA_##r, v)
  214 #define AZ_WRITE_2(z, r, v)     bus_space_write_2((z)->iot, (z)->ioh, HDA_##r, v)
  215 #define AZ_WRITE_4(z, r, v)     bus_space_write_4((z)->iot, (z)->ioh, HDA_##r, v)
  216 
  217 
  218 /* prototypes */
  219 int     azalia_pci_match(struct device *, void *, void *);
  220 void    azalia_pci_attach(struct device *, struct device *, void *);
  221 int     azalia_pci_activate(struct device *, enum devact);
  222 int     azalia_pci_detach(struct device *, int);
  223 int     azalia_intr(void *);
  224 int     azalia_attach(azalia_t *);
  225 void    azalia_attach_intr(struct device *);
  226 int     azalia_init_corb(azalia_t *);
  227 int     azalia_delete_corb(azalia_t *);
  228 int     azalia_init_rirb(azalia_t *);
  229 int     azalia_delete_rirb(azalia_t *);
  230 int     azalia_set_command(azalia_t *, nid_t, int, uint32_t,
  231         uint32_t);
  232 int     azalia_get_response(azalia_t *, uint32_t *);
  233 void    azalia_rirb_kick_unsol_events(azalia_t *);
  234 void    azalia_rirb_intr(azalia_t *);
  235 int     azalia_alloc_dmamem(azalia_t *, size_t, size_t, azalia_dma_t *);
  236 int     azalia_free_dmamem(const azalia_t *, azalia_dma_t*);
  237 
  238 int     azalia_codec_init(codec_t *);
  239 int     azalia_codec_delete(codec_t *);
  240 void    azalia_codec_add_bits(codec_t *, int, uint32_t, int);
  241 void    azalia_codec_add_format(codec_t *, int, int, int, uint32_t,
  242         int32_t);
  243 int     azalia_codec_comresp(const codec_t *, nid_t, uint32_t,
  244         uint32_t, uint32_t *);
  245 int     azalia_codec_connect_stream(codec_t *, int, uint16_t, int);
  246 
  247 int     azalia_widget_init(widget_t *, const codec_t *, int);
  248 int     azalia_widget_init_audio(widget_t *, const codec_t *);
  249 int     azalia_widget_print_audio(const widget_t *, const char *);
  250 int     azalia_widget_init_pin(widget_t *, const codec_t *);
  251 int     azalia_widget_print_pin(const widget_t *);
  252 int     azalia_widget_init_connection(widget_t *, const codec_t *);
  253 
  254 int     azalia_stream_init(stream_t *, azalia_t *, int, int, int);
  255 int     azalia_stream_delete(stream_t *, azalia_t *);
  256 int     azalia_stream_reset(stream_t *);
  257 int     azalia_stream_start(stream_t *, void *, void *, int,
  258         void (*)(void *), void *, uint16_t);
  259 int     azalia_stream_halt(stream_t *);
  260 int     azalia_stream_intr(stream_t *, uint32_t);
  261 
  262 int     azalia_open(void *, int);
  263 void    azalia_close(void *);
  264 int     azalia_query_encoding(void *, audio_encoding_t *);
  265 int     azalia_set_params(void *, int, int, audio_params_t *,
  266         audio_params_t *);
  267 int     azalia_round_blocksize(void *, int);
  268 int     azalia_halt_output(void *);
  269 int     azalia_halt_input(void *);
  270 int     azalia_getdev(void *, struct audio_device *);
  271 int     azalia_set_port(void *, mixer_ctrl_t *);
  272 int     azalia_get_port(void *, mixer_ctrl_t *);
  273 int     azalia_query_devinfo(void *, mixer_devinfo_t *);
  274 void    *azalia_allocm(void *, int, size_t, int, int);
  275 void    azalia_freem(void *, void *, int);
  276 size_t  azalia_round_buffersize(void *, int, size_t);
  277 int     azalia_get_props(void *);
  278 int     azalia_trigger_output(void *, void *, void *, int,
  279         void (*)(void *), void *, audio_params_t *);
  280 int     azalia_trigger_input(void *, void *, void *, int,
  281         void (*)(void *), void *, audio_params_t *);
  282 
  283 int     azalia_params2fmt(const audio_params_t *, uint16_t *);
  284 int azalia_create_encodings(struct audio_format *, int,
  285     struct audio_encoding_set **);
  286 
  287 /* variables */
  288 struct cfattach azalia_ca = {
  289         sizeof(azalia_t), azalia_pci_match, azalia_pci_attach,
  290         azalia_pci_detach, azalia_pci_activate
  291 };
  292 
  293 struct cfdriver azalia_cd = {
  294         NULL, "azalia", DV_DULL
  295 };
  296 
  297 struct audio_hw_if azalia_hw_if = {
  298         azalia_open,
  299         azalia_close,
  300         NULL,                   /* drain */
  301         azalia_query_encoding,
  302         azalia_set_params,
  303         azalia_round_blocksize,
  304         NULL,                   /* commit_settings */
  305         NULL,                   /* init_output */
  306         NULL,                   /* init_input */
  307         NULL,                   /* start_output */
  308         NULL,                   /* start_input */
  309         azalia_halt_output,
  310         azalia_halt_input,
  311         NULL,                   /* speaker_ctl */
  312         azalia_getdev,
  313         NULL,                   /* setfd */
  314         azalia_set_port,
  315         azalia_get_port,
  316         azalia_query_devinfo,
  317         azalia_allocm,
  318         azalia_freem,
  319         azalia_round_buffersize,
  320         NULL,                   /* mappage */
  321         azalia_get_props,
  322         azalia_trigger_output,
  323         azalia_trigger_input,
  324 };
  325 
  326 static const char *pin_colors[16] = {
  327         "unknown", "black", "gray", "blue",
  328         "green", "red", "orange", "yellow",
  329         "purple", "pink", "col0a", "col0b",
  330         "col0c", "col0d", "white", "other"};
  331 #ifdef AZALIA_DEBUG
  332 static const char *pin_devices[16] = {
  333         "line-out", AudioNspeaker, AudioNheadphone, AudioNcd,
  334         "SPDIF-out", "digital-out", "modem-line", "modem-handset",
  335         "line-in", AudioNaux, AudioNmicrophone, "telephony",
  336         "SPDIF-in", "digital-in", "dev0e", "other"};
  337 #endif
  338 
  339 /* ================================================================
  340  * PCI functions
  341  * ================================================================ */
  342 
  343 #define PCI_ID_CODE0(v, p)      PCI_ID_CODE(PCI_VENDOR_##v, PCI_PRODUCT_##v##_##p)
  344 #define PCIID_NVIDIA_MCP51      PCI_ID_CODE0(NVIDIA, MCP51_HDA)
  345 #define PCIID_NVIDIA_MCP55      PCI_ID_CODE0(NVIDIA, MCP55_HDA)
  346 #define PCIID_ALI_M5461         PCI_ID_CODE0(ALI, M5461)
  347 #define PCIID_VIATECH_HDA       PCI_ID_CODE0(VIATECH, HDA)
  348 
  349 int
  350 azalia_pci_match(struct device *parent, void *match, void *aux)
  351 {
  352         struct pci_attach_args *pa;
  353 
  354         pa = aux;
  355         if (PCI_CLASS(pa->pa_class) == PCI_CLASS_MULTIMEDIA
  356             && PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MULTIMEDIA_HDAUDIO)
  357                 return 1;
  358         return 0;
  359 }
  360 
  361 void
  362 azalia_pci_attach(struct device *parent, struct device *self, void *aux)
  363 {
  364         azalia_t *sc;
  365         struct pci_attach_args *pa;
  366         pcireg_t v;
  367         pci_intr_handle_t ih;
  368         const char *intrrupt_str;
  369 
  370         sc = (azalia_t*)self;
  371         pa = aux;
  372 
  373         sc->dmat = pa->pa_dmat;
  374 
  375         v = pci_conf_read(pa->pa_pc, pa->pa_tag, ICH_PCI_HDBARL);
  376         v &= PCI_MAPREG_TYPE_MASK | PCI_MAPREG_MEM_TYPE_MASK;
  377         if (pci_mapreg_map(pa, ICH_PCI_HDBARL, v, 0,
  378                            &sc->iot, &sc->ioh, NULL, &sc->map_size, 0)) {
  379                 printf(": can't map device i/o space\n");
  380                 return;
  381         }
  382 
  383         /* enable back-to-back */
  384         v = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
  385         pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
  386             v | PCI_COMMAND_BACKTOBACK_ENABLE);
  387 
  388         v = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x44);
  389         pci_conf_write(pa->pa_pc, pa->pa_tag, 0x44, v & (~0x7));
  390 
  391         /* interrupt */
  392         if (pci_intr_map(pa, &ih)) {
  393                 printf(": can't map interrupt\n");
  394                 return;
  395         }
  396         sc->pc = pa->pa_pc;
  397         intrrupt_str = pci_intr_string(pa->pa_pc, ih);
  398         sc->ih = pci_intr_establish(pa->pa_pc, ih, IPL_AUDIO, azalia_intr,
  399             sc, sc->dev.dv_xname);
  400         if (sc->ih == NULL) {
  401                 printf(": can't establish interrupt");
  402                 if (intrrupt_str != NULL)
  403                         printf(" at %s", intrrupt_str);
  404                 printf("\n");
  405                 return;
  406         }
  407         printf(": %s\n", intrrupt_str);
  408 
  409         sc->pciid = pa->pa_id;
  410 
  411         if (azalia_attach(sc)) {
  412                 printf("%s: initialization failure\n", XNAME(sc));
  413                 azalia_pci_detach(self, 0);
  414                 return;
  415         }
  416         sc->subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
  417 
  418         azalia_attach_intr(self);
  419 }
  420 
  421 int
  422 azalia_pci_activate(struct device *self, enum devact act)
  423 {
  424         azalia_t *sc;
  425         int ret;
  426 
  427         sc = (azalia_t*)self;
  428         ret = 0;
  429         switch (act) {
  430         case DVACT_ACTIVATE:
  431                 return ret;
  432         case DVACT_DEACTIVATE:
  433                 if (sc->audiodev != NULL)
  434                         ret = config_deactivate(sc->audiodev);
  435                 return ret;
  436         }
  437         return EOPNOTSUPP;
  438 }
  439 
  440 int
  441 azalia_pci_detach(struct device *self, int flags)
  442 {
  443         azalia_t *az;
  444         int i;
  445 
  446         DPRINTF(("%s\n", __func__));
  447         az = (azalia_t*)self;
  448         if (az->audiodev != NULL) {
  449                 config_detach(az->audiodev, flags);
  450                 az->audiodev = NULL;
  451         }
  452 
  453         DPRINTF(("%s: delete streams\n", __func__));
  454         azalia_stream_delete(&az->rstream, az);
  455         azalia_stream_delete(&az->pstream, az);
  456 
  457         DPRINTF(("%s: delete codecs\n", __func__));
  458         for (i = 0; i < az->ncodecs; i++) {
  459                 azalia_codec_delete(&az->codecs[i]);
  460         }
  461         az->ncodecs = 0;
  462 
  463         DPRINTF(("%s: delete CORB and RIRB\n", __func__));
  464         azalia_delete_corb(az);
  465         azalia_delete_rirb(az);
  466 
  467         DPRINTF(("%s: delete PCI resources\n", __func__));
  468         if (az->ih != NULL) {
  469                 pci_intr_disestablish(az->pc, az->ih);
  470                 az->ih = NULL;
  471         }
  472         if (az->map_size != 0) {
  473                 bus_space_unmap(az->iot, az->ioh, az->map_size);
  474                 az->map_size = 0;
  475         }
  476         return 0;
  477 }
  478 
  479 int
  480 azalia_intr(void *v)
  481 {
  482         azalia_t *az = v;
  483         int ret = 0;
  484         uint32_t intsts;
  485         uint8_t rirbsts, rirbctl;
  486 
  487         intsts = AZ_READ_4(az, INTSTS);
  488         if (intsts == 0)
  489                 return (0);
  490 
  491         AZ_WRITE_4(az, INTSTS, intsts);
  492 
  493         ret += azalia_stream_intr(&az->pstream, intsts);
  494         ret += azalia_stream_intr(&az->rstream, intsts);
  495 
  496         rirbctl = AZ_READ_1(az, RIRBCTL);
  497         rirbsts = AZ_READ_1(az, RIRBSTS);
  498 
  499         if (intsts & HDA_INTCTL_CIE) {
  500                 if (rirbctl & HDA_RIRBCTL_RINTCTL) {
  501                         if (rirbsts & HDA_RIRBSTS_RINTFL)
  502                                 azalia_rirb_intr(az);
  503                 }
  504         }
  505 
  506         return (1);
  507 }
  508 
  509 /* ================================================================
  510  * HDA controller functions
  511  * ================================================================ */
  512 
  513 int
  514 azalia_attach(azalia_t *az)
  515 {
  516         int i, n;
  517         uint32_t gctl;
  518         uint16_t gcap;
  519         uint16_t statests;
  520 
  521         printf("%s: host: High Definition Audio rev. %d.%d\n",
  522             XNAME(az), AZ_READ_1(az, VMAJ), AZ_READ_1(az, VMIN));
  523         gcap = AZ_READ_2(az, GCAP);
  524         az->nistreams = HDA_GCAP_ISS(gcap);
  525         az->nostreams = HDA_GCAP_OSS(gcap);
  526         az->nbstreams = HDA_GCAP_BSS(gcap);
  527         az->ok64 = (gcap & HDA_GCAP_64OK) != 0;
  528         DPRINTF(("%s: host: %d output, %d input, and %d bidi streams\n",
  529             XNAME(az), az->nostreams, az->nistreams, az->nbstreams));
  530 
  531         /* 4.2.2 Starting the High Definition Audio Controller */
  532         DPRINTF(("%s: resetting\n", __func__));
  533         gctl = AZ_READ_4(az, GCTL);
  534         AZ_WRITE_4(az, GCTL, gctl & ~HDA_GCTL_CRST);
  535         for (i = 5000; i >= 0; i--) {
  536                 DELAY(10);
  537                 if ((AZ_READ_4(az, GCTL) & HDA_GCTL_CRST) == 0)
  538                         break;
  539         }
  540         DPRINTF(("%s: reset counter = %d\n", __func__, i));
  541         if (i <= 0) {
  542                 printf("%s: reset failure\n", XNAME(az));
  543                 return ETIMEDOUT;
  544         }
  545         DELAY(1000);
  546         gctl = AZ_READ_4(az, GCTL);
  547         AZ_WRITE_4(az, GCTL, gctl | HDA_GCTL_CRST);
  548         for (i = 5000; i >= 0; i--) {
  549                 DELAY(10);
  550                 if (AZ_READ_4(az, GCTL) & HDA_GCTL_CRST)
  551                         break;
  552         }
  553         DPRINTF(("%s: reset counter = %d\n", __func__, i));
  554         if (i <= 0) {
  555                 printf("%s: reset-exit failure\n", XNAME(az));
  556                 return ETIMEDOUT;
  557         }
  558 
  559         /* enable unsolicited response */
  560         gctl = AZ_READ_4(az, GCTL);
  561         AZ_WRITE_4(az, GCTL, gctl | HDA_GCTL_UNSOL);
  562 
  563         /* 4.3 Codec discovery */
  564         DELAY(1000);
  565         statests = AZ_READ_2(az, STATESTS);
  566         for (i = 0, n = 0; i < 15; i++) {
  567                 if ((statests >> i) & 1) {
  568                         DPRINTF(("%s: found a codec at #%d\n", XNAME(az), i));
  569                         az->codecs[n].address = i;
  570                         az->codecs[n++].az = az;
  571                 }
  572         }
  573         az->ncodecs = n;
  574         if (az->ncodecs < 1) {
  575                 printf("%s: No HD-Audio codecs\n", XNAME(az));
  576                 return -1;
  577         }
  578         return 0;
  579 }
  580 
  581 void
  582 azalia_attach_intr(struct device *self)
  583 {
  584         azalia_t *az;
  585         int err, i, c;
  586 
  587         az = (azalia_t*)self;
  588 
  589         AZ_WRITE_2(az, STATESTS, HDA_STATESTS_SDIWAKE);
  590         AZ_WRITE_1(az, RIRBSTS, HDA_RIRBSTS_RINTFL | HDA_RIRBSTS_RIRBOIS);
  591         AZ_WRITE_4(az, INTSTS, HDA_INTSTS_CIS | HDA_INTSTS_GIS);
  592         AZ_WRITE_4(az, DPLBASE, 0);
  593         AZ_WRITE_4(az, DPUBASE, 0);
  594 
  595         /* 4.4.1 Command Outbound Ring Buffer */
  596         if (azalia_init_corb(az))
  597                 goto err_exit;
  598         /* 4.4.2 Response Inbound Ring Buffer */
  599         if (azalia_init_rirb(az))
  600                 goto err_exit;
  601 
  602         AZ_WRITE_4(az, INTCTL,
  603             AZ_READ_4(az, INTCTL) | HDA_INTCTL_CIE | HDA_INTCTL_GIE);
  604 
  605         c = -1;
  606         for (i = 0; i < az->ncodecs; i++) {
  607                 err = azalia_codec_init(&az->codecs[i]);
  608                 if (!err && c < 0)
  609                         c = i;
  610         }
  611         if (c < 0)
  612                 goto err_exit;
  613         /* Use the first audio codec */
  614         az->codecno = c;
  615         DPRINTF(("%s: using the #%d codec\n", XNAME(az), az->codecno));
  616 
  617         if (azalia_stream_init(&az->pstream, az, az->nistreams + 0,
  618             1, AUMODE_PLAY))
  619                 goto err_exit;
  620         if (azalia_stream_init(&az->rstream, az, 0, 2, AUMODE_RECORD))
  621                 goto err_exit;
  622 
  623         az->audiodev = audio_attach_mi(&azalia_hw_if, az, &az->dev);
  624         return;
  625 err_exit:
  626         azalia_pci_detach(self, 0);
  627         return;
  628 }
  629 
  630 int
  631 azalia_init_corb(azalia_t *az)
  632 {
  633         int entries, err, i;
  634         uint16_t corbrp, corbwp;
  635         uint8_t corbsize, cap, corbctl;
  636 
  637         /* stop the CORB */
  638         corbctl = AZ_READ_1(az, CORBCTL);
  639         if (corbctl & HDA_CORBCTL_CORBRUN) { /* running? */
  640                 AZ_WRITE_1(az, CORBCTL, corbctl & ~HDA_CORBCTL_CORBRUN);
  641                 for (i = 5000; i >= 0; i--) {
  642                         DELAY(10);
  643                         corbctl = AZ_READ_1(az, CORBCTL);
  644                         if ((corbctl & HDA_CORBCTL_CORBRUN) == 0)
  645                                 break;
  646                 }
  647                 if (i <= 0) {
  648                         printf("%s: CORB is running\n", XNAME(az));
  649                         return EBUSY;
  650                 }
  651         }
  652 
  653         /* determine CORB size */
  654         corbsize = AZ_READ_1(az, CORBSIZE);
  655         cap = corbsize & HDA_CORBSIZE_CORBSZCAP_MASK;
  656         corbsize &= ~HDA_CORBSIZE_CORBSIZE_MASK;
  657         if (cap & HDA_CORBSIZE_CORBSZCAP_256) {
  658                 entries = 256;
  659                 corbsize |= HDA_CORBSIZE_CORBSIZE_256;
  660         } else if (cap & HDA_CORBSIZE_CORBSZCAP_16) {
  661                 entries = 16;
  662                 corbsize |= HDA_CORBSIZE_CORBSIZE_16;
  663         } else if (cap & HDA_CORBSIZE_CORBSZCAP_2) {
  664                 entries = 2;
  665                 corbsize |= HDA_CORBSIZE_CORBSIZE_2;
  666         } else {
  667                 printf("%s: Invalid CORBSZCAP: 0x%2x\n", XNAME(az), cap);
  668                 return -1;
  669         }
  670 
  671         err = azalia_alloc_dmamem(az, entries * sizeof(corb_entry_t),
  672             128, &az->corb_dma);
  673         if (err) {
  674                 printf("%s: can't allocate CORB buffer\n", XNAME(az));
  675                 return err;
  676         }
  677         AZ_WRITE_4(az, CORBLBASE, (uint32_t)AZALIA_DMA_DMAADDR(&az->corb_dma));
  678         AZ_WRITE_4(az, CORBUBASE, PTR_UPPER32(AZALIA_DMA_DMAADDR(&az->corb_dma)));
  679         AZ_WRITE_1(az, CORBSIZE, corbsize);
  680         az->corb_size = entries;
  681 
  682         DPRINTF(("%s: CORB allocation succeeded.\n", __func__));
  683 
  684         /* reset CORBRP */
  685         corbrp = AZ_READ_2(az, CORBRP);
  686         AZ_WRITE_2(az, CORBRP, corbrp | HDA_CORBRP_CORBRPRST);
  687         AZ_WRITE_2(az, CORBRP, corbrp & ~HDA_CORBRP_CORBRPRST);
  688         for (i = 5000; i >= 0; i--) {
  689                 DELAY(10);
  690                 corbrp = AZ_READ_2(az, CORBRP);
  691                 if ((corbrp & HDA_CORBRP_CORBRPRST) == 0)
  692                         break;
  693         }
  694         if (i <= 0) {
  695                 printf("%s: CORBRP reset failure\n", XNAME(az));
  696                 return -1;
  697         }
  698         DPRINTF(("%s: CORBWP=%d; size=%d\n", __func__,
  699                  AZ_READ_2(az, CORBRP) & HDA_CORBRP_CORBRP, az->corb_size));
  700 
  701         /* clear CORBWP */
  702         corbwp = AZ_READ_2(az, CORBWP);
  703         AZ_WRITE_2(az, CORBWP, corbwp & ~HDA_CORBWP_CORBWP);
  704 
  705         /* Run! */
  706         corbctl = AZ_READ_1(az, CORBCTL);
  707         AZ_WRITE_1(az, CORBCTL, corbctl | HDA_CORBCTL_CORBRUN);
  708         return 0;
  709 }
  710 
  711 int
  712 azalia_delete_corb(azalia_t *az)
  713 {
  714         int i;
  715         uint8_t corbctl;
  716 
  717         if (az->corb_dma.addr == NULL)
  718                 return 0;
  719         /* stop the CORB */
  720         corbctl = AZ_READ_1(az, CORBCTL);
  721         AZ_WRITE_1(az, CORBCTL, corbctl & ~HDA_CORBCTL_CORBRUN);
  722         for (i = 5000; i >= 0; i--) {
  723                 DELAY(10);
  724                 corbctl = AZ_READ_1(az, CORBCTL);
  725                 if ((corbctl & HDA_CORBCTL_CORBRUN) == 0)
  726                         break;
  727         }
  728         azalia_free_dmamem(az, &az->corb_dma);
  729         return 0;
  730 }
  731 
  732 int
  733 azalia_init_rirb(azalia_t *az)
  734 {
  735         int entries, err, i;
  736         uint16_t rirbwp;
  737         uint8_t rirbsize, cap, rirbctl;
  738 
  739         /* stop the RIRB */
  740         rirbctl = AZ_READ_1(az, RIRBCTL);
  741         if (rirbctl & HDA_RIRBCTL_RIRBDMAEN) { /* running? */
  742                 AZ_WRITE_1(az, RIRBCTL, rirbctl & ~HDA_RIRBCTL_RIRBDMAEN);
  743                 for (i = 5000; i >= 0; i--) {
  744                         DELAY(10);
  745                         rirbctl = AZ_READ_1(az, RIRBCTL);
  746                         if ((rirbctl & HDA_RIRBCTL_RIRBDMAEN) == 0)
  747                                 break;
  748                 }
  749                 if (i <= 0) {
  750                         printf("%s: RIRB is running\n", XNAME(az));
  751                         return EBUSY;
  752                 }
  753         }
  754 
  755         /* determine RIRB size */
  756         rirbsize = AZ_READ_1(az, RIRBSIZE);
  757         cap = rirbsize & HDA_RIRBSIZE_RIRBSZCAP_MASK;
  758         rirbsize &= ~HDA_RIRBSIZE_RIRBSIZE_MASK;
  759         if (cap & HDA_RIRBSIZE_RIRBSZCAP_256) {
  760                 entries = 256;
  761                 rirbsize |= HDA_RIRBSIZE_RIRBSIZE_256;
  762         } else if (cap & HDA_RIRBSIZE_RIRBSZCAP_16) {
  763                 entries = 16;
  764                 rirbsize |= HDA_RIRBSIZE_RIRBSIZE_16;
  765         } else if (cap & HDA_RIRBSIZE_RIRBSZCAP_2) {
  766                 entries = 2;
  767                 rirbsize |= HDA_RIRBSIZE_RIRBSIZE_2;
  768         } else {
  769                 printf("%s: Invalid RIRBSZCAP: 0x%2x\n", XNAME(az), cap);
  770                 return -1;
  771         }
  772 
  773         err = azalia_alloc_dmamem(az, entries * sizeof(rirb_entry_t),
  774             128, &az->rirb_dma);
  775         if (err) {
  776                 printf("%s: can't allocate RIRB buffer\n", XNAME(az));
  777                 return err;
  778         }
  779         AZ_WRITE_4(az, RIRBLBASE, (uint32_t)AZALIA_DMA_DMAADDR(&az->rirb_dma));
  780         AZ_WRITE_4(az, RIRBUBASE, PTR_UPPER32(AZALIA_DMA_DMAADDR(&az->rirb_dma)));
  781         AZ_WRITE_1(az, RIRBSIZE, rirbsize);
  782         az->rirb_size = entries;
  783 
  784         DPRINTF(("%s: RIRB allocation succeeded.\n", __func__));
  785 
  786         /* setup the unsolicited response queue */
  787         az->unsolq_rp = 0;
  788         az->unsolq_wp = 0;
  789         az->unsolq_kick = FALSE;
  790         az->unsolq = malloc(sizeof(rirb_entry_t) * UNSOLQ_SIZE,
  791             M_DEVBUF, M_NOWAIT);
  792         if (az->unsolq == NULL) {
  793                 DPRINTF(("%s: can't allocate unsolicited response queue.\n",
  794                     XNAME(az)));
  795                 azalia_free_dmamem(az, &az->rirb_dma);
  796                 return ENOMEM;
  797         }
  798         bzero(az->unsolq, sizeof(rirb_entry_t) * UNSOLQ_SIZE);
  799 
  800         /* reset the write pointer */
  801         rirbwp = AZ_READ_2(az, RIRBWP);
  802         AZ_WRITE_2(az, RIRBWP, rirbwp | HDA_RIRBWP_RIRBWPRST);
  803 
  804         /* clear the read pointer */
  805         az->rirb_rp = AZ_READ_2(az, RIRBWP) & HDA_RIRBWP_RIRBWP;
  806         DPRINTF(("%s: RIRBRP=%d, size=%d\n", __func__, az->rirb_rp, az->rirb_size));
  807 
  808         AZ_WRITE_2(az, RINTCNT, 1);
  809 
  810         /* Run! */
  811         rirbctl = AZ_READ_1(az, RIRBCTL);
  812         AZ_WRITE_1(az, RIRBCTL, rirbctl |
  813             HDA_RIRBCTL_RIRBDMAEN | HDA_RIRBCTL_RINTCTL);
  814 
  815         return (0);
  816 }
  817 
  818 int
  819 azalia_delete_rirb(azalia_t *az)
  820 {
  821         int i;
  822         uint8_t rirbctl;
  823 
  824         if (az->unsolq != NULL) {
  825                 free(az->unsolq, M_DEVBUF);
  826                 az->unsolq = NULL;
  827         }
  828         if (az->rirb_dma.addr == NULL)
  829                 return 0;
  830         /* stop the RIRB */
  831         rirbctl = AZ_READ_1(az, RIRBCTL);
  832         AZ_WRITE_1(az, RIRBCTL, rirbctl & ~HDA_RIRBCTL_RIRBDMAEN);
  833         for (i = 5000; i >= 0; i--) {
  834                 DELAY(10);
  835                 rirbctl = AZ_READ_1(az, RIRBCTL);
  836                 if ((rirbctl & HDA_RIRBCTL_RIRBDMAEN) == 0)
  837                         break;
  838         }
  839         azalia_free_dmamem(az, &az->rirb_dma);
  840         return 0;
  841 }
  842 
  843 int
  844 azalia_set_command(azalia_t *az, int caddr, nid_t nid, uint32_t control,
  845                    uint32_t param)
  846 {
  847         corb_entry_t *corb;
  848         int  wp;
  849         uint32_t verb;
  850         uint16_t corbwp;
  851         uint8_t rirbctl;
  852 
  853 #ifdef DIAGNOSTIC
  854         if ((AZ_READ_1(az, CORBCTL) & HDA_CORBCTL_CORBRUN) == 0) {
  855                 printf("%s: CORB is not running.\n", XNAME(az));
  856                 return -1;
  857         }
  858 #endif
  859         verb = (caddr << 28) | (nid << 20) | (control << 8) | param;
  860         corbwp = AZ_READ_2(az, CORBWP);
  861         wp = corbwp & HDA_CORBWP_CORBWP;
  862         corb = (corb_entry_t*)az->corb_dma.addr;
  863         if (++wp >= az->corb_size)
  864                 wp = 0;
  865         corb[wp] = verb;
  866 
  867         /* disable RIRB interrupts */
  868         rirbctl = AZ_READ_1(az, RIRBCTL);
  869         if (rirbctl & HDA_RIRBCTL_RINTCTL) {
  870                 AZ_WRITE_1(az, RIRBCTL, rirbctl & ~HDA_RIRBCTL_RINTCTL);
  871                 azalia_rirb_intr(az);
  872         }
  873 
  874         AZ_WRITE_2(az, CORBWP, (corbwp & ~HDA_CORBWP_CORBWP) | wp);
  875 #if 0
  876         DPRINTF(("%s: caddr=%d nid=%d control=0x%x param=0x%x verb=0x%8.8x wp=%d\n",
  877                  __func__, caddr, nid, control, param, verb, wp));
  878 #endif
  879         return 0;
  880 }
  881 
  882 int
  883 azalia_get_response(azalia_t *az, uint32_t *result)
  884 {
  885         const rirb_entry_t *rirb;
  886         int i;
  887         uint16_t wp;
  888         uint8_t rirbctl;
  889 
  890 #ifdef DIAGNOSTIC
  891         if ((AZ_READ_1(az, RIRBCTL) & HDA_RIRBCTL_RIRBDMAEN) == 0) {
  892                 printf("%s: RIRB is not running.\n", XNAME(az));
  893                 return -1;
  894         }
  895 #endif
  896         for (i = 5000; i >= 0; i--) {
  897                 wp = AZ_READ_2(az, RIRBWP) & HDA_RIRBWP_RIRBWP;
  898                 if (az->rirb_rp != wp)
  899                         break;
  900                 DELAY(10);
  901         }
  902         if (i <= 0) {
  903                 printf("%s: RIRB time out\n", XNAME(az));
  904                 return ETIMEDOUT;
  905         }
  906         rirb = (rirb_entry_t*)az->rirb_dma.addr;
  907         for (;;) {
  908                 if (++az->rirb_rp >= az->rirb_size)
  909                         az->rirb_rp = 0;
  910                 if (rirb[az->rirb_rp].resp_ex & RIRB_RESP_UNSOL) {
  911                         az->unsolq[az->unsolq_wp].resp = rirb[az->rirb_rp].resp;
  912                         az->unsolq[az->unsolq_wp++].resp_ex = rirb[az->rirb_rp].resp_ex;
  913                         az->unsolq_wp %= UNSOLQ_SIZE;
  914                 } else
  915                         break;
  916         }
  917         if (result != NULL)
  918                 *result = rirb[az->rirb_rp].resp;
  919 
  920         azalia_rirb_kick_unsol_events(az);
  921 #if 0
  922         for (i = 0; i < 16 /*az->rirb_size*/; i++) {
  923                 DPRINTF(("rirb[%d] 0x%8.8x:0x%8.8x ", i, rirb[i].resp, rirb[i].resp_ex));
  924                 if ((i % 2) == 1)
  925                         DPRINTF(("\n"));
  926         }
  927 #endif
  928 
  929         /* re-enable RIRB interrupts */
  930         rirbctl = AZ_READ_1(az, RIRBCTL);
  931         AZ_WRITE_1(az, RIRBCTL, rirbctl | HDA_RIRBCTL_RINTCTL);
  932 
  933         return 0;
  934 }
  935 
  936 void
  937 azalia_rirb_kick_unsol_events(azalia_t *az)
  938 {
  939         if (az->unsolq_kick)
  940                 return;
  941         az->unsolq_kick = TRUE;
  942         while (az->unsolq_rp != az->unsolq_wp) {
  943                 int i;
  944                 int tag;
  945                 codec_t *codec;
  946                 i = RIRB_RESP_CODEC(az->unsolq[az->unsolq_rp].resp_ex);
  947                 tag = RIRB_UNSOL_TAG(az->unsolq[az->unsolq_rp].resp);
  948                 codec = &az->codecs[i];
  949                 DPRINTF(("%s: codec#=%d tag=%d\n", __func__, i, tag));
  950                 az->unsolq_rp++;
  951                 az->unsolq_rp %= UNSOLQ_SIZE;
  952                 if (codec->unsol_event != NULL)
  953                         codec->unsol_event(codec, tag);
  954         }
  955         az->unsolq_kick = FALSE;
  956 }
  957 
  958 void
  959 azalia_rirb_intr(azalia_t *az)
  960 {
  961         const rirb_entry_t *rirb;
  962         uint16_t wp, rp;
  963         uint8_t rirbsts;
  964 
  965         rirbsts = AZ_READ_1(az, RIRBSTS);
  966 
  967         wp = AZ_READ_2(az, RIRBWP) & HDA_RIRBWP_RIRBWP;
  968         if (rp == wp)
  969                 return;         /* interrupted but no data in RIRB */
  970         rirb = (rirb_entry_t*)az->rirb_dma.addr;
  971         while (az->rirb_rp != wp) {
  972                 if (++az->rirb_rp >= az->rirb_size)
  973                         az->rirb_rp = 0;
  974                 if (rirb[az->rirb_rp].resp_ex & RIRB_RESP_UNSOL) {
  975                         az->unsolq[az->unsolq_wp].resp = rirb[az->rirb_rp].resp;
  976                         az->unsolq[az->unsolq_wp++].resp_ex = rirb[az->rirb_rp].resp_ex;
  977                         az->unsolq_wp %= UNSOLQ_SIZE;
  978                 } else {
  979                         break;
  980                 }
  981         }
  982 
  983         azalia_rirb_kick_unsol_events(az);
  984 
  985         AZ_WRITE_1(az, RIRBSTS,
  986             rirbsts | HDA_RIRBSTS_RIRBOIS | HDA_RIRBSTS_RINTFL);
  987 }
  988 
  989 int
  990 azalia_alloc_dmamem(azalia_t *az, size_t size, size_t align, azalia_dma_t *d)
  991 {
  992         int err;
  993         int nsegs;
  994 
  995         d->size = size;
  996         err = bus_dmamem_alloc(az->dmat, size, align, 0, d->segments, 1,
  997             &nsegs, BUS_DMA_NOWAIT);
  998         if (err)
  999                 return err;
 1000         if (nsegs != 1)
 1001                 goto free;
 1002         err = bus_dmamem_map(az->dmat, d->segments, 1, size,
 1003             &d->addr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT | BUS_DMA_NOCACHE);
 1004         if (err)
 1005                 goto free;
 1006         err = bus_dmamap_create(az->dmat, size, 1, size, 0,
 1007             BUS_DMA_NOWAIT, &d->map);
 1008         if (err)
 1009                 goto unmap;
 1010         err = bus_dmamap_load(az->dmat, d->map, d->addr, size,
 1011             NULL, BUS_DMA_NOWAIT);
 1012         if (err)
 1013                 goto destroy;
 1014 
 1015         if (!az->ok64 && PTR_UPPER32(AZALIA_DMA_DMAADDR(d)) != 0) {
 1016                 azalia_free_dmamem(az, d);
 1017                 return -1;
 1018         }
 1019         return 0;
 1020 
 1021 destroy:
 1022         bus_dmamap_destroy(az->dmat, d->map);
 1023 unmap:
 1024         bus_dmamem_unmap(az->dmat, d->addr, size);
 1025 free:
 1026         bus_dmamem_free(az->dmat, d->segments, 1);
 1027         d->addr = NULL;
 1028         return err;
 1029 }
 1030 
 1031 int
 1032 azalia_free_dmamem(const azalia_t *az, azalia_dma_t* d)
 1033 {
 1034         if (d->addr == NULL)
 1035                 return 0;
 1036         bus_dmamap_unload(az->dmat, d->map);
 1037         bus_dmamap_destroy(az->dmat, d->map);
 1038         bus_dmamem_unmap(az->dmat, d->addr, d->size);
 1039         bus_dmamem_free(az->dmat, d->segments, 1);
 1040         d->addr = NULL;
 1041         return 0;
 1042 }
 1043 
 1044 /* ================================================================
 1045  * HDA codec functions
 1046  * ================================================================ */
 1047 
 1048 int
 1049 azalia_codec_init(codec_t *this)
 1050 {
 1051         uint32_t rev, id, result;
 1052         int err, addr, n, i;
 1053         const char *vendor;
 1054 
 1055         this->comresp = azalia_codec_comresp;
 1056         addr = this->address;
 1057         DPRINTF(("%s: information of codec[%d] follows:\n",
 1058             XNAME(this->az), addr));
 1059         /* codec vendor/device/revision */
 1060         err = this->comresp(this, CORB_NID_ROOT, CORB_GET_PARAMETER,
 1061             COP_REVISION_ID, &rev);
 1062         if (err)
 1063                 return err;
 1064         err = this->comresp(this, CORB_NID_ROOT, CORB_GET_PARAMETER,
 1065             COP_VENDOR_ID, &id);
 1066         if (err)
 1067                 return err;
 1068         this->vid = id;
 1069         this->subid = this->az->subid;
 1070         azalia_codec_init_vtbl(this);
 1071 
 1072         printf("%s: codec:", XNAME(this->az));
 1073         if (this->name == NULL) {
 1074                 vendor = pci_findvendor(id >> 16);
 1075                 if (vendor == NULL)
 1076                         printf(" 0x%04x/0x%04x", id >> 16, id & 0xffff);
 1077                 else
 1078                         printf(" %s/0x%04x", vendor, id & 0xffff);
 1079         } else
 1080                 printf(" %s", this->name);
 1081         printf(" (rev. %u.%u), HDA version %u.%u\n",
 1082             COP_RID_REVISION(rev), COP_RID_STEPPING(rev),
 1083             COP_RID_MAJ(rev), COP_RID_MIN(rev));
 1084 
 1085         /* identify function nodes */
 1086         err = this->comresp(this, CORB_NID_ROOT, CORB_GET_PARAMETER,
 1087             COP_SUBORDINATE_NODE_COUNT, &result);
 1088         if (err)
 1089                 return err;
 1090         this->nfunctions = COP_NSUBNODES(result);
 1091         if (COP_NSUBNODES(result) <= 0) {
 1092                 printf("%s: No function groups\n", XNAME(this->az));
 1093                 return -1;
 1094         }
 1095         /* iterate function nodes and find an audio function */
 1096         n = COP_START_NID(result);
 1097         DPRINTF(("%s: nidstart=%d #functions=%d\n",
 1098             __func__, n, this->nfunctions));
 1099         this->audiofunc = -1;
 1100         for (i = 0; i < this->nfunctions; i++) {
 1101                 err = this->comresp(this, n + i, CORB_GET_PARAMETER,
 1102                     COP_FUNCTION_GROUP_TYPE, &result);
 1103                 if (err)
 1104                         continue;
 1105                 DPRINTF(("%s: FTYPE result = 0x%8.8x\n", __func__, result));
 1106                 if (COP_FTYPE(result) == COP_FTYPE_AUDIO) {
 1107                         this->audiofunc = n + i;
 1108                         break;  /* XXX multiple audio functions? */
 1109                 } else if (COP_FTYPE(result) == COP_FTYPE_MODEM) {
 1110                         printf("%s: codec[%d]: No support for modem function groups\n",
 1111                             XNAME(this->az), addr);
 1112                 }
 1113         }
 1114         if (this->audiofunc < 0) {
 1115                 printf("%s: codec[%d]: No audio function groups\n",
 1116                     XNAME(this->az), addr);
 1117                 return -1;
 1118         }
 1119 
 1120         /* power the audio function */
 1121         this->comresp(this, this->audiofunc, CORB_SET_POWER_STATE, CORB_PS_D0, &result);
 1122         DELAY(100);
 1123 
 1124         /* check widgets in the audio function */
 1125         err = this->comresp(this, this->audiofunc,
 1126             CORB_GET_PARAMETER, COP_SUBORDINATE_NODE_COUNT, &result);
 1127         if (err)
 1128                 return err;
 1129         DPRINTF(("%s: There are %d widgets in the audio function.\n",
 1130            __func__, COP_NSUBNODES(result)));
 1131         this->wstart = COP_START_NID(result);
 1132         if (this->wstart < 2) {
 1133                 printf("%s: invalid node structure\n", XNAME(this->az));
 1134                 return -1;
 1135         }
 1136         this->wend = this->wstart + COP_NSUBNODES(result);
 1137         this->w = malloc(sizeof(widget_t) * this->wend, M_DEVBUF, M_NOWAIT);
 1138         if (this->w == NULL) {
 1139                 printf("%s: out of memory\n", XNAME(this->az));
 1140                 return ENOMEM;
 1141         }
 1142         bzero(this->w, sizeof(widget_t) * this->wend);
 1143 
 1144         /* query the base parameters */
 1145         this->comresp(this, this->audiofunc, CORB_GET_PARAMETER,
 1146             COP_STREAM_FORMATS, &result);
 1147         this->w[this->audiofunc].d.audio.encodings = result;
 1148         this->comresp(this, this->audiofunc, CORB_GET_PARAMETER,
 1149             COP_PCM, &result);
 1150         this->w[this->audiofunc].d.audio.bits_rates = result;
 1151         this->comresp(this, this->audiofunc, CORB_GET_PARAMETER,
 1152             COP_INPUT_AMPCAP, &result);
 1153         this->w[this->audiofunc].inamp_cap = result;
 1154         this->comresp(this, this->audiofunc, CORB_GET_PARAMETER,
 1155             COP_OUTPUT_AMPCAP, &result);
 1156         this->w[this->audiofunc].outamp_cap = result;
 1157 #ifdef AZALIA_DEBUG
 1158         azalia_widget_print_audio(&this->w[this->audiofunc], "\t");
 1159         result = this->w[this->audiofunc].inamp_cap;
 1160         DPRINTF(("\tinamp: mute=%u size=%u steps=%u offset=%u\n",
 1161             (result & COP_AMPCAP_MUTE) != 0, COP_AMPCAP_STEPSIZE(result),
 1162             COP_AMPCAP_NUMSTEPS(result), COP_AMPCAP_OFFSET(result)));
 1163         result = this->w[this->audiofunc].outamp_cap;
 1164         DPRINTF(("\toutamp: mute=%u size=%u steps=%u offset=%u\n",
 1165             (result & COP_AMPCAP_MUTE) != 0, COP_AMPCAP_STEPSIZE(result),
 1166             COP_AMPCAP_NUMSTEPS(result), COP_AMPCAP_OFFSET(result)));
 1167 #endif
 1168 
 1169         strlcpy(this->w[CORB_NID_ROOT].name, "root",
 1170             sizeof(this->w[CORB_NID_ROOT].name));
 1171         strlcpy(this->w[this->audiofunc].name, "hdaudio",
 1172             sizeof(this->w[this->audiofunc].name));
 1173         FOR_EACH_WIDGET(this, i) {
 1174                 err = azalia_widget_init(&this->w[i], this, i);
 1175                 if (err)
 1176                         return err;
 1177         }
 1178 
 1179         err = this->init_dacgroup(this);
 1180         if (err)
 1181                 return err;
 1182 #ifdef AZALIA_DEBUG
 1183         for (i = 0; i < this->dacs.ngroups; i++) {
 1184                 DPRINTF(("%s: dacgroup[%d]:", __func__, i));
 1185                 for (n = 0; n < this->dacs.groups[i].nconv; n++) {
 1186                         DPRINTF((" %2.2x", this->dacs.groups[i].conv[n]));
 1187                 }
 1188                 DPRINTF(("\n"));
 1189         }
 1190 #endif
 1191 
 1192         /* set invalid values for azalia_codec_construct_format() to work */
 1193         this->dacs.cur = -1;
 1194         this->adcs.cur = -1;
 1195         err = azalia_codec_construct_format(this, 0, 0);
 1196         if (err)
 1197                 return err;
 1198 
 1199         return this->mixer_init(this);
 1200 }
 1201 
 1202 int
 1203 azalia_codec_delete(codec_t *this)
 1204 {
 1205         if (this->mixer_delete != NULL)
 1206                 this->mixer_delete(this);
 1207         if (this->formats != NULL) {
 1208                 free(this->formats, M_DEVBUF);
 1209                 this->formats = NULL;
 1210         }
 1211         printf("delete_encodings...\n");
 1212         auconv_delete_encodings(this->encodings);
 1213         this->encodings = NULL;
 1214         return 0;
 1215 }
 1216 
 1217 int
 1218 azalia_codec_construct_format(codec_t *this, int newdac, int newadc)
 1219 {
 1220         const convgroup_t *group;
 1221         uint32_t bits_rates;
 1222         int prev_dac, prev_adc;
 1223         int pvariation, rvariation;
 1224         int nbits, c, chan, i, err;
 1225         nid_t nid;
 1226 
 1227         prev_dac = this->dacs.cur;
 1228         this->dacs.cur = newdac;
 1229         group = &this->dacs.groups[this->dacs.cur];
 1230         bits_rates = this->w[group->conv[0]].d.audio.bits_rates;
 1231         nbits = 0;
 1232         if (bits_rates & COP_PCM_B8)
 1233                 nbits++;
 1234         if (bits_rates & COP_PCM_B16)
 1235                 nbits++;
 1236         if (bits_rates & COP_PCM_B20)
 1237                 nbits++;
 1238         if (bits_rates & COP_PCM_B24)
 1239                 nbits++;
 1240         if (bits_rates & COP_PCM_B32)
 1241                 nbits++;
 1242         if (nbits == 0) {
 1243                 printf("%s: %s/%d invalid PCM format: 0x%8.8x\n",
 1244                     XNAME(this->az), __FILE__, __LINE__, bits_rates);
 1245                 return -1;
 1246         }
 1247         pvariation = group->nconv * nbits;
 1248 
 1249         prev_adc = this->adcs.cur;
 1250         this->adcs.cur = newadc;
 1251         group = &this->adcs.groups[this->adcs.cur];
 1252         bits_rates = this->w[group->conv[0]].d.audio.bits_rates;
 1253         nbits = 0;
 1254         if (bits_rates & COP_PCM_B8)
 1255                 nbits++;
 1256         if (bits_rates & COP_PCM_B16)
 1257                 nbits++;
 1258         if (bits_rates & COP_PCM_B20)
 1259                 nbits++;
 1260         if (bits_rates & COP_PCM_B24)
 1261                 nbits++;
 1262         if (bits_rates & COP_PCM_B32)
 1263                 nbits++;
 1264         if (nbits == 0) {
 1265                 printf("%s: %s/%d invalid PCM format: 0x%8.8x\n",
 1266                     XNAME(this->az), __FILE__, __LINE__, bits_rates);
 1267                 return -1;
 1268         }
 1269         rvariation = group->nconv * nbits;
 1270 
 1271         if (this->formats != NULL)
 1272                 free(this->formats, M_DEVBUF);
 1273         this->nformats = 0;
 1274         this->formats = malloc(sizeof(struct audio_format) *
 1275             (pvariation + rvariation), M_DEVBUF, M_NOWAIT);
 1276         if (this->formats == NULL) {
 1277                 printf("%s: out of memory in %s\n",
 1278                     XNAME(this->az), __func__);
 1279                 return ENOMEM;
 1280         }
 1281         bzero(this->formats, sizeof(struct audio_format) *
 1282             (pvariation + rvariation));
 1283 
 1284         /* register formats for playback */
 1285         group = &this->dacs.groups[this->dacs.cur];
 1286         nid = group->conv[0];
 1287         chan = 0;
 1288         bits_rates = this->w[nid].d.audio.bits_rates;
 1289         for (c = 0; c < group->nconv; c++) {
 1290                 for (chan = 0, i = 0; i <= c; i++)
 1291                         chan += WIDGET_CHANNELS(&this->w[group->conv[c]]);
 1292                 azalia_codec_add_bits(this, chan, bits_rates, AUMODE_PLAY);
 1293         }
 1294 
 1295         /* register formats for recording */
 1296         group = &this->adcs.groups[this->adcs.cur];
 1297         nid = group->conv[0];
 1298         chan = 0;
 1299         bits_rates = this->w[nid].d.audio.bits_rates;
 1300         for (c = 0; c < group->nconv; c++) {
 1301                 for (chan = 0, i = 0; i <= c; i++)
 1302                         chan += WIDGET_CHANNELS(&this->w[group->conv[c]]);
 1303                 azalia_codec_add_bits(this, chan, bits_rates, AUMODE_RECORD);
 1304         }
 1305 
 1306         err = azalia_create_encodings(this->formats, this->nformats,
 1307             &this->encodings);
 1308         if (err)
 1309                 return err;
 1310         return 0;
 1311 }
 1312 
 1313 void
 1314 azalia_codec_add_bits(codec_t *this, int chan, uint32_t bits_rates, int mode)
 1315 {
 1316         if (bits_rates & COP_PCM_B8)
 1317                 azalia_codec_add_format(this, chan, 8, 16, bits_rates, mode);
 1318         if (bits_rates & COP_PCM_B16)
 1319                 azalia_codec_add_format(this, chan, 16, 16, bits_rates, mode);
 1320         if (bits_rates & COP_PCM_B20)
 1321                 azalia_codec_add_format(this, chan, 20, 32, bits_rates, mode);
 1322         if (bits_rates & COP_PCM_B24)
 1323                 azalia_codec_add_format(this, chan, 24, 32, bits_rates, mode);
 1324         if (bits_rates & COP_PCM_B32)
 1325                 azalia_codec_add_format(this, chan, 32, 32, bits_rates, mode);
 1326 }
 1327 
 1328 void
 1329 azalia_codec_add_format(codec_t *this, int chan, int valid, int prec,
 1330     uint32_t rates, int32_t mode)
 1331 {
 1332         struct audio_format *f;
 1333 
 1334         f = &this->formats[this->nformats++];
 1335         f->mode = mode;
 1336         f->encoding = AUDIO_ENCODING_SLINEAR_LE;
 1337         if (valid == 8 && prec == 8)
 1338                 f->encoding = AUDIO_ENCODING_ULINEAR_LE;
 1339         f->validbits = valid;
 1340         f->precision = prec;
 1341         f->channels = chan;
 1342         switch (chan) {
 1343         case 1:
 1344                 f->channel_mask = AUFMT_MONAURAL;
 1345                 break;
 1346         case 2:
 1347                 f->channel_mask = AUFMT_STEREO;
 1348                 break;
 1349         case 4:
 1350                 f->channel_mask = AUFMT_SURROUND4;
 1351                 break;
 1352         case 6:
 1353                 f->channel_mask = AUFMT_DOLBY_5_1;
 1354                 break;
 1355         case 8:
 1356                 f->channel_mask = AUFMT_DOLBY_5_1
 1357                     | AUFMT_SIDE_LEFT | AUFMT_SIDE_RIGHT;
 1358                 break;
 1359         default:
 1360                 f->channel_mask = 0;
 1361         }
 1362         if (rates & COP_PCM_R80)
 1363                 f->frequency[f->frequency_type++] = 8000;
 1364         if (rates & COP_PCM_R110)
 1365                 f->frequency[f->frequency_type++] = 11025;
 1366         if (rates & COP_PCM_R160)
 1367                 f->frequency[f->frequency_type++] = 16000;
 1368         if (rates & COP_PCM_R220)
 1369                 f->frequency[f->frequency_type++] = 22050;
 1370         if (rates & COP_PCM_R320)
 1371                 f->frequency[f->frequency_type++] = 32000;
 1372         if (rates & COP_PCM_R441)
 1373                 f->frequency[f->frequency_type++] = 44100;
 1374         if (rates & COP_PCM_R480)
 1375                 f->frequency[f->frequency_type++] = 48000;
 1376         if (rates & COP_PCM_R882)
 1377                 f->frequency[f->frequency_type++] = 88200;
 1378         if (rates & COP_PCM_R960)
 1379                 f->frequency[f->frequency_type++] = 96000;
 1380         if (rates & COP_PCM_R1764)
 1381                 f->frequency[f->frequency_type++] = 176400;
 1382         if (rates & COP_PCM_R1920)
 1383                 f->frequency[f->frequency_type++] = 192000;
 1384         if (rates & COP_PCM_R3840)
 1385                 f->frequency[f->frequency_type++] = 384000;
 1386 }
 1387 
 1388 int
 1389 azalia_codec_comresp(const codec_t *codec, nid_t nid, uint32_t control,
 1390                      uint32_t param, uint32_t* result)
 1391 {
 1392         int err;
 1393 
 1394         err = azalia_set_command(codec->az, codec->address, nid, control, param);
 1395         if (err)
 1396                 return err;
 1397         return azalia_get_response(codec->az, result);
 1398 }
 1399 
 1400 int
 1401 azalia_codec_connect_stream(codec_t *this, int dir, uint16_t fmt, int number)
 1402 {
 1403         const convgroup_t *group;
 1404         int i, err, startchan, nchan;
 1405         nid_t nid;
 1406         boolean_t flag222;
 1407 
 1408         DPRINTF(("%s: fmt=0x%4.4x number=%d\n", __func__, fmt, number));
 1409         err = 0;
 1410         if (dir == AUMODE_RECORD)
 1411                 group = &this->adcs.groups[this->adcs.cur];
 1412         else
 1413                 group = &this->dacs.groups[this->dacs.cur];
 1414         flag222 = group->nconv >= 3 &&
 1415             (WIDGET_CHANNELS(&this->w[group->conv[0]]) == 2) &&
 1416             (WIDGET_CHANNELS(&this->w[group->conv[1]]) == 2) &&
 1417             (WIDGET_CHANNELS(&this->w[group->conv[2]]) == 2);
 1418         nchan = (fmt & HDA_SD_FMT_CHAN) + 1;
 1419         startchan = 0;
 1420         for (i = 0; i < group->nconv; i++) {
 1421                 nid = group->conv[i];
 1422 
 1423                 /* surround and c/lfe handling */
 1424                 if (nchan >= 6 && flag222 && i == 1) {
 1425                         nid = group->conv[2];
 1426                 } else if (nchan >= 6 && flag222 && i == 2) {
 1427                         nid = group->conv[1];
 1428                 }
 1429 
 1430                 err = this->comresp(this, nid, CORB_SET_CONVERTER_FORMAT, fmt, NULL);
 1431                 if (err)
 1432                         goto exit;
 1433                 err = this->comresp(this, nid, CORB_SET_CONVERTER_STREAM_CHANNEL,
 1434                                     (number << 4) | startchan, NULL);
 1435                 if (err)
 1436                         goto exit;
 1437                 if (nchan > 2)
 1438                         startchan += WIDGET_CHANNELS(&this->w[nid]);
 1439         }
 1440 
 1441 exit:
 1442         DPRINTF(("%s: leave with %d\n", __func__, err));
 1443         return err;
 1444 }
 1445 
 1446 /* ================================================================
 1447  * HDA widget functions
 1448  * ================================================================ */
 1449 
 1450 #define WIDGETCAP_BITS                                                  \
 1451     "\20\014LRSWAP\013POWER\012DIGITAL"                                 \
 1452     "\011CONNLIST\010UNSOL\07PROC\06STRIPE\05FORMATOV\04AMPOV\03OUTAMP" \
 1453     "\02INAMP\01STEREO"
 1454 
 1455 int
 1456 azalia_widget_init(widget_t *this, const codec_t *codec, nid_t nid)
 1457 {
 1458         uint32_t result;
 1459         int err;
 1460 
 1461         err = codec->comresp(codec, nid, CORB_GET_PARAMETER,
 1462             COP_AUDIO_WIDGET_CAP, &result);
 1463         if (err)
 1464                 return err;
 1465         this->nid = nid;
 1466         this->widgetcap = result;
 1467         this->type = COP_AWCAP_TYPE(result);
 1468         DPRINTF(("%s: ", XNAME(codec->az)));
 1469         if (this->widgetcap & COP_AWCAP_POWER) {
 1470                 codec->comresp(codec, nid, CORB_SET_POWER_STATE, CORB_PS_D0, &result);
 1471                 DELAY(100);
 1472         }
 1473         switch (this->type) {
 1474         case COP_AWTYPE_AUDIO_OUTPUT:
 1475                 snprintf(this->name, sizeof(this->name), "dac%2.2x", nid);
 1476                 DPRINTF(("%s wcap=%b\n", this->name,
 1477                     this->widgetcap, WIDGETCAP_BITS));
 1478                 azalia_widget_init_audio(this, codec);
 1479                 break;
 1480         case COP_AWTYPE_AUDIO_INPUT:
 1481                 snprintf(this->name, sizeof(this->name), "adc%2.2x", nid);
 1482                 DPRINTF(("%s wcap=%b\n", this->name,
 1483                     this->widgetcap, WIDGETCAP_BITS));
 1484                 azalia_widget_init_audio(this, codec);
 1485                 break;
 1486         case COP_AWTYPE_AUDIO_MIXER:
 1487                 snprintf(this->name, sizeof(this->name), "mix%2.2x", nid);
 1488                 DPRINTF(("%s wcap=%b\n", this->name,
 1489                     this->widgetcap, WIDGETCAP_BITS));
 1490                 break;
 1491         case COP_AWTYPE_AUDIO_SELECTOR:
 1492                 snprintf(this->name, sizeof(this->name), "sel%2.2x", nid);
 1493                 DPRINTF(("%s wcap=%b\n", this->name,
 1494                     this->widgetcap, WIDGETCAP_BITS));
 1495                 break;
 1496         case COP_AWTYPE_PIN_COMPLEX:
 1497                 azalia_widget_init_pin(this, codec);
 1498                 snprintf(this->name, sizeof(this->name), "%s%2.2x",
 1499                     pin_colors[this->d.pin.color], nid);
 1500                 DPRINTF(("%s wcap=%b\n", this->name,
 1501                     this->widgetcap, WIDGETCAP_BITS));
 1502                 azalia_widget_print_pin(this);
 1503                 break;
 1504         case COP_AWTYPE_POWER:
 1505                 snprintf(this->name, sizeof(this->name), "pow%2.2x", nid);
 1506                 DPRINTF(("%s wcap=%b\n", this->name,
 1507                     this->widgetcap, WIDGETCAP_BITS));
 1508                 break;
 1509         case COP_AWTYPE_VOLUME_KNOB:
 1510                 snprintf(this->name, sizeof(this->name), "volume%2.2x", nid);
 1511                 DPRINTF(("%s wcap=%b\n", this->name,
 1512                     this->widgetcap, WIDGETCAP_BITS));
 1513                 err = codec->comresp(codec, nid, CORB_GET_PARAMETER,
 1514                     COP_VOLUME_KNOB_CAPABILITIES, &result);
 1515                 if (!err) {
 1516                         this->d.volume.cap = result;
 1517                         DPRINTF(("\tdelta=%d steps=%d\n",
 1518                             !!(result & COP_VKCAP_DELTA),
 1519                             COP_VKCAP_NUMSTEPS(result)));
 1520                 }
 1521                 break;
 1522         case COP_AWTYPE_BEEP_GENERATOR:
 1523                 snprintf(this->name, sizeof(this->name), "beep%2.2x", nid);
 1524                 DPRINTF(("%s wcap=%b\n", this->name,
 1525                     this->widgetcap, WIDGETCAP_BITS));
 1526                 break;
 1527         default:
 1528                 snprintf(this->name, sizeof(this->name), "widget%2.2x", nid);
 1529                 DPRINTF(("%s wcap=%b\n", this->name,
 1530                     this->widgetcap, WIDGETCAP_BITS));
 1531                 break;
 1532         }
 1533         azalia_widget_init_connection(this, codec);
 1534 
 1535         /* amplifier information */
 1536         if (this->widgetcap & COP_AWCAP_INAMP) {
 1537                 if (this->widgetcap & COP_AWCAP_AMPOV)
 1538                         codec->comresp(codec, nid, CORB_GET_PARAMETER,
 1539                             COP_INPUT_AMPCAP, &this->inamp_cap);
 1540                 else
 1541                         this->inamp_cap = codec->w[codec->audiofunc].inamp_cap;
 1542                 DPRINTF(("\tinamp: mute=%u size=%u steps=%u offset=%u\n",
 1543                     (this->inamp_cap & COP_AMPCAP_MUTE) != 0,
 1544                     COP_AMPCAP_STEPSIZE(this->inamp_cap),
 1545                     COP_AMPCAP_NUMSTEPS(this->inamp_cap),
 1546                     COP_AMPCAP_OFFSET(this->inamp_cap)));
 1547         }
 1548         if (this->widgetcap & COP_AWCAP_OUTAMP) {
 1549                 if (this->widgetcap & COP_AWCAP_AMPOV)
 1550                         codec->comresp(codec, nid, CORB_GET_PARAMETER,
 1551                             COP_OUTPUT_AMPCAP, &this->outamp_cap);
 1552                 else
 1553                         this->outamp_cap = codec->w[codec->audiofunc].outamp_cap;
 1554                 DPRINTF(("\toutamp: mute=%u size=%u steps=%u offset=%u\n",
 1555                     (this->outamp_cap & COP_AMPCAP_MUTE) != 0,
 1556                     COP_AMPCAP_STEPSIZE(this->outamp_cap),
 1557                     COP_AMPCAP_NUMSTEPS(this->outamp_cap),
 1558                     COP_AMPCAP_OFFSET(this->outamp_cap)));
 1559         }
 1560         if (codec->init_widget != NULL)
 1561                 codec->init_widget(codec, this, nid);
 1562         return 0;
 1563 }
 1564 
 1565 int
 1566 azalia_widget_init_audio(widget_t *this, const codec_t *codec)
 1567 {
 1568         uint32_t result;
 1569         int err;
 1570 
 1571         /* check audio format */
 1572         if (this->widgetcap & COP_AWCAP_FORMATOV) {
 1573                 err = codec->comresp(codec, this->nid,
 1574                     CORB_GET_PARAMETER, COP_STREAM_FORMATS, &result);
 1575                 if (err)
 1576                         return err;
 1577                 this->d.audio.encodings = result;
 1578                 if (result == 0) { /* quirk for CMI9880.
 1579                                     * This must not occuur usually... */
 1580                         this->d.audio.encodings =
 1581                             codec->w[codec->audiofunc].d.audio.encodings;
 1582                         this->d.audio.bits_rates =
 1583                             codec->w[codec->audiofunc].d.audio.bits_rates;
 1584                 } else {
 1585                         if ((result & COP_STREAM_FORMAT_PCM) == 0) {
 1586                                 printf("%s: %s: No PCM support: %x\n",
 1587                                     XNAME(codec->az), this->name, result);
 1588                                 return -1;
 1589                         }
 1590                         err = codec->comresp(codec, this->nid, CORB_GET_PARAMETER,
 1591                             COP_PCM, &result);
 1592                         if (err)
 1593                                 return err;
 1594                         this->d.audio.bits_rates = result;
 1595                 }
 1596                 this->d.audio.bits_rates = result;
 1597         } else {
 1598                 this->d.audio.encodings =
 1599                     codec->w[codec->audiofunc].d.audio.encodings;
 1600                 this->d.audio.bits_rates =
 1601                     codec->w[codec->audiofunc].d.audio.bits_rates;
 1602         }
 1603 #ifdef AZALIA_DEBUG
 1604         azalia_widget_print_audio(this, "\t");
 1605 #endif
 1606         return 0;
 1607 }
 1608 
 1609 #define ENCODING_BITS   "\20\3AC3\2FLOAT32\1PCM"
 1610 #define BITSRATES_BITS  "\20\x15""32bit\x14""24bit\x13""20bit"          \
 1611     "\x12""16bit\x11""8bit""\x0c""384kHz\x0b""192kHz\x0a""176.4kHz"     \
 1612     "\x09""96kHz\x08""88.2kHz\x07""48kHz\x06""44.1kHz\x05""32kHz\x04"   \
 1613     "22.05kHz\x03""16kHz\x02""11.025kHz\x01""8kHz"
 1614 
 1615 int
 1616 azalia_widget_print_audio(const widget_t *this, const char *lead)
 1617 {
 1618         printf("%sencodings=%b\n", lead, this->d.audio.encodings,
 1619             ENCODING_BITS);
 1620         printf("%sPCM formats=%b\n", lead, this->d.audio.bits_rates,
 1621             BITSRATES_BITS);
 1622         return 0;
 1623 }
 1624 
 1625 int
 1626 azalia_widget_init_pin(widget_t *this, const codec_t *codec)
 1627 {
 1628         uint32_t result;
 1629         int err;
 1630 
 1631         err = codec->comresp(codec, this->nid, CORB_GET_CONFIGURATION_DEFAULT,
 1632             0, &result);
 1633         if (err)
 1634                 return err;
 1635         this->d.pin.config = result;
 1636         this->d.pin.sequence = CORB_CD_SEQUENCE(result);
 1637         this->d.pin.association = CORB_CD_ASSOCIATION(result);
 1638         this->d.pin.color = CORB_CD_COLOR(result);
 1639         this->d.pin.device = CORB_CD_DEVICE(result);
 1640 
 1641         err = codec->comresp(codec, this->nid, CORB_GET_PARAMETER,
 1642             COP_PINCAP, &result);
 1643         if (err)
 1644                 return err;
 1645         this->d.pin.cap = result;
 1646         return 0;
 1647 }
 1648 
 1649 #define PINCAP_BITS     "\20\021EAPD\07BALANCE\06INPUT" \
 1650     "\05OUTPUT\04HEADPHONE\03PRESENCE\02TRIGGER\01IMPEDANCE"
 1651 
 1652 int
 1653 azalia_widget_print_pin(const widget_t *this)
 1654 {
 1655         DPRINTF(("\tpin config; device=%s color=%s assoc=%d seq=%d",
 1656             pin_devices[this->d.pin.device], pin_colors[this->d.pin.color],
 1657             this->d.pin.association, this->d.pin.sequence));
 1658         DPRINTF((" cap=%b\n", this->d.pin.cap, PINCAP_BITS));
 1659         return 0;
 1660 }
 1661 
 1662 int
 1663 azalia_widget_init_connection(widget_t *this, const codec_t *codec)
 1664 {
 1665         uint32_t result;
 1666         int err;
 1667         boolean_t longform;
 1668         int length, i;
 1669 
 1670         this->selected = -1;
 1671         if ((this->widgetcap & COP_AWCAP_CONNLIST) == 0)
 1672                 return 0;
 1673 
 1674         err = codec->comresp(codec, this->nid, CORB_GET_PARAMETER,
 1675             COP_CONNECTION_LIST_LENGTH, &result);
 1676         if (err)
 1677                 return err;
 1678         longform = (result & COP_CLL_LONG) != 0;
 1679         length = COP_CLL_LENGTH(result);
 1680         if (length == 0)
 1681                 return 0;
 1682         this->nconnections = length;
 1683         this->connections = malloc(sizeof(nid_t) * (length + 3),
 1684             M_DEVBUF, M_NOWAIT);
 1685         if (this->connections == NULL) {
 1686                 printf("%s: out of memory\n", XNAME(codec->az));
 1687                 return ENOMEM;
 1688         }
 1689         if (longform) {
 1690                 for (i = 0; i < length;) {
 1691                         err = codec->comresp(codec, this->nid,
 1692                             CORB_GET_CONNECTION_LIST_ENTRY, i, &result);
 1693                         if (err)
 1694                                 return err;
 1695                         this->connections[i++] = CORB_CLE_LONG_0(result);
 1696                         this->connections[i++] = CORB_CLE_LONG_1(result);
 1697                 }
 1698         } else {
 1699                 for (i = 0; i < length;) {
 1700                         err = codec->comresp(codec, this->nid,
 1701                             CORB_GET_CONNECTION_LIST_ENTRY, i, &result);
 1702                         if (err)
 1703                                 return err;
 1704                         this->connections[i++] = CORB_CLE_SHORT_0(result);
 1705                         this->connections[i++] = CORB_CLE_SHORT_1(result);
 1706                         this->connections[i++] = CORB_CLE_SHORT_2(result);
 1707                         this->connections[i++] = CORB_CLE_SHORT_3(result);
 1708                 }
 1709         }
 1710         if (length > 0) {
 1711                 DPRINTF(("\tconnections=0x%x", this->connections[0]));
 1712                 for (i = 1; i < length; i++) {
 1713                         DPRINTF((",0x%x", this->connections[i]));
 1714                 }
 1715 
 1716                 err = codec->comresp(codec, this->nid,
 1717                     CORB_GET_CONNECTION_SELECT_CONTROL, 0, &result);
 1718                 if (err)
 1719                         return err;
 1720                 this->selected = CORB_CSC_INDEX(result);
 1721                 DPRINTF(("; selected=0x%x\n", this->connections[result]));
 1722         }
 1723         return 0;
 1724 }
 1725 
 1726 /* ================================================================
 1727  * Stream functions
 1728  * ================================================================ */
 1729 
 1730 int
 1731 azalia_stream_init(stream_t *this, azalia_t *az, int regindex, int strnum, int dir)
 1732 {
 1733         int err;
 1734 
 1735         this->az = az;
 1736         this->regbase = HDA_SD_BASE + regindex * HDA_SD_SIZE;
 1737         this->intr_bit = 1 << regindex;
 1738         this->number = strnum;
 1739         this->dir = dir;
 1740 
 1741         /* setup BDL buffers */
 1742         err = azalia_alloc_dmamem(az, sizeof(bdlist_entry_t) * HDA_BDL_MAX,
 1743                                   128, &this->bdlist);
 1744         if (err) {
 1745                 printf("%s: can't allocate a BDL buffer\n", XNAME(az));
 1746                 return err;
 1747         }
 1748         return 0;
 1749 }
 1750 
 1751 int
 1752 azalia_stream_delete(stream_t *this, azalia_t *az)
 1753 {
 1754         if (this->bdlist.addr == NULL)
 1755                 return 0;
 1756         azalia_free_dmamem(az, &this->bdlist);
 1757         return 0;
 1758 }
 1759 
 1760 int
 1761 azalia_stream_reset(stream_t *this)
 1762 {
 1763         int i;
 1764         uint16_t ctl;
 1765         uint8_t sts;
 1766 
 1767         /* Make sure RUN bit is zero before resetting */
 1768         ctl = STR_READ_2(this, CTL);
 1769         ctl &= ~HDA_SD_CTL_RUN;
 1770         STR_WRITE_2(this, CTL, ctl);
 1771 
 1772         /* Start reset and wait for chip to enter. */
 1773         ctl = STR_READ_2(this, CTL);
 1774         STR_WRITE_2(this, CTL, ctl | HDA_SD_CTL_SRST);
 1775         for (i = 5000; i >= 0; i--) {
 1776                 DELAY(10);
 1777                 ctl = STR_READ_2(this, CTL);
 1778                 if (ctl & HDA_SD_CTL_SRST)
 1779                         break;
 1780         }
 1781         if (i <= 0) {
 1782                 printf("%s: stream reset failure 1\n", XNAME(this->az));
 1783                 return -1;
 1784         }
 1785 
 1786         /* Clear reset and wait for chip to finish */
 1787         STR_WRITE_2(this, CTL, ctl & ~HDA_SD_CTL_SRST);
 1788         for (i = 5000; i >= 0; i--) {
 1789                 DELAY(10);
 1790                 ctl = STR_READ_2(this, CTL);
 1791                 if ((ctl & HDA_SD_CTL_SRST) == 0)
 1792                         break;
 1793         }
 1794         if (i <= 0) {
 1795                 printf("%s: stream reset failure 2\n", XNAME(this->az));
 1796                 return -1;
 1797         }
 1798 
 1799         sts = STR_READ_1(this, STS);
 1800         sts |= HDA_SD_STS_DESE | HDA_SD_STS_FIFOE | HDA_SD_STS_BCIS;
 1801         STR_WRITE_1(this, STS, sts);
 1802 
 1803         return (0);
 1804 }
 1805 
 1806 int
 1807 azalia_stream_start(stream_t *this, void *start, void *end, int blk,
 1808     void (*intr)(void *), void *arg, uint16_t fmt)
 1809 {
 1810         bdlist_entry_t *bdlist;
 1811         bus_addr_t dmaaddr, dmaend;
 1812         int err, index;
 1813         uint32_t intctl;
 1814         uint8_t ctl2;
 1815 
 1816         this->intr = intr;
 1817         this->intr_arg = arg;
 1818 
 1819         err = azalia_stream_reset(this);
 1820         if (err) {
 1821                 printf("%s: stream reset failed\n", "azalia");
 1822                 return err;
 1823         }
 1824 
 1825         STR_WRITE_4(this, BDPL, 0);
 1826         STR_WRITE_4(this, BDPU, 0);
 1827 
 1828         /* setup BDL */
 1829         dmaaddr = AZALIA_DMA_DMAADDR(&this->buffer);
 1830         dmaend = dmaaddr + ((caddr_t)end - (caddr_t)start);
 1831         bdlist = (bdlist_entry_t*)this->bdlist.addr;
 1832         for (index = 0; index < HDA_BDL_MAX; index++) {
 1833                 bdlist[index].low = htole32(dmaaddr);
 1834                 bdlist[index].high = htole32(PTR_UPPER32(dmaaddr));
 1835                 bdlist[index].length = htole32(blk);
 1836                 bdlist[index].flags = htole32(BDLIST_ENTRY_IOC);
 1837                 dmaaddr += blk;
 1838                 if (dmaaddr >= dmaend) {
 1839                         index++;
 1840                         break;
 1841                 }
 1842         }
 1843 
 1844         dmaaddr = AZALIA_DMA_DMAADDR(&this->bdlist);
 1845         STR_WRITE_4(this, BDPL, dmaaddr);
 1846         STR_WRITE_4(this, BDPU, PTR_UPPER32(dmaaddr));
 1847         STR_WRITE_2(this, LVI, (index - 1) & HDA_SD_LVI_LVI);
 1848         ctl2 = STR_READ_1(this, CTL2);
 1849         STR_WRITE_1(this, CTL2,
 1850             (ctl2 & ~HDA_SD_CTL2_STRM) | (this->number << HDA_SD_CTL2_STRM_SHIFT));
 1851         STR_WRITE_4(this, CBL, ((caddr_t)end - (caddr_t)start));
 1852         STR_WRITE_2(this, FMT, fmt);
 1853 
 1854         err = azalia_codec_connect_stream(&this->az->codecs[this->az->codecno],
 1855             this->dir, fmt, this->number);
 1856         if (err)
 1857                 return EINVAL;
 1858 
 1859         intctl = AZ_READ_4(this->az, INTCTL);
 1860         intctl |= this->intr_bit;
 1861         AZ_WRITE_4(this->az, INTCTL, intctl);
 1862 
 1863         STR_WRITE_1(this, CTL, STR_READ_1(this, CTL) |
 1864             HDA_SD_CTL_DEIE | HDA_SD_CTL_FEIE | HDA_SD_CTL_IOCE |
 1865             HDA_SD_CTL_RUN);
 1866 
 1867         return (0);
 1868 }
 1869 
 1870 int
 1871 azalia_stream_halt(stream_t *this)
 1872 {
 1873         uint16_t ctl;
 1874 
 1875         ctl = STR_READ_2(this, CTL);
 1876         ctl &= ~(HDA_SD_CTL_DEIE | HDA_SD_CTL_FEIE | HDA_SD_CTL_IOCE | HDA_SD_CTL_RUN);
 1877         STR_WRITE_2(this, CTL, ctl);
 1878         AZ_WRITE_4(this->az, INTCTL,
 1879             AZ_READ_4(this->az, INTCTL) & ~this->intr_bit);
 1880         return (0);
 1881 }
 1882 
 1883 #define HDA_SD_STS_BITS "\20\3BCIS\4FIFOE\5DESE\6FIFORDY"
 1884 
 1885 int
 1886 azalia_stream_intr(stream_t *this, uint32_t intsts)
 1887 {
 1888         u_int8_t sts;
 1889 
 1890         if ((intsts & this->intr_bit) == 0)
 1891                 return (0);
 1892 
 1893         sts = STR_READ_1(this, STS);
 1894         STR_WRITE_1(this, STS, sts |
 1895             HDA_SD_STS_DESE | HDA_SD_STS_FIFOE | HDA_SD_STS_BCIS);
 1896 
 1897         if (sts & (HDA_SD_STS_DESE | HDA_SD_STS_FIFOE))
 1898                 printf("%s: stream %d: sts=%b\n", XNAME(this->az),
 1899                     this->number, sts, HDA_SD_STS_BITS);
 1900         if (sts & HDA_SD_STS_BCIS)
 1901                 this->intr(this->intr_arg);
 1902         return (1);
 1903 }
 1904 
 1905 /* ================================================================
 1906  * MI audio entries
 1907  * ================================================================ */
 1908 
 1909 int
 1910 azalia_open(void *v, int flags)
 1911 {
 1912         azalia_t *az;
 1913         codec_t *codec;
 1914 
 1915         DPRINTF(("%s: flags=0x%x\n", __func__, flags));
 1916         az = v;
 1917         codec = &az->codecs[az->codecno];
 1918         codec->running++;
 1919         return 0;
 1920 }
 1921 
 1922 void
 1923 azalia_close(void *v)
 1924 {
 1925         azalia_t *az;
 1926         codec_t *codec;
 1927 
 1928         DPRINTF(("%s\n", __func__));
 1929         az = v;
 1930         codec = &az->codecs[az->codecno];
 1931         codec->running--;
 1932 }
 1933 
 1934 int
 1935 azalia_query_encoding(void *v, audio_encoding_t *enc)
 1936 {
 1937         azalia_t *az;
 1938         codec_t *codec;
 1939         int i, j;
 1940 
 1941         az = v;
 1942         codec = &az->codecs[az->codecno];
 1943         for (j = 0, i = 0; j < codec->nformats; j++) {
 1944                 if (codec->formats[j].validbits !=
 1945                     codec->formats[j].precision)
 1946                         continue;
 1947                 if (i == enc->index) {
 1948                         enc->encoding = codec->formats[j].encoding;
 1949                         enc->precision = codec->formats[j].precision;
 1950                         switch (enc->encoding) {
 1951                         case AUDIO_ENCODING_SLINEAR_LE:
 1952                                 strlcpy(enc->name, enc->precision == 8 ?
 1953                                     AudioEslinear : AudioEslinear_le,
 1954                                     sizeof enc->name);
 1955                                 break;
 1956                         case AUDIO_ENCODING_ULINEAR_LE:
 1957                                 strlcpy(enc->name, enc->precision == 8 ?
 1958                                     AudioEulinear : AudioEulinear_le,
 1959                                     sizeof enc->name);
 1960                                 break;
 1961                         default:
 1962                                 strlcpy(enc->name, "unknown", sizeof enc->name);
 1963                                 break;
 1964                         }
 1965                         return (0);
 1966                 }
 1967                 i++;
 1968         }
 1969         return (EINVAL);
 1970 }
 1971 
 1972 int
 1973 azalia_set_params(void *v, int smode, int umode, audio_params_t *p,
 1974     audio_params_t *r)
 1975 {
 1976         azalia_t *az;
 1977         codec_t *codec;
 1978         void (*pswcode)(void *, u_char *, int) = NULL;
 1979         void (*rswcode)(void *, u_char *, int) = NULL;
 1980         int i, j;
 1981 
 1982         az = v;
 1983         codec = &az->codecs[az->codecno];
 1984         if (smode & AUMODE_RECORD && r != NULL) {
 1985                 if (r->encoding == AUDIO_ENCODING_ULAW) {        /*XXX*/
 1986                         r->encoding = AUDIO_ENCODING_SLINEAR_LE;
 1987                         r->precision = 16;
 1988                         r->channels = 2;
 1989                         r->sample_rate = 44100;
 1990                 }
 1991                 for (i = 0; i < codec->nformats; i++) {
 1992                         if (r->encoding != codec->formats[i].encoding)
 1993                                 continue;
 1994                         if (r->precision != codec->formats[i].precision)
 1995                                 continue;
 1996                         if (r->channels != codec->formats[i].channels)
 1997                                 continue;
 1998                         break;
 1999                 }
 2000                 if (i == codec->nformats) {
 2001                         printf("didn't find Record format %u/%u/%u\n",
 2002                             r->encoding, r->precision, r->channels);
 2003                         return (EINVAL);
 2004                 }
 2005                 for (j = 0; j < codec->formats[i].frequency_type; j++) {
 2006                         if (r->sample_rate != codec->formats[i].frequency[j])
 2007                                 continue;
 2008                         break;
 2009                 }
 2010                 if (j == codec->formats[i].frequency_type) {
 2011                         printf("didn't find Record rate %u\n",
 2012                             r->sample_rate);
 2013                         return (EINVAL);
 2014                 }
 2015                 r->sw_code = rswcode;
 2016         }
 2017         if (smode & AUMODE_PLAY && p != NULL) {
 2018                 if (p->encoding == AUDIO_ENCODING_ULAW) {        /*XXX*/
 2019                         p->encoding = AUDIO_ENCODING_SLINEAR_LE;
 2020                         p->precision = 16;
 2021                         p->channels = 2;
 2022                         p->sample_rate = 44100;
 2023                 }
 2024                 for (i = 0; i < codec->nformats; i++) {
 2025                         if (p->encoding != codec->formats[i].encoding)
 2026                                 continue;
 2027                         if (p->precision != codec->formats[i].precision)
 2028                                 continue;
 2029                         if (p->channels != codec->formats[i].channels)
 2030                                 continue;
 2031                         break;
 2032                 }
 2033                 if (i == codec->nformats) {
 2034                         printf("can't find playback format %u/%u/%u\n",
 2035                             r->encoding, r->precision, r->channels);
 2036                         return (EINVAL);
 2037                 }
 2038                 for (j = 0; j < codec->formats[i].frequency_type; j++) {
 2039                         if (p->sample_rate != codec->formats[i].frequency[j])
 2040                                 continue;
 2041                         break;
 2042                 }
 2043                 if (j == codec->formats[i].frequency_type) {
 2044                         printf("can't find playback rate %u\n",
 2045                             p->sample_rate);
 2046                         return (EINVAL);
 2047                 }
 2048                 p->sw_code = pswcode;
 2049         }
 2050 
 2051         return (0);
 2052 }
 2053 
 2054 int
 2055 azalia_round_blocksize(void *v, int blk)
 2056 {
 2057         azalia_t *az;
 2058         size_t size;
 2059 
 2060         blk &= ~0x7f;           /* must be multiple of 128 */
 2061         if (blk <= 0)
 2062                 blk = 128;
 2063         /* number of blocks must be <= HDA_BDL_MAX */
 2064         az = v;
 2065         size = az->pstream.buffer.size;
 2066 #ifdef DIAGNOSTIC
 2067         if (size <= 0) {
 2068                 printf("%s: size is 0", __func__);
 2069                 return 256;
 2070         }
 2071 #endif
 2072         if (size > HDA_BDL_MAX * blk) {
 2073                 blk = size / HDA_BDL_MAX;
 2074                 if (blk & 0x7f)
 2075                         blk = (blk + 0x7f) & ~0x7f;
 2076         }
 2077         DPRINTF(("%s: resultant block size = %d\n", __func__, blk));
 2078         return blk;
 2079 }
 2080 
 2081 int
 2082 azalia_halt_output(void *v)
 2083 {
 2084         azalia_t *az;
 2085 
 2086         DPRINTF(("%s\n", __func__));
 2087         az = v;
 2088         return azalia_stream_halt(&az->pstream);
 2089 }
 2090 
 2091 int
 2092 azalia_halt_input(void *v)
 2093 {
 2094         azalia_t *az;
 2095 
 2096         DPRINTF(("%s\n", __func__));
 2097         az = v;
 2098         return azalia_stream_halt(&az->rstream);
 2099 }
 2100 
 2101 int
 2102 azalia_getdev(void *v, struct audio_device *dev)
 2103 {
 2104         azalia_t *az;
 2105 
 2106         az = v;
 2107         strlcpy(dev->name, "HD-Audio", MAX_AUDIO_DEV_LEN);
 2108         snprintf(dev->version, MAX_AUDIO_DEV_LEN,
 2109             "%d.%d", AZ_READ_1(az, VMAJ), AZ_READ_1(az, VMIN));
 2110         strlcpy(dev->config, XNAME(az), MAX_AUDIO_DEV_LEN);
 2111         return 0;
 2112 }
 2113 
 2114 int
 2115 azalia_set_port(void *v, mixer_ctrl_t *mc)
 2116 {
 2117         azalia_t *az;
 2118         codec_t *co;
 2119 
 2120         az = v;
 2121         co = &az->codecs[az->codecno];
 2122         return co->set_port(co, mc);
 2123 }
 2124 
 2125 int
 2126 azalia_get_port(void *v, mixer_ctrl_t *mc)
 2127 {
 2128         azalia_t *az;
 2129         codec_t *co;
 2130 
 2131         az = v;
 2132         co = &az->codecs[az->codecno];
 2133         return co->get_port(co, mc);
 2134 }
 2135 
 2136 int
 2137 azalia_query_devinfo(void *v, mixer_devinfo_t *mdev)
 2138 {
 2139         azalia_t *az;
 2140         const codec_t *co;
 2141 
 2142         az = v;
 2143         co = &az->codecs[az->codecno];
 2144         if (mdev->index >= co->nmixers)
 2145                 return ENXIO;
 2146         *mdev = co->mixers[mdev->index].devinfo;
 2147         return 0;
 2148 }
 2149 
 2150 void *
 2151 azalia_allocm(void *v, int dir, size_t size, int pool, int flags)
 2152 {
 2153         azalia_t *az;
 2154         stream_t *stream;
 2155         int err;
 2156 
 2157         az = v;
 2158         stream = dir == AUMODE_PLAY ? &az->pstream : &az->rstream;
 2159         err = azalia_alloc_dmamem(az, size, 128, &stream->buffer);
 2160         if (err) {
 2161                 printf("%s: allocm failed\n", az->dev.dv_xname);
 2162                 return NULL;
 2163         }
 2164         return stream->buffer.addr;
 2165 }
 2166 
 2167 void
 2168 azalia_freem(void *v, void *addr, int pool)
 2169 {
 2170         azalia_t *az;
 2171         stream_t *stream;
 2172 
 2173         az = v;
 2174         if (addr == az->pstream.buffer.addr) {
 2175                 stream = &az->pstream;
 2176         } else if (addr == az->rstream.buffer.addr) {
 2177                 stream = &az->rstream;
 2178         } else {
 2179                 return;
 2180         }
 2181         azalia_free_dmamem(az, &stream->buffer);
 2182 }
 2183 
 2184 size_t
 2185 azalia_round_buffersize(void *v, int dir, size_t size)
 2186 {
 2187         size &= ~0x7f;          /* must be multiple of 128 */
 2188         if (size <= 0)
 2189                 size = 128;
 2190         return size;
 2191 }
 2192 
 2193 int
 2194 azalia_get_props(void *v)
 2195 {
 2196         return AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX;
 2197 }
 2198 
 2199 int
 2200 azalia_trigger_output(void *v, void *start, void *end, int blk,
 2201     void (*intr)(void *), void *arg, audio_params_t *param)
 2202 {
 2203         azalia_t *az;
 2204         int err;
 2205         uint16_t fmt;
 2206 
 2207         err = azalia_params2fmt(param, &fmt);
 2208         if (err)
 2209                 return EINVAL;
 2210 
 2211         az = v;
 2212         return azalia_stream_start(&az->pstream, start, end, blk, intr, arg, fmt);
 2213 }
 2214 
 2215 int
 2216 azalia_trigger_input(void *v, void *start, void *end, int blk,
 2217     void (*intr)(void *), void *arg, audio_params_t *param)
 2218 {
 2219         azalia_t *az;
 2220         int err;
 2221         uint16_t fmt;
 2222 
 2223         DPRINTF(("%s: this=%p start=%p end=%p blk=%d {enc=%u %uch %u/%ubit %uHz}\n",
 2224             __func__, v, start, end, blk, param->encoding, param->channels,
 2225             param->precision, param->precision, param->sample_rate));
 2226 
 2227         err = azalia_params2fmt(param, &fmt);
 2228         if (err)
 2229                 return EINVAL;
 2230 
 2231         az = v;
 2232         return azalia_stream_start(&az->rstream, start, end, blk, intr, arg, fmt);
 2233 }
 2234 
 2235 /* --------------------------------
 2236  * helpers for MI audio functions
 2237  * -------------------------------- */
 2238 int
 2239 azalia_params2fmt(const audio_params_t *param, uint16_t *fmt)
 2240 {
 2241         uint16_t ret;
 2242 
 2243         ret = 0;
 2244 #ifdef DIAGNOSTIC
 2245         if (param->channels > HDA_MAX_CHANNELS) {
 2246                 printf("%s: too many channels: %u\n", __func__,
 2247                     param->channels);
 2248                 return EINVAL;
 2249         }
 2250 #endif
 2251         ret |= param->channels - 1;
 2252 
 2253         switch (param->precision) {
 2254         case 8:
 2255                 ret |= HDA_SD_FMT_BITS_8_16;
 2256                 break;
 2257         case 16:
 2258                 ret |= HDA_SD_FMT_BITS_16_16;
 2259                 break;
 2260         case 32:
 2261                 ret |= HDA_SD_FMT_BITS_32_32;
 2262                 break;
 2263         }
 2264 
 2265 #if 0
 2266         switch (param->validbits) {
 2267         case 8:
 2268                 ret |= HDA_SD_FMT_BITS_8_16;
 2269                 break;
 2270         case 16:
 2271                 ret |= HDA_SD_FMT_BITS_16_16;
 2272                 break;
 2273         case 20:
 2274                 ret |= HDA_SD_FMT_BITS_20_32;
 2275                 break;
 2276         case 24:
 2277                 ret |= HDA_SD_FMT_BITS_24_32;
 2278                 break;
 2279         case 32:
 2280                 ret |= HDA_SD_FMT_BITS_32_32;
 2281                 break;
 2282         default:
 2283                 printf("%s: invalid validbits: %u\n", __func__,
 2284                     param->validbits);
 2285         }
 2286 #endif
 2287 
 2288         if (param->sample_rate == 384000) {
 2289                 printf("%s: invalid sample_rate: %u\n", __func__,
 2290                     param->sample_rate);
 2291                 return EINVAL;
 2292         } else if (param->sample_rate == 192000) {
 2293                 ret |= HDA_SD_FMT_BASE_48 | HDA_SD_FMT_MULT_X4 | HDA_SD_FMT_DIV_BY1;
 2294         } else if (param->sample_rate == 176400) {
 2295                 ret |= HDA_SD_FMT_BASE_44 | HDA_SD_FMT_MULT_X4 | HDA_SD_FMT_DIV_BY1;
 2296         } else if (param->sample_rate == 96000) {
 2297                 ret |= HDA_SD_FMT_BASE_48 | HDA_SD_FMT_MULT_X2 | HDA_SD_FMT_DIV_BY1;
 2298         } else if (param->sample_rate == 88200) {
 2299                 ret |= HDA_SD_FMT_BASE_44 | HDA_SD_FMT_MULT_X2 | HDA_SD_FMT_DIV_BY1;
 2300         } else if (param->sample_rate == 48000) {
 2301                 ret |= HDA_SD_FMT_BASE_48 | HDA_SD_FMT_MULT_X1 | HDA_SD_FMT_DIV_BY1;
 2302         } else if (param->sample_rate == 44100) {
 2303                 ret |= HDA_SD_FMT_BASE_44 | HDA_SD_FMT_MULT_X1 | HDA_SD_FMT_DIV_BY1;
 2304         } else if (param->sample_rate == 32000) {
 2305                 ret |= HDA_SD_FMT_BASE_48 | HDA_SD_FMT_MULT_X2 | HDA_SD_FMT_DIV_BY3;
 2306         } else if (param->sample_rate == 22050) {
 2307                 ret |= HDA_SD_FMT_BASE_44 | HDA_SD_FMT_MULT_X1 | HDA_SD_FMT_DIV_BY2;
 2308         } else if (param->sample_rate == 16000) {
 2309                 ret |= HDA_SD_FMT_BASE_48 | HDA_SD_FMT_MULT_X1 | HDA_SD_FMT_DIV_BY3;
 2310         } else if (param->sample_rate == 11025) {
 2311                 ret |= HDA_SD_FMT_BASE_44 | HDA_SD_FMT_MULT_X1 | HDA_SD_FMT_DIV_BY4;
 2312         } else if (param->sample_rate == 8000) {
 2313                 ret |= HDA_SD_FMT_BASE_48 | HDA_SD_FMT_MULT_X1 | HDA_SD_FMT_DIV_BY6;
 2314         } else {
 2315                 printf("%s: invalid sample_rate: %u\n", __func__,
 2316                     param->sample_rate);
 2317                 return EINVAL;
 2318         }
 2319         *fmt = ret;
 2320         return 0;
 2321 }
 2322 
 2323 int
 2324 azalia_create_encodings(struct audio_format *formats, int nformats,
 2325     struct audio_encoding_set **encodings)
 2326 {
 2327 #if 0
 2328         int i;
 2329         u_int j;
 2330 
 2331         for (i = 0; i < nformats; i++) {
 2332                 printf("format(%d): encoding %u vbits %u prec %u chans %u cmask 0x%x\n",
 2333                     i, formats[i].encoding, formats[i].validbits,
 2334                     formats[i].precision, formats[i].channels,
 2335                     formats[i].channel_mask);
 2336                 printf("format(%d) rates:", i);
 2337                 for (j = 0; j < formats[i].frequency_type; j++) {
 2338                         printf(" %u", formats[i].frequency[j]);
 2339                 }
 2340                 printf("\n");
 2341         }
 2342 #endif
 2343         return (0);
 2344 }

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