patch-2.1.111 linux/drivers/sound/msnd_pinnacle.c
Next file: linux/drivers/sound/msnd_pinnacle.h
Previous file: linux/drivers/sound/msnd_classic.h
Back to the patch index
Back to the overall index
- Lines: 494
- Date:
Wed Jul 22 13:45:53 1998
- Orig file:
v2.1.110/linux/drivers/sound/msnd_pinnacle.c
- Orig date:
Tue Jul 21 00:15:31 1998
diff -u --recursive --new-file v2.1.110/linux/drivers/sound/msnd_pinnacle.c linux/drivers/sound/msnd_pinnacle.c
@@ -1,8 +1,17 @@
/*********************************************************************
*
- * msnd_pinnacle.c - Support for Turtle Beach Pinnacle and Fiji
- *
* Turtle Beach MultiSound Sound Card Driver for Linux
+ * Linux 2.0/2.2 Version
+ *
+ * msnd_pinnacle.c / msnd_classic.c
+ *
+ * -- If MSND_CLASSIC is defined:
+ *
+ * -> driver for Turtle Beach Classic/Monterey/Tahiti
+ *
+ * -- Else
+ *
+ * -> driver for Turtle Beach Pinnacle/Fiji
*
* Copyright (C) 1998 Andrew Veliath
*
@@ -20,22 +29,36 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: msnd_pinnacle.c,v 1.2 1998/06/09 20:37:39 andrewtv Exp $
+ * $Id: msnd_pinnacle.c,v 1.5 1998/07/18 00:12:16 andrewtv Exp $
*
********************************************************************/
#include <linux/config.h>
+#include <linux/version.h>
+#if LINUX_VERSION_CODE < 0x020101
+# define LINUX20
+#endif
#include <linux/module.h>
#include <linux/malloc.h>
#include <linux/types.h>
#include <linux/delay.h>
-#include <linux/init.h>
+#ifndef LINUX20
+# include <linux/init.h>
+#endif
#include "sound_config.h"
#include "sound_firmware.h"
+#ifdef MSND_CLASSIC
+# define SLOWIO
+#endif
#include "msnd.h"
-#include "msnd_pinnacle.h"
+#ifdef MSND_CLASSIC
+# include "msnd_classic.h"
+# define LOGNAME "msnd_classic"
+#else
+# include "msnd_pinnacle.h"
+# define LOGNAME "msnd_pinnacle"
+#endif
-#define LOGNAME "msnd_pinnacle"
#define DEVNAME dev.name
#define MIXERMINOR dev.mixer_minor
#define DSPMINOR dev.dsp_minor
@@ -111,7 +134,7 @@
static int dsp_ioctl(unsigned int cmd, unsigned long arg)
{
- int val, i, data;
+ int val, i, data, tmp;
LPDAQD lpDAQ, lpDARQ;
lpDAQ = (LPDAQD)(dev.base + DAPQ_DATA_BUFF);
@@ -139,8 +162,9 @@
case SNDCTL_DSP_GETBLKSIZE:
- if (put_user(dev.fifosize / 4, (int *)arg))
- return -EFAULT;
+ tmp = dev.fifosize / 4;
+ if (put_user(tmp, (int *)arg))
+ return -EFAULT;
return 0;
@@ -283,7 +307,9 @@
case SOUND_MIXER_SYNTH:
case SOUND_MIXER_PCM:
case SOUND_MIXER_LINE:
+#ifndef MSND_CLASSIC
case SOUND_MIXER_MIC:
+#endif
case SOUND_MIXER_IMIX:
case SOUND_MIXER_LINE1:
return (dev.left_levels[d] >> 8) * 100 / 0xff |
@@ -332,12 +358,14 @@
msnd_send_dsp_cmd(&dev, HDEX_AUX_REQ);
break;
+#ifndef MSND_CLASSIC
case SOUND_MIXER_MIC: /* mic pot control */
writeb(bLeft, &dev.SMA->bMicPotPosLeft);
writeb(bRight, &dev.SMA->bMicPotPosRight);
if (msnd_send_word(&dev, 0, 0, HDEXAR_MIC_SET_POTS) == 0)
msnd_send_dsp_cmd(&dev, HDEX_AUX_REQ);
break;
+#endif
case SOUND_MIXER_LINE1: /* line pot control */
writeb(bLeft, &dev.SMA->bAuxPotPosLeft);
@@ -359,7 +387,9 @@
/* update digital controls for master volume */
update_vol(SOUND_MIXER_PCM, wCurrPlayVol, 1);
update_vol(SOUND_MIXER_IMIX, wCurrInVol, 1);
+#ifndef MSND_CLASSIC
update_vol(SOUND_MIXER_SYNTH, wCurrMHdrVol, 1);
+#endif
return mixer_get(d);
}
@@ -373,6 +403,7 @@
#endif
dev.recsrc ^= recsrc;
+#ifndef MSND_CLASSIC
if (dev.recsrc & SOUND_MASK_LINE) {
if (msnd_send_word(&dev, 0, 0, HDEXAR_SET_ANA_IN) == 0)
@@ -395,6 +426,7 @@
msnd_send_dsp_cmd(&dev, HDEX_AUX_REQ);
#endif
}
+#endif /* MSND_CLASSIC */
return dev.recsrc;
}
@@ -432,16 +464,22 @@
case SOUND_MIXER_DEVMASK:
case SOUND_MIXER_STEREODEVS:
val = SOUND_MASK_VOLUME |
+#ifndef MSND_CLASSIC
SOUND_MASK_SYNTH |
+ SOUND_MASK_MIC |
+#endif
SOUND_MASK_PCM |
SOUND_MASK_LINE |
- SOUND_MASK_IMIX |
- SOUND_MASK_MIC;
+ SOUND_MASK_IMIX;
break;
case SOUND_MIXER_RECMASK:
+#ifdef MSND_CLASSIC
+ val = 0;
+#else
val = SOUND_MASK_LINE |
SOUND_MASK_SYNTH;
+#endif
break;
case SOUND_MIXER_CAPS:
@@ -476,15 +514,23 @@
static void dsp_halt(void)
{
mdelay(1);
+#ifdef LINUX20
+ if (test_bit(F_READING, &dev.flags)) {
+ clear_bit(F_READING, &dev.flags);
+#else
if (test_and_clear_bit(F_READING, &dev.flags)) {
-
+#endif
msnd_send_dsp_cmd(&dev, HDEX_RECORD_STOP);
msnd_disable_irq(&dev);
}
mdelay(1);
+#ifdef LINUX20
+ if (test_bit(F_WRITING, &dev.flags)) {
+ clear_bit(F_WRITING, &dev.flags);
+#else
if (test_and_clear_bit(F_WRITING, &dev.flags)) {
-
+#endif
set_bit(F_WRITEFLUSH, &dev.flags);
interruptible_sleep_on(&dev.writeflush);
current->state = TASK_INTERRUPTIBLE;
@@ -540,23 +586,37 @@
return err;
}
+#ifdef LINUX20
+static void dev_close(struct inode *inode, struct file *file)
+#else
static int dev_close(struct inode *inode, struct file *file)
+#endif
{
int minor = MINOR(inode->i_rdev);
+#ifndef LINUX20
int err = 0;
+#endif
if (minor == DSPMINOR) {
- err = dsp_close();
+#ifndef LINUX20
+ err =
+#endif
+ dsp_close();
}
else if (minor == MIXERMINOR) {
/* nothing */
- } else
+ }
+#ifndef LINUX20
+ else
err = -EINVAL;
if (err >= 0)
+#endif
MOD_DEC_USE_COUNT;
-
+
+#ifndef LINUX20
return err;
+#endif
}
static int DAPF_to_bank(int bank)
@@ -586,9 +646,13 @@
buf += n;
count -= n;
-
- if (!test_and_set_bit(F_READING, &dev.flags) && (dev.mode & FMODE_READ)) {
+#ifdef LINUX20
+ if (!test_bit(F_READING, &dev.flags) && (dev.mode & FMODE_READ)) {
+ set_bit(F_READING, &dev.flags);
+#else
+ if (!test_and_set_bit(F_READING, &dev.flags) && (dev.mode & FMODE_READ)) {
+#endif
reset_record_queue();
msnd_enable_irq(&dev);
msnd_send_dsp_cmd(&dev, HDEX_RECORD_START);
@@ -634,8 +698,12 @@
buf += n;
count -= n;
+#ifdef LINUX20
+ if (!test_bit(F_WRITING, &dev.flags) && (dev.mode & FMODE_WRITE)) {
+ set_bit(F_WRITING, &dev.flags);
+#else
if (!test_and_set_bit(F_WRITING, &dev.flags) && (dev.mode & FMODE_WRITE)) {
-
+#endif
reset_play_queue();
msnd_enable_irq(&dev);
msnd_send_dsp_cmd(&dev, HDEX_PLAY_START);
@@ -663,9 +731,15 @@
return len - count;
}
+#ifdef LINUX20
+static int dev_read(struct inode *inode, struct file *file, char *buf, int count)
+{
+ int minor = MINOR(inode->i_rdev);
+#else
static ssize_t dev_read(struct file *file, char *buf, size_t count, loff_t *off)
{
int minor = MINOR(file->f_dentry->d_inode->i_rdev);
+#endif
if (minor == DSPMINOR) {
@@ -675,9 +749,15 @@
return -EINVAL;
}
+#ifdef LINUX20
+static int dev_write(struct inode *inode, struct file *file, const char *buf, int count)
+{
+ int minor = MINOR(inode->i_rdev);
+#else
static ssize_t dev_write(struct file *file, const char *buf, size_t count, loff_t *off)
{
int minor = MINOR(file->f_dentry->d_inode->i_rdev);
+#endif
if (minor == DSPMINOR) {
@@ -716,8 +796,15 @@
else if (!test_bit(F_WRITEBLOCK, &dev.flags)) {
clear_bit(F_WRITING, &dev.flags);
+#ifdef LINUX20
+ if (test_bit(F_WRITEFLUSH, &dev.flags)) {
+ clear_bit(F_WRITEFLUSH, &dev.flags);
+ wake_up_interruptible(&dev.writeflush);
+ }
+#else
if (test_and_clear_bit(F_WRITEFLUSH, &dev.flags))
wake_up_interruptible(&dev.writeflush);
+#endif
msnd_disable_irq(&dev);
}
@@ -759,7 +846,9 @@
case HIMT_DSP:
switch (LOBYTE(wMessage)) {
+#ifndef MSND_CLASSIC
case HIDSP_PLAY_UNDER:
+#endif
case HIDSP_INT_PLAY_UNDER:
printk(KERN_INFO LOGNAME ": Write underflow\n");
reset_play_queue();
@@ -858,9 +947,11 @@
__initfunc(static int probe_multisound(void))
{
+#ifndef MSND_CLASSIC
char *xv, *rev = NULL;
char *pin = "Pinnacle", *fiji = "Fiji";
char *pinfiji = "Pinnacle/Fiji";
+#endif
if (check_region(dev.io, dev.numio)) {
@@ -878,6 +969,10 @@
printk(KERN_INFO LOGNAME ": DSP reset successful\n");
+#ifdef MSND_CLASSIC
+ dev.name = "Classic/Tahiti/Monterey";
+ printk(KERN_INFO LOGNAME ": Turtle Beach %s, "
+#else
switch (dev.info >> 4) {
case 0xf: xv = "<= 1.15"; break;
case 0x1: xv = "1.18/1.2"; break;
@@ -899,11 +994,13 @@
dev.name = pinfiji;
break;
}
-
printk(KERN_INFO LOGNAME ": Turtle Beach %s revision %s, Xilinx version %s, "
+#endif /* MSND_CLASSIC */
"I/O 0x%x-0x%x, IRQ %d, memory mapped to 0x%p-0x%p\n",
dev.name,
+#ifndef MSND_CLASSIC
rev, xv,
+#endif
dev.io, dev.io + dev.numio - 1,
dev.irq,
dev.base, dev.base + 0x7fff);
@@ -918,6 +1015,9 @@
int n;
LPDAQD lpDAQ;
+#ifdef MSND_CLASSIC
+ outb(dev.memid, dev.io + HP_MEMM);
+#endif
outb(HPBLKSEL_0, dev.io + HP_BLKS);
memset_io(dev.base, 0, 0x8000);
@@ -1007,8 +1107,10 @@
writew(0, &dev.SMA->wCurrMastVolLeft);
writew(0, &dev.SMA->wCurrMastVolRight);
+#ifndef MSND_CLASSIC
writel(0x00010000, &dev.SMA->dwCurrPlayPitch);
writel(0x00000001, &dev.SMA->dwCurrPlayRate);
+#endif
writew(0x0000, &dev.SMA->wCurrDSPStatusFlags);
writew(0x0000, &dev.SMA->wCurrHostStatusFlags);
@@ -1023,10 +1125,12 @@
writeb(0, &dev.SMA->bAuxPotPosRight);
writeb(0, &dev.SMA->bAuxPotPosLeft);
+#ifndef MSND_CLASSIC
writew(1, &dev.SMA->wCurrPlayFormat);
writew(dev.sample_size, &dev.SMA->wCurrPlaySampleSize);
writew(dev.channels, &dev.SMA->wCurrPlayChannels);
writew(dev.sample_rate, &dev.SMA->wCurrPlaySampleRate);
+#endif
writew(dev.sample_rate, &dev.SMA->wCalFreqAtoD);
return 0;
@@ -1102,10 +1206,27 @@
return 0;
}
+#ifdef MSND_CLASSIC
+__initfunc(static void reset_proteus(void))
+{
+ outb(HPPRORESET_ON, dev.io + HP_PROR);
+ mdelay(TIME_PRO_RESET);
+ outb(HPPRORESET_OFF, dev.io + HP_PROR);
+ mdelay(TIME_PRO_RESET_DONE);
+}
+#endif
+
__initfunc(static int initialize(void))
{
int err, timeout;
+#ifdef MSND_CLASSIC
+ outb(HPWAITSTATE_0, dev.io + HP_WAIT);
+ outb(HPBITMODE_16, dev.io + HP_BITM);
+
+ reset_proteus();
+#endif
+
if ((err = init_sma()) < 0) {
printk(KERN_WARNING LOGNAME ": Cannot initialize SMA\n");
@@ -1229,14 +1350,24 @@
static int calibrate_signal __initdata;
int init_module(void)
+#else /* not a module */
+#ifdef MSND_CLASSIC
+static int io __initdata = CONFIG_MSNDCLAS_IO;
+static int irq __initdata = CONFIG_MSNDCLAS_IRQ;
+static int mem __initdata = CONFIG_MSNDCLAS_MEM;
#else
static int io __initdata = CONFIG_MSNDPIN_IO;
static int irq __initdata = CONFIG_MSNDPIN_IRQ;
static int mem __initdata = CONFIG_MSNDPIN_MEM;
+#endif
static int fifosize __initdata = DEFFIFOSIZE;
static int calibrate_signal __initdata;
+#ifdef MSND_CLASSIC
+__initfunc(int msnd_classic_init(void))
+#else
__initfunc(int msnd_pinnacle_init(void))
+#endif /* MSND_CLASSIC */
#endif
{
int err;
@@ -1288,13 +1419,37 @@
return -EINVAL;
}
+#ifdef MSND_CLASSIC
+ switch (irq) {
+ case 5: dev.irqid = HPIRQ_5; break;
+ case 7: dev.irqid = HPIRQ_7; break;
+ case 9: dev.irqid = HPIRQ_9; break;
+ case 10: dev.irqid = HPIRQ_10; break;
+ case 11: dev.irqid = HPIRQ_11; break;
+ case 12: dev.irqid = HPIRQ_12; break;
+ }
+
+ switch (mem) {
+ case 0xb0000: dev.memid = HPMEM_B000; break;
+ case 0xc8000: dev.memid = HPMEM_C800; break;
+ case 0xd0000: dev.memid = HPMEM_D000; break;
+ case 0xd8000: dev.memid = HPMEM_D800; break;
+ case 0xe0000: dev.memid = HPMEM_E000; break;
+ case 0xe8000: dev.memid = HPMEM_E800; break;
+ }
+#endif /* MSND_CLASSIC */
+
if (fifosize < 16)
fifosize = 16;
if (fifosize > 768)
fifosize = 768;
+#ifdef MSND_CLASSIC
+ dev.type = msndClassic;
+#else
dev.type = msndPinnacle;
+#endif
dev.io = io;
dev.numio = DSP_NUMIO;
dev.irq = irq;
@@ -1310,7 +1465,9 @@
init_waitqueue(&dev.writeflush);
msnd_fifo_init(&dev.DAPF);
msnd_fifo_init(&dev.DARF);
+#ifndef LINUX20
spin_lock_init(&dev.lock);
+#endif
printk(KERN_INFO LOGNAME ": Using %u byte digital audio FIFOs (x2)\n", dev.fifosize);
@@ -1349,7 +1506,6 @@
}
#ifdef MODULE
-
void cleanup_module(void)
{
printk(KERN_INFO LOGNAME ": Unloading\n");
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov