summaryrefslogtreecommitdiff
path: root/attic/drv/oss_neomagic/neomagic.h
diff options
context:
space:
mode:
Diffstat (limited to 'attic/drv/oss_neomagic/neomagic.h')
-rw-r--r--attic/drv/oss_neomagic/neomagic.h302
1 files changed, 302 insertions, 0 deletions
diff --git a/attic/drv/oss_neomagic/neomagic.h b/attic/drv/oss_neomagic/neomagic.h
new file mode 100644
index 0000000..ba35123
--- /dev/null
+++ b/attic/drv/oss_neomagic/neomagic.h
@@ -0,0 +1,302 @@
+/*
+ * Purpose: Definitions for the neomagic driver
+ */
+/*
+ *
+ * This file is part of Open Sound System.
+ *
+ * Copyright (C) 4Front Technologies 1996-2008.
+ *
+ * This this source file is released under GPL v2 license (no other versions).
+ * See the COPYING file included in the main directory of this source
+ * distribution for the license terms and conditions.
+ *
+ */
+
+typedef unsigned char U8;
+typedef unsigned short U16;
+typedef unsigned int U32;
+
+/* The revisions that we currently handle. */
+enum neomagicrev
+{
+ REV_NEOMAGICAV, REV_NEOMAGICZX
+};
+
+#define MAX_PORTC 2
+
+/* The two memory ports. */
+typedef struct neomagic_portc
+{
+ unsigned int physaddr; /* Physical address of the port. */
+ char *ptr; /* Our mapped-in pointer. */
+ unsigned int start_offset; /* PTR's offset within the physical port. */
+ unsigned int end_offset; /* And the offset of the end of the buffer. */
+ unsigned int samplerate;
+ unsigned char bits;
+ unsigned char stereo;
+}
+neomagic_portc;
+
+
+typedef struct neomagic_devc
+{
+ /* OS struct for OSS */
+ oss_device_t *osdev;
+
+ /* Our IRQ number. */
+ int irq;
+
+ /* Mutex */
+ oss_mutex_t mutex;
+ oss_mutex_t low_mutex;
+
+ /* Magic number used to verify that this struct is valid. */
+#define NM_MAGIC_SIG 0x55aa00ff
+ int magsig;
+
+ enum neomagicrev rev; /* Revision number */
+
+ char *chip_name; /* Chip name. */
+
+ ac97_devc ac97devc;
+
+ int dev[2]; /* Our audio device numbers. */
+
+ int opencnt[2]; /* The # of times each device has been opened. */
+
+ /* We use two devices, because we can do simultaneous play and record.
+ This keeps track of which device is being used for what purpose;
+ these are the actual device numbers. */
+ int dev_for_play;
+ int dev_for_record;
+
+ int mixer_dev; /* The mixer device. */
+
+ /*
+ * Can only be opened once for each operation. These aren't set
+ * until an actual I/O operation is performed; this allows one
+ * device to be open for read/write without inhibiting I/O to
+ * the other device.
+ */
+ int is_open_play;
+ int is_open_record;
+
+ int playing; /* Non-zero if we're currently playing a sample. */
+ int recording; /* Same for recording a sample. */
+
+ neomagic_portc portc[MAX_PORTC];
+
+ /* The following are offsets within memory port 1. */
+ unsigned int coeffBuf;
+ unsigned int allCoeffBuf;
+
+ /* Record and playback buffers. */
+ unsigned int abuf1, abuf2;
+ char *abuf1virt, *abuf2virt;
+
+ /* Offset of the mixer status register in memory port 2. */
+ unsigned int mixer_status_offset;
+
+ /*
+ * Status mask bit; (*mixer_status_loc & mixer_status_mask) == 0 means
+ * it's ready.
+ */
+ unsigned short mixer_status_mask;
+
+ /* The sizes of the playback and record ring buffers. */
+ unsigned int playbackBufferSize;
+ unsigned int recordBufferSize;
+
+ /* The devc interrupt service routine. */
+ int (*introutine) (struct neomagic_devc *);
+
+ int mixer_cache[64];
+}
+neomagic_devc;
+
+/* The BIOS signature. */
+#define NM_SIGNATURE 0x4e4d0000
+/* Signature mask. */
+#define NM_SIG_MASK 0xffff0000
+
+/* Size of the second memory area. */
+#define NM_PORT2_SIZE 4096
+
+/* The base offset of the mixer in the second memory area. */
+#define NM_MIXER_OFFSET 0x600
+
+/* The maximum size of a coefficient entry. */
+#define NM_MAX_COEFFICIENT 0x5000
+
+/* The interrupt register. */
+#define NM_INT_REG 0xa04
+/* And its bits. */
+#define NM_PLAYBACK_INT 0x40
+#define NM_RECORD_INT 0x100
+#define NM_MISC_INT_1 0x4000
+#define NM_MISC_INT_2 0x1
+#define NM_ACK_INT(CARD, X) neomagic_writePort16((CARD), 2, NM_INT_REG, (X) << 1)
+
+/* The AV's "mixer ready" status bit and location. */
+#define NM_MIXER_STATUS_OFFSET 0xa06
+#define NM_MIXER_READY_MASK 0x0800
+#define NM_PRESENCE_MASK 0x0050
+#define NM_PRESENCE_VALUE 0x0040
+
+/*
+ * For the ZX. It uses the same interrupt register, but it holds 32
+ * bits instead of 16.
+ */
+#define NMZX_PLAYBACK_INT 0x10000
+#define NMZX_RECORD_INT 0x80000
+#define NMZX_MISC_INT_1 0x8
+#define NMZX_MISC_INT_2 0x2
+#define NMZX_ACK_INT(CARD, X) neomagic_writePort32((CARD), 2, NM_INT_REG, (X))
+
+/* The ZX's "mixer ready" status bit and location. */
+#define NMZX_MIXER_STATUS_OFFSET 0xa08
+#define NMZX_MIXER_READY_MASK 0x0800
+
+/* The playback registers start from here. */
+#define NM_PLAYBACK_REG_OFFSET 0x0
+/* The record registers start from here. */
+#define NM_RECORD_REG_OFFSET 0x200
+
+/* The rate register is located 2 bytes from the start of the register area. */
+#define NM_RATE_REG_OFFSET 2
+
+/* Mono/stereo flag, number of bits on playback, and rate mask. */
+#define NM_RATE_STEREO 1
+#define NM_RATE_BITS_16 2
+#define NM_RATE_MASK 0xf0
+
+/* Playback enable register. */
+#define NM_PLAYBACK_ENABLE_REG (NM_PLAYBACK_REG_OFFSET + 0x1)
+#define NM_PLAYBACK_ENABLE_FLAG 1
+#define NM_PLAYBACK_ONESHOT 2
+#define NM_PLAYBACK_FREERUN 4
+
+/* Mutes the audio output. */
+#define NM_AUDIO_MUTE_REG (NM_PLAYBACK_REG_OFFSET + 0x18)
+#define NM_AUDIO_MUTE_LEFT 0x8000
+#define NM_AUDIO_MUTE_RIGHT 0x0080
+
+/* Recording enable register. */
+#define NM_RECORD_ENABLE_REG (NM_RECORD_REG_OFFSET + 0)
+#define NM_RECORD_ENABLE_FLAG 1
+#define NM_RECORD_FREERUN 2
+
+#define NM_RBUFFER_START (NM_RECORD_REG_OFFSET + 0x4)
+#define NM_RBUFFER_END (NM_RECORD_REG_OFFSET + 0x10)
+#define NM_RBUFFER_WMARK (NM_RECORD_REG_OFFSET + 0xc)
+#define NM_RBUFFER_CURRP (NM_RECORD_REG_OFFSET + 0x8)
+
+#define NM_PBUFFER_START (NM_PLAYBACK_REG_OFFSET + 0x4)
+#define NM_PBUFFER_END (NM_PLAYBACK_REG_OFFSET + 0x14)
+#define NM_PBUFFER_WMARK (NM_PLAYBACK_REG_OFFSET + 0xc)
+#define NM_PBUFFER_CURRP (NM_PLAYBACK_REG_OFFSET + 0x8)
+
+/* A few trivial routines to make it easier to work with the registers
+ on the chip. */
+
+/* This is a common code portion used to fix up the port offsets. */
+#define NM_FIX_PORT \
+ if (port < 1 || port > 2 || devc == NULL) \
+ return 0; \
+\
+ if (offset < devc->portc[port - 1].start_offset \
+ || offset >= devc->portc[port - 1].end_offset) { \
+ cmn_err(CE_WARN, "Bad access: port %d, offset 0x%x\n", port, offset); \
+ return 0; \
+ } \
+ offset -= devc->portc[port - 1].start_offset;
+
+#define DEFwritePortX(X, func) \
+static inline int neomagic_writePort##X (neomagic_devc *devc,\
+ int port, int offset, int value)\
+{\
+ U##X *addr;\
+\
+ DDB (cmn_err(CE_CONT, "Writing 0x%x to %d:0x%x\n", value, port, offset));\
+\
+ NM_FIX_PORT;\
+\
+ addr = (U##X *)(devc->portc[port - 1].ptr + offset);\
+ func (value, addr);\
+ return 0;\
+}
+
+static inline void
+nm_writeb (unsigned char value, unsigned char *ptr)
+{
+ *ptr = value;
+}
+
+static inline void
+nm_writew (unsigned short value, unsigned short *ptr)
+{
+ *ptr = value;
+}
+
+static inline void
+nm_writel (unsigned int value, unsigned int *ptr)
+{
+ *ptr = value;
+}
+
+
+DEFwritePortX (8, nm_writeb)
+DEFwritePortX (16, nm_writew) DEFwritePortX (32, nm_writel)
+#define DEFreadPortX(X, func) \
+static inline U##X neomagic_readPort##X (neomagic_devc *devc,\
+ int port, int offset)\
+{\
+ U##X *addr;\
+\
+ NM_FIX_PORT\
+\
+ addr = (U##X *)(devc->portc[port - 1].ptr + offset);\
+ return func(addr);\
+}
+ static inline unsigned char
+ nm_readb (unsigned char *ptr)
+{
+ return *ptr;
+}
+
+static inline unsigned short
+nm_readw (unsigned short *ptr)
+{
+ return *ptr;
+}
+
+static inline unsigned int
+nm_readl (unsigned int *ptr)
+{
+ return *ptr;
+}
+
+DEFreadPortX (8, nm_readb)
+DEFreadPortX (16, nm_readw)
+DEFreadPortX (32, nm_readl)
+
+static inline int
+neomagic_writeBuffer8 (neomagic_devc * devc, unsigned char *src,
+ int port, int offset, int amt)
+{
+ NM_FIX_PORT;
+ memcpy (devc->portc[port - 1].ptr + offset, src, amt);
+ return 0;
+}
+
+#if 0
+static inline int
+neomagic_readBuffer8 (neomagic_devc * devc, unsigned char *dst, int port,
+ int offset, int amt)
+{
+ NM_FIX_PORT;
+ memcpy (dst, devc->portc[port - 1].ptr + offset, amt);
+ return 0;
+}
+#endif