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.8 (new, via patch, ...



details:   https://anonhg.NetBSD.org/src/rev/abb07a63f1cb
branches:  netbsd-1-5
changeset: 492607:abb07a63f1cb
user:      he <he%NetBSD.org@localhost>
date:      Thu Jan 24 22:35:57 2002 +0000

description:
Pull up revisions 1.1-1.8 (new, via patch, requested by he):
  Add driver for the ESS Allegro-1 / Maestro-3 audio hardware.

diffstat:

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

diffs (truncated from 1541 to 300 lines):

diff -r c23ae3af744b -r abb07a63f1cb sys/dev/pci/esa.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/pci/esa.c Thu Jan 24 22:35:57 2002 +0000
@@ -0,0 +1,1537 @@
+/* $NetBSD: esa.c,v 1.8.2.2 2002/01/24 22:35:57 he Exp $ */
+
+/*
+ * Copyright (c) 2001, 2002 Jared D. McNeill <jmcneill%invisible.yi.org@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. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ */
+
+/*
+ * ESS Allegro-1 / Maestro3 Audio Driver
+ * 
+ * Based on the FreeBSD maestro3 driver and the NetBSD eap driver.
+ * Original driver by Don Kim.
+ */
+
+#include <sys/types.h>
+#include <sys/errno.h>
+#include <sys/null.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/device.h>
+#include <sys/conf.h>
+#include <sys/exec.h>
+#include <sys/select.h>
+#include <sys/audioio.h>
+
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <dev/pci/pcidevs.h>
+#include <dev/pci/pcivar.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/esareg.h>
+#include <dev/pci/esadsp.h>
+#include <dev/pci/esavar.h>
+
+#define PCI_CBIO       0x10
+
+#define ESA_DAC_DATA   0x1100
+
+enum {
+       ESS_ALLEGRO1,
+       ESS_MAESTRO3
+};
+
+static struct esa_card_type {
+       u_int16_t pci_vendor_id;
+       u_int16_t pci_product_id;
+       int type;
+       int delay1, delay2;
+} esa_card_types[] = {
+       { PCI_VENDOR_ESSTECH, PCI_PRODUCT_ESSTECH_ALLEGRO1,
+         ESS_ALLEGRO1, 50, 800 },
+       { PCI_VENDOR_ESSTECH, PCI_PRODUCT_ESSTECH_MAESTRO3,
+         ESS_MAESTRO3, 20, 500 },
+       { PCI_VENDOR_ESSTECH, PCI_PRODUCT_ESSTECH_MAESTRO3_2,
+         ESS_MAESTRO3, 20, 500 },
+       { 0, 0, 0, 0, 0 }
+};
+
+struct audio_device esa_device = {
+       "ESS Allegro",
+       "",
+       "esa"
+};
+
+int            esa_match(struct device *, struct cfdata *, void *);
+void           esa_attach(struct device *, struct device *, void *);
+int            esa_detach(struct device *, int);
+
+/* audio(9) functions */
+int            esa_open(void *, int);
+void           esa_close(void *);
+int            esa_query_encoding(void *, struct audio_encoding *);
+int            esa_set_params(void *, int, int, struct audio_params *,
+                              struct audio_params *);
+int            esa_round_blocksize(void *, int);
+int            esa_init_output(void *, void *, int);
+int            esa_halt_output(void *);
+int            esa_halt_input(void *);
+int            esa_set_port(void *, mixer_ctrl_t *);
+int            esa_get_port(void *, mixer_ctrl_t *);
+int            esa_query_devinfo(void *, mixer_devinfo_t *);
+void *         esa_malloc(void *, int, size_t, int, int);
+void           esa_free(void *, void *, int);
+int            esa_getdev(void *, struct audio_device *);
+size_t         esa_round_buffersize(void *, int, size_t);
+int            esa_get_props(void *);
+int            esa_trigger_output(void *, void *, void *, int,
+                                  void (*)(void *), void *,
+                                  struct audio_params *);
+int            esa_trigger_input(void *, void *, void *, int,
+                                 void (*)(void *), void *,
+                                 struct audio_params *);
+
+int            esa_intr(void *);
+int            esa_allocmem(struct esa_softc *, size_t, size_t,
+                            struct esa_dma *);
+int            esa_freemem(struct esa_softc *, struct esa_dma *);
+paddr_t                esa_mappage(void *addr, void *mem, off_t off, int prot);
+
+/* Supporting subroutines */
+u_int16_t      esa_read_assp(struct esa_softc *, u_int16_t, u_int16_t);
+void           esa_write_assp(struct esa_softc *, u_int16_t, u_int16_t,
+                              u_int16_t);
+int            esa_init_codec(struct esa_softc *);
+int            esa_attach_codec(void *, struct ac97_codec_if *);
+int            esa_read_codec(void *, u_int8_t, u_int16_t *);
+int            esa_write_codec(void *, u_int8_t, u_int16_t);
+void           esa_reset_codec(void *);
+enum ac97_host_flags   esa_flags_codec(void *);
+int            esa_wait(struct esa_softc *);
+int            esa_init(struct esa_softc *);
+void           esa_config(struct esa_softc *);
+u_int8_t       esa_assp_halt(struct esa_softc *);
+void           esa_codec_reset(struct esa_softc *);
+int            esa_amp_enable(struct esa_softc *);
+void           esa_enable_interrupts(struct esa_softc *);
+u_int32_t      esa_get_pointer(struct esa_softc *, struct esa_channel *);
+
+/* power management */
+int            esa_power(struct esa_softc *, int);
+void           esa_powerhook(int, void *);
+int            esa_suspend(struct esa_softc *);
+int            esa_resume(struct esa_softc *);
+
+struct device *        audio_attach_mi_lkm(struct audio_hw_if *, void *,
+                                   struct device *);
+
+static audio_encoding_t esa_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,
+               AUDIO_ENCODINGFLAG_EMULATED }, /* XXX: Are you sure? */
+       { 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 ESA_NENCODINGS 8
+
+struct audio_hw_if esa_hw_if = {
+       esa_open,
+       esa_close,
+       NULL,                   /* drain */
+       esa_query_encoding,
+       esa_set_params,
+       esa_round_blocksize,
+       NULL,                   /* commit_settings */
+       esa_init_output,
+       NULL,                   /* esa_init_input */
+       NULL,                   /* start_output */
+       NULL,                   /* start_input */
+       esa_halt_output,
+       esa_halt_input,
+       NULL,                   /* speaker_ctl */
+       esa_getdev,
+       NULL,                   /* getfd */
+       esa_set_port,
+       esa_get_port,
+       esa_query_devinfo,
+       esa_malloc,
+       esa_free,
+       esa_round_buffersize,
+       esa_mappage,
+       esa_get_props,
+       esa_trigger_output,
+       esa_trigger_input
+};
+
+struct cfattach esa_ca = {
+       sizeof(struct esa_softc), esa_match, esa_attach,
+       esa_detach, /*esa_activate*/ NULL
+};
+
+/*
+ * audio(9) functions
+ */
+
+int
+esa_open(void *hdl, int flags)
+{
+
+       return (0);
+}
+
+void
+esa_close(void *hdl)
+{
+
+       return;
+}
+
+int
+esa_query_encoding(void *hdl, struct audio_encoding *ae)
+{
+
+       if (ae->index < 0 || ae->index >= ESA_NENCODINGS)
+               return (EINVAL);
+       *ae = esa_encoding[ae->index];
+
+       return (0);
+}
+
+int
+esa_set_params(void *hdl, int setmode, int usemode, struct audio_params *play,
+              struct audio_params *rec)
+{
+       struct esa_softc *sc = hdl;
+       struct esa_channel *ch;
+       struct audio_params *p;
+       u_int32_t data;
+       u_int32_t freq;
+       int mode;
+
+       for (mode = AUMODE_RECORD; mode != -1;
+            mode = (mode == AUMODE_RECORD) ? AUMODE_PLAY : -1) {
+               if ((setmode & mode) == 0)
+                       continue;
+
+               switch (mode) {
+               case AUMODE_PLAY:
+                       p = play;
+                       ch = &sc->play;
+                       break;
+               case AUMODE_RECORD:
+                       p = rec;
+                       ch = &sc->rec;
+                       break;
+               }
+
+               if (p->sample_rate < ESA_MINRATE ||
+                   p->sample_rate > ESA_MAXRATE ||
+                   (p->precision != 8 && p->precision != 16) ||
+                   (p->channels < 1 && p->channels > 2))
+                       return (EINVAL);
+
+               p->factor = 1;
+               p->sw_code = 0;
+
+               switch(p->encoding) {
+               case AUDIO_ENCODING_SLINEAR_BE:
+                       if (p->precision == 16)
+                               p->sw_code = swap_bytes;
+                       else
+                               p->sw_code = change_sign8;
+                       break;
+               case AUDIO_ENCODING_SLINEAR_LE:
+                       if (p->precision != 16)
+                               p->sw_code = change_sign8;
+                       break;
+               case AUDIO_ENCODING_ULINEAR_BE:
+                       if (p->precision == 16) {
+                               if (mode == AUMODE_PLAY)
+                                       p->sw_code =
+                                           swap_bytes_change_sign16_le;
+                               else
+                                       p->sw_code =
+                                           change_sign16_swap_bytes_le;
+                       }
+                       break;
+               case AUDIO_ENCODING_ULINEAR_LE:
+                       if (p->precision == 16)
+                               p->sw_code = change_sign16_le;



Home | Main Index | Thread Index | Old Index