Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-1-5]: src/sys/dev/pci Pull up revisions 1.1-1.10 (new, via patch, ...



details:   https://anonhg.NetBSD.org/src/rev/5dc28fd253df
branches:  netbsd-1-5
changeset: 491605:5dc28fd253df
user:      he <he%NetBSD.org@localhost>
date:      Thu May 03 20:57:08 2001 +0000

description:
Pull up revisions 1.1-1.10 (new, via patch, requested by skrll):
  Add a driver for the ESS Technology Maestro-1/2/2E AC97 audio chips,
  ES1968 and ES1978.

diffstat:

 sys/dev/pci/esm.c |  1510 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 1510 insertions(+), 0 deletions(-)

diffs (truncated from 1514 to 300 lines):

diff -r b2a03b380025 -r 5dc28fd253df sys/dev/pci/esm.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/pci/esm.c Thu May 03 20:57:08 2001 +0000
@@ -0,0 +1,1510 @@
+/*      $NetBSD: esm.c,v 1.10.2.2 2001/05/03 20:57:08 he Exp $      */
+
+/*-
+ * Copyright (c) 2000, 2001 Rene Hexel <rh%netbsd.org@localhost>
+ * All rights reserved.
+ *
+ * Copyright (c) 2000 Taku YAMAMOTO <taku%cent.saitama-u.ac.jp@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Taku Id: maestro.c,v 1.12 2000/09/06 03:32:34 taku Exp
+ * FreeBSD: /c/ncvs/src/sys/dev/sound/pci/maestro.c,v 1.4 2000/12/18 01:36:35 cg Exp
+ */
+
+/*
+ * TODO:
+ *     - hardware volume support
+ *     - recording
+ *     - MIDI support
+ *     - joystick support
+ *
+ *
+ * Credits:
+ *
+ * This code is based on the FreeBSD driver written by Taku YAMAMOTO
+ *
+ *
+ * Original credits from the FreeBSD driver:
+ *
+ * Part of this code (especially in many magic numbers) was heavily inspired
+ * by the Linux driver originally written by
+ * Alan Cox <alan.cox%linux.org@localhost>, modified heavily by
+ * Zach Brown <zab%zabbo.net@localhost>.
+ *
+ * busdma()-ize and buffer size reduction were suggested by
+ * Cameron Grant <gandalf%vilnya.demon.co.uk@localhost>.
+ * Also he showed me the way to use busdma() suite.
+ *
+ * Internal speaker problems on NEC VersaPro's and Dell Inspiron 7500
+ * were looked at by
+ * Munehiro Matsuda <haro%tk.kubota.co.jp@localhost>,
+ * who brought patches based on the Linux driver with some simplification.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/device.h>
+
+#include <machine/bus.h>
+
+#include <sys/audioio.h>
+#include <dev/audio_if.h>
+#include <dev/mulaw.h>
+#include <dev/auconv.h>
+#include <dev/ic/ac97var.h>
+#include <dev/ic/ac97reg.h>
+
+#include <dev/pci/pcidevs.h>
+#include <dev/pci/pcivar.h>
+
+#include <dev/pci/esmreg.h>
+#include <dev/pci/esmvar.h>
+
+#define        PCI_CBIO                0x10    /* Configuration Base I/O Address */
+
+/* Debug */
+#ifdef AUDIO_DEBUG
+#define DPRINTF(l,x)   do { if (esm_debug & (l)) printf x; } while(0)
+#define DUMPREG(x)     do { if (esm_debug & ESM_DEBUG_REG)     \
+                                esm_dump_regs(x); } while(0)
+int esm_debug = 0xfffc;
+#define ESM_DEBUG_CODECIO      0x0001
+#define ESM_DEBUG_IRQ          0x0002
+#define ESM_DEBUG_DMA          0x0004
+#define ESM_DEBUG_TIMER                0x0008
+#define ESM_DEBUG_REG          0x0010
+#define ESM_DEBUG_PARAM                0x0020
+#define ESM_DEBUG_APU          0x0040
+#define ESM_DEBUG_CODEC                0x0080
+#define ESM_DEBUG_PCI          0x0100
+#define ESM_DEBUG_RESUME       0x0200
+#else
+#define DPRINTF(x,y)   /* nothing */
+#define DUMPREG(x)     /* nothing */
+#endif
+
+#ifdef DIAGNOSTIC
+#define RANGE(n, l, h) if ((n) < (l) || (n) >= (h))                    \
+               printf (#n "=%d out of range (%d, %d) in "              \
+               __FILE__ ", line %d\n", (n), (l), (h), __LINE__)
+#else
+#define RANGE(x,y,z)   /* nothing */
+#endif
+
+#define inline __inline
+
+static inline void      ringbus_setdest(struct esm_softc *, int, int);
+
+static inline u_int16_t        wp_rdreg(struct esm_softc *, u_int16_t);
+static inline void     wp_wrreg(struct esm_softc *, u_int16_t, u_int16_t);
+static inline u_int16_t        wp_rdapu(struct esm_softc *, int, u_int16_t);
+static inline void     wp_wrapu(struct esm_softc *, int, u_int16_t,
+                           u_int16_t);
+static inline void     wp_settimer(struct esm_softc *, u_int);
+static inline void     wp_starttimer(struct esm_softc *);
+static inline void     wp_stoptimer(struct esm_softc *);
+
+static inline u_int16_t        wc_rdreg(struct esm_softc *, u_int16_t);
+static inline void     wc_wrreg(struct esm_softc *, u_int16_t, u_int16_t);
+static inline u_int16_t        wc_rdchctl(struct esm_softc *, int);
+static inline void     wc_wrchctl(struct esm_softc *, int, u_int16_t);
+
+static inline u_int    calc_timer_freq(struct esm_chinfo*);
+static void            set_timer(struct esm_softc *);
+
+static void            esmch_set_format(struct esm_chinfo *,
+                           struct audio_params *p);
+
+/* Power Management */
+void esm_powerhook(int, void *);
+
+struct cfattach esm_ca = {
+       sizeof(struct esm_softc), esm_match, esm_attach
+};
+
+struct audio_hw_if esm_hw_if = {
+       esm_open,
+       esm_close,
+       NULL,                           /* drain */
+       esm_query_encoding,
+       esm_set_params,
+       esm_round_blocksize,
+       NULL,                           /* commit_settings */
+       esm_init_output,
+       NULL,                           /* init_input */
+       NULL,                           /* start_output */
+       NULL,                           /* start_input */
+       esm_halt_output,
+       esm_halt_input,
+       NULL,                           /* speaker_ctl */
+       esm_getdev,
+       NULL,                           /* getfd */
+       esm_set_port,
+       esm_get_port,
+       esm_query_devinfo,
+       esm_malloc,
+       esm_free,
+       esm_round_buffersize,
+       esm_mappage,
+       esm_get_props,
+       esm_trigger_output,
+       esm_trigger_input
+};
+
+struct audio_device esm_device = {
+       "ESS Maestro",
+       "",
+       "esm"
+};
+
+
+static audio_encoding_t esm_encoding[] = {
+       { 0, AudioEulinear, AUDIO_ENCODING_ULINEAR, 8, 0 }, 
+       { 1, AudioEmulaw, AUDIO_ENCODING_ULAW, 8,
+               AUDIO_ENCODINGFLAG_EMULATED }, 
+       { 2, AudioEalaw, AUDIO_ENCODING_ALAW, 8, AUDIO_ENCODINGFLAG_EMULATED }, 
+       { 3, AudioEslinear, AUDIO_ENCODING_SLINEAR, 8, 0 }, 
+       { 4, AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 16, 0 }, 
+       { 5, AudioEulinear_le, AUDIO_ENCODING_ULINEAR_LE, 16,
+               AUDIO_ENCODINGFLAG_EMULATED }, 
+       { 6, AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 16,
+               AUDIO_ENCODINGFLAG_EMULATED }, 
+       { 7, AudioEulinear_be, AUDIO_ENCODING_ULINEAR_BE, 16,
+               AUDIO_ENCODINGFLAG_EMULATED }, 
+};
+
+#define MAESTRO_NENCODINGS 8
+
+
+static const struct esm_quirks esm_quirks[] = {
+       /* COMPAL 38W2 OEM Notebook, e.g. Dell INSPIRON 5000e */
+       { PCI_VENDOR_COMPAL, PCI_PRODUCT_COMPAL_38W2, ESM_QUIRKF_SWAPPEDCH },
+
+       /* COMPAQ Armada M700 Notebook */
+       { PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_M700, ESM_QUIRKF_SWAPPEDCH },
+
+       /* NEC Versa Pro LX VA26D */
+       { PCI_VENDOR_NEC, PCI_PRODUCT_NEC_VA26D, ESM_QUIRKF_GPIO },
+
+       /* NEC Versa LX */
+       { PCI_VENDOR_NEC, PCI_PRODUCT_NEC_VERSALX, ESM_QUIRKF_GPIO },
+
+       /* Toshiba Portege */
+       { PCI_VENDOR_TOSHIBA2, PCI_PRODUCT_TOSHIBA2_PORTEGE, ESM_QUIRKF_SWAPPEDCH }
+};
+
+enum esm_quirk_flags
+esm_get_quirks(pcireg_t subid)
+{
+       int i;
+
+       for (i = 0; i < (sizeof esm_quirks / sizeof esm_quirks[0]); i++) {
+               if (PCI_VENDOR(subid) == esm_quirks[i].eq_vendor &&
+                   PCI_PRODUCT(subid) == esm_quirks[i].eq_product) {
+                       return esm_quirks[i].eq_quirks;
+               }
+       }
+
+       return 0;
+}
+
+
+#ifdef AUDIO_DEBUG
+struct esm_reg_info {
+       int     offset;                 /* register offset */
+       int     width;                  /* 1/2/4 bytes */
+} dump_regs[] = {
+       { PORT_WAVCACHE_CTRL,           2 },
+       { PORT_HOSTINT_CTRL,            2 },
+       { PORT_HOSTINT_STAT,            2 },
+       { PORT_HWVOL_VOICE_SHADOW,      1 },
+       { PORT_HWVOL_VOICE,             1 },
+       { PORT_HWVOL_MASTER_SHADOW,     1 },
+       { PORT_HWVOL_MASTER,            1 },
+       { PORT_RINGBUS_CTRL,            4 },
+       { PORT_GPIO_DATA,               2 },
+       { PORT_GPIO_MASK,               2 },
+       { PORT_GPIO_DIR,                2 },
+       { PORT_ASSP_CTRL_A,             1 },
+       { PORT_ASSP_CTRL_B,             1 },
+       { PORT_ASSP_CTRL_C,             1 },
+       { PORT_ASSP_INT_STAT,           1 }
+};
+
+static void
+esm_dump_regs(struct esm_softc *ess)
+{
+       int i;
+
+       printf("%s registers:", ess->sc_dev.dv_xname);
+       for (i = 0; i < (sizeof dump_regs / sizeof dump_regs[0]); i++) {
+               if (i % 5 == 0)
+                       printf("\n");
+               printf("0x%2.2x: ", dump_regs[i].offset);
+               switch(dump_regs[i].width) {
+               case 4:
+                       printf("%8.8x, ", bus_space_read_4(ess->st, ess->sh,
+                           dump_regs[i].offset));
+                       break;
+               case 2:
+                       printf("%4.4x,     ", bus_space_read_2(ess->st, ess->sh,
+                           dump_regs[i].offset));
+                       break;
+               default:
+                       printf("%2.2x,       ",
+                           bus_space_read_1(ess->st, ess->sh,
+                           dump_regs[i].offset));
+               }
+       }
+       printf("\n");
+}
+#endif
+
+
+/* -----------------------------
+ * Subsystems.
+ */
+
+/* Codec/Ringbus */
+
+/* -------------------------------------------------------------------- */
+
+int
+esm_read_codec(void *sc, u_int8_t regno, u_int16_t *result)



Home | Main Index | Thread Index | Old Index