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