patch-2.1.6 linux/drivers/sound/pss.c
Next file: linux/drivers/sound/sb.h
Previous file: linux/drivers/sound/patmgr.c
Back to the patch index
Back to the overall index
- Lines: 336
- Date:
Tue Oct 29 09:31:47 1996
- Orig file:
v2.1.5/linux/drivers/sound/pss.c
- Orig date:
Wed Oct 16 10:48:24 1996
diff -u --recursive --new-file v2.1.5/linux/drivers/sound/pss.c linux/drivers/sound/pss.c
@@ -6,7 +6,7 @@
/*
* Copyright (C) by Hannu Savolainen 1993-1996
*
- * USS/Lite for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
+ * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
*/
@@ -74,6 +74,31 @@
static int pss_initialized = 0;
static int nonstandard_microcode = 0;
+static void
+pss_write (int data)
+{
+ int i, limit;
+
+ limit = jiffies + 10; /* The timeout is 0.1 seconds */
+ /*
+ * Note! the i<5000000 is an emergency exit. The dsp_command() is sometimes
+ * called while interrupts are disabled. This means that the timer is
+ * disabled also. However the timeout situation is a abnormal condition.
+ * Normally the DSP should be ready to accept commands after just couple of
+ * loops.
+ */
+
+ for (i = 0; i < 5000000 && jiffies < limit; i++)
+ {
+ if (inw (devc->base + PSS_STATUS) & PSS_WRITE_EMPTY)
+ {
+ outw (devc->base + PSS_DATA, data);
+ return;
+ }
+ }
+ printk ("PSS: DSP Command (%04x) Timeout.\n", data);
+}
+
int
probe_pss (struct address_info *hw_config)
{
@@ -354,6 +379,22 @@
conf_printf (tmp, hw_config);
}
+static void
+pss_init_speaker (void)
+{
+/* Don't ask what are these commands. I really don't know */
+ pss_write (0x0010);
+ pss_write (0x0000 | 252); /* Left master volume */
+ pss_write (0x0010);
+ pss_write (0x0100 | 252); /* Right master volume */
+ pss_write (0x0010);
+ pss_write (0x0200 | 246); /* Bass */
+ pss_write (0x0010);
+ pss_write (0x0300 | 246); /* Treble */
+ pss_write (0x0010);
+ pss_write (0x0800 | 0x00ce); /* Stereo switch? */
+}
+
int
probe_pss_mpu (struct address_info *hw_config)
{
@@ -392,6 +433,8 @@
return 0;
}
+ pss_init_speaker ();
+
/*
* Finally wait until the DSP algorithm has initialized itself and
* deactivates receive interrupt.
@@ -422,14 +465,14 @@
if (pss_synthLen == 0)
{
printk ("PSS: MIDI synth microcode not available.\n");
- return -(EIO);
+ return -EIO;
}
if (nonstandard_microcode)
if (!pss_download_boot (devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST))
{
printk ("PSS: Unable to load MIDI synth microcode to DSP.\n");
- return -(EIO);
+ return -EIO;
}
nonstandard_microcode = 0;
break;
@@ -460,12 +503,12 @@
download_boot_block (void *dev_info, copr_buffer * buf)
{
if (buf->len <= 0 || buf->len > sizeof (buf->data))
- return -(EINVAL);
+ return -EINVAL;
if (!pss_download_boot (devc, buf->data, buf->len, buf->flags))
{
printk ("PSS: Unable to load microcode block to DSP.\n");
- return -(EIO);
+ return -EIO;
}
nonstandard_microcode = 1; /* The MIDI microcode has been overwritten */
@@ -491,7 +534,7 @@
buf = (copr_buffer *) vmalloc (sizeof (copr_buffer));
if (buf == NULL)
- return -(ENOSPC);
+ return -ENOSPC;
copy_from_user ((char *) buf, &((char *) arg)[0], sizeof (*buf));
err = download_boot_block (dev_info, buf);
@@ -509,7 +552,7 @@
buf = (copr_msg *) vmalloc (sizeof (copr_msg));
if (buf == NULL)
- return -(ENOSPC);
+ return -ENOSPC;
copy_from_user ((char *) buf, &((char *) arg)[0], sizeof (*buf));
@@ -524,9 +567,13 @@
{
restore_flags (flags);
buf->len = i; /* feed back number of WORDs sent */
- copy_to_user (&((char *) arg)[0], &buf, sizeof (buf));
+ {
+ char *fixit = (char *) buf;
+
+ copy_to_user (&((char *) arg)[0], fixit, sizeof (*buf));
+ };
vfree (buf);
- return -(EIO);
+ return -EIO;
}
}
@@ -548,7 +595,7 @@
buf = (copr_msg *) vmalloc (sizeof (copr_msg));
if (buf == NULL)
- return -(ENOSPC);
+ return -ENOSPC;
data = (unsigned short *) buf->data;
@@ -562,14 +609,18 @@
if (!pss_get_dspword (devc, data++))
{
if (i == 0)
- err = -(EIO);
+ err = -EIO;
break;
}
}
restore_flags (flags);
- copy_to_user (&((char *) arg)[0], &buf, sizeof (buf));
+ {
+ char *fixit = (char *) buf;
+
+ copy_to_user (&((char *) arg)[0], fixit, sizeof (*buf));
+ };
vfree (buf);
return err;
@@ -590,25 +641,29 @@
if (!pss_put_dspword (devc, 0x00d0))
{
restore_flags (flags);
- return -(EIO);
+ return -EIO;
}
if (!pss_put_dspword (devc, (unsigned short) (buf.parm1 & 0xffff)))
{
restore_flags (flags);
- return -(EIO);
+ return -EIO;
}
if (!pss_get_dspword (devc, &tmp))
{
restore_flags (flags);
- return -(EIO);
+ return -EIO;
}
buf.parm1 = tmp;
restore_flags (flags);
- copy_to_user (&((char *) arg)[0], &buf, sizeof (buf));
+ {
+ char *fixit = (char *) &buf;
+
+ copy_to_user (&((char *) arg)[0], fixit, sizeof (buf));
+ };
return 0;
}
break;
@@ -626,20 +681,20 @@
if (!pss_put_dspword (devc, 0x00d1))
{
restore_flags (flags);
- return -(EIO);
+ return -EIO;
}
if (!pss_put_dspword (devc, (unsigned short) (buf.parm1 & 0xffff)))
{
restore_flags (flags);
- return -(EIO);
+ return -EIO;
}
tmp = (unsigned int) buf.parm2 & 0xffff;
if (!pss_put_dspword (devc, tmp))
{
restore_flags (flags);
- return -(EIO);
+ return -EIO;
}
restore_flags (flags);
@@ -660,27 +715,27 @@
if (!pss_put_dspword (devc, 0x00d3))
{
restore_flags (flags);
- return -(EIO);
+ return -EIO;
}
if (!pss_put_dspword (devc, (unsigned short) (buf.parm1 & 0xffff)))
{
restore_flags (flags);
- return -(EIO);
+ return -EIO;
}
tmp = (unsigned int) buf.parm2 & 0x00ff;
if (!pss_put_dspword (devc, tmp))
{
restore_flags (flags);
- return -(EIO);
+ return -EIO;
}
tmp = ((unsigned int) buf.parm2 >> 8) & 0xffff;
if (!pss_put_dspword (devc, tmp))
{
restore_flags (flags);
- return -(EIO);
+ return -EIO;
}
restore_flags (flags);
@@ -701,19 +756,19 @@
if (!pss_put_dspword (devc, 0x00d2))
{
restore_flags (flags);
- return -(EIO);
+ return -EIO;
}
if (!pss_put_dspword (devc, (unsigned short) (buf.parm1 & 0xffff)))
{
restore_flags (flags);
- return -(EIO);
+ return -EIO;
}
if (!pss_get_dspword (devc, &tmp)) /* Read MSB */
{
restore_flags (flags);
- return -(EIO);
+ return -EIO;
}
buf.parm1 = tmp << 8;
@@ -721,23 +776,27 @@
if (!pss_get_dspword (devc, &tmp)) /* Read LSB */
{
restore_flags (flags);
- return -(EIO);
+ return -EIO;
}
buf.parm1 |= tmp & 0x00ff;
restore_flags (flags);
- copy_to_user (&((char *) arg)[0], &buf, sizeof (buf));
+ {
+ char *fixit = (char *) &buf;
+
+ copy_to_user (&((char *) arg)[0], fixit, sizeof (buf));
+ };
return 0;
}
break;
default:
- return -(EINVAL);
+ return -EINVAL;
}
- return -(EINVAL);
+ return -EINVAL;
}
static coproc_operations pss_coproc_operations =
@@ -769,7 +828,7 @@
int
probe_pss_mss (struct address_info *hw_config)
{
- int timeout;
+ volatile int timeout;
if (!pss_initialized)
return 0;
@@ -808,7 +867,11 @@
timeout < 100000 && (inb (hw_config->io_base + 3) & 0x3f) != 0x04;
timeout++);
- outb (0x0b, hw_config->io_base + 4); /* Required by some cards */
+ outb ((0x0b), hw_config->io_base + 4); /* Required by some cards */
+
+ for (timeout = 0;
+ timeout < 100000;
+ timeout++);
return probe_ms_sound (hw_config);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov