Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/dreamcast Added AICA sound driver contributed by Ry...
details: https://anonhg.NetBSD.org/src/rev/47b8d67f6a91
branches: trunk
changeset: 550885:47b8d67f6a91
user: marcus <marcus%NetBSD.org@localhost>
date: Sun Aug 24 17:33:27 2003 +0000
description:
Added AICA sound driver contributed by Ryo Shimizu.
diffstat:
sys/arch/dreamcast/conf/GENERIC | 5 +-
sys/arch/dreamcast/conf/files.dreamcast | 6 +-
sys/arch/dreamcast/dev/g2/aica.c | 806 ++++++++++++++++++++
sys/arch/dreamcast/dev/g2/aicavar.h | 94 ++
sys/arch/dreamcast/dev/g2/g2bus_bus_mem.c | 96 ++-
sys/arch/dreamcast/dev/microcode/Makefile | 34 +
sys/arch/dreamcast/dev/microcode/aica_arm.c | 380 +++++++++
sys/arch/dreamcast/dev/microcode/aica_arm_locore.S | 72 +
sys/arch/dreamcast/dev/microcode/aica_armcode.h | 816 +++++++++++++++++++++
sys/arch/dreamcast/dev/microcode/ldscript | 23 +
10 files changed, 2328 insertions(+), 4 deletions(-)
diffs (truncated from 2433 to 300 lines):
diff -r fbbe13bc3994 -r 47b8d67f6a91 sys/arch/dreamcast/conf/GENERIC
--- a/sys/arch/dreamcast/conf/GENERIC Sun Aug 24 17:31:59 2003 +0000
+++ b/sys/arch/dreamcast/conf/GENERIC Sun Aug 24 17:33:27 2003 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: GENERIC,v 1.36 2003/06/14 16:28:32 tsutsui Exp $
+# $NetBSD: GENERIC,v 1.37 2003/08/24 17:33:27 marcus Exp $
#
# GENERIC machine description file
#
@@ -167,6 +167,9 @@
mbe* at g2bus? # SEGA LAN Adapter
+aica* at g2bus? # AICA Sound Processing Unit
+audio* at aica?
+
#pseudo-device cgd 2 # cryptographic disk devices
pseudo-device md 1 # memory disk device (ramdisk)
pseudo-device vnd 2 # disk-like interface to files
diff -r fbbe13bc3994 -r 47b8d67f6a91 sys/arch/dreamcast/conf/files.dreamcast
--- a/sys/arch/dreamcast/conf/files.dreamcast Sun Aug 24 17:31:59 2003 +0000
+++ b/sys/arch/dreamcast/conf/files.dreamcast Sun Aug 24 17:33:27 2003 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.dreamcast,v 1.24 2003/06/14 16:15:16 tsutsui Exp $
+# $NetBSD: files.dreamcast,v 1.25 2003/08/24 17:33:27 marcus Exp $
# maxpartitions must be first item in files.${MACHINE}
maxpartitions 16
@@ -99,4 +99,8 @@
attach mbe at g2bus with mbe_g2bus
file arch/dreamcast/dev/g2/if_mbe_g2.c mbe_g2bus
+device aica: audiobus, auconv, mulaw
+attach aica at g2bus
+file arch/dreamcast/dev/g2/aica.c aica needs-flag
+
include "arch/dreamcast/conf/majors.dreamcast"
diff -r fbbe13bc3994 -r 47b8d67f6a91 sys/arch/dreamcast/dev/g2/aica.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/dreamcast/dev/g2/aica.c Sun Aug 24 17:33:27 2003 +0000
@@ -0,0 +1,806 @@
+/* $NetBSD: aica.c,v 1.1 2003/08/24 17:33:29 marcus Exp $ */
+
+/*
+ * Copyright (c) 2003 SHIMIZU Ryo <ryo%misakimix.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. 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. 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.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: aica.c,v 1.1 2003/08/24 17:33:29 marcus Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/audioio.h>
+
+#include <dev/audio_if.h>
+#include <dev/mulaw.h>
+#include <dev/auconv.h>
+
+#include <machine/bus.h>
+#include <machine/sysasicvar.h>
+
+#include <dreamcast/dev/g2/g2busvar.h>
+#include <dreamcast/dev/g2/aicavar.h>
+#include <dreamcast/dev/microcode/aica_armcode.h>
+
+#define AICA_REG_ADDR 0x00700000
+#define AICA_RAM_START 0x00800000
+#define AICA_RAM_SIZE 0x00200000
+#define AICA_NCHAN 64
+#define AICA_TIMEOUT 0x1800
+
+struct aica_softc {
+ struct device sc_dev; /* base device */
+ bus_space_tag_t sc_memt;
+ bus_space_handle_t sc_aica_regh;
+ bus_space_handle_t sc_aica_memh;
+
+ /* audio property */
+ int sc_open;
+ int sc_encodings;
+ int sc_precision;
+ int sc_channels;
+ int sc_rate;
+ void (*sc_intr)(void *);
+ void *sc_intr_arg;
+
+ int sc_output_master;
+ int sc_output_gain[2];
+#define AICA_VOLUME_LEFT 0
+#define AICA_VOLUME_RIGHT 1
+
+ /* work for output */
+ void *sc_buffer;
+ void *sc_buffer_start;
+ void *sc_buffer_end;
+ int sc_blksize;
+ int sc_nextfill;
+};
+
+struct {
+ char *name;
+ int encoding;
+ int precision;
+} aica_encodings[] = {
+ {AudioEadpcm, AUDIO_ENCODING_ADPCM, 4},
+ {AudioEslinear, AUDIO_ENCODING_SLINEAR, 8},
+ {AudioEulinear, AUDIO_ENCODING_ULINEAR, 8},
+ {AudioEmulaw, AUDIO_ENCODING_ULAW, 8},
+ {AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 16},
+ {AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 16},
+};
+
+int aica_match(struct device *, struct cfdata *, void *);
+void aica_attach(struct device *, struct device *, void *);
+int aica_print(void *, const char *);
+
+CFATTACH_DECL(aica, sizeof(struct aica_softc), aica_match, aica_attach,
+ NULL, NULL);
+
+struct audio_device aica_device = {
+ "Dreamcast Sound",
+ "",
+ "aica"
+};
+
+__inline static void aica_g2fifo_wait(void);
+void aica_enable(struct aica_softc *);
+void aica_disable(struct aica_softc *);
+void aica_memwrite(struct aica_softc *, bus_size_t, u_int32_t *, int);
+void aica_ch2p16write(struct aica_softc *, bus_size_t, u_int16_t *, int);
+void aica_ch2p8write(struct aica_softc *, bus_size_t, u_int8_t *, int);
+void aica_command(struct aica_softc *, u_int32_t);
+void aica_sendparam(struct aica_softc *, u_int32_t, int, int);
+void aica_play(struct aica_softc *, int, int, int, int);
+void aica_fillbuffer(struct aica_softc *);
+
+/* intr */
+int aica_intr(void *);
+
+/* for audio */
+int aica_open(void *, int);
+void aica_close(void *);
+int aica_query_encoding(void *, struct audio_encoding *);
+int aica_set_params(void *, int, int, struct audio_params *,
+ struct audio_params *);
+int aica_round_blocksize(void *, int);
+size_t aica_round_buffersize(void *, int, size_t);
+int aica_trigger_output(void *, void *, void *, int, void (*)(void *), void *,
+ struct audio_params *);
+int aica_trigger_input(void *, void *, void *, int, void (*)(void *), void *,
+ struct audio_params *);
+int aica_halt_output(void *);
+int aica_halt_input(void *);
+int aica_getdev(void *, struct audio_device *);
+int aica_set_port(void *, mixer_ctrl_t *);
+int aica_get_port(void *, mixer_ctrl_t *);
+int aica_query_devinfo(void *, mixer_devinfo_t *);
+void aica_encode(int, int, int, int, u_char *, u_short **);
+int aica_get_props(void *);
+
+struct audio_hw_if aica_hw_if = {
+ aica_open,
+ aica_close,
+ NULL, /* aica_drain */
+ aica_query_encoding,
+ aica_set_params,
+ aica_round_blocksize,
+ NULL, /* aica_commit_setting */
+ NULL, /* aica_init_output */
+ NULL, /* aica_init_input */
+ NULL, /* aica_start_output */
+ NULL, /* aica_start_input */
+ aica_halt_output,
+ aica_halt_input,
+ NULL, /* aica_speaker_ctl */
+ aica_getdev,
+ NULL, /* aica_setfd */
+ aica_set_port,
+ aica_get_port,
+ aica_query_devinfo,
+ NULL, /* aica_allocm */
+ NULL, /* aica_freem */
+
+ aica_round_buffersize, /* aica_round_buffersize */
+
+ NULL, /* aica_mappage */
+ aica_get_props,
+ aica_trigger_output,
+ aica_trigger_input,
+ NULL, /* aica_dev_ioctl */
+};
+
+int
+aica_match(struct device *parent, struct cfdata *cf, void *aux)
+{
+ static int aica_matched = 0;
+
+ if (aica_matched)
+ return 0;
+
+ aica_matched = 1;
+ return 1;
+}
+
+void
+aica_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct aica_softc *sc = (struct aica_softc *)self;
+ struct g2bus_attach_args *ga = aux;
+ int i;
+
+ sc->sc_memt = ga->ga_memt;
+
+ if (bus_space_map(sc->sc_memt, AICA_REG_ADDR, 0x3000, 0,
+ &sc->sc_aica_regh) != 0) {
+ printf(": can't map AICA register space\n");
+ return;
+ }
+
+ if (bus_space_map(sc->sc_memt, AICA_RAM_START, AICA_RAM_SIZE, 0,
+ &sc->sc_aica_memh) != 0) {
+ printf(": can't map AICA memory space\n");
+ return;
+ }
+
+ printf(": ARM7 Sound Processing Unit\n");
+
+ aica_disable(sc);
+
+ for (i = 0; i < AICA_NCHAN; i++)
+ bus_space_write_4(sc->sc_memt,sc->sc_aica_regh, i << 7,
+ ((bus_space_read_4(sc->sc_memt, sc->sc_aica_regh, i << 7)
+ & ~0x4000) | 0x8000));
+
+ /* load microcode, and clear memory */
+ bus_space_set_region_4(sc->sc_memt, sc->sc_aica_memh,
+ 0, 0, AICA_RAM_SIZE);
+
+ aica_memwrite(sc, 0, aica_armcode, sizeof(aica_armcode));
+
+ aica_enable(sc);
+
+ printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname,
+ sysasic_intr_string(IPL_BIO));
+ sysasic_intr_establish(SYSASIC_EVENT_AICA, IPL_BIO, aica_intr, sc);
+
+ audio_attach_mi(&aica_hw_if, sc, &sc->sc_dev);
+
+ /* init parameters */
+ sc->sc_output_master = 255;
+ sc->sc_output_gain[AICA_VOLUME_LEFT] = 255;
+ sc->sc_output_gain[AICA_VOLUME_RIGHT] = 255;
+}
+
+void
+aica_enable(struct aica_softc *sc)
+{
+
+ bus_space_write_4(sc->sc_memt, sc->sc_aica_regh, 0x28a8, 24);
+ bus_space_write_4(sc->sc_memt, sc->sc_aica_regh, 0x2c00,
+ bus_space_read_4(sc->sc_memt, sc->sc_aica_regh, 0x2c00) & ~1);
+}
+
+void
+aica_disable(struct aica_softc *sc)
+{
+
+ bus_space_write_4(sc->sc_memt, sc->sc_aica_regh, 0x2c00,
+ bus_space_read_4(sc->sc_memt, sc->sc_aica_regh, 0x2c00) | 1);
+}
+
+inline static void
+aica_g2fifo_wait()
+{
Home |
Main Index |
Thread Index |
Old Index