Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/sgimips Support for HAL2 audio controller attached ...



details:   https://anonhg.NetBSD.org/src/rev/1d5f4e11df42
branches:  trunk
changeset: 552420:1d5f4e11df42
user:      lonewolf <lonewolf%NetBSD.org@localhost>
date:      Thu Sep 25 16:35:50 2003 +0000

description:
Support for HAL2 audio controller attached to the HPC ASIC, found on SGI Indy.

The driver is not too heavily tested and only supports audio playback and
master volume setting currently.

diffstat:

 sys/arch/sgimips/conf/GENERIC    |    7 +-
 sys/arch/sgimips/hpc/files.hpc   |    6 +-
 sys/arch/sgimips/hpc/haltwo.c    |  795 +++++++++++++++++++++++++++++++++++++++
 sys/arch/sgimips/hpc/haltworeg.h |   79 +++
 sys/arch/sgimips/hpc/haltwovar.h |   86 ++++
 sys/arch/sgimips/hpc/hpc.c       |    9 +-
 6 files changed, 977 insertions(+), 5 deletions(-)

diffs (truncated from 1057 to 300 lines):

diff -r e41d2db2d962 -r 1d5f4e11df42 sys/arch/sgimips/conf/GENERIC
--- a/sys/arch/sgimips/conf/GENERIC     Thu Sep 25 16:34:55 2003 +0000
+++ b/sys/arch/sgimips/conf/GENERIC     Thu Sep 25 16:35:50 2003 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: GENERIC,v 1.20 2003/05/04 01:36:53 gmcgarry Exp $
+#      $NetBSD: GENERIC,v 1.21 2003/09/25 16:35:50 lonewolf Exp $
 #
 # GENERIC machine description file
 # 
@@ -28,7 +28,7 @@
 
 options        INCLUDE_CONFIG_FILE     # embed config file in kernel binary
 
-#ident         "GENERIC-$Revision: 1.20 $"
+#ident         "GENERIC-$Revision: 1.21 $"
 
 maxusers       32
 
@@ -224,6 +224,7 @@
 sq*            at hpc0 offset ?
 wdsc*          at hpc0 offset ?
 dsclock*       at hpc0 offset ?
+haltwo*        at hpc0 offset ?
 
 #
 # As always, the zs chip is wired funny, so channel 1 is actually the
@@ -237,6 +238,8 @@
 
 scsibus*       at wdsc?                # HPC SCSI
 
+audio*                 at audiobus?
+
 # Pseudo-Devices
 
 # disk/mass storage pseudo-devices
diff -r e41d2db2d962 -r 1d5f4e11df42 sys/arch/sgimips/hpc/files.hpc
--- a/sys/arch/sgimips/hpc/files.hpc    Thu Sep 25 16:34:55 2003 +0000
+++ b/sys/arch/sgimips/hpc/files.hpc    Thu Sep 25 16:35:50 2003 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.hpc,v 1.4 2002/03/13 13:12:27 simonb Exp $
+# $NetBSD: files.hpc,v 1.5 2003/09/25 16:35:50 lonewolf Exp $
 
 device sq: arp, ether, ifnet
 attach sq at hpc
@@ -18,6 +18,10 @@
 attach dsclock at hpc
 file   arch/sgimips/hpc/dsclock_hpc.c
 
+device haltwo: audiobus, auconv, mulaw
+attach haltwo at hpc
+file   arch/sgimips/hpc/haltwo.c
+
 attach zsc at hpc with zsc_hpc
 
 attach pckbc at hpc with pckbc_hpc
diff -r e41d2db2d962 -r 1d5f4e11df42 sys/arch/sgimips/hpc/haltwo.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/sgimips/hpc/haltwo.c     Thu Sep 25 16:35:50 2003 +0000
@@ -0,0 +1,795 @@
+/* $NetBSD: haltwo.c,v 1.1 2003/09/25 16:35:50 lonewolf Exp $ */
+
+/*
+ * Copyright (c) 2003 Ilpo Ruotsalainen
+ * 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.
+ * 
+ * <<Id: LICENSE_GC,v 1.1 2001/10/01 23:24:05 cgd Exp>>
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: haltwo.c,v 1.1 2003/09/25 16:35:50 lonewolf Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/audioio.h>
+#include <sys/malloc.h>
+#include <dev/audio_if.h>
+#include <dev/auconv.h>
+#include <dev/mulaw.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <machine/bus.h>
+
+#include <sgimips/hpc/hpcvar.h>
+#include <sgimips/hpc/hpcreg.h>
+
+#include <sgimips/hpc/haltworeg.h>
+#include <sgimips/hpc/haltwovar.h>
+
+#ifdef AUDIO_DEBUG
+#define DPRINTF(x)      printf x
+#else
+#define DPRINTF(x)
+#endif
+
+static int haltwo_open(void *, int);
+static void haltwo_close(void *);
+static int haltwo_query_encoding(void *, struct audio_encoding *);
+static int haltwo_set_params(void *, int, int, struct audio_params *,
+               struct audio_params *);
+static int haltwo_round_blocksize(void *, int);
+static int haltwo_halt_output(void *);
+static int haltwo_halt_input(void *);
+static int haltwo_getdev(void *, struct audio_device *);
+static int haltwo_set_port(void *, mixer_ctrl_t *);
+static int haltwo_get_port(void *, mixer_ctrl_t *);
+static int haltwo_query_devinfo(void *, mixer_devinfo_t *);
+static void *haltwo_malloc(void *, int, size_t, struct malloc_type *, int);
+static void haltwo_free(void *, void *, struct malloc_type *);
+static int haltwo_get_props(void *);
+static int haltwo_trigger_output(void *, void *, void *, int, void (*)(void *),
+               void *, struct audio_params *);
+static int haltwo_trigger_input(void *, void *, void *, int, void (*)(void *),
+               void *, struct audio_params *);
+
+static struct audio_hw_if haltwo_hw_if = {
+       haltwo_open,
+       haltwo_close,
+       NULL, /* drain */
+       haltwo_query_encoding,
+       haltwo_set_params,
+       haltwo_round_blocksize,
+       NULL, /* commit_settings */
+       NULL, /* init_output */
+       NULL, /* init_input */
+       NULL, /* start_output */
+       NULL, /* start_input */
+       haltwo_halt_output,
+       haltwo_halt_input,
+       NULL, /* speaker_ctl */
+       haltwo_getdev,
+       NULL, /* setfd */
+       haltwo_set_port,
+       haltwo_get_port,
+       haltwo_query_devinfo,
+       haltwo_malloc,
+       haltwo_free,
+       NULL, /* round_buffersize */
+       NULL, /* mappage */
+       haltwo_get_props,
+       haltwo_trigger_output,
+       haltwo_trigger_input,
+       NULL  /* dev_ioctl */
+};
+
+static const struct audio_device haltwo_device = {
+  "HAL2",
+  "",
+  "haltwo"
+};
+
+static int  haltwo_match(struct device *, struct cfdata *, void *);
+static void haltwo_attach(struct device *, struct device *, void *);
+static int  haltwo_intr(void *);
+
+CFATTACH_DECL(haltwo, sizeof(struct haltwo_softc),
+    haltwo_match, haltwo_attach, NULL, NULL);
+
+#define haltwo_write(sc,type,off,val) \
+       bus_space_write_4(sc->sc_st, sc->sc_##type##_sh, off, val)
+
+#define haltwo_read(sc,type,off) \
+       bus_space_read_4(sc->sc_st, sc->sc_##type##_sh, off)
+
+static void
+haltwo_write_indirect(struct haltwo_softc *sc, uint32_t ireg, uint16_t low,
+               uint16_t high)
+{
+       haltwo_write(sc, ctl, HAL2_REG_CTL_IDR0, low);
+       haltwo_write(sc, ctl, HAL2_REG_CTL_IDR1, high);
+       haltwo_write(sc, ctl, HAL2_REG_CTL_IDR2, 0);
+       haltwo_write(sc, ctl, HAL2_REG_CTL_IDR3, 0);
+       haltwo_write(sc, ctl, HAL2_REG_CTL_IAR, ireg);
+
+       while (haltwo_read(sc, ctl, HAL2_REG_CTL_ISR) & HAL2_ISR_TSTATUS)
+               ;
+}
+
+static void
+haltwo_read_indirect(struct haltwo_softc *sc, uint32_t ireg, uint16_t *low,
+               uint16_t *high)
+{
+       haltwo_write(sc, ctl, HAL2_REG_CTL_IAR,
+           ireg | HAL2_IAR_READ);
+
+       while (haltwo_read(sc, ctl, HAL2_REG_CTL_ISR) & HAL2_ISR_TSTATUS)
+               ;
+
+       if (low)
+               *low = haltwo_read(sc, ctl, HAL2_REG_CTL_IDR0);
+       
+       if (high)
+               *high = haltwo_read(sc, ctl, HAL2_REG_CTL_IDR1);
+}
+
+static int
+haltwo_init_codec(struct haltwo_softc *sc, struct haltwo_codec *codec)
+{
+       int err;
+       int rseg;
+       size_t allocsz = sizeof(struct hpc_dma_desc) * HALTWO_MAX_DMASEGS;
+
+       KASSERT(allocsz <= PAGE_SIZE);
+
+       err = bus_dmamem_alloc(sc->sc_dma_tag, allocsz, 0, 0, &codec->dma_seg,
+           1, &rseg, BUS_DMA_NOWAIT);
+       if (err)
+               goto out;
+
+       err = bus_dmamem_map(sc->sc_dma_tag, &codec->dma_seg, rseg, allocsz,
+           (caddr_t *)&codec->dma_descs, BUS_DMA_NOWAIT);
+       if (err)
+               goto out_free;
+
+       err = bus_dmamap_create(sc->sc_dma_tag, allocsz, 1, PAGE_SIZE, 0,
+           BUS_DMA_NOWAIT, &codec->dma_map);
+       if (err)
+               goto out_free;
+
+       err = bus_dmamap_load(sc->sc_dma_tag, codec->dma_map, codec->dma_descs,
+           allocsz, NULL, BUS_DMA_NOWAIT);
+       if (err)
+               goto out_destroy;
+
+       DPRINTF(("haltwo_init_codec: allocated %d descriptors (%d bytes)"
+           " at %p\n", HALTWO_MAX_DMASEGS, allocsz, codec->dma_descs));
+
+       memset(codec->dma_descs, 0, allocsz);
+
+       return (0);
+
+out_destroy:
+       bus_dmamap_destroy(sc->sc_dma_tag, codec->dma_map);
+out_free:
+       bus_dmamem_free(sc->sc_dma_tag, &codec->dma_seg, rseg);
+out:
+       DPRINTF(("haltwo_init_codec failed: %d\n",err));
+
+       return (err);
+}
+
+static void
+haltwo_setup_dma(struct haltwo_softc *sc, struct haltwo_codec *codec,
+               struct haltwo_dmabuf *dmabuf, size_t len, int blksize,
+               void (*intr)(void *), void *intrarg)
+{
+       int i;
+       bus_dma_segment_t *segp;
+       struct hpc_dma_desc *descp;
+       int next_intr = blksize;
+  
+       KASSERT(len % blksize == 0);
+
+       codec->intr = intr;
+       codec->intr_arg = intrarg;
+
+       segp = dmabuf->dma_map->dm_segs;
+       descp = codec->dma_descs;
+
+       /* Build descriptor chain for looping DMA, triggering interrupt every
+        * blksize bytes */
+       for (i = 0; i < dmabuf->dma_map->dm_nsegs; i++) {
+               descp->hdd_bufptr = segp->ds_addr;
+               descp->hdd_ctl = segp->ds_len;
+
+               KASSERT(next_intr >= segp->ds_len);
+
+               if (next_intr == segp->ds_len) {
+                       /* Generate intr after this DMA buffer */
+                       descp->hdd_ctl |= HDD_CTL_INTR;
+                       next_intr = blksize;
+               }
+               else
+                       next_intr -= segp->ds_len;
+
+               if (i < dmabuf->dma_map->dm_nsegs - 1)
+                       descp->hdd_descptr = codec->dma_seg.ds_addr +



Home | Main Index | Thread Index | Old Index