root/dev/isa/ess.c

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

DEFINITIONS

This source file includes following definitions.
  1. ess_printsc
  2. ess_dump_mixer
  3. ess_config_addr
  4. ess_config_irq
  5. ess_config_drq
  6. ess_setup
  7. ess_identify
  8. ess_setup_sc
  9. essmatch
  10. essattach
  11. ess_open
  12. ess_1788_close
  13. ess_1888_close
  14. ess_drain
  15. ess_speaker_ctl
  16. ess_getdev
  17. ess_query_encoding
  18. ess_set_params
  19. ess_audio1_trigger_output
  20. ess_audio2_trigger_output
  21. ess_audio1_trigger_input
  22. ess_audio1_halt
  23. ess_audio2_halt
  24. ess_audio1_intr
  25. ess_audio2_intr
  26. ess_audio1_poll
  27. ess_audio2_poll
  28. ess_round_blocksize
  29. ess_set_port
  30. ess_get_port
  31. ess_query_devinfo
  32. ess_malloc
  33. ess_free
  34. ess_round_buffersize
  35. ess_mappage
  36. ess_1788_get_props
  37. ess_1888_get_props
  38. ess_reset
  39. ess_set_gain
  40. ess_set_in_port
  41. ess_set_in_ports
  42. ess_speaker_on
  43. ess_speaker_off
  44. ess_srtotc
  45. ess_srtofc
  46. ess_get_dsp_status
  47. ess_dsp_read_ready
  48. ess_dsp_write_ready
  49. ess_rdsp
  50. ess_wdsp
  51. ess_write_x_reg
  52. ess_read_x_reg
  53. ess_clear_xreg_bits
  54. ess_set_xreg_bits
  55. ess_write_mix_reg
  56. ess_read_mix_reg
  57. ess_clear_mreg_bits
  58. ess_set_mreg_bits
  59. ess_read_multi_mix_reg

    1 /*      $OpenBSD: ess.c,v 1.11 2006/02/22 19:43:42 miod Exp $   */
    2 /*      $NetBSD: ess.c,v 1.44.4.1 1999/06/21 01:18:00 thorpej Exp $     */
    3 
    4 /*
    5  * Copyright 1997
    6  * Digital Equipment Corporation. All rights reserved.
    7  *
    8  * This software is furnished under license and may be used and
    9  * copied only in accordance with the following terms and conditions.
   10  * Subject to these conditions, you may download, copy, install,
   11  * use, modify and distribute this software in source and/or binary
   12  * form. No title or ownership is transferred hereby.
   13  *
   14  * 1) Any source code used, modified or distributed must reproduce
   15  *    and retain this copyright notice and list of conditions as
   16  *    they appear in the source file.
   17  *
   18  * 2) No right is granted to use any trade name, trademark, or logo of
   19  *    Digital Equipment Corporation. Neither the "Digital Equipment
   20  *    Corporation" name nor any trademark or logo of Digital Equipment
   21  *    Corporation may be used to endorse or promote products derived
   22  *    from this software without the prior written permission of
   23  *    Digital Equipment Corporation.
   24  *
   25  * 3) This software is provided "AS-IS" and any express or implied
   26  *    warranties, including but not limited to, any implied warranties
   27  *    of merchantability, fitness for a particular purpose, or
   28  *    non-infringement are disclaimed. In no event shall DIGITAL be
   29  *    liable for any damages whatsoever, and in particular, DIGITAL
   30  *    shall not be liable for special, indirect, consequential, or
   31  *    incidental damages or damages for lost profits, loss of
   32  *    revenue or loss of use, whether such damages arise in contract,
   33  *    negligence, tort, under statute, in equity, at law or otherwise,
   34  *    even if advised of the possibility of such damage.
   35  */
   36 
   37 /*
   38 **++
   39 **
   40 **  ess.c
   41 **
   42 **  FACILITY:
   43 **
   44 **      DIGITAL Network Appliance Reference Design (DNARD)
   45 **
   46 **  MODULE DESCRIPTION:
   47 **
   48 **      This module contains the device driver for the ESS
   49 **      Technologies 1888/1887/888 sound chip. The code in sbdsp.c was
   50 **      used as a reference point when implementing this driver.
   51 **
   52 **  AUTHORS:
   53 **
   54 **      Blair Fidler    Software Engineering Australia
   55 **                      Gold Coast, Australia.
   56 **
   57 **  CREATION DATE:
   58 **
   59 **      March 10, 1997.
   60 **
   61 **  MODIFICATION HISTORY:
   62 **
   63 **      Heavily modified by Lennart Augustsson and Charles M. Hannum for
   64 **      bus_dma, changes to audio interface, and many bug fixes.
   65 **      ESS1788 support by Nathan J. Williams and Charles M. Hannum.
   66 **--
   67 */
   68 
   69 #include <sys/param.h>
   70 #include <sys/systm.h>
   71 #include <sys/errno.h>
   72 #include <sys/ioctl.h>
   73 #include <sys/syslog.h>
   74 #include <sys/device.h>
   75 #include <sys/proc.h>
   76 #include <sys/kernel.h>
   77 #include <sys/timeout.h>
   78 
   79 #include <machine/cpu.h>
   80 #include <machine/intr.h>
   81 #include <machine/bus.h>
   82 
   83 #include <sys/audioio.h>
   84 #include <dev/audio_if.h>
   85 #include <dev/auconv.h>
   86 #include <dev/mulaw.h>
   87 
   88 #include <dev/isa/isavar.h>
   89 #include <dev/isa/isadmavar.h>
   90 
   91 #include <dev/isa/essvar.h>
   92 #include <dev/isa/essreg.h>
   93 
   94 #ifdef AUDIO_DEBUG
   95 #define DPRINTF(x)      if (essdebug) printf x
   96 #define DPRINTFN(n,x)   if (essdebug>(n)) printf x
   97 int     essdebug = 0;
   98 #else
   99 #define DPRINTF(x)
  100 #define DPRINTFN(n,x)
  101 #endif
  102 
  103 #if 0
  104 unsigned uuu;
  105 #define EREAD1(t, h, a) (uuu=bus_space_read_1(t, h, a),printf("EREAD  %02x=%02x\n", ((int)h&0xfff)+a, uuu),uuu)
  106 #define EWRITE1(t, h, a, d) (printf("EWRITE %02x=%02x\n", ((int)h & 0xfff)+a, d), bus_space_write_1(t, h, a, d))
  107 #else
  108 #define EREAD1(t, h, a) bus_space_read_1(t, h, a)
  109 #define EWRITE1(t, h, a, d) bus_space_write_1(t, h, a, d)
  110 #endif
  111 
  112 struct cfdriver ess_cd = {
  113         NULL, "ess", DV_DULL
  114 };
  115 
  116 int     ess_setup_sc(struct ess_softc *, int);
  117 
  118 int     ess_open(void *, int);
  119 void    ess_1788_close(void *);
  120 void    ess_1888_close(void *);
  121 int     ess_getdev(void *, struct audio_device *);
  122 int     ess_drain(void *);
  123 
  124 int     ess_query_encoding(void *, struct audio_encoding *);
  125 
  126 int     ess_set_params(void *, int, int, struct audio_params *,
  127             struct audio_params *);
  128 
  129 int     ess_round_blocksize(void *, int);
  130 
  131 int     ess_audio1_trigger_output(void *, void *, void *, int,
  132             void (*)(void *), void *, struct audio_params *);
  133 int     ess_audio2_trigger_output(void *, void *, void *, int,
  134             void (*)(void *), void *, struct audio_params *);
  135 int     ess_audio1_trigger_input(void *, void *, void *, int,
  136             void (*)(void *), void *, struct audio_params *);
  137 int     ess_audio1_halt(void *);
  138 int     ess_audio2_halt(void *);
  139 int     ess_audio1_intr(void *);
  140 int     ess_audio2_intr(void *);
  141 void    ess_audio1_poll(void *);
  142 void    ess_audio2_poll(void *);
  143 
  144 int     ess_speaker_ctl(void *, int);
  145 
  146 int     ess_getdev(void *, struct audio_device *);
  147 
  148 int     ess_set_port(void *, mixer_ctrl_t *);
  149 int     ess_get_port(void *, mixer_ctrl_t *);
  150 
  151 void   *ess_malloc(void *, int, size_t, int, int);
  152 void    ess_free(void *, void *, int);
  153 size_t  ess_round_buffersize(void *, int, size_t);
  154 paddr_t ess_mappage(void *, void *, off_t, int);
  155 
  156 
  157 int     ess_query_devinfo(void *, mixer_devinfo_t *);
  158 int     ess_1788_get_props(void *);
  159 int     ess_1888_get_props(void *);
  160 
  161 void    ess_speaker_on(struct ess_softc *);
  162 void    ess_speaker_off(struct ess_softc *);
  163 
  164 int     ess_config_addr(struct ess_softc *);
  165 void    ess_config_irq(struct ess_softc *);
  166 void    ess_config_drq(struct ess_softc *);
  167 void    ess_setup(struct ess_softc *);
  168 int     ess_identify(struct ess_softc *);
  169 
  170 int     ess_reset(struct ess_softc *);
  171 void    ess_set_gain(struct ess_softc *, int, int);
  172 int     ess_set_in_port(struct ess_softc *, int);
  173 int     ess_set_in_ports(struct ess_softc *, int);
  174 u_int   ess_srtotc(u_int);
  175 u_int   ess_srtofc(u_int);
  176 u_char  ess_get_dsp_status(struct ess_softc *);
  177 u_char  ess_dsp_read_ready(struct ess_softc *);
  178 u_char  ess_dsp_write_ready(struct ess_softc *);
  179 int     ess_rdsp(struct ess_softc *);
  180 int     ess_wdsp(struct ess_softc *, u_char);
  181 u_char  ess_read_x_reg(struct ess_softc *, u_char);
  182 int     ess_write_x_reg(struct ess_softc *, u_char, u_char);
  183 void    ess_clear_xreg_bits(struct ess_softc *, u_char, u_char);
  184 void    ess_set_xreg_bits(struct ess_softc *, u_char, u_char);
  185 u_char  ess_read_mix_reg(struct ess_softc *, u_char);
  186 void    ess_write_mix_reg(struct ess_softc *, u_char, u_char);
  187 void    ess_clear_mreg_bits(struct ess_softc *, u_char, u_char);
  188 void    ess_set_mreg_bits(struct ess_softc *, u_char, u_char);
  189 void    ess_read_multi_mix_reg(struct ess_softc *, u_char, u_int8_t *, bus_size_t);
  190 
  191 static char *essmodel[] = {
  192         "unsupported",
  193         "1888",
  194         "1887",
  195         "888",
  196         "1788",
  197         "1869",
  198         "1879",
  199         "1868",
  200         "1878",
  201 };
  202 
  203 struct audio_device ess_device = {
  204         "ESS Technology",
  205         "x",
  206         "ess"
  207 };
  208 
  209 /*
  210  * Define our interface to the higher level audio driver.
  211  */
  212 
  213 struct audio_hw_if ess_1788_hw_if = {
  214         ess_open,
  215         ess_1788_close,
  216         ess_drain,
  217         ess_query_encoding,
  218         ess_set_params,
  219         ess_round_blocksize,
  220         NULL,
  221         NULL,
  222         NULL,
  223         NULL,
  224         NULL,
  225         ess_audio1_halt,
  226         ess_audio1_halt,
  227         ess_speaker_ctl,
  228         ess_getdev,
  229         NULL,
  230         ess_set_port,
  231         ess_get_port,
  232         ess_query_devinfo,
  233         ess_malloc,
  234         ess_free,
  235         ess_round_buffersize,
  236         ess_mappage,
  237         ess_1788_get_props,
  238         ess_audio1_trigger_output,
  239         ess_audio1_trigger_input,
  240 };
  241 
  242 struct audio_hw_if ess_1888_hw_if = {
  243         ess_open,
  244         ess_1888_close,
  245         ess_drain,
  246         ess_query_encoding,
  247         ess_set_params,
  248         ess_round_blocksize,
  249         NULL,
  250         NULL,
  251         NULL,
  252         NULL,
  253         NULL,
  254         ess_audio2_halt,
  255         ess_audio1_halt,
  256         ess_speaker_ctl,
  257         ess_getdev,
  258         NULL,
  259         ess_set_port,
  260         ess_get_port,
  261         ess_query_devinfo,
  262         ess_malloc,
  263         ess_free,
  264         ess_round_buffersize,
  265         ess_mappage,
  266         ess_1888_get_props,
  267         ess_audio2_trigger_output,
  268         ess_audio1_trigger_input,
  269 };
  270 
  271 #ifdef AUDIO_DEBUG
  272 void ess_printsc(struct ess_softc *);
  273 void ess_dump_mixer(struct ess_softc *);
  274 
  275 void
  276 ess_printsc(sc)
  277         struct ess_softc *sc;
  278 {
  279         int i;
  280 
  281         printf("open %d iobase 0x%x outport %u inport %u speaker %s\n",
  282                (int)sc->sc_open, sc->sc_iobase, sc->out_port,
  283                sc->in_port, sc->spkr_state ? "on" : "off");
  284 
  285         printf("audio1: dmachan %d irq %d nintr %lu intr %p arg %p\n",
  286                sc->sc_audio1.drq, sc->sc_audio1.irq, sc->sc_audio1.nintr,
  287                sc->sc_audio1.intr, sc->sc_audio1.arg);
  288 
  289         if (!ESS_USE_AUDIO1(sc->sc_model)) {
  290                 printf("audio2: dmachan %d irq %d nintr %lu intr %p arg %p\n",
  291                        sc->sc_audio2.drq, sc->sc_audio2.irq, sc->sc_audio2.nintr,
  292                        sc->sc_audio2.intr, sc->sc_audio2.arg);
  293         }
  294 
  295         printf("gain:");
  296         for (i = 0; i < sc->ndevs; i++)
  297                 printf(" %u,%u", sc->gain[i][ESS_LEFT], sc->gain[i][ESS_RIGHT]);
  298         printf("\n");
  299 }
  300 
  301 void
  302 ess_dump_mixer(sc)
  303         struct ess_softc *sc;
  304 {
  305         printf("ESS_DAC_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
  306                0x7C, ess_read_mix_reg(sc, 0x7C));
  307         printf("ESS_MIC_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
  308                0x1A, ess_read_mix_reg(sc, 0x1A));
  309         printf("ESS_LINE_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
  310                0x3E, ess_read_mix_reg(sc, 0x3E));
  311         printf("ESS_SYNTH_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
  312                0x36, ess_read_mix_reg(sc, 0x36));
  313         printf("ESS_CD_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
  314                0x38, ess_read_mix_reg(sc, 0x38));
  315         printf("ESS_AUXB_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
  316                0x3A, ess_read_mix_reg(sc, 0x3A));
  317         printf("ESS_MASTER_VOL: mix reg 0x%02x=0x%02x\n",
  318                0x32, ess_read_mix_reg(sc, 0x32));
  319         printf("ESS_PCSPEAKER_VOL: mix reg 0x%02x=0x%02x\n",
  320                0x3C, ess_read_mix_reg(sc, 0x3C));
  321         printf("ESS_DAC_REC_VOL: mix reg 0x%02x=0x%02x\n",
  322                0x69, ess_read_mix_reg(sc, 0x69));
  323         printf("ESS_MIC_REC_VOL: mix reg 0x%02x=0x%02x\n",
  324                0x68, ess_read_mix_reg(sc, 0x68));
  325         printf("ESS_LINE_REC_VOL: mix reg 0x%02x=0x%02x\n",
  326                0x6E, ess_read_mix_reg(sc, 0x6E));
  327         printf("ESS_SYNTH_REC_VOL: mix reg 0x%02x=0x%02x\n",
  328                0x6B, ess_read_mix_reg(sc, 0x6B));
  329         printf("ESS_CD_REC_VOL: mix reg 0x%02x=0x%02x\n",
  330                0x6A, ess_read_mix_reg(sc, 0x6A));
  331         printf("ESS_AUXB_REC_VOL: mix reg 0x%02x=0x%02x\n",
  332                0x6C, ess_read_mix_reg(sc, 0x6C));
  333         printf("ESS_RECORD_VOL: x reg 0x%02x=0x%02x\n",
  334                0xB4, ess_read_x_reg(sc, 0xB4));
  335         printf("Audio 1 play vol (unused): mix reg 0x%02x=0x%02x\n",
  336                0x14, ess_read_mix_reg(sc, 0x14));
  337 
  338         printf("ESS_MIC_PREAMP: x reg 0x%02x=0x%02x\n",
  339                ESS_XCMD_PREAMP_CTRL, ess_read_x_reg(sc, ESS_XCMD_PREAMP_CTRL));
  340         printf("ESS_RECORD_MONITOR: x reg 0x%02x=0x%02x\n",
  341                ESS_XCMD_AUDIO_CTRL, ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL));
  342         printf("Record source: mix reg 0x%02x=0x%02x, 0x%02x=0x%02x\n",
  343                ESS_MREG_ADC_SOURCE, ess_read_mix_reg(sc, ESS_MREG_ADC_SOURCE),
  344                ESS_MREG_AUDIO2_CTRL2, ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2));
  345 }
  346 
  347 #endif
  348 
  349 /*
  350  * Configure the ESS chip for the desired audio base address.
  351  */
  352 int
  353 ess_config_addr(sc)
  354         struct ess_softc *sc;
  355 {
  356         int iobase = sc->sc_iobase;
  357         bus_space_tag_t iot = sc->sc_iot;
  358 
  359         /*
  360          * Configure using the System Control Register method.  This
  361          * method is used when the AMODE line is tied high, which is
  362          * the case for the Shark, but not for the evaluation board.
  363          */
  364 
  365         bus_space_handle_t scr_access_ioh;
  366         bus_space_handle_t scr_ioh;
  367         u_short scr_value;
  368 
  369         /*
  370          * Set the SCR bit to enable audio.
  371          */
  372         scr_value = ESS_SCR_AUDIO_ENABLE;
  373 
  374         /*
  375          * Set the SCR bits necessary to select the specified audio
  376          * base address.
  377          */
  378         switch(iobase) {
  379         case 0x220:
  380                 scr_value |= ESS_SCR_AUDIO_220;
  381                 break;
  382         case 0x230:
  383                 scr_value |= ESS_SCR_AUDIO_230;
  384                 break;
  385         case 0x240:
  386                 scr_value |= ESS_SCR_AUDIO_240;
  387                 break;
  388         case 0x250:
  389                 scr_value |= ESS_SCR_AUDIO_250;
  390                 break;
  391         default:
  392                 printf("ess: configured iobase 0x%x invalid\n", iobase);
  393                 return (1);
  394                 break;
  395         }
  396 
  397         /*
  398          * Get a mapping for the System Control Register (SCR) access
  399          * registers and the SCR data registers.
  400          */
  401         if (bus_space_map(iot, ESS_SCR_ACCESS_BASE, ESS_SCR_ACCESS_PORTS,
  402                           0, &scr_access_ioh)) {
  403                 printf("ess: can't map SCR access registers\n");
  404                 return (1);
  405         }
  406         if (bus_space_map(iot, ESS_SCR_BASE, ESS_SCR_PORTS,
  407                           0, &scr_ioh)) {
  408                 printf("ess: can't map SCR registers\n");
  409                 bus_space_unmap(iot, scr_access_ioh, ESS_SCR_ACCESS_PORTS);
  410                 return (1);
  411         }
  412 
  413         /* Unlock the SCR. */
  414         EWRITE1(iot, scr_access_ioh, ESS_SCR_UNLOCK, 0);
  415 
  416         /* Write the base address information into SCR[0]. */
  417         EWRITE1(iot, scr_ioh, ESS_SCR_INDEX, 0);
  418         EWRITE1(iot, scr_ioh, ESS_SCR_DATA, scr_value);
  419 
  420         /* Lock the SCR. */
  421         EWRITE1(iot, scr_access_ioh, ESS_SCR_LOCK, 0);
  422 
  423         /* Unmap the SCR access ports and the SCR data ports. */
  424         bus_space_unmap(iot, scr_access_ioh, ESS_SCR_ACCESS_PORTS);
  425         bus_space_unmap(iot, scr_ioh, ESS_SCR_PORTS);
  426 
  427         return 0;
  428 }
  429 
  430 
  431 /*
  432  * Configure the ESS chip for the desired IRQ and DMA channels.
  433  * ESS  ISA
  434  * --------
  435  * IRQA irq9
  436  * IRQB irq5
  437  * IRQC irq7
  438  * IRQD irq10
  439  * IRQE irq15
  440  *
  441  * DRQA drq0
  442  * DRQB drq1
  443  * DRQC drq3
  444  * DRQD drq5
  445  */
  446 void
  447 ess_config_irq(sc)
  448         struct ess_softc *sc;
  449 {
  450         int v;
  451 
  452         DPRINTFN(2,("ess_config_irq\n"));
  453 
  454         if (sc->sc_model == ESS_1887 &&
  455             sc->sc_audio1.irq == sc->sc_audio2.irq &&
  456             sc->sc_audio1.irq != -1) {
  457                 /* Use new method, both interrupts are the same. */
  458                 v = ESS_IS_SELECT_IRQ;  /* enable intrs */
  459                 switch (sc->sc_audio1.irq) {
  460                 case 5:
  461                         v |= ESS_IS_INTRB;
  462                         break;
  463                 case 7:
  464                         v |= ESS_IS_INTRC;
  465                         break;
  466                 case 9:
  467                         v |= ESS_IS_INTRA;
  468                         break;
  469                 case 10:
  470                         v |= ESS_IS_INTRD;
  471                         break;
  472                 case 15:
  473                         v |= ESS_IS_INTRE;
  474                         break;
  475 #ifdef DIAGNOSTIC
  476                 default:
  477                         printf("ess_config_irq: configured irq %d not supported for Audio 1\n",
  478                                sc->sc_audio1.irq);
  479                         return;
  480 #endif
  481                 }
  482                 /* Set the IRQ */
  483                 ess_write_mix_reg(sc, ESS_MREG_INTR_ST, v);
  484                 return;
  485         }
  486 
  487         if (sc->sc_model == ESS_1887) {
  488                 /* Tell the 1887 to use the old interrupt method. */
  489                 ess_write_mix_reg(sc, ESS_MREG_INTR_ST, ESS_IS_ES1888);
  490         }
  491 
  492         if (sc->sc_audio1.polled) {
  493                 /* Turn off Audio1 interrupts. */
  494                 v = 0;
  495         } else {
  496                 /* Configure Audio 1 for the appropriate IRQ line. */
  497                 v = ESS_IRQ_CTRL_MASK | ESS_IRQ_CTRL_EXT; /* All intrs on */
  498                 switch (sc->sc_audio1.irq) {
  499                 case 5:
  500                         v |= ESS_IRQ_CTRL_INTRB;
  501                         break;
  502                 case 7:
  503                         v |= ESS_IRQ_CTRL_INTRC;
  504                         break;
  505                 case 9:
  506                         v |= ESS_IRQ_CTRL_INTRA;
  507                         break;
  508                 case 10:
  509                         v |= ESS_IRQ_CTRL_INTRD;
  510                         break;
  511 #ifdef DIAGNOSTIC
  512                 default:
  513                         printf("ess: configured irq %d not supported for Audio 1\n",
  514                                sc->sc_audio1.irq);
  515                         return;
  516 #endif
  517                 }
  518         }
  519         ess_write_x_reg(sc, ESS_XCMD_IRQ_CTRL, v);
  520 
  521         if (ESS_USE_AUDIO1(sc->sc_model))
  522                 return;
  523 
  524         if (sc->sc_audio2.polled) {
  525                 /* Turn off Audio2 interrupts. */
  526                 ess_clear_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2,
  527                                     ESS_AUDIO2_CTRL2_IRQ2_ENABLE);
  528         } else {
  529                 /* Audio2 is hardwired to INTRE in this mode. */
  530                 ess_set_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2,
  531                                   ESS_AUDIO2_CTRL2_IRQ2_ENABLE);
  532         }
  533 }
  534 
  535 
  536 void
  537 ess_config_drq(sc)
  538         struct ess_softc *sc;
  539 {
  540         int v;
  541 
  542         DPRINTFN(2,("ess_config_drq\n"));
  543 
  544         /* Configure Audio 1 (record) for DMA on the appropriate channel. */
  545         v = ESS_DRQ_CTRL_PU | ESS_DRQ_CTRL_EXT;
  546         switch (sc->sc_audio1.drq) {
  547         case 0:
  548                 v |= ESS_DRQ_CTRL_DRQA;
  549                 break;
  550         case 1:
  551                 v |= ESS_DRQ_CTRL_DRQB;
  552                 break;
  553         case 3:
  554                 v |= ESS_DRQ_CTRL_DRQC;
  555                 break;
  556 #ifdef DIAGNOSTIC
  557         default:
  558                 printf("ess_config_drq: configured dma chan %d not supported for Audio 1\n",
  559                        sc->sc_audio1.drq);
  560                 return;
  561 #endif
  562         }
  563         /* Set DRQ1 */
  564         ess_write_x_reg(sc, ESS_XCMD_DRQ_CTRL, v);
  565 
  566         if (ESS_USE_AUDIO1(sc->sc_model))
  567                 return;
  568 
  569         /* Configure DRQ2 */
  570         v = ESS_AUDIO2_CTRL3_DRQ_PD;
  571         switch (sc->sc_audio2.drq) {
  572         case 0:
  573                 v |= ESS_AUDIO2_CTRL3_DRQA;
  574                 break;
  575         case 1:
  576                 v |= ESS_AUDIO2_CTRL3_DRQB;
  577                 break;
  578         case 3:
  579                 v |= ESS_AUDIO2_CTRL3_DRQC;
  580                 break;
  581         case 5:
  582                 v |= ESS_AUDIO2_CTRL3_DRQD;
  583                 break;
  584 #ifdef DIAGNOSTIC
  585         default:
  586                 printf("ess_config_drq: configured dma chan %d not supported for Audio 2\n",
  587                        sc->sc_audio2.drq);
  588                 return;
  589 #endif
  590         }
  591         ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL3, v);
  592         /* Enable DMA 2 */
  593         ess_set_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2,
  594                           ESS_AUDIO2_CTRL2_DMA_ENABLE);
  595 }
  596 
  597 /*
  598  * Set up registers after a reset.
  599  */
  600 void
  601 ess_setup(sc)
  602         struct ess_softc *sc;
  603 {
  604 
  605         ess_config_irq(sc);
  606         ess_config_drq(sc);
  607 
  608         DPRINTFN(2,("ess_setup: done\n"));
  609 }
  610 
  611 /*
  612  * Determine the model of ESS chip we are talking to.  Currently we
  613  * only support ES1888, ES1887 and ES888.  The method of determining
  614  * the chip is based on the information on page 27 of the ES1887 data
  615  * sheet.
  616  *
  617  * This routine sets the values of sc->sc_model and sc->sc_version.
  618  */
  619 int
  620 ess_identify(sc)
  621         struct ess_softc *sc;
  622 {
  623         u_char reg1;
  624         u_char reg2;
  625         u_char reg3;
  626         u_int8_t ident[4];
  627 
  628         sc->sc_model = ESS_UNSUPPORTED;
  629         sc->sc_version = 0;
  630 
  631         memset(ident, 0, sizeof(ident));
  632 
  633         /*
  634          * 1. Check legacy ID bytes.  These should be 0x68 0x8n, where
  635          *    n >= 8 for an ES1887 or an ES888.  Other values indicate
  636          *    earlier (unsupported) chips.
  637          */
  638         ess_wdsp(sc, ESS_ACMD_LEGACY_ID);
  639 
  640         if ((reg1 = ess_rdsp(sc)) != 0x68) {
  641                 printf("ess: First ID byte wrong (0x%02x)\n", reg1);
  642                 return 1;
  643         }
  644 
  645         reg2 = ess_rdsp(sc);
  646         if (((reg2 & 0xf0) != 0x80) ||
  647             ((reg2 & 0x0f) < 8)) {
  648                 printf("ess: Second ID byte wrong (0x%02x)\n", reg2);
  649                 return 1;
  650         }
  651 
  652         /*
  653          * Store the ID bytes as the version.
  654          */
  655         sc->sc_version = (reg1 << 8) + reg2;
  656 
  657 
  658         /*
  659          * 2. Verify we can change bit 2 in mixer register 0x64.  This
  660          *    should be possible on all supported chips.
  661          */
  662         reg1 = ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL);
  663         reg2 = reg1 ^ 0x04;  /* toggle bit 2 */
  664 
  665         ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg2);
  666 
  667         if (ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL) != reg2) {
  668                 printf("ess: Hardware error (unable to toggle bit 2 of mixer register 0x64)\n");
  669                 return 1;
  670         }
  671 
  672         /*
  673          * Restore the original value of mixer register 0x64.
  674          */
  675         ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg1);
  676 
  677 
  678         /*
  679          * 3. Verify we can change the value of mixer register
  680          *    ESS_MREG_SAMPLE_RATE.
  681          *    This is possible on the 1888/1887/888, but not on the 1788.
  682          *    It is not necessary to restore the value of this mixer register.
  683          */
  684         reg1 = ess_read_mix_reg(sc, ESS_MREG_SAMPLE_RATE);
  685         reg2 = reg1 ^ 0xff;  /* toggle all bits */
  686 
  687         ess_write_mix_reg(sc, ESS_MREG_SAMPLE_RATE, reg2);
  688 
  689         if (ess_read_mix_reg(sc, ESS_MREG_SAMPLE_RATE) != reg2) {
  690                 /* If we got this far before failing, it's a 1788. */
  691                 sc->sc_model = ESS_1788;
  692 
  693                 /*
  694                  * Identify ESS model for ES18[67]8.
  695                  */
  696                 ess_read_multi_mix_reg(sc, 0x40, ident, sizeof(ident));
  697                 if(ident[0] == 0x18) {
  698                         switch(ident[1]) {
  699                         case 0x68:
  700                                 sc->sc_model = ESS_1868;
  701                                 break;
  702                         case 0x78:
  703                                 sc->sc_model = ESS_1878;
  704                                 break;
  705                         }
  706                 }
  707         } else {
  708                 /*
  709                  * 4. Determine if we can change bit 5 in mixer register 0x64.
  710                  *    This determines whether we have an ES1887:
  711                  *
  712                  *    - can change indicates ES1887
  713                  *    - can't change indicates ES1888 or ES888
  714                  */
  715                 reg1 = ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL);
  716                 reg2 = reg1 ^ 0x20;  /* toggle bit 5 */
  717 
  718                 ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg2);
  719 
  720                 if (ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL) == reg2) {
  721                         sc->sc_model = ESS_1887;
  722 
  723                         /*
  724                          * Restore the original value of mixer register 0x64.
  725                          */
  726                         ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg1);
  727 
  728                         /*
  729                          * Identify ESS model for ES18[67]9.
  730                          */
  731                         ess_read_multi_mix_reg(sc, 0x40, ident, sizeof(ident));
  732                         if(ident[0] == 0x18) {
  733                                 switch(ident[1]) {
  734                                 case 0x69:
  735                                         sc->sc_model = ESS_1869;
  736                                         break;
  737                                 case 0x79:
  738                                         sc->sc_model = ESS_1879;
  739                                         break;
  740                                 }
  741                         }
  742                 } else {
  743                         /*
  744                          * 5. Determine if we can change the value of mixer
  745                          *    register 0x69 independently of mixer register
  746                          *    0x68. This determines which chip we have:
  747                          *
  748                          *    - can modify idependently indicates ES888
  749                          *    - register 0x69 is an alias of 0x68 indicates ES1888
  750                          */
  751                         reg1 = ess_read_mix_reg(sc, 0x68);
  752                         reg2 = ess_read_mix_reg(sc, 0x69);
  753                         reg3 = reg2 ^ 0xff;  /* toggle all bits */
  754 
  755                         /*
  756                          * Write different values to each register.
  757                          */
  758                         ess_write_mix_reg(sc, 0x68, reg2);
  759                         ess_write_mix_reg(sc, 0x69, reg3);
  760 
  761                         if (ess_read_mix_reg(sc, 0x68) == reg2 &&
  762                             ess_read_mix_reg(sc, 0x69) == reg3)
  763                                 sc->sc_model = ESS_888;
  764                         else
  765                                 sc->sc_model = ESS_1888;
  766 
  767                         /*
  768                          * Restore the original value of the registers.
  769                          */
  770                         ess_write_mix_reg(sc, 0x68, reg1);
  771                         ess_write_mix_reg(sc, 0x69, reg2);
  772                 }
  773         }
  774 
  775         return 0;
  776 }
  777 
  778 
  779 int
  780 ess_setup_sc(sc, doinit)
  781         struct ess_softc *sc;
  782         int doinit;
  783 {
  784         /* Reset the chip. */
  785         if (ess_reset(sc) != 0) {
  786                 DPRINTF(("ess_setup_sc: couldn't reset chip\n"));
  787                 return (1);
  788         }
  789 
  790         /* Identify the ESS chip, and check that it is supported. */
  791         if (ess_identify(sc)) {
  792                 DPRINTF(("ess_setup_sc: couldn't identify\n"));
  793                 return (1);
  794         }
  795 
  796         return (0);
  797 }
  798 
  799 /*
  800  * Probe for the ESS hardware.
  801  */
  802 int
  803 essmatch(sc)
  804         struct ess_softc *sc;
  805 {
  806         if (!ESS_BASE_VALID(sc->sc_iobase)) {
  807                 printf("ess: configured iobase 0x%x invalid\n", sc->sc_iobase);
  808                 return (0);
  809         }
  810 
  811         /* Configure the ESS chip for the desired audio base address. */
  812         if (ess_config_addr(sc))
  813                 return (0);
  814 
  815         if (ess_setup_sc(sc, 1))
  816                 return (0);
  817 
  818         if (sc->sc_model == ESS_UNSUPPORTED) {
  819                 DPRINTF(("ess: Unsupported model\n"));
  820                 return (0);
  821         }
  822 
  823         /* Check that requested DMA channels are valid and different. */
  824         if (!ESS_DRQ1_VALID(sc->sc_audio1.drq)) {
  825                 printf("ess: record drq %d invalid\n", sc->sc_audio1.drq);
  826                 return (0);
  827         }
  828         if (!isa_drq_isfree(sc->sc_isa, sc->sc_audio1.drq))
  829                 return (0);
  830         if (!ESS_USE_AUDIO1(sc->sc_model)) {
  831                 if (!ESS_DRQ2_VALID(sc->sc_audio2.drq)) {
  832                         printf("ess: play drq %d invalid\n", sc->sc_audio2.drq);
  833                         return (0);
  834                 }
  835                 if (sc->sc_audio1.drq == sc->sc_audio2.drq) {
  836                         printf("ess: play and record drq both %d\n",
  837                                sc->sc_audio1.drq);
  838                         return (0);
  839                 }
  840                 if (!isa_drq_isfree(sc->sc_isa, sc->sc_audio2.drq))
  841                         return (0);
  842         }
  843 
  844         /*
  845          * The 1887 has an additional IRQ mode where both channels are mapped
  846          * to the same IRQ.
  847          */
  848         if (sc->sc_model == ESS_1887 &&
  849             sc->sc_audio1.irq == sc->sc_audio2.irq &&
  850             sc->sc_audio1.irq != -1 &&
  851             ESS_IRQ12_VALID(sc->sc_audio1.irq))
  852                 goto irq_not1888;
  853 
  854         /* Check that requested IRQ lines are valid and different. */
  855         if (sc->sc_audio1.irq != -1 &&
  856             !ESS_IRQ1_VALID(sc->sc_audio1.irq)) {
  857                 printf("ess: record irq %d invalid\n", sc->sc_audio1.irq);
  858                 return (0);
  859         }
  860         if (!ESS_USE_AUDIO1(sc->sc_model)) {
  861                 if (sc->sc_audio2.irq != -1 &&
  862                     !ESS_IRQ2_VALID(sc->sc_audio2.irq)) {
  863                         printf("ess: play irq %d invalid\n", sc->sc_audio2.irq);
  864                         return (0);
  865                 }
  866                 if (sc->sc_audio1.irq == sc->sc_audio2.irq &&
  867                     sc->sc_audio1.irq != -1) {
  868                         printf("ess: play and record irq both %d\n",
  869                                sc->sc_audio1.irq);
  870                         return (0);
  871                 }
  872         }
  873 
  874 irq_not1888:
  875         /* XXX should we check IRQs as well? */
  876 
  877         return (1);
  878 }
  879 
  880 
  881 /*
  882  * Attach hardware to driver, attach hardware driver to audio
  883  * pseudo-device driver.
  884  */
  885 void
  886 essattach(sc)
  887         struct ess_softc *sc;
  888 {
  889         struct audio_attach_args arg;
  890         struct audio_params pparams, rparams;
  891         int i;
  892         u_int v;
  893 
  894         if (ess_setup_sc(sc, 0)) {
  895                 printf(": setup failed\n");
  896                 return;
  897         }
  898 
  899         printf(": ESS Technology ES%s [version 0x%04x]\n",
  900                essmodel[sc->sc_model], sc->sc_version);
  901 
  902         sc->sc_audio1.polled = sc->sc_audio1.irq == -1;
  903         if (!sc->sc_audio1.polled) {
  904                 sc->sc_audio1.ih = isa_intr_establish(sc->sc_ic,
  905                     sc->sc_audio1.irq, sc->sc_audio1.ist, IPL_AUDIO,
  906                     ess_audio1_intr, sc, sc->sc_dev.dv_xname);
  907                 printf("%s: audio1 interrupting at irq %d\n",
  908                     sc->sc_dev.dv_xname, sc->sc_audio1.irq);
  909         } else
  910                 printf("%s: audio1 polled\n", sc->sc_dev.dv_xname);
  911         if (isa_dmamap_create(sc->sc_isa, sc->sc_audio1.drq,
  912             MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
  913                 printf("%s: can't create map for drq %d\n",
  914                        sc->sc_dev.dv_xname, sc->sc_audio1.drq);
  915                 return;
  916         }
  917 
  918         if (!ESS_USE_AUDIO1(sc->sc_model)) {
  919                 sc->sc_audio2.polled = sc->sc_audio2.irq == -1;
  920                 if (!sc->sc_audio2.polled) {
  921                         sc->sc_audio2.ih = isa_intr_establish(sc->sc_ic,
  922                             sc->sc_audio2.irq, sc->sc_audio2.ist, IPL_AUDIO,
  923                             ess_audio2_intr, sc, sc->sc_dev.dv_xname);
  924                         printf("%s: audio2 interrupting at irq %d\n",
  925                             sc->sc_dev.dv_xname, sc->sc_audio2.irq);
  926                 } else
  927                         printf("%s: audio2 polled\n", sc->sc_dev.dv_xname);
  928                 if (isa_dmamap_create(sc->sc_isa, sc->sc_audio2.drq,
  929                     MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
  930                         printf("%s: can't create map for drq %d\n",
  931                                sc->sc_dev.dv_xname, sc->sc_audio2.drq);
  932                         return;
  933                 }
  934         }
  935 
  936         timeout_set(&sc->sc_tmo1, ess_audio1_poll, sc);
  937         timeout_set(&sc->sc_tmo2, ess_audio2_poll, sc);
  938 
  939         /*
  940          * Set record and play parameters to default values defined in
  941          * generic audio driver.
  942          */
  943         pparams = audio_default;
  944         rparams = audio_default;
  945         ess_set_params(sc, AUMODE_RECORD|AUMODE_PLAY, 0, &pparams, &rparams);
  946 
  947         /* Do a hardware reset on the mixer. */
  948         ess_write_mix_reg(sc, ESS_MIX_RESET, ESS_MIX_RESET);
  949 
  950         /*
  951          * Set volume of Audio 1 to zero and disable Audio 1 DAC input
  952          * to playback mixer, since playback is always through Audio 2.
  953          */
  954         if (!ESS_USE_AUDIO1(sc->sc_model))
  955                 ess_write_mix_reg(sc, ESS_MREG_VOLUME_VOICE, 0);
  956         ess_wdsp(sc, ESS_ACMD_DISABLE_SPKR);
  957 
  958         if (ESS_USE_AUDIO1(sc->sc_model)) {
  959                 ess_write_mix_reg(sc, ESS_MREG_ADC_SOURCE, ESS_SOURCE_MIC);
  960                 sc->in_port = ESS_SOURCE_MIC;
  961                 sc->ndevs = ESS_1788_NDEVS;
  962         } else {
  963                 /*
  964                  * Set hardware record source to use output of the record
  965                  * mixer. We do the selection of record source in software by
  966                  * setting the gain of the unused sources to zero. (See
  967                  * ess_set_in_ports.)
  968                  */
  969                 ess_write_mix_reg(sc, ESS_MREG_ADC_SOURCE, ESS_SOURCE_MIXER);
  970                 sc->in_mask = 1 << ESS_MIC_REC_VOL;
  971                 sc->ndevs = ESS_1888_NDEVS;
  972                 ess_clear_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2, 0x10);
  973                 ess_set_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2, 0x08);
  974         }
  975 
  976         /*
  977          * Set gain on each mixer device to a sensible value.
  978          * Devices not normally used are turned off, and other devices
  979          * are set to 50% volume.
  980          */
  981         for (i = 0; i < sc->ndevs; i++) {
  982                 switch (i) {
  983                 case ESS_MIC_PLAY_VOL:
  984                 case ESS_LINE_PLAY_VOL:
  985                 case ESS_CD_PLAY_VOL:
  986                 case ESS_AUXB_PLAY_VOL:
  987                 case ESS_DAC_REC_VOL:
  988                 case ESS_LINE_REC_VOL:
  989                 case ESS_SYNTH_REC_VOL:
  990                 case ESS_CD_REC_VOL:
  991                 case ESS_AUXB_REC_VOL:
  992                         v = 0;
  993                         break;
  994                 default:
  995                         v = ESS_4BIT_GAIN(AUDIO_MAX_GAIN / 2);
  996                         break;
  997                 }
  998                 sc->gain[i][ESS_LEFT] = sc->gain[i][ESS_RIGHT] = v;
  999                 ess_set_gain(sc, i, 1);
 1000         }
 1001 
 1002         ess_setup(sc);
 1003 
 1004         /* Disable the speaker until the device is opened.  */
 1005         ess_speaker_off(sc);
 1006         sc->spkr_state = SPKR_OFF;
 1007 
 1008         snprintf(ess_device.name, sizeof ess_device.name, "ES%s",
 1009             essmodel[sc->sc_model]);
 1010         snprintf(ess_device.version, sizeof ess_device.version, "0x%04x",
 1011             sc->sc_version);
 1012 
 1013         if (ESS_USE_AUDIO1(sc->sc_model))
 1014                 audio_attach_mi(&ess_1788_hw_if, sc, &sc->sc_dev);
 1015         else
 1016                 audio_attach_mi(&ess_1888_hw_if, sc, &sc->sc_dev);
 1017 
 1018         arg.type = AUDIODEV_TYPE_OPL;
 1019         arg.hwif = 0;
 1020         arg.hdl = 0;
 1021         (void)config_found(&sc->sc_dev, &arg, audioprint);
 1022 
 1023 #ifdef AUDIO_DEBUG
 1024         if (essdebug > 0)
 1025                 ess_printsc(sc);
 1026 #endif
 1027 }
 1028 
 1029 /*
 1030  * Various routines to interface to higher level audio driver
 1031  */
 1032 
 1033 int
 1034 ess_open(addr, flags)
 1035         void *addr;
 1036         int flags;
 1037 {
 1038         struct ess_softc *sc = addr;
 1039 
 1040         DPRINTF(("ess_open: sc=%p\n", sc));
 1041 
 1042         if (sc->sc_open != 0 || ess_reset(sc) != 0)
 1043                 return ENXIO;
 1044 
 1045         ess_setup(sc);          /* because we did a reset */
 1046 
 1047         sc->sc_open = 1;
 1048 
 1049         DPRINTF(("ess_open: opened\n"));
 1050 
 1051         return (0);
 1052 }
 1053 
 1054 void
 1055 ess_1788_close(addr)
 1056         void *addr;
 1057 {
 1058         struct ess_softc *sc = addr;
 1059 
 1060         DPRINTF(("ess_1788_close: sc=%p\n", sc));
 1061 
 1062         ess_speaker_off(sc);
 1063         sc->spkr_state = SPKR_OFF;
 1064 
 1065         ess_audio1_halt(sc);
 1066 
 1067         sc->sc_open = 0;
 1068         DPRINTF(("ess_1788_close: closed\n"));
 1069 }
 1070 
 1071 void
 1072 ess_1888_close(addr)
 1073         void *addr;
 1074 {
 1075         struct ess_softc *sc = addr;
 1076 
 1077         DPRINTF(("ess_1888_close: sc=%p\n", sc));
 1078 
 1079         ess_speaker_off(sc);
 1080         sc->spkr_state = SPKR_OFF;
 1081 
 1082         ess_audio1_halt(sc);
 1083         ess_audio2_halt(sc);
 1084 
 1085         sc->sc_open = 0;
 1086         DPRINTF(("ess_1888_close: closed\n"));
 1087 }
 1088 
 1089 /*
 1090  * Wait for FIFO to drain, and analog section to settle.
 1091  * XXX should check FIFO empty bit.
 1092  */
 1093 int
 1094 ess_drain(addr)
 1095         void *addr;
 1096 {
 1097         tsleep(addr, PWAIT | PCATCH, "essdr", hz/20); /* XXX */
 1098         return (0);
 1099 }
 1100 
 1101 /* XXX should use reference count */
 1102 int
 1103 ess_speaker_ctl(addr, newstate)
 1104         void *addr;
 1105         int newstate;
 1106 {
 1107         struct ess_softc *sc = addr;
 1108 
 1109         if ((newstate == SPKR_ON) && (sc->spkr_state == SPKR_OFF)) {
 1110                 ess_speaker_on(sc);
 1111                 sc->spkr_state = SPKR_ON;
 1112         }
 1113         if ((newstate == SPKR_OFF) && (sc->spkr_state == SPKR_ON)) {
 1114                 ess_speaker_off(sc);
 1115                 sc->spkr_state = SPKR_OFF;
 1116         }
 1117         return (0);
 1118 }
 1119 
 1120 int
 1121 ess_getdev(addr, retp)
 1122         void *addr;
 1123         struct audio_device *retp;
 1124 {
 1125         *retp = ess_device;
 1126         return (0);
 1127 }
 1128 
 1129 int
 1130 ess_query_encoding(addr, fp)
 1131         void *addr;
 1132         struct audio_encoding *fp;
 1133 {
 1134         /*struct ess_softc *sc = addr;*/
 1135 
 1136         switch (fp->index) {
 1137         case 0:
 1138                 strlcpy(fp->name, AudioEulinear, sizeof fp->name);
 1139                 fp->encoding = AUDIO_ENCODING_ULINEAR;
 1140                 fp->precision = 8;
 1141                 fp->flags = 0;
 1142                 return (0);
 1143         case 1:
 1144                 strlcpy(fp->name, AudioEmulaw, sizeof fp->name);
 1145                 fp->encoding = AUDIO_ENCODING_ULAW;
 1146                 fp->precision = 8;
 1147                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
 1148                 return (0);
 1149         case 2:
 1150                 strlcpy(fp->name, AudioEalaw, sizeof fp->name);
 1151                 fp->encoding = AUDIO_ENCODING_ALAW;
 1152                 fp->precision = 8;
 1153                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
 1154                 return (0);
 1155         case 3:
 1156                 strlcpy(fp->name, AudioEslinear, sizeof fp->name);
 1157                 fp->encoding = AUDIO_ENCODING_SLINEAR;
 1158                 fp->precision = 8;
 1159                 fp->flags = 0;
 1160                 return (0);
 1161         case 4:
 1162                 strlcpy(fp->name, AudioEslinear_le, sizeof fp->name);
 1163                 fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
 1164                 fp->precision = 16;
 1165                 fp->flags = 0;
 1166                 return (0);
 1167         case 5:
 1168                 strlcpy(fp->name, AudioEulinear_le, sizeof fp->name);
 1169                 fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
 1170                 fp->precision = 16;
 1171                 fp->flags = 0;
 1172                 return (0);
 1173         case 6:
 1174                 strlcpy(fp->name, AudioEslinear_be, sizeof fp->name);
 1175                 fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
 1176                 fp->precision = 16;
 1177                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
 1178                 return (0);
 1179         case 7:
 1180                 strlcpy(fp->name, AudioEulinear_be, sizeof fp->name);
 1181                 fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
 1182                 fp->precision = 16;
 1183                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
 1184                 return (0);
 1185         default:
 1186                 return EINVAL;
 1187         }
 1188         return (0);
 1189 }
 1190 
 1191 int
 1192 ess_set_params(addr, setmode, usemode, play, rec)
 1193         void *addr;
 1194         int setmode, usemode;
 1195         struct audio_params *play, *rec;
 1196 {
 1197         struct ess_softc *sc = addr;
 1198         struct audio_params *p;
 1199         int mode;
 1200         int rate;
 1201 
 1202         DPRINTF(("ess_set_params: set=%d use=%d\n", setmode, usemode));
 1203 
 1204         /*
 1205          * The ES1887 manual (page 39, `Full-Duplex DMA Mode') claims that in
 1206          * full-duplex operation the sample rates must be the same for both
 1207          * channels.  This appears to be false; the only bit in common is the
 1208          * clock source selection.  However, we'll be conservative here.
 1209          * - mycroft
 1210          */
 1211         if (play->sample_rate != rec->sample_rate &&
 1212             usemode == (AUMODE_PLAY | AUMODE_RECORD)) {
 1213                 if (setmode == AUMODE_PLAY) {
 1214                         rec->sample_rate = play->sample_rate;
 1215                         setmode |= AUMODE_RECORD;
 1216                 } else if (setmode == AUMODE_RECORD) {
 1217                         play->sample_rate = rec->sample_rate;
 1218                         setmode |= AUMODE_PLAY;
 1219                 } else
 1220                         return (EINVAL);
 1221         }
 1222 
 1223         for (mode = AUMODE_RECORD; mode != -1;
 1224              mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
 1225                 if ((setmode & mode) == 0)
 1226                         continue;
 1227 
 1228                 p = mode == AUMODE_PLAY ? play : rec;
 1229 
 1230                 if (p->sample_rate < ESS_MINRATE ||
 1231                     p->sample_rate > ESS_MAXRATE ||
 1232                     (p->precision != 8 && p->precision != 16) ||
 1233                     (p->channels != 1 && p->channels != 2))
 1234                         return (EINVAL);
 1235 
 1236                 p->factor = 1;
 1237                 p->sw_code = 0;
 1238                 switch (p->encoding) {
 1239                 case AUDIO_ENCODING_SLINEAR_BE:
 1240                 case AUDIO_ENCODING_ULINEAR_BE:
 1241                         if (p->precision == 16)
 1242                                 p->sw_code = swap_bytes;
 1243                         break;
 1244                 case AUDIO_ENCODING_SLINEAR_LE:
 1245                 case AUDIO_ENCODING_ULINEAR_LE:
 1246                         break;
 1247                 case AUDIO_ENCODING_ULAW:
 1248                         if (mode == AUMODE_PLAY) {
 1249                                 p->factor = 2;
 1250                                 p->sw_code = mulaw_to_ulinear16;
 1251                         } else
 1252                                 p->sw_code = ulinear8_to_mulaw;
 1253                         break;
 1254                 case AUDIO_ENCODING_ALAW:
 1255                         if (mode == AUMODE_PLAY) {
 1256                                 p->factor = 2;
 1257                                 p->sw_code = alaw_to_ulinear16;
 1258                         } else
 1259                                 p->sw_code = ulinear8_to_alaw;
 1260                         break;
 1261                 default:
 1262                         return (EINVAL);
 1263                 }
 1264         }
 1265 
 1266         if (usemode == AUMODE_RECORD)
 1267                 rate = rec->sample_rate;
 1268         else
 1269                 rate = play->sample_rate;
 1270 
 1271         ess_write_x_reg(sc, ESS_XCMD_SAMPLE_RATE, ess_srtotc(rate));
 1272         ess_write_x_reg(sc, ESS_XCMD_FILTER_CLOCK, ess_srtofc(rate));
 1273 
 1274         if (!ESS_USE_AUDIO1(sc->sc_model)) {
 1275                 ess_write_mix_reg(sc, ESS_MREG_SAMPLE_RATE, ess_srtotc(rate));
 1276                 ess_write_mix_reg(sc, ESS_MREG_FILTER_CLOCK, ess_srtofc(rate));
 1277         }
 1278 
 1279         return (0);
 1280 }
 1281 
 1282 int
 1283 ess_audio1_trigger_output(addr, start, end, blksize, intr, arg, param)
 1284         void *addr;
 1285         void *start, *end;
 1286         int blksize;
 1287         void (*intr)(void *);
 1288         void *arg;
 1289         struct audio_params *param;
 1290 {
 1291         struct ess_softc *sc = addr;
 1292         u_int8_t reg;
 1293 
 1294         DPRINTFN(1, ("ess_audio1_trigger_output: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n",
 1295             addr, start, end, blksize, intr, arg));
 1296 
 1297         if (sc->sc_audio1.active)
 1298                 panic("ess_audio1_trigger_output: already running");
 1299 
 1300         sc->sc_audio1.active = 1;
 1301         sc->sc_audio1.intr = intr;
 1302         sc->sc_audio1.arg = arg;
 1303         if (sc->sc_audio1.polled) {
 1304                 sc->sc_audio1.dmapos = 0;
 1305                 sc->sc_audio1.buffersize = (char *)end - (char *)start;
 1306                 sc->sc_audio1.dmacount = 0;
 1307                 sc->sc_audio1.blksize = blksize;
 1308                 timeout_add(&sc->sc_tmo1, hz/30);
 1309         }
 1310 
 1311         reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL);
 1312         if (param->channels == 2) {
 1313                 reg &= ~ESS_AUDIO_CTRL_MONO;
 1314                 reg |= ESS_AUDIO_CTRL_STEREO;
 1315         } else {
 1316                 reg |= ESS_AUDIO_CTRL_MONO;
 1317                 reg &= ~ESS_AUDIO_CTRL_STEREO;
 1318         }
 1319         ess_write_x_reg(sc, ESS_XCMD_AUDIO_CTRL, reg);
 1320 
 1321         reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1);
 1322         if (param->precision * param->factor == 16)
 1323                 reg |= ESS_AUDIO1_CTRL1_FIFO_SIZE;
 1324         else
 1325                 reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIZE;
 1326         if (param->channels == 2)
 1327                 reg |= ESS_AUDIO1_CTRL1_FIFO_STEREO;
 1328         else
 1329                 reg &= ~ESS_AUDIO1_CTRL1_FIFO_STEREO;
 1330         if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
 1331             param->encoding == AUDIO_ENCODING_SLINEAR_LE)
 1332                 reg |= ESS_AUDIO1_CTRL1_FIFO_SIGNED;
 1333         else
 1334                 reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIGNED;
 1335         reg |= ESS_AUDIO1_CTRL1_FIFO_CONNECT;
 1336         ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1, reg);
 1337 
 1338         isa_dmastart(sc->sc_isa, sc->sc_audio1.drq, start,
 1339                      (char *)end - (char *)start, NULL,
 1340             DMAMODE_WRITE | DMAMODE_LOOP, BUS_DMA_NOWAIT);
 1341 
 1342         /* Program transfer count registers with 2's complement of count. */
 1343         blksize = -blksize;
 1344         ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTLO, blksize);
 1345         ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTHI, blksize >> 8);
 1346 
 1347         /* Use 4 bytes per output DMA. */
 1348         ess_set_xreg_bits(sc, ESS_XCMD_DEMAND_CTRL, ESS_DEMAND_CTRL_DEMAND_4);
 1349 
 1350         /* Start auto-init DMA */
 1351         ess_wdsp(sc, ESS_ACMD_ENABLE_SPKR);
 1352         reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2);
 1353         reg &= ~(ESS_AUDIO1_CTRL2_DMA_READ | ESS_AUDIO1_CTRL2_ADC_ENABLE);
 1354         reg |= ESS_AUDIO1_CTRL2_FIFO_ENABLE | ESS_AUDIO1_CTRL2_AUTO_INIT;
 1355         ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2, reg);
 1356 
 1357         return (0);
 1358 }
 1359 
 1360 int
 1361 ess_audio2_trigger_output(addr, start, end, blksize, intr, arg, param)
 1362         void *addr;
 1363         void *start, *end;
 1364         int blksize;
 1365         void (*intr)(void *);
 1366         void *arg;
 1367         struct audio_params *param;
 1368 {
 1369         struct ess_softc *sc = addr;
 1370         u_int8_t reg;
 1371 
 1372         DPRINTFN(1, ("ess_audio2_trigger_output: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n",
 1373             addr, start, end, blksize, intr, arg));
 1374 
 1375         if (sc->sc_audio2.active)
 1376                 panic("ess_audio2_trigger_output: already running");
 1377 
 1378         sc->sc_audio2.active = 1;
 1379         sc->sc_audio2.intr = intr;
 1380         sc->sc_audio2.arg = arg;
 1381         if (sc->sc_audio2.polled) {
 1382                 sc->sc_audio2.dmapos = 0;
 1383                 sc->sc_audio2.buffersize = (char *)end - (char *)start;
 1384                 sc->sc_audio2.dmacount = 0;
 1385                 sc->sc_audio2.blksize = blksize;
 1386                 timeout_add(&sc->sc_tmo2, hz/30);
 1387         }
 1388 
 1389         reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2);
 1390         if (param->precision * param->factor == 16)
 1391                 reg |= ESS_AUDIO2_CTRL2_FIFO_SIZE;
 1392         else
 1393                 reg &= ~ESS_AUDIO2_CTRL2_FIFO_SIZE;
 1394         if (param->channels == 2)
 1395                 reg |= ESS_AUDIO2_CTRL2_CHANNELS;
 1396         else
 1397                 reg &= ~ESS_AUDIO2_CTRL2_CHANNELS;
 1398         if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
 1399             param->encoding == AUDIO_ENCODING_SLINEAR_LE)
 1400                 reg |= ESS_AUDIO2_CTRL2_FIFO_SIGNED;
 1401         else
 1402                 reg &= ~ESS_AUDIO2_CTRL2_FIFO_SIGNED;
 1403         ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2, reg);
 1404 
 1405         isa_dmastart(sc->sc_isa, sc->sc_audio2.drq, start,
 1406                      (char *)end - (char *)start, NULL,
 1407             DMAMODE_WRITE | DMAMODE_LOOP, BUS_DMA_NOWAIT);
 1408 
 1409         if (IS16BITDRQ(sc->sc_audio2.drq))
 1410                 blksize >>= 1;  /* use word count for 16 bit DMA */
 1411         /* Program transfer count registers with 2's complement of count. */
 1412         blksize = -blksize;
 1413         ess_write_mix_reg(sc, ESS_MREG_XFER_COUNTLO, blksize);
 1414         ess_write_mix_reg(sc, ESS_MREG_XFER_COUNTHI, blksize >> 8);
 1415 
 1416         reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL1);
 1417         if (IS16BITDRQ(sc->sc_audio2.drq))
 1418                 reg |= ESS_AUDIO2_CTRL1_XFER_SIZE;
 1419         else
 1420                 reg &= ~ESS_AUDIO2_CTRL1_XFER_SIZE;
 1421         reg |= ESS_AUDIO2_CTRL1_DEMAND_8;
 1422         reg |= ESS_AUDIO2_CTRL1_DAC_ENABLE | ESS_AUDIO2_CTRL1_FIFO_ENABLE |
 1423                ESS_AUDIO2_CTRL1_AUTO_INIT;
 1424         ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL1, reg);
 1425 
 1426         return (0);
 1427 }
 1428 
 1429 int
 1430 ess_audio1_trigger_input(addr, start, end, blksize, intr, arg, param)
 1431         void *addr;
 1432         void *start, *end;
 1433         int blksize;
 1434         void (*intr)(void *);
 1435         void *arg;
 1436         struct audio_params *param;
 1437 {
 1438         struct ess_softc *sc = addr;
 1439         u_int8_t reg;
 1440 
 1441         DPRINTFN(1, ("ess_audio1_trigger_input: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n",
 1442             addr, start, end, blksize, intr, arg));
 1443 
 1444         if (sc->sc_audio1.active)
 1445                 panic("ess_audio1_trigger_input: already running");
 1446 
 1447         sc->sc_audio1.active = 1;
 1448         sc->sc_audio1.intr = intr;
 1449         sc->sc_audio1.arg = arg;
 1450         if (sc->sc_audio1.polled) {
 1451                 sc->sc_audio1.dmapos = 0;
 1452                 sc->sc_audio1.buffersize = (char *)end - (char *)start;
 1453                 sc->sc_audio1.dmacount = 0;
 1454                 sc->sc_audio1.blksize = blksize;
 1455                 timeout_add(&sc->sc_tmo1, hz/30);
 1456         }
 1457 
 1458         reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL);
 1459         if (param->channels == 2) {
 1460                 reg &= ~ESS_AUDIO_CTRL_MONO;
 1461                 reg |= ESS_AUDIO_CTRL_STEREO;
 1462         } else {
 1463                 reg |= ESS_AUDIO_CTRL_MONO;
 1464                 reg &= ~ESS_AUDIO_CTRL_STEREO;
 1465         }
 1466         ess_write_x_reg(sc, ESS_XCMD_AUDIO_CTRL, reg);
 1467 
 1468         reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1);
 1469         if (param->precision * param->factor == 16)
 1470                 reg |= ESS_AUDIO1_CTRL1_FIFO_SIZE;
 1471         else
 1472                 reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIZE;
 1473         if (param->channels == 2)
 1474                 reg |= ESS_AUDIO1_CTRL1_FIFO_STEREO;
 1475         else
 1476                 reg &= ~ESS_AUDIO1_CTRL1_FIFO_STEREO;
 1477         if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
 1478             param->encoding == AUDIO_ENCODING_SLINEAR_LE)
 1479                 reg |= ESS_AUDIO1_CTRL1_FIFO_SIGNED;
 1480         else
 1481                 reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIGNED;
 1482         reg |= ESS_AUDIO1_CTRL1_FIFO_CONNECT;
 1483         ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1, reg);
 1484 
 1485         isa_dmastart(sc->sc_isa, sc->sc_audio1.drq, start,
 1486                      (char *)end - (char *)start, NULL,
 1487             DMAMODE_READ | DMAMODE_LOOP, BUS_DMA_NOWAIT);
 1488 
 1489         /* Program transfer count registers with 2's complement of count. */
 1490         blksize = -blksize;
 1491         ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTLO, blksize);
 1492         ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTHI, blksize >> 8);
 1493 
 1494         /* Use 4 bytes per input DMA. */
 1495         ess_set_xreg_bits(sc, ESS_XCMD_DEMAND_CTRL, ESS_DEMAND_CTRL_DEMAND_4);
 1496 
 1497         /* Start auto-init DMA */
 1498         ess_wdsp(sc, ESS_ACMD_DISABLE_SPKR);
 1499         reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2);
 1500         reg |= ESS_AUDIO1_CTRL2_DMA_READ | ESS_AUDIO1_CTRL2_ADC_ENABLE;
 1501         reg |= ESS_AUDIO1_CTRL2_FIFO_ENABLE | ESS_AUDIO1_CTRL2_AUTO_INIT;
 1502         ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2, reg);
 1503 
 1504         return (0);
 1505 }
 1506 
 1507 int
 1508 ess_audio1_halt(addr)
 1509         void *addr;
 1510 {
 1511         struct ess_softc *sc = addr;
 1512 
 1513         DPRINTF(("ess_audio1_halt: sc=%p\n", sc));
 1514 
 1515         if (sc->sc_audio1.active) {
 1516                 ess_clear_xreg_bits(sc, ESS_XCMD_AUDIO1_CTRL2,
 1517                     ESS_AUDIO1_CTRL2_FIFO_ENABLE);
 1518                 isa_dmaabort(sc->sc_isa, sc->sc_audio1.drq);
 1519                 if (sc->sc_audio1.polled)
 1520                         timeout_del(&sc->sc_tmo1);
 1521                 sc->sc_audio1.active = 0;
 1522         }
 1523 
 1524         return (0);
 1525 }
 1526 
 1527 int
 1528 ess_audio2_halt(addr)
 1529         void *addr;
 1530 {
 1531         struct ess_softc *sc = addr;
 1532 
 1533         DPRINTF(("ess_audio2_halt: sc=%p\n", sc));
 1534 
 1535         if (sc->sc_audio2.active) {
 1536                 ess_clear_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL1,
 1537                     ESS_AUDIO2_CTRL1_DAC_ENABLE |
 1538                     ESS_AUDIO2_CTRL1_FIFO_ENABLE);
 1539                 isa_dmaabort(sc->sc_isa, sc->sc_audio2.drq);
 1540                 if (sc->sc_audio2.polled)
 1541                         timeout_del(&sc->sc_tmo2);
 1542                 sc->sc_audio2.active = 0;
 1543         }
 1544 
 1545         return (0);
 1546 }
 1547 
 1548 int
 1549 ess_audio1_intr(arg)
 1550         void *arg;
 1551 {
 1552         struct ess_softc *sc = arg;
 1553         u_int8_t reg;
 1554 
 1555         DPRINTFN(1,("ess_audio1_intr: intr=%p\n", sc->sc_audio1.intr));
 1556 
 1557         /* Check and clear interrupt on Audio1. */
 1558         reg = EREAD1(sc->sc_iot, sc->sc_ioh, ESS_DSP_RW_STATUS);
 1559         if ((reg & ESS_DSP_READ_OFLOW) == 0)
 1560                 return (0);
 1561         reg = EREAD1(sc->sc_iot, sc->sc_ioh, ESS_CLEAR_INTR);
 1562 
 1563         sc->sc_audio1.nintr++;
 1564 
 1565         if (sc->sc_audio1.active) {
 1566                 (*sc->sc_audio1.intr)(sc->sc_audio1.arg);
 1567                 return (1);
 1568         } else
 1569                 return (0);
 1570 }
 1571 
 1572 int
 1573 ess_audio2_intr(arg)
 1574         void *arg;
 1575 {
 1576         struct ess_softc *sc = arg;
 1577         u_int8_t reg;
 1578 
 1579         DPRINTFN(1,("ess_audio2_intr: intr=%p\n", sc->sc_audio2.intr));
 1580 
 1581         /* Check and clear interrupt on Audio2. */
 1582         reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2);
 1583         if ((reg & ESS_AUDIO2_CTRL2_IRQ_LATCH) == 0)
 1584                 return (0);
 1585         reg &= ~ESS_AUDIO2_CTRL2_IRQ_LATCH;
 1586         ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2, reg);
 1587 
 1588         sc->sc_audio2.nintr++;
 1589 
 1590         if (sc->sc_audio2.active) {
 1591                 (*sc->sc_audio2.intr)(sc->sc_audio2.arg);
 1592                 return (1);
 1593         } else
 1594                 return (0);
 1595 }
 1596 
 1597 void
 1598 ess_audio1_poll(addr)
 1599         void *addr;
 1600 {
 1601         struct ess_softc *sc = addr;
 1602         int dmapos, dmacount;
 1603 
 1604         if (!sc->sc_audio1.active)
 1605                 return;
 1606 
 1607         sc->sc_audio1.nintr++;
 1608 
 1609         dmapos = isa_dmacount(sc->sc_isa, sc->sc_audio1.drq);
 1610         dmacount = sc->sc_audio1.dmapos - dmapos;
 1611         if (dmacount < 0)
 1612                 dmacount += sc->sc_audio1.buffersize;
 1613         sc->sc_audio1.dmapos = dmapos;
 1614 #if 1
 1615         dmacount += sc->sc_audio1.dmacount;
 1616         while (dmacount > sc->sc_audio1.blksize) {
 1617                 dmacount -= sc->sc_audio1.blksize;
 1618                 (*sc->sc_audio1.intr)(sc->sc_audio1.arg);
 1619         }
 1620         sc->sc_audio1.dmacount = dmacount;
 1621 #else
 1622         (*sc->sc_audio1.intr)(sc->sc_audio1.arg, dmacount);
 1623 #endif
 1624 
 1625         timeout_add(&sc->sc_tmo1, hz/30);
 1626 }
 1627 
 1628 void
 1629 ess_audio2_poll(addr)
 1630         void *addr;
 1631 {
 1632         struct ess_softc *sc = addr;
 1633         int dmapos, dmacount;
 1634 
 1635         if (!sc->sc_audio2.active)
 1636                 return;
 1637 
 1638         sc->sc_audio2.nintr++;
 1639 
 1640         dmapos = isa_dmacount(sc->sc_isa, sc->sc_audio2.drq);
 1641         dmacount = sc->sc_audio2.dmapos - dmapos;
 1642         if (dmacount < 0)
 1643                 dmacount += sc->sc_audio2.buffersize;
 1644         sc->sc_audio2.dmapos = dmapos;
 1645 #if 1
 1646         dmacount += sc->sc_audio2.dmacount;
 1647         while (dmacount > sc->sc_audio2.blksize) {
 1648                 dmacount -= sc->sc_audio2.blksize;
 1649                 (*sc->sc_audio2.intr)(sc->sc_audio2.arg);
 1650         }
 1651         sc->sc_audio2.dmacount = dmacount;
 1652 #else
 1653         (*sc->sc_audio2.intr)(sc->sc_audio2.arg, dmacount);
 1654 #endif
 1655 
 1656         timeout_add(&sc->sc_tmo2, hz/30);
 1657 }
 1658 
 1659 int
 1660 ess_round_blocksize(addr, blk)
 1661         void *addr;
 1662         int blk;
 1663 {
 1664         return ((blk + 7) & -8);        /* round for max DMA size */
 1665 }
 1666 
 1667 int
 1668 ess_set_port(addr, cp)
 1669         void *addr;
 1670         mixer_ctrl_t *cp;
 1671 {
 1672         struct ess_softc *sc = addr;
 1673         int lgain, rgain;
 1674 
 1675         DPRINTFN(5,("ess_set_port: port=%d num_channels=%d\n",
 1676                     cp->dev, cp->un.value.num_channels));
 1677 
 1678         switch (cp->dev) {
 1679         /*
 1680          * The following mixer ports are all stereo. If we get a
 1681          * single-channel gain value passed in, then we duplicate it
 1682          * to both left and right channels.
 1683          */
 1684         case ESS_MASTER_VOL:
 1685         case ESS_DAC_PLAY_VOL:
 1686         case ESS_MIC_PLAY_VOL:
 1687         case ESS_LINE_PLAY_VOL:
 1688         case ESS_SYNTH_PLAY_VOL:
 1689         case ESS_CD_PLAY_VOL:
 1690         case ESS_AUXB_PLAY_VOL:
 1691         case ESS_RECORD_VOL:
 1692                 if (cp->type != AUDIO_MIXER_VALUE)
 1693                         return EINVAL;
 1694 
 1695                 switch (cp->un.value.num_channels) {
 1696                 case 1:
 1697                         lgain = rgain = ESS_4BIT_GAIN(
 1698                           cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
 1699                         break;
 1700                 case 2:
 1701                         lgain = ESS_4BIT_GAIN(
 1702                           cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]);
 1703                         rgain = ESS_4BIT_GAIN(
 1704                           cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]);
 1705                         break;
 1706                 default:
 1707                         return EINVAL;
 1708                 }
 1709 
 1710                 sc->gain[cp->dev][ESS_LEFT]  = lgain;
 1711                 sc->gain[cp->dev][ESS_RIGHT] = rgain;
 1712                 ess_set_gain(sc, cp->dev, 1);
 1713                 return (0);
 1714 
 1715         /*
 1716          * The PC speaker port is mono. If we get a stereo gain value
 1717          * passed in, then we return EINVAL.
 1718          */
 1719         case ESS_PCSPEAKER_VOL:
 1720                 if (cp->un.value.num_channels != 1)
 1721                         return EINVAL;
 1722 
 1723                 sc->gain[cp->dev][ESS_LEFT] = sc->gain[cp->dev][ESS_RIGHT] =
 1724                   ESS_3BIT_GAIN(cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
 1725                 ess_set_gain(sc, cp->dev, 1);
 1726                 return (0);
 1727 
 1728         case ESS_RECORD_SOURCE:
 1729                 if (ESS_USE_AUDIO1(sc->sc_model)) {
 1730                         if (cp->type == AUDIO_MIXER_ENUM)
 1731                                 return (ess_set_in_port(sc, cp->un.ord));
 1732                         else
 1733                                 return (EINVAL);
 1734                 } else {
 1735                         if (cp->type == AUDIO_MIXER_SET)
 1736                                 return (ess_set_in_ports(sc, cp->un.mask));
 1737                         else
 1738                                 return (EINVAL);
 1739                 }
 1740                 return (0);
 1741 
 1742         case ESS_RECORD_MONITOR:
 1743                 if (cp->type != AUDIO_MIXER_ENUM)
 1744                         return EINVAL;
 1745 
 1746                 if (cp->un.ord)
 1747                         /* Enable monitor */
 1748                         ess_set_xreg_bits(sc, ESS_XCMD_AUDIO_CTRL,
 1749                                           ESS_AUDIO_CTRL_MONITOR);
 1750                 else
 1751                         /* Disable monitor */
 1752                         ess_clear_xreg_bits(sc, ESS_XCMD_AUDIO_CTRL,
 1753                                             ESS_AUDIO_CTRL_MONITOR);
 1754                 return (0);
 1755         }
 1756 
 1757         if (ESS_USE_AUDIO1(sc->sc_model))
 1758                 return (EINVAL);
 1759 
 1760         switch (cp->dev) {
 1761         case ESS_DAC_REC_VOL:
 1762         case ESS_MIC_REC_VOL:
 1763         case ESS_LINE_REC_VOL:
 1764         case ESS_SYNTH_REC_VOL:
 1765         case ESS_CD_REC_VOL:
 1766         case ESS_AUXB_REC_VOL:
 1767                 if (cp->type != AUDIO_MIXER_VALUE)
 1768                         return EINVAL;
 1769 
 1770                 switch (cp->un.value.num_channels) {
 1771                 case 1:
 1772                         lgain = rgain = ESS_4BIT_GAIN(
 1773                           cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
 1774                         break;
 1775                 case 2:
 1776                         lgain = ESS_4BIT_GAIN(
 1777                           cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]);
 1778                         rgain = ESS_4BIT_GAIN(
 1779                           cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]);
 1780                         break;
 1781                 default:
 1782                         return EINVAL;
 1783                 }
 1784 
 1785                 sc->gain[cp->dev][ESS_LEFT]  = lgain;
 1786                 sc->gain[cp->dev][ESS_RIGHT] = rgain;
 1787                 ess_set_gain(sc, cp->dev, 1);
 1788                 return (0);
 1789 
 1790         case ESS_MIC_PREAMP:
 1791                 if (cp->type != AUDIO_MIXER_ENUM)
 1792                         return EINVAL;
 1793 
 1794                 if (cp->un.ord)
 1795                         /* Enable microphone preamp */
 1796                         ess_set_xreg_bits(sc, ESS_XCMD_PREAMP_CTRL,
 1797                                           ESS_PREAMP_CTRL_ENABLE);
 1798                 else
 1799                         /* Disable microphone preamp */
 1800                         ess_clear_xreg_bits(sc, ESS_XCMD_PREAMP_CTRL,
 1801                                           ESS_PREAMP_CTRL_ENABLE);
 1802                 return (0);
 1803         }
 1804 
 1805         return (EINVAL);
 1806 }
 1807 
 1808 int
 1809 ess_get_port(addr, cp)
 1810         void *addr;
 1811         mixer_ctrl_t *cp;
 1812 {
 1813         struct ess_softc *sc = addr;
 1814 
 1815         DPRINTFN(5,("ess_get_port: port=%d\n", cp->dev));
 1816 
 1817         switch (cp->dev) {
 1818         case ESS_MASTER_VOL:
 1819         case ESS_DAC_PLAY_VOL:
 1820         case ESS_MIC_PLAY_VOL:
 1821         case ESS_LINE_PLAY_VOL:
 1822         case ESS_SYNTH_PLAY_VOL:
 1823         case ESS_CD_PLAY_VOL:
 1824         case ESS_AUXB_PLAY_VOL:
 1825         case ESS_RECORD_VOL:
 1826                 switch (cp->un.value.num_channels) {
 1827                 case 1:
 1828                         cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
 1829                                 sc->gain[cp->dev][ESS_LEFT];
 1830                         break;
 1831                 case 2:
 1832                         cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
 1833                                 sc->gain[cp->dev][ESS_LEFT];
 1834                         cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
 1835                                 sc->gain[cp->dev][ESS_RIGHT];
 1836                         break;
 1837                 default:
 1838                         return EINVAL;
 1839                 }
 1840                 return (0);
 1841 
 1842         case ESS_PCSPEAKER_VOL:
 1843                 if (cp->un.value.num_channels != 1)
 1844                         return EINVAL;
 1845 
 1846                 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
 1847                         sc->gain[cp->dev][ESS_LEFT];
 1848                 return (0);
 1849 
 1850         case ESS_RECORD_SOURCE:
 1851                 if (ESS_USE_AUDIO1(sc->sc_model))
 1852                         cp->un.ord = sc->in_port;
 1853                 else
 1854                         cp->un.mask = sc->in_mask;
 1855                 return (0);
 1856 
 1857         case ESS_RECORD_MONITOR:
 1858                 cp->un.ord = (ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL) &
 1859                               ESS_AUDIO_CTRL_MONITOR) ? 1 : 0;
 1860                 return (0);
 1861         }
 1862 
 1863         if (ESS_USE_AUDIO1(sc->sc_model))
 1864                 return (EINVAL);
 1865 
 1866         switch (cp->dev) {
 1867         case ESS_DAC_REC_VOL:
 1868         case ESS_MIC_REC_VOL:
 1869         case ESS_LINE_REC_VOL:
 1870         case ESS_SYNTH_REC_VOL:
 1871         case ESS_CD_REC_VOL:
 1872         case ESS_AUXB_REC_VOL:
 1873                 switch (cp->un.value.num_channels) {
 1874                 case 1:
 1875                         cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
 1876                                 sc->gain[cp->dev][ESS_LEFT];
 1877                         break;
 1878                 case 2:
 1879                         cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
 1880                                 sc->gain[cp->dev][ESS_LEFT];
 1881                         cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
 1882                                 sc->gain[cp->dev][ESS_RIGHT];
 1883                         break;
 1884                 default:
 1885                         return EINVAL;
 1886                 }
 1887                 return (0);
 1888 
 1889         case ESS_MIC_PREAMP:
 1890                 cp->un.ord = (ess_read_x_reg(sc, ESS_XCMD_PREAMP_CTRL) &
 1891                               ESS_PREAMP_CTRL_ENABLE) ? 1 : 0;
 1892                 return (0);
 1893         }
 1894 
 1895         return (EINVAL);
 1896 }
 1897 
 1898 int
 1899 ess_query_devinfo(addr, dip)
 1900         void *addr;
 1901         mixer_devinfo_t *dip;
 1902 {
 1903         struct ess_softc *sc = addr;
 1904 
 1905         DPRINTFN(5,("ess_query_devinfo: model=%d index=%d\n",
 1906                     sc->sc_model, dip->index));
 1907 
 1908         /*
 1909          * REVISIT: There are some slight differences between the
 1910          *          mixers on the different ESS chips, which can
 1911          *          be sorted out using the chip model rather than a
 1912          *          separate mixer model.
 1913          *          This is currently coded assuming an ES1887; we
 1914          *          need to work out which bits are not applicable to
 1915          *          the other models (1888 and 888).
 1916          */
 1917         switch (dip->index) {
 1918         case ESS_DAC_PLAY_VOL:
 1919                 dip->mixer_class = ESS_INPUT_CLASS;
 1920                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1921                 strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name);
 1922                 dip->type = AUDIO_MIXER_VALUE;
 1923                 dip->un.v.num_channels = 2;
 1924                 strlcpy(dip->un.v.units.name, AudioNvolume,
 1925                     sizeof dip->un.v.units.name);
 1926                 return (0);
 1927 
 1928         case ESS_MIC_PLAY_VOL:
 1929                 dip->mixer_class = ESS_INPUT_CLASS;
 1930                 dip->prev = AUDIO_MIXER_LAST;
 1931                 if (ESS_USE_AUDIO1(sc->sc_model))
 1932                         dip->next = AUDIO_MIXER_LAST;
 1933                 else
 1934                         dip->next = ESS_MIC_PREAMP;
 1935                 strlcpy(dip->label.name, AudioNmicrophone,
 1936                     sizeof dip->label.name);
 1937                 dip->type = AUDIO_MIXER_VALUE;
 1938                 dip->un.v.num_channels = 2;
 1939                 strlcpy(dip->un.v.units.name, AudioNvolume,
 1940                     sizeof dip->un.v.units.name);
 1941                 return (0);
 1942 
 1943         case ESS_LINE_PLAY_VOL:
 1944                 dip->mixer_class = ESS_INPUT_CLASS;
 1945                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1946                 strlcpy(dip->label.name, AudioNline, sizeof dip->label.name);
 1947                 dip->type = AUDIO_MIXER_VALUE;
 1948                 dip->un.v.num_channels = 2;
 1949                 strlcpy(dip->un.v.units.name, AudioNvolume,
 1950                     sizeof dip->un.v.units.name);
 1951                 return (0);
 1952 
 1953         case ESS_SYNTH_PLAY_VOL:
 1954                 dip->mixer_class = ESS_INPUT_CLASS;
 1955                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1956                 strlcpy(dip->label.name, AudioNfmsynth,
 1957                     sizeof dip->label.name);
 1958                 dip->type = AUDIO_MIXER_VALUE;
 1959                 dip->un.v.num_channels = 2;
 1960                 strlcpy(dip->un.v.units.name, AudioNvolume,
 1961                     sizeof dip->un.v.units.name);
 1962                 return (0);
 1963 
 1964         case ESS_CD_PLAY_VOL:
 1965                 dip->mixer_class = ESS_INPUT_CLASS;
 1966                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1967                 strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name);
 1968                 dip->type = AUDIO_MIXER_VALUE;
 1969                 dip->un.v.num_channels = 2;
 1970                 strlcpy(dip->un.v.units.name, AudioNvolume,
 1971                     sizeof dip->un.v.units.name);
 1972                 return (0);
 1973 
 1974         case ESS_AUXB_PLAY_VOL:
 1975                 dip->mixer_class = ESS_INPUT_CLASS;
 1976                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1977                 strlcpy(dip->label.name, "auxb", sizeof dip->label.name);
 1978                 dip->type = AUDIO_MIXER_VALUE;
 1979                 dip->un.v.num_channels = 2;
 1980                 strlcpy(dip->un.v.units.name, AudioNvolume,
 1981                     sizeof dip->un.v.units.name);
 1982                 return (0);
 1983 
 1984         case ESS_INPUT_CLASS:
 1985                 dip->mixer_class = ESS_INPUT_CLASS;
 1986                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1987                 strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name);
 1988                 dip->type = AUDIO_MIXER_CLASS;
 1989                 return (0);
 1990 
 1991         case ESS_MASTER_VOL:
 1992                 dip->mixer_class = ESS_OUTPUT_CLASS;
 1993                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 1994                 strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name);
 1995                 dip->type = AUDIO_MIXER_VALUE;
 1996                 dip->un.v.num_channels = 2;
 1997                 strlcpy(dip->un.v.units.name, AudioNvolume,
 1998                     sizeof dip->un.v.units.name);
 1999                 return (0);
 2000 
 2001         case ESS_PCSPEAKER_VOL:
 2002                 dip->mixer_class = ESS_OUTPUT_CLASS;
 2003                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 2004                 strlcpy(dip->label.name, "pc_speaker", sizeof dip->label.name);
 2005                 dip->type = AUDIO_MIXER_VALUE;
 2006                 dip->un.v.num_channels = 1;
 2007                 strlcpy(dip->un.v.units.name, AudioNvolume,
 2008                     sizeof dip->un.v.units.name);
 2009                 return (0);
 2010 
 2011         case ESS_OUTPUT_CLASS:
 2012                 dip->mixer_class = ESS_OUTPUT_CLASS;
 2013                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 2014                 strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name);
 2015                 dip->type = AUDIO_MIXER_CLASS;
 2016                 return (0);
 2017 
 2018         case ESS_RECORD_VOL:
 2019                 dip->mixer_class = ESS_RECORD_CLASS;
 2020                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 2021                 strlcpy(dip->label.name, AudioNrecord, sizeof dip->label.name);
 2022                 dip->type = AUDIO_MIXER_VALUE;
 2023                 dip->un.v.num_channels = 2;
 2024                 strlcpy(dip->un.v.units.name, AudioNvolume,
 2025                     sizeof dip->un.v.units.name);
 2026                 return (0);
 2027 
 2028         case ESS_RECORD_SOURCE:
 2029                 dip->mixer_class = ESS_RECORD_CLASS;
 2030                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 2031                 strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name);
 2032                 if (ESS_USE_AUDIO1(sc->sc_model)) {
 2033                         /*
 2034                          * The 1788 doesn't use the input mixer control that
 2035                          * the 1888 uses, because it's a pain when you only
 2036                          * have one mixer.
 2037                          * Perhaps it could be emulated by keeping both sets of
 2038                          * gain values, and doing a `context switch' of the
 2039                          * mixer registers when shifting from playing to
 2040                          * recording.
 2041                          */
 2042                         dip->type = AUDIO_MIXER_ENUM;
 2043                         dip->un.e.num_mem = 4;
 2044                         strlcpy(dip->un.e.member[0].label.name,
 2045                             AudioNmicrophone,
 2046                             sizeof dip->un.e.member[0].label.name);
 2047                         dip->un.e.member[0].ord = ESS_SOURCE_MIC;
 2048                         strlcpy(dip->un.e.member[1].label.name, AudioNline,
 2049                             sizeof dip->un.e.member[1].label.name);
 2050                         dip->un.e.member[1].ord = ESS_SOURCE_LINE;
 2051                         strlcpy(dip->un.e.member[2].label.name, AudioNcd,
 2052                             sizeof dip->un.e.member[2].label.name);
 2053                         dip->un.e.member[2].ord = ESS_SOURCE_CD;
 2054                         strlcpy(dip->un.e.member[3].label.name, AudioNmixerout,
 2055                             sizeof dip->un.e.member[3].label.name);
 2056                         dip->un.e.member[3].ord = ESS_SOURCE_MIXER;
 2057                 } else {
 2058                         dip->type = AUDIO_MIXER_SET;
 2059                         dip->un.s.num_mem = 6;
 2060                         strlcpy(dip->un.s.member[0].label.name, AudioNdac,
 2061                             sizeof dip->un.e.member[0].label.name);
 2062                         dip->un.s.member[0].mask = 1 << ESS_DAC_REC_VOL;
 2063                         strlcpy(dip->un.s.member[1].label.name,
 2064                             AudioNmicrophone,
 2065                             sizeof dip->un.e.member[1].label.name);
 2066                         dip->un.s.member[1].mask = 1 << ESS_MIC_REC_VOL;
 2067                         strlcpy(dip->un.s.member[2].label.name, AudioNline,
 2068                             sizeof dip->un.e.member[2].label.name);
 2069                         dip->un.s.member[2].mask = 1 << ESS_LINE_REC_VOL;
 2070                         strlcpy(dip->un.s.member[3].label.name, AudioNfmsynth,
 2071                             sizeof dip->un.e.member[3].label.name);
 2072                         dip->un.s.member[3].mask = 1 << ESS_SYNTH_REC_VOL;
 2073                         strlcpy(dip->un.s.member[4].label.name, AudioNcd,
 2074                             sizeof dip->un.e.member[4].label.name);
 2075                         dip->un.s.member[4].mask = 1 << ESS_CD_REC_VOL;
 2076                         strlcpy(dip->un.s.member[5].label.name, "auxb",
 2077                             sizeof dip->un.e.member[5].label.name);
 2078                         dip->un.s.member[5].mask = 1 << ESS_AUXB_REC_VOL;
 2079                 }
 2080                 return (0);
 2081 
 2082         case ESS_RECORD_CLASS:
 2083                 dip->mixer_class = ESS_RECORD_CLASS;
 2084                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 2085                 strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name);
 2086                 dip->type = AUDIO_MIXER_CLASS;
 2087                 return (0);
 2088 
 2089         case ESS_RECORD_MONITOR:
 2090                 dip->prev = dip->next = AUDIO_MIXER_LAST;
 2091                 strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name);
 2092                 dip->type = AUDIO_MIXER_ENUM;
 2093                 dip->mixer_class = ESS_MONITOR_CLASS;
 2094                 dip->un.e.num_mem = 2;
 2095                 strlcpy(dip->un.e.member[0].label.name, AudioNoff,
 2096                     sizeof dip->un.e.member[0].label.name);
 2097                 dip->un.e.member[0].ord = 0;
 2098                 strlcpy(dip->un.e.member[1].label.name, AudioNon,
 2099                     sizeof dip->un.e.member[1].label.name);
 2100                 dip->un.e.member[1].ord = 1;
 2101                 return (0);
 2102 
 2103         case ESS_MONITOR_CLASS:
 2104                 dip->mixer_class = ESS_MONITOR_CLASS;
 2105                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 2106                 strlcpy(dip->label.name, AudioCmonitor,
 2107                     sizeof dip->label.name);
 2108                 dip->type = AUDIO_MIXER_CLASS;
 2109                 return (0);
 2110         }
 2111 
 2112         if (ESS_USE_AUDIO1(sc->sc_model))
 2113                 return (ENXIO);
 2114 
 2115         switch (dip->index) {
 2116         case ESS_DAC_REC_VOL:
 2117                 dip->mixer_class = ESS_RECORD_CLASS;
 2118                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 2119                 strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name);
 2120                 dip->type = AUDIO_MIXER_VALUE;
 2121                 dip->un.v.num_channels = 2;
 2122                 strlcpy(dip->un.v.units.name, AudioNvolume,
 2123                     sizeof dip->un.v.units.name);
 2124                 return (0);
 2125 
 2126         case ESS_MIC_REC_VOL:
 2127                 dip->mixer_class = ESS_RECORD_CLASS;
 2128                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 2129                 strlcpy(dip->label.name, AudioNmicrophone,
 2130                     sizeof dip->label.name);
 2131                 dip->type = AUDIO_MIXER_VALUE;
 2132                 dip->un.v.num_channels = 2;
 2133                 strlcpy(dip->un.v.units.name, AudioNvolume,
 2134                     sizeof dip->un.v.units.name);
 2135                 return (0);
 2136 
 2137         case ESS_LINE_REC_VOL:
 2138                 dip->mixer_class = ESS_RECORD_CLASS;
 2139                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 2140                 strlcpy(dip->label.name, AudioNline, sizeof dip->label.name);
 2141                 dip->type = AUDIO_MIXER_VALUE;
 2142                 dip->un.v.num_channels = 2;
 2143                 strlcpy(dip->un.v.units.name, AudioNvolume,
 2144                     sizeof dip->un.v.units.name);
 2145                 return (0);
 2146 
 2147         case ESS_SYNTH_REC_VOL:
 2148                 dip->mixer_class = ESS_RECORD_CLASS;
 2149                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 2150                 strlcpy(dip->label.name, AudioNfmsynth,
 2151                     sizeof dip->label.name);
 2152                 dip->type = AUDIO_MIXER_VALUE;
 2153                 dip->un.v.num_channels = 2;
 2154                 strlcpy(dip->un.v.units.name, AudioNvolume,
 2155                     sizeof dip->un.v.units.name);
 2156                 return (0);
 2157 
 2158         case ESS_CD_REC_VOL:
 2159                 dip->mixer_class = ESS_RECORD_CLASS;
 2160                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 2161                 strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name);
 2162                 dip->type = AUDIO_MIXER_VALUE;
 2163                 dip->un.v.num_channels = 2;
 2164                 strlcpy(dip->un.v.units.name, AudioNvolume,
 2165                     sizeof dip->un.v.units.name);
 2166                 return (0);
 2167 
 2168         case ESS_AUXB_REC_VOL:
 2169                 dip->mixer_class = ESS_RECORD_CLASS;
 2170                 dip->next = dip->prev = AUDIO_MIXER_LAST;
 2171                 strlcpy(dip->label.name, "auxb", sizeof dip->label.name);
 2172                 dip->type = AUDIO_MIXER_VALUE;
 2173                 dip->un.v.num_channels = 2;
 2174                 strlcpy(dip->un.v.units.name, AudioNvolume,
 2175                     sizeof dip->un.v.units.name);
 2176                 return (0);
 2177 
 2178         case ESS_MIC_PREAMP:
 2179                 dip->mixer_class = ESS_INPUT_CLASS;
 2180                 dip->prev = ESS_MIC_PLAY_VOL;
 2181                 dip->next = AUDIO_MIXER_LAST;
 2182                 strlcpy(dip->label.name, AudioNpreamp, sizeof dip->label.name);
 2183                 dip->type = AUDIO_MIXER_ENUM;
 2184                 dip->un.e.num_mem = 2;
 2185                 strlcpy(dip->un.e.member[0].label.name, AudioNoff,
 2186                     sizeof dip->un.e.member[0].label.name);
 2187                 dip->un.e.member[0].ord = 0;
 2188                 strlcpy(dip->un.e.member[1].label.name, AudioNon,
 2189                     sizeof dip->un.e.member[1].label.name);
 2190                 dip->un.e.member[1].ord = 1;
 2191                 return (0);
 2192         }
 2193 
 2194         return (ENXIO);
 2195 }
 2196 
 2197 void *
 2198 ess_malloc(addr, direction, size, pool, flags)
 2199         void *addr;
 2200         int direction;
 2201         size_t size;
 2202         int pool, flags;
 2203 {
 2204         struct ess_softc *sc = addr;
 2205         int drq;
 2206 
 2207         if (!ESS_USE_AUDIO1(sc->sc_model))
 2208                 drq = sc->sc_audio2.drq;
 2209         else
 2210                 drq = sc->sc_audio1.drq;
 2211         return (isa_malloc(sc->sc_isa, drq, size, pool, flags));
 2212 }
 2213 
 2214 void
 2215 ess_free(addr, ptr, pool)
 2216         void *addr;
 2217         void *ptr;
 2218         int pool;
 2219 {
 2220         isa_free(ptr, pool);
 2221 }
 2222 
 2223 size_t
 2224 ess_round_buffersize(addr, direction, size)
 2225         void *addr;
 2226         int direction;
 2227         size_t size;
 2228 {
 2229         if (size > MAX_ISADMA)
 2230                 size = MAX_ISADMA;
 2231         return (size);
 2232 }
 2233 
 2234 paddr_t
 2235 ess_mappage(addr, mem, off, prot)
 2236         void *addr;
 2237         void *mem;
 2238         off_t off;
 2239         int prot;
 2240 {
 2241         return (isa_mappage(mem, off, prot));
 2242 }
 2243 
 2244 int
 2245 ess_1788_get_props(addr)
 2246         void *addr;
 2247 {
 2248 
 2249         return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT);
 2250 }
 2251 
 2252 int
 2253 ess_1888_get_props(addr)
 2254         void *addr;
 2255 {
 2256 
 2257         return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX);
 2258 }
 2259 
 2260 /* ============================================
 2261  * Generic functions for ess, not used by audio h/w i/f
 2262  * =============================================
 2263  */
 2264 
 2265 /*
 2266  * Reset the chip.
 2267  * Return non-zero if the chip isn't detected.
 2268  */
 2269 int
 2270 ess_reset(sc)
 2271         struct ess_softc *sc;
 2272 {
 2273         bus_space_tag_t iot = sc->sc_iot;
 2274         bus_space_handle_t ioh = sc->sc_ioh;
 2275 
 2276         sc->sc_audio1.active = 0;
 2277         sc->sc_audio2.active = 0;
 2278 
 2279         EWRITE1(iot, ioh, ESS_DSP_RESET, ESS_RESET_EXT);
 2280         delay(10000);
 2281         EWRITE1(iot, ioh, ESS_DSP_RESET, 0);
 2282         if (ess_rdsp(sc) != ESS_MAGIC)
 2283                 return (1);
 2284 
 2285         /* Enable access to the ESS extension commands. */
 2286         ess_wdsp(sc, ESS_ACMD_ENABLE_EXT);
 2287 
 2288         return (0);
 2289 }
 2290 
 2291 void
 2292 ess_set_gain(sc, port, on)
 2293         struct ess_softc *sc;
 2294         int port;
 2295         int on;
 2296 {
 2297         int gain, left, right;
 2298         int mix;
 2299         int src;
 2300         int stereo;
 2301 
 2302         /*
 2303          * Most gain controls are found in the mixer registers and
 2304          * are stereo. Any that are not, must set mix and stereo as
 2305          * required.
 2306          */
 2307         mix = 1;
 2308         stereo = 1;
 2309 
 2310         switch (port) {
 2311         case ESS_MASTER_VOL:
 2312                 src = ESS_MREG_VOLUME_MASTER;
 2313                 break;
 2314         case ESS_DAC_PLAY_VOL:
 2315                 if (ESS_USE_AUDIO1(sc->sc_model))
 2316                         src = ESS_MREG_VOLUME_VOICE;
 2317                 else
 2318                         src = 0x7C;
 2319                 break;
 2320         case ESS_MIC_PLAY_VOL:
 2321                 src = ESS_MREG_VOLUME_MIC;
 2322                 break;
 2323         case ESS_LINE_PLAY_VOL:
 2324                 src = ESS_MREG_VOLUME_LINE;
 2325                 break;
 2326         case ESS_SYNTH_PLAY_VOL:
 2327                 src = ESS_MREG_VOLUME_SYNTH;
 2328                 break;
 2329         case ESS_CD_PLAY_VOL:
 2330                 src = ESS_MREG_VOLUME_CD;
 2331                 break;
 2332         case ESS_AUXB_PLAY_VOL:
 2333                 src = ESS_MREG_VOLUME_AUXB;
 2334                 break;
 2335         case ESS_PCSPEAKER_VOL:
 2336                 src = ESS_MREG_VOLUME_PCSPKR;
 2337                 stereo = 0;
 2338                 break;
 2339         case ESS_DAC_REC_VOL:
 2340                 src = 0x69;
 2341                 break;
 2342         case ESS_MIC_REC_VOL:
 2343                 src = 0x68;
 2344                 break;
 2345         case ESS_LINE_REC_VOL:
 2346                 src = 0x6E;
 2347                 break;
 2348         case ESS_SYNTH_REC_VOL:
 2349                 src = 0x6B;
 2350                 break;
 2351         case ESS_CD_REC_VOL:
 2352                 src = 0x6A;
 2353                 break;
 2354         case ESS_AUXB_REC_VOL:
 2355                 src = 0x6C;
 2356                 break;
 2357         case ESS_RECORD_VOL:
 2358                 src = ESS_XCMD_VOLIN_CTRL;
 2359                 mix = 0;
 2360                 break;
 2361         default:
 2362                 return;
 2363         }
 2364 
 2365         /* 1788 doesn't have a separate recording mixer */
 2366         if (ESS_USE_AUDIO1(sc->sc_model) && mix && src > 0x62)
 2367                 return;
 2368 
 2369         if (on) {
 2370                 left = sc->gain[port][ESS_LEFT];
 2371                 right = sc->gain[port][ESS_RIGHT];
 2372         } else {
 2373                 left = right = 0;
 2374         }
 2375 
 2376         if (stereo)
 2377                 gain = ESS_STEREO_GAIN(left, right);
 2378         else
 2379                 gain = ESS_MONO_GAIN(left);
 2380 
 2381         if (mix)
 2382                 ess_write_mix_reg(sc, src, gain);
 2383         else
 2384                 ess_write_x_reg(sc, src, gain);
 2385 }
 2386 
 2387 /* Set the input device on devices without an input mixer. */
 2388 int
 2389 ess_set_in_port(sc, ord)
 2390         struct ess_softc *sc;
 2391         int ord;
 2392 {
 2393         mixer_devinfo_t di;
 2394         int i;
 2395 
 2396         DPRINTF(("ess_set_in_port: ord=0x%x\n", ord));
 2397 
 2398         /*
 2399          * Get the device info for the record source control,
 2400          * including the list of available sources.
 2401          */
 2402         di.index = ESS_RECORD_SOURCE;
 2403         if (ess_query_devinfo(sc, &di))
 2404                 return EINVAL;
 2405 
 2406         /* See if the given ord value was anywhere in the list. */
 2407         for (i = 0; i < di.un.e.num_mem; i++) {
 2408                 if (ord == di.un.e.member[i].ord)
 2409                         break;
 2410         }
 2411         if (i == di.un.e.num_mem)
 2412                 return EINVAL;
 2413 
 2414         ess_write_mix_reg(sc, ESS_MREG_ADC_SOURCE, ord);
 2415 
 2416         sc->in_port = ord;
 2417         return (0);
 2418 }
 2419 
 2420 /* Set the input device levels on input-mixer-enabled devices. */
 2421 int
 2422 ess_set_in_ports(sc, mask)
 2423         struct ess_softc *sc;
 2424         int mask;
 2425 {
 2426         mixer_devinfo_t di;
 2427         int i, port;
 2428 
 2429         DPRINTF(("ess_set_in_ports: mask=0x%x\n", mask));
 2430 
 2431         /*
 2432          * Get the device info for the record source control,
 2433          * including the list of available sources.
 2434          */
 2435         di.index = ESS_RECORD_SOURCE;
 2436         if (ess_query_devinfo(sc, &di))
 2437                 return EINVAL;
 2438 
 2439         /*
 2440          * Set or disable the record volume control for each of the
 2441          * possible sources.
 2442          */
 2443         for (i = 0; i < di.un.s.num_mem; i++) {
 2444                 /*
 2445                  * Calculate the source port number from its mask.
 2446                  */
 2447                 port = ffs(di.un.s.member[i].mask);
 2448 
 2449                 /*
 2450                  * Set the source gain:
 2451                  *      to the current value if source is enabled
 2452                  *      to zero if source is disabled
 2453                  */
 2454                 ess_set_gain(sc, port, mask & di.un.s.member[i].mask);
 2455         }
 2456 
 2457         sc->in_mask = mask;
 2458         return (0);
 2459 }
 2460 
 2461 void
 2462 ess_speaker_on(sc)
 2463         struct ess_softc *sc;
 2464 {
 2465         /* Unmute the DAC. */
 2466         ess_set_gain(sc, ESS_DAC_PLAY_VOL, 1);
 2467 }
 2468 
 2469 void
 2470 ess_speaker_off(sc)
 2471         struct ess_softc *sc;
 2472 {
 2473         /* Mute the DAC. */
 2474         ess_set_gain(sc, ESS_DAC_PLAY_VOL, 0);
 2475 }
 2476 
 2477 /*
 2478  * Calculate the time constant for the requested sampling rate.
 2479  */
 2480 u_int
 2481 ess_srtotc(rate)
 2482         u_int rate;
 2483 {
 2484         u_int tc;
 2485 
 2486         /* The following formulae are from the ESS data sheet. */
 2487         if (rate <= 22050)
 2488                 tc = 128 - 397700L / rate;
 2489         else
 2490                 tc = 256 - 795500L / rate;
 2491 
 2492         return (tc);
 2493 }
 2494 
 2495 
 2496 /*
 2497  * Calculate the filter constant for the reuqested sampling rate.
 2498  */
 2499 u_int
 2500 ess_srtofc(rate)
 2501         u_int rate;
 2502 {
 2503         /*
 2504          * The following formula is derived from the information in
 2505          * the ES1887 data sheet, based on a roll-off frequency of
 2506          * 87%.
 2507          */
 2508         return (256 - 200279L / rate);
 2509 }
 2510 
 2511 
 2512 /*
 2513  * Return the status of the DSP.
 2514  */
 2515 u_char
 2516 ess_get_dsp_status(sc)
 2517         struct ess_softc *sc;
 2518 {
 2519         return (EREAD1(sc->sc_iot, sc->sc_ioh, ESS_DSP_RW_STATUS));
 2520 }
 2521 
 2522 
 2523 /*
 2524  * Return the read status of the DSP:   1 -> DSP ready for reading
 2525  *                                      0 -> DSP not ready for reading
 2526  */
 2527 u_char
 2528 ess_dsp_read_ready(sc)
 2529         struct ess_softc *sc;
 2530 {
 2531         return ((ess_get_dsp_status(sc) & ESS_DSP_READ_READY) ? 1 : 0);
 2532 }
 2533 
 2534 
 2535 /*
 2536  * Return the write status of the DSP:  1 -> DSP ready for writing
 2537  *                                      0 -> DSP not ready for writing
 2538  */
 2539 u_char
 2540 ess_dsp_write_ready(sc)
 2541         struct ess_softc *sc;
 2542 {
 2543         return ((ess_get_dsp_status(sc) & ESS_DSP_WRITE_BUSY) ? 0 : 1);
 2544 }
 2545 
 2546 
 2547 /*
 2548  * Read a byte from the DSP.
 2549  */
 2550 int
 2551 ess_rdsp(sc)
 2552         struct ess_softc *sc;
 2553 {
 2554         bus_space_tag_t iot = sc->sc_iot;
 2555         bus_space_handle_t ioh = sc->sc_ioh;
 2556         int i;
 2557 
 2558         for (i = ESS_READ_TIMEOUT; i > 0; --i) {
 2559                 if (ess_dsp_read_ready(sc)) {
 2560                         i = EREAD1(iot, ioh, ESS_DSP_READ);
 2561                         DPRINTFN(8,("ess_rdsp() = 0x%02x\n", i));
 2562                         return i;
 2563                 } else
 2564                         delay(10);
 2565         }
 2566 
 2567         DPRINTF(("ess_rdsp: timed out\n"));
 2568         return (-1);
 2569 }
 2570 
 2571 /*
 2572  * Write a byte to the DSP.
 2573  */
 2574 int
 2575 ess_wdsp(sc, v)
 2576         struct ess_softc *sc;
 2577         u_char v;
 2578 {
 2579         bus_space_tag_t iot = sc->sc_iot;
 2580         bus_space_handle_t ioh = sc->sc_ioh;
 2581         int i;
 2582 
 2583         DPRINTFN(8,("ess_wdsp(0x%02x)\n", v));
 2584 
 2585         for (i = ESS_WRITE_TIMEOUT; i > 0; --i) {
 2586                 if (ess_dsp_write_ready(sc)) {
 2587                         EWRITE1(iot, ioh, ESS_DSP_WRITE, v);
 2588                         return (0);
 2589                 } else
 2590                         delay(10);
 2591         }
 2592 
 2593         DPRINTF(("ess_wdsp(0x%02x): timed out\n", v));
 2594         return (-1);
 2595 }
 2596 
 2597 /*
 2598  * Write a value to one of the ESS extended registers.
 2599  */
 2600 int
 2601 ess_write_x_reg(sc, reg, val)
 2602         struct ess_softc *sc;
 2603         u_char reg;
 2604         u_char val;
 2605 {
 2606         int error;
 2607 
 2608         DPRINTFN(2,("ess_write_x_reg: %02x=%02x\n", reg, val));
 2609         if ((error = ess_wdsp(sc, reg)) == 0)
 2610                 error = ess_wdsp(sc, val);
 2611 
 2612         return error;
 2613 }
 2614 
 2615 /*
 2616  * Read the value of one of the ESS extended registers.
 2617  */
 2618 u_char
 2619 ess_read_x_reg(sc, reg)
 2620         struct ess_softc *sc;
 2621         u_char reg;
 2622 {
 2623         int error;
 2624         int val;
 2625 
 2626         if ((error = ess_wdsp(sc, 0xC0)) == 0)
 2627                 error = ess_wdsp(sc, reg);
 2628         if (error)
 2629                 DPRINTF(("Error reading extended register 0x%02x\n", reg));
 2630 /* REVISIT: what if an error is returned above? */
 2631         val = ess_rdsp(sc);
 2632         DPRINTFN(2,("ess_read_x_reg: %02x=%02x\n", reg, val));
 2633         return val;
 2634 }
 2635 
 2636 void
 2637 ess_clear_xreg_bits(sc, reg, mask)
 2638         struct ess_softc *sc;
 2639         u_char reg;
 2640         u_char mask;
 2641 {
 2642         if (ess_write_x_reg(sc, reg, ess_read_x_reg(sc, reg) & ~mask) == -1)
 2643                 DPRINTF(("Error clearing bits in extended register 0x%02x\n",
 2644                          reg));
 2645 }
 2646 
 2647 void
 2648 ess_set_xreg_bits(sc, reg, mask)
 2649         struct ess_softc *sc;
 2650         u_char reg;
 2651         u_char mask;
 2652 {
 2653         if (ess_write_x_reg(sc, reg, ess_read_x_reg(sc, reg) | mask) == -1)
 2654                 DPRINTF(("Error setting bits in extended register 0x%02x\n",
 2655                          reg));
 2656 }
 2657 
 2658 
 2659 /*
 2660  * Write a value to one of the ESS mixer registers.
 2661  */
 2662 void
 2663 ess_write_mix_reg(sc, reg, val)
 2664         struct ess_softc *sc;
 2665         u_char reg;
 2666         u_char val;
 2667 {
 2668         bus_space_tag_t iot = sc->sc_iot;
 2669         bus_space_handle_t ioh = sc->sc_ioh;
 2670         int s;
 2671 
 2672         DPRINTFN(2,("ess_write_mix_reg: %x=%x\n", reg, val));
 2673 
 2674         s = splaudio();
 2675         EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg);
 2676         EWRITE1(iot, ioh, ESS_MIX_REG_DATA, val);
 2677         splx(s);
 2678 }
 2679 
 2680 /*
 2681  * Read the value of one of the ESS mixer registers.
 2682  */
 2683 u_char
 2684 ess_read_mix_reg(sc, reg)
 2685         struct ess_softc *sc;
 2686         u_char reg;
 2687 {
 2688         bus_space_tag_t iot = sc->sc_iot;
 2689         bus_space_handle_t ioh = sc->sc_ioh;
 2690         int s;
 2691         u_char val;
 2692 
 2693         s = splaudio();
 2694         EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg);
 2695         val = EREAD1(iot, ioh, ESS_MIX_REG_DATA);
 2696         splx(s);
 2697 
 2698         DPRINTFN(2,("ess_read_mix_reg: %x=%x\n", reg, val));
 2699         return val;
 2700 }
 2701 
 2702 void
 2703 ess_clear_mreg_bits(sc, reg, mask)
 2704         struct ess_softc *sc;
 2705         u_char reg;
 2706         u_char mask;
 2707 {
 2708         ess_write_mix_reg(sc, reg, ess_read_mix_reg(sc, reg) & ~mask);
 2709 }
 2710 
 2711 void
 2712 ess_set_mreg_bits(sc, reg, mask)
 2713         struct ess_softc *sc;
 2714         u_char reg;
 2715         u_char mask;
 2716 {
 2717         ess_write_mix_reg(sc, reg, ess_read_mix_reg(sc, reg) | mask);
 2718 }
 2719 
 2720 void
 2721 ess_read_multi_mix_reg(sc, reg, datap, count)
 2722         struct ess_softc *sc;
 2723         u_char reg;
 2724         u_int8_t *datap;
 2725         bus_size_t count;
 2726 {
 2727         bus_space_tag_t iot = sc->sc_iot;
 2728         bus_space_handle_t ioh = sc->sc_ioh;
 2729         int s;
 2730 
 2731         s = splaudio();
 2732         EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg);
 2733         bus_space_read_multi_1(iot, ioh, ESS_MIX_REG_DATA, datap, count);
 2734         splx(s);
 2735 }

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