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.3 (new, via patch, ...
details: https://anonhg.NetBSD.org/src/rev/ebb308a404ac
branches: netbsd-1-5
changeset: 491500:ebb308a404ac
user: he <he%NetBSD.org@localhost>
date: Tue May 01 11:45:46 2001 +0000
description:
Pull up revisions 1.1-1.3 (new, via patch, requested by minoura):
Add Yamaha YMF724/740/744/745-based sound driver and
its subordinates.
diffstat:
sys/dev/pci/yds.c | 1805 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 1805 insertions(+), 0 deletions(-)
diffs (truncated from 1809 to 300 lines):
diff -r f64e6399a7e3 -r ebb308a404ac sys/dev/pci/yds.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/pci/yds.c Tue May 01 11:45:46 2001 +0000
@@ -0,0 +1,1805 @@
+/* $NetBSD: yds.c,v 1.3.6.2 2001/05/01 11:45:46 he Exp $ */
+
+/*
+ * Copyright (c) 2000, 2001 Kazuki Sakamoto and Minoura Makoto.
+ * 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 ``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.
+ */
+
+/*
+ * Yamaha YMF724[B-F]/740[B-C]/744/754
+ *
+ * Documentation links:
+ * - ftp://ftp.alsa-project.org/pub/manuals/yamaha/
+ * - ftp://ftp.alsa-project.org/pub/manuals/yamaha/pci/
+ *
+ * TODO:
+ * - FM synth volume (difficult: mixed before ac97)
+ * - Digital in/out (SPDIF) support
+ * - Effect??
+ */
+
+#include "mpu.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/fcntl.h>
+#include <sys/malloc.h>
+#include <sys/device.h>
+#include <sys/proc.h>
+
+#include <dev/pci/pcidevs.h>
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+
+#include <sys/audioio.h>
+#include <dev/audio_if.h>
+#include <dev/mulaw.h>
+#include <dev/auconv.h>
+#include <dev/ic/ac97reg.h>
+#include <dev/ic/ac97var.h>
+#include <dev/ic/mpuvar.h>
+
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <dev/microcode/yds/yds_hwmcode.h>
+#include <dev/pci/ydsreg.h>
+#include <dev/pci/ydsvar.h>
+
+/* Debug */
+#undef YDS_USE_REC_SLOT
+#define YDS_USE_P44
+
+#ifdef AUDIO_DEBUG
+# define DPRINTF(x) if (ydsdebug) printf x
+# define DPRINTFN(n,x) if (ydsdebug>(n)) printf x
+int ydsdebug = 0;
+#else
+# define DPRINTF(x)
+# define DPRINTFN(n,x)
+#endif
+#ifdef YDS_USE_REC_SLOT
+# define YDS_INPUT_SLOT 0 /* REC slot = ADC + loopbacks */
+#else
+# define YDS_INPUT_SLOT 1 /* ADC slot */
+#endif
+
+int yds_match __P((struct device *, struct cfdata *, void *));
+void yds_attach __P((struct device *, struct device *, void *));
+int yds_intr __P((void *));
+
+#define DMAADDR(p) ((p)->map->dm_segs[0].ds_addr)
+#define KERNADDR(p) ((void *)((p)->addr))
+
+int yds_allocmem __P((struct yds_softc *, size_t, size_t,
+ struct yds_dma *));
+int yds_freemem __P((struct yds_softc *, struct yds_dma *));
+
+#ifndef AUDIO_DEBUG
+#define YWRITE1(sc, r, x) bus_space_write_1((sc)->memt, (sc)->memh, (r), (x))
+#define YWRITE2(sc, r, x) bus_space_write_2((sc)->memt, (sc)->memh, (r), (x))
+#define YWRITE4(sc, r, x) bus_space_write_4((sc)->memt, (sc)->memh, (r), (x))
+#define YREAD1(sc, r) bus_space_read_1((sc)->memt, (sc)->memh, (r))
+#define YREAD2(sc, r) bus_space_read_2((sc)->memt, (sc)->memh, (r))
+#define YREAD4(sc, r) bus_space_read_4((sc)->memt, (sc)->memh, (r))
+#else
+
+u_int16_t YREAD2(struct yds_softc *sc,bus_size_t r);
+u_int32_t YREAD4(struct yds_softc *sc,bus_size_t r);
+void YWRITE1(struct yds_softc *sc,bus_size_t r,u_int8_t x);
+void YWRITE2(struct yds_softc *sc,bus_size_t r,u_int16_t x);
+void YWRITE4(struct yds_softc *sc,bus_size_t r,u_int32_t x);
+
+u_int16_t YREAD2(struct yds_softc *sc,bus_size_t r)
+{
+ DPRINTFN(5, (" YREAD2(0x%lX)\n",(unsigned long)r));
+ return bus_space_read_2(sc->memt,sc->memh,r);
+}
+u_int32_t YREAD4(struct yds_softc *sc,bus_size_t r)
+{
+ DPRINTFN(5, (" YREAD4(0x%lX)\n",(unsigned long)r));
+ return bus_space_read_4(sc->memt,sc->memh,r);
+}
+void YWRITE1(struct yds_softc *sc,bus_size_t r,u_int8_t x)
+{
+ DPRINTFN(5, (" YWRITE1(0x%lX,0x%lX)\n",(unsigned long)r,(unsigned long)x));
+ bus_space_write_1(sc->memt,sc->memh,r,x);
+}
+void YWRITE2(struct yds_softc *sc,bus_size_t r,u_int16_t x)
+{
+ DPRINTFN(5, (" YWRITE2(0x%lX,0x%lX)\n",(unsigned long)r,(unsigned long)x));
+ bus_space_write_2(sc->memt,sc->memh,r,x);
+}
+void YWRITE4(struct yds_softc *sc,bus_size_t r,u_int32_t x)
+{
+ DPRINTFN(5, (" YWRITE4(0x%lX,0x%lX)\n",(unsigned long)r,(unsigned long)x));
+ bus_space_write_4(sc->memt,sc->memh,r,x);
+}
+#endif
+
+#define YWRITEREGION4(sc, r, x, c) \
+ bus_space_write_region_4((sc)->memt, (sc)->memh, (r), (x), (c) / 4)
+
+struct cfattach yds_ca = {
+ sizeof(struct yds_softc), yds_match, yds_attach
+};
+
+int yds_open __P((void *, int));
+void yds_close __P((void *));
+int yds_query_encoding __P((void *, struct audio_encoding *));
+int yds_set_params __P((void *, int, int,
+ struct audio_params *, struct audio_params *));
+int yds_round_blocksize __P((void *, int));
+int yds_trigger_output __P((void *, void *, void *, int, void (*)(void *),
+ void *, struct audio_params *));
+int yds_trigger_input __P((void *, void *, void *, int, void (*)(void *),
+ void *, struct audio_params *));
+int yds_halt_output __P((void *));
+int yds_halt_input __P((void *));
+int yds_getdev __P((void *, struct audio_device *));
+int yds_mixer_set_port __P((void *, mixer_ctrl_t *));
+int yds_mixer_get_port __P((void *, mixer_ctrl_t *));
+void *yds_malloc __P((void *, int, size_t, int, int));
+void yds_free __P((void *, void *, int));
+size_t yds_round_buffersize __P((void *, int, size_t));
+paddr_t yds_mappage __P((void *, void *, off_t, int));
+int yds_get_props __P((void *));
+int yds_query_devinfo __P((void *addr, mixer_devinfo_t *dip));
+
+int yds_attach_codec __P((void *sc, struct ac97_codec_if *));
+int yds_read_codec __P((void *sc, u_int8_t a, u_int16_t *d));
+int yds_write_codec __P((void *sc, u_int8_t a, u_int16_t d));
+void yds_reset_codec __P((void *sc));
+int yds_get_portnum_by_name __P((struct yds_softc *, char *, char *,
+ char *));
+
+static u_int yds_get_dstype __P((int));
+static int yds_download_mcode __P((struct yds_softc *));
+static int yds_allocate_slots __P((struct yds_softc *));
+static void yds_configure_legacy __P((struct device *arg));
+static void yds_enable_dsp __P((struct yds_softc *));
+static int yds_disable_dsp __P((struct yds_softc *));
+static int yds_ready_codec __P((struct yds_codec_softc *));
+static int yds_halt __P((struct yds_softc *));
+static u_int32_t yds_get_lpfq __P((u_int));
+static u_int32_t yds_get_lpfk __P((u_int));
+static struct yds_dma *yds_find_dma __P((struct yds_softc *, void *));
+
+#ifdef AUDIO_DEBUG
+static void yds_dump_play_slot __P((struct yds_softc *, int));
+#define YDS_DUMP_PLAY_SLOT(n,sc,bank) \
+ if (ydsdebug > (n)) yds_dump_play_slot(sc, bank)
+#else
+#define YDS_DUMP_PLAY_SLOT(n,sc,bank)
+#endif /* AUDIO_DEBUG */
+
+static struct audio_hw_if yds_hw_if = {
+ yds_open,
+ yds_close,
+ NULL,
+ yds_query_encoding,
+ yds_set_params,
+ yds_round_blocksize,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ yds_halt_output,
+ yds_halt_input,
+ NULL,
+ yds_getdev,
+ NULL,
+ yds_mixer_set_port,
+ yds_mixer_get_port,
+ yds_query_devinfo,
+ yds_malloc,
+ yds_free,
+ yds_round_buffersize,
+ yds_mappage,
+ yds_get_props,
+ yds_trigger_output,
+ yds_trigger_input,
+};
+
+struct audio_device yds_device = {
+ "Yamaha DS-1",
+ "",
+ "yds"
+};
+
+const static struct {
+ u_int id;
+ u_int flags;
+#define YDS_CAP_MCODE_1 0x0001
+#define YDS_CAP_MCODE_1E 0x0002
+#define YDS_CAP_LEGACY_SELECTABLE 0x0004
+#define YDS_CAP_LEGACY_FLEXIBLE 0x0008
+#define YDS_CAP_HAS_P44 0x0010
+} yds_chip_capabliity_list[] = {
+ { PCI_PRODUCT_YAMAHA_YMF724,
+ YDS_CAP_MCODE_1|YDS_CAP_LEGACY_SELECTABLE },
+ /* 740[C] has only 32 slots. But anyway we use only 2 */
+ { PCI_PRODUCT_YAMAHA_YMF740,
+ YDS_CAP_MCODE_1|YDS_CAP_LEGACY_SELECTABLE }, /* XXX NOT TESTED */
+ { PCI_PRODUCT_YAMAHA_YMF740C,
+ YDS_CAP_MCODE_1E|YDS_CAP_LEGACY_SELECTABLE },
+ { PCI_PRODUCT_YAMAHA_YMF724F,
+ YDS_CAP_MCODE_1E|YDS_CAP_LEGACY_SELECTABLE },
+ { PCI_PRODUCT_YAMAHA_YMF744B,
+ YDS_CAP_MCODE_1E|YDS_CAP_LEGACY_FLEXIBLE },
+ { PCI_PRODUCT_YAMAHA_YMF754,
+ YDS_CAP_MCODE_1E|YDS_CAP_LEGACY_FLEXIBLE|YDS_CAP_HAS_P44 },
+ { 0, 0 }
+};
+#ifdef AUDIO_DEBUG
+#define YDS_CAP_BITS "\020\005P44\004LEGFLEX\003LEGSEL\002MCODE1E\001MCODE1"
+#endif
+
+#ifdef AUDIO_DEBUG
+static void
+yds_dump_play_slot(sc, bank)
+ struct yds_softc *sc;
+ int bank;
+{
+ int i, j;
+ u_int32_t *p;
+ u_int32_t num;
+ char *pa;
+
+ for (i = 0; i < N_PLAY_SLOTS; i++) {
+ printf("pbankp[%d] = %p,", i*2, sc->pbankp[i*2]);
+ printf("pbankp[%d] = %p\n", i*2+1, sc->pbankp[i*2+1]);
+ }
+
+ pa = (char *)DMAADDR(&sc->sc_ctrldata) + sc->pbankoff;
+ p = (u_int32_t *)sc->ptbl;
+ printf("ptbl + 0: %d\n", *p++);
+ for (i = 0; i < N_PLAY_SLOTS; i++) {
+ printf("ptbl + %d: 0x%x, should be %p\n",
+ i+1, *p,
+ pa + i * sizeof(struct play_slot_ctrl_bank) *
+ N_PLAY_SLOT_CTRL_BANK);
+ p++;
+ }
+
+ num = *(u_int32_t*)sc->ptbl;
+ printf("numofplay = %d\n", num);
+
+ for (i = 0; i < num; i++) {
+ p = (u_int32_t *)sc->pbankp[i*2];
+
+ printf(" pbankp[%d], bank 0 : %p\n", i*2, p);
+ for (j = 0;
+ j < sizeof(struct play_slot_ctrl_bank) / sizeof(u_int32_t);
+ j++) {
Home |
Main Index |
Thread Index |
Old Index