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.7 (new, via patch, ...
details: https://anonhg.NetBSD.org/src/rev/fb8fe9b539bc
branches: netbsd-1-5
changeset: 492576:fb8fe9b539bc
user: he <he%NetBSD.org@localhost>
date: Sat Jan 19 21:55:09 2002 +0000
description:
Pull up revisions 1.1-1.7 (new, via patch, requested by he):
Add driver for Creative Labs SBLive! EMU10000 and (probably) PCI512.
Fixes PR#15260.
diffstat:
sys/dev/pci/emuxki.c | 2055 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 2055 insertions(+), 0 deletions(-)
diffs (truncated from 2059 to 300 lines):
diff -r 5482cf59c1e6 -r fb8fe9b539bc sys/dev/pci/emuxki.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/pci/emuxki.c Sat Jan 19 21:55:09 2002 +0000
@@ -0,0 +1,2055 @@
+/* $NetBSD: emuxki.c,v 1.7.4.2 2002/01/19 21:55:09 he Exp $ */
+
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Yannick Montulet.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+/*
+ * Driver for Creative Labs SBLive! series and probably PCI512.
+ *
+ * Known bugs:
+ * - inversed stereo at ac97 codec level
+ * (XXX jdolecek - don't see the problem? maybe because auvia(4) has
+ * it swapped too?)
+ * - bass disapear when you plug rear jack-in on Cambridge FPS2000 speakers
+ * (and presumably all speakers that support front and rear jack-in)
+ *
+ * TODO:
+ * - Digital Outputs
+ * - (midi/mpu),joystick support
+ * - Single source recording
+ * - Multiple voices play (problem with /dev/audio architecture)
+ * - Multiple sources recording (Pb with audio(4))
+ * - Independant modification of each channel's parameters (via mixer ?)
+ * - DSP FX patches (to make fx like chipmunk)
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: emuxki.c,v 1.7.4.2 2002/01/19 21:55:09 he Exp $");
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/errno.h>
+#include <sys/malloc.h>
+#include <sys/systm.h>
+#include <sys/audioio.h>
+#include <sys/select.h>
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcidevs.h>
+#include <dev/audio_if.h>
+#include <dev/audiovar.h>
+#include <dev/auconv.h>
+#include <dev/mulaw.h>
+#include <dev/ic/ac97reg.h>
+#include <dev/ic/ac97var.h>
+
+#include <dev/pci/emuxkireg.h>
+#include <dev/pci/emuxkivar.h>
+
+/* autconf goo */
+static int emuxki_match(struct device *, struct cfdata *, void *);
+static void emuxki_attach(struct device *, struct device *, void *);
+static int emuxki_detach(struct device *, int);
+
+/* dma mem mgmt */
+static struct dmamem *dmamem_alloc(bus_dma_tag_t, size_t, bus_size_t,
+ int, int, int);
+static void dmamem_free(struct dmamem *, int);
+
+/* Emu10k1 init & shutdown */
+static int emuxki_init(struct emuxki_softc *);
+static void emuxki_shutdown(struct emuxki_softc *);
+
+/* Emu10k1 mem mgmt */
+static void *emuxki_pmem_alloc(struct emuxki_softc *, size_t,int,int);
+static void *emuxki_rmem_alloc(struct emuxki_softc *, size_t,int,int);
+
+/*
+ * Emu10k1 channels funcs : There is no direct access to channels, everything
+ * is done through voices I will at least provide channel based fx params
+ * modification, later...
+ */
+
+/* Emu10k1 voice mgmt */
+static struct emuxki_voice *emuxki_voice_new(struct emuxki_softc *,
+ u_int8_t);
+static void emuxki_voice_delete(struct emuxki_voice *);
+static int emuxki_voice_set_audioparms(struct emuxki_voice *, u_int8_t,
+ u_int8_t, u_int32_t);
+/* emuxki_voice_set_fxparms will come later, it'll need channel distinction */
+static int emuxki_voice_set_bufparms(struct emuxki_voice *,
+ void *, u_int32_t, u_int16_t);
+static void emuxki_voice_commit_parms(struct emuxki_voice *);
+static u_int32_t emuxki_voice_curaddr(struct emuxki_voice *);
+static void emuxki_voice_start(struct emuxki_voice *,
+ void (*) (void *), void *);
+static void emuxki_voice_halt(struct emuxki_voice *);
+
+/*
+ * Emu10k1 stream mgmt : not done yet
+ */
+#if 0
+static struct emuxki_stream *emuxki_stream_new(struct emu10k1 *);
+static void emuxki_stream_delete(struct emuxki_stream *);
+static int emuxki_stream_set_audio_params(struct emuxki_stream *, u_int8_t,
+ u_int8_t, u_int8_t, u_int16_t);
+static void emuxki_stream_start(struct emuxki_stream *);
+static void emuxki_stream_halt(struct emuxki_stream *);
+#endif
+
+/* audio interface callbacks */
+
+static int emuxki_open(void *, int);
+static void emuxki_close(void *);
+
+static int emuxki_query_encoding(void *, struct audio_encoding *);
+static int emuxki_set_params(void *, int, int,
+ struct audio_params *,
+ struct audio_params *);
+
+static size_t emuxki_round_buffersize(void *, int, size_t);
+
+static int emuxki_trigger_output(void *, void *, void *, int,
+ void (*)(void *), void *,
+ struct audio_params *);
+static int emuxki_trigger_input(void *, void *, void *, int,
+ void (*) (void *), void *,
+ struct audio_params *);
+static int emuxki_halt_output(void *);
+static int emuxki_halt_input(void *);
+
+static int emuxki_getdev(void *, struct audio_device *);
+static int emuxki_set_port(void *, mixer_ctrl_t *);
+static int emuxki_get_port(void *, mixer_ctrl_t *);
+static int emuxki_query_devinfo(void *, mixer_devinfo_t *);
+
+static void *emuxki_allocm(void *, int, size_t, int, int);
+static void emuxki_freem(void *, void *, int);
+
+static paddr_t emuxki_mappage(void *, void *, off_t, int);
+static int emuxki_get_props(void *);
+
+/* Interrupt handler */
+static int emuxki_intr(void *);
+
+/* Emu10k1 AC97 interface callbacks */
+static int emuxki_ac97_attach(void *, struct ac97_codec_if *);
+static int emuxki_ac97_read(void *, u_int8_t, u_int16_t *);
+static int emuxki_ac97_write(void *, u_int8_t, u_int16_t);
+static void emuxki_ac97_reset(void *);
+static enum ac97_host_flags emuxki_ac97_flags(void *);
+
+/*
+ * Autoconfig goo.
+ */
+struct cfattach emuxki_ca = {
+ sizeof(struct emuxki_softc),
+ emuxki_match,
+ emuxki_attach,
+ emuxki_detach,
+ NULL /* config activate */
+};
+
+static struct audio_hw_if emuxki_hw_if = {
+ emuxki_open,
+ emuxki_close,
+ NULL, /* drain */
+ emuxki_query_encoding,
+ emuxki_set_params,
+ NULL, /* round blocksize */
+ NULL, /* commit settings */
+ NULL, /* init_output */
+ NULL, /* init_input */
+ NULL, /* start_output */
+ NULL, /* start_input */
+ emuxki_halt_output,
+ emuxki_halt_input,
+ NULL, /* speaker_ctl */
+ emuxki_getdev,
+ NULL, /* setfd */
+ emuxki_set_port,
+ emuxki_get_port,
+ emuxki_query_devinfo,
+ emuxki_allocm,
+ emuxki_freem,
+ emuxki_round_buffersize,
+ emuxki_mappage,
+ emuxki_get_props,
+ emuxki_trigger_output,
+ emuxki_trigger_input,
+};
+
+/*
+ * Dma memory mgmt
+ */
+
+static void
+dmamem_delete(struct dmamem *mem, int type)
+{
+ free(mem->segs, type);
+ free(mem, type);
+}
+
+static struct dmamem *
+dmamem_alloc(bus_dma_tag_t dmat, size_t size, bus_size_t align,
+ int nsegs, int type, int flags)
+{
+ struct dmamem *mem;
+ int bus_dma_flags;
+
+ /* Allocate memory for structure */
+ if ((mem = malloc(sizeof(*mem), type, flags)) == NULL)
+ return (NULL);
+ mem->dmat = dmat;
+ mem->size = size;
+ mem->align = align;
+ mem->nsegs = nsegs;
+ mem->bound = 0;
+
+ mem->segs = malloc(mem->nsegs * sizeof(*(mem->segs)), type, flags);
+ if (mem->segs == NULL) {
+ free(mem, type);
+ return (NULL);
+ }
+
+ bus_dma_flags = (flags & M_NOWAIT) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK;
+ if (bus_dmamem_alloc(dmat, mem->size, mem->align, mem->bound,
+ mem->segs, mem->nsegs, &(mem->rsegs),
+ bus_dma_flags)) {
+ dmamem_delete(mem, type);
+ return (NULL);
+ }
+
+ if (bus_dmamem_map(dmat, mem->segs, mem->nsegs, mem->size,
+ &(mem->kaddr), bus_dma_flags | BUS_DMA_COHERENT)) {
+ bus_dmamem_free(dmat, mem->segs, mem->nsegs);
+ dmamem_delete(mem, type);
+ return (NULL);
+ }
+
+ if (bus_dmamap_create(dmat, mem->size, mem->nsegs, mem->size,
+ mem->bound, bus_dma_flags, &(mem->map))) {
+ bus_dmamem_unmap(dmat, mem->kaddr, mem->size);
+ bus_dmamem_free(dmat, mem->segs, mem->nsegs);
+ dmamem_delete(mem, type);
+ return (NULL);
+ }
+
+ if (bus_dmamap_load(dmat, mem->map, mem->kaddr,
+ mem->size, NULL, bus_dma_flags)) {
+ bus_dmamap_destroy(dmat, mem->map);
+ bus_dmamem_unmap(dmat, mem->kaddr, mem->size);
+ bus_dmamem_free(dmat, mem->segs, mem->nsegs);
+ dmamem_delete(mem, type);
+ return (NULL);
+ }
+
+ return (mem);
+}
+
+static void
+dmamem_free(struct dmamem *mem, int type)
+{
+ bus_dmamap_unload(mem->dmat, mem->map);
+ bus_dmamap_destroy(mem->dmat, mem->map);
+ bus_dmamem_unmap(mem->dmat, mem->kaddr, mem->size);
+ bus_dmamem_free(mem->dmat, mem->segs, mem->nsegs);
+ dmamem_delete(mem, type);
+}
+
+
+/*
+ * Autoconf device callbacks : attach and detach
+ */
Home |
Main Index |
Thread Index |
Old Index