summaryrefslogtreecommitdiffstats
path: root/drivers/sound/soundcard.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/sound/soundcard.c')
-rw-r--r--drivers/sound/soundcard.c275
1 files changed, 27 insertions, 248 deletions
diff --git a/drivers/sound/soundcard.c b/drivers/sound/soundcard.c
index 81f9cdb19..00f8b6e7b 100644
--- a/drivers/sound/soundcard.c
+++ b/drivers/sound/soundcard.c
@@ -2,24 +2,24 @@
* linux/drivers/sound/soundcard.c
*
* Sound card driver for Linux
- */
-/*
+ *
+ *
* Copyright (C) by Hannu Savolainen 1993-1997
*
* 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.
- */
-/*
- * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
+ *
+ *
+ * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
* integrated sound_switch.c
- * Stefan Reinauer : integrated /proc/sound (equals to /dev/sndstat,
+ * Stefan Reinauer : integrated /proc/sound (equals to /dev/sndstat,
* which should disappear in the near future)
- * Eric Dumas : devfs support (22-Jan-98) <dumas@linux.eu.org> with fixups
- * by C. Scott Ananian <cananian@alumni.princeton.edu>
- * Richard Gooch : moved common (non OSS-specific) devices to sound_core.c
- *
- * Rob Riggs Added persistent DMA buffers support (1998/10/17)
+ * Eric Dumas : devfs support (22-Jan-98) <dumas@linux.eu.org> with
+ * fixups by C. Scott Ananian <cananian@alumni.princeton.edu>
+ * Richard Gooch : moved common (non OSS-specific) devices to sound_core.c
+ * Rob Riggs : Added persistent DMA buffers support (1998/10/17)
+ * Christoph Hellwig : Some cleanup work (2000/03/01)
*/
#include <linux/config.h>
@@ -32,7 +32,6 @@
#include <linux/ctype.h>
#include <linux/stddef.h>
#include <linux/kmod.h>
-#ifdef __KERNEL__
#include <asm/dma.h>
#include <asm/io.h>
#include <asm/segment.h>
@@ -41,24 +40,23 @@
#include <linux/ioport.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/major.h>
-#endif /* __KERNEL__ */
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/smp_lock.h>
#include "soundmodule.h"
+
+#if defined(CONFIG_LOWLEVEL_SOUND) && !defined MODULE
+extern void sound_preinit_lowlevel_drivers(void);
+extern void sound_init_lowlevel_drivers(void);
+#endif
+
/* From obsolete legacy.h */
#define SELECTED_SOUND_OPTIONS 0x0
struct notifier_block *sound_locker=(struct notifier_block *)0;
static int lock_depth = 0;
-#ifdef MODULE
-#define modular 1
-#else
-#define modular 0
-#endif
-
/*
* This ought to be moved into include/asm/dma.h
*/
@@ -76,16 +74,9 @@ caddr_t sound_mem_blocks[1024];
int sound_nblocks = 0;
/* Persistent DMA buffers */
-#ifdef CONFIG_SOUND_DMAP
-int sound_dmap_flag = 1;
-#else
int sound_dmap_flag = 0;
-#endif
-
static int soundcard_configured = 0;
-
-static char dma_alloc_map[MAX_DMA_CHANNELS] =
-{0};
+static char dma_alloc_map[MAX_DMA_CHANNELS] = {0};
#define DMA_MAP_UNAVAIL 0
#define DMA_MAP_FREE 1
@@ -101,6 +92,8 @@ unsigned long seq_time = 0; /* Time for /dev/sequencer */
static mixer_vol_table mixer_vols[MAX_MIXER_DEV];
static int num_mixer_volumes = 0;
+int traceinit = 0;
+
int *load_mixer_volumes(char *name, int *levels, int present)
{
int i, n;
@@ -159,137 +152,6 @@ static int get_mixer_levels(caddr_t arg)
return 0;
}
-static int sound_proc_get_info(char *buffer, char **start, off_t offset, int length)
-{
- int len, i, drv;
- off_t pos = 0;
- off_t begin = 0;
-
-#ifdef MODULE
-#define MODULEPROCSTRING "Driver loaded as a module"
-#else
-#define MODULEPROCSTRING "Driver compiled into kernel"
-#endif
-
- down_read(&uts_sem);
-
- len = sprintf(buffer, "OSS/Free:" SOUND_VERSION_STRING "\n"
- "Load type: " MODULEPROCSTRING "\n"
- "Kernel: %s %s %s %s %s\n"
- "Config options: %x\n\nInstalled drivers: \n",
- system_utsname.sysname, system_utsname.nodename, system_utsname.release,
- system_utsname.version, system_utsname.machine, SELECTED_SOUND_OPTIONS);
- up_read(&uts_sem);
-
- for (i = 0; (i < num_sound_drivers) && (pos <= offset + length); i++) {
- if (!sound_drivers[i].card_type)
- continue;
- len += sprintf(buffer + len, "Type %d: %s\n",
- sound_drivers[i].card_type, sound_drivers[i].name);
- pos = begin + len;
- if (pos < offset) {
- len = 0;
- begin = pos;
- }
- }
- len += sprintf(buffer + len, "\nCard config: \n");
-
- for (i = 0; (i < num_sound_cards) && (pos <= offset + length); i++)
- {
- if (!snd_installed_cards[i].card_type)
- continue;
- if (!snd_installed_cards[i].enabled)
- len += sprintf(buffer + len, "(");
- if ((drv = snd_find_driver(snd_installed_cards[i].card_type)) != -1)
- len += sprintf(buffer + len, "%s", sound_drivers[drv].name);
- if (snd_installed_cards[i].config.io_base)
- len += sprintf(buffer + len, " at 0x%x", snd_installed_cards[i].config.io_base);
- if (snd_installed_cards[i].config.irq != 0)
- len += sprintf(buffer + len, " irq %d", abs(snd_installed_cards[i].config.irq));
- if (snd_installed_cards[i].config.dma != -1) {
- len += sprintf(buffer + len, " drq %d", snd_installed_cards[i].config.dma);
- if (snd_installed_cards[i].config.dma2 != -1)
- len += sprintf(buffer + len, ",%d", snd_installed_cards[i].config.dma2);
- }
- if (!snd_installed_cards[i].enabled)
- len += sprintf(buffer + len, ")");
- len += sprintf(buffer + len, "\n");
- pos = begin + len;
- if (pos < offset) {
- len = 0;
- begin = pos;
- }
- }
- if (!sound_started)
- len += sprintf(buffer + len, "\n\n***** Sound driver not started *****\n\n");
- len += sprintf(buffer + len, "\nAudio devices:\n");
- for (i = 0; (i < num_audiodevs) && (pos <= offset + length); i++) {
- if (audio_devs[i] == NULL)
- continue;
- len += sprintf(buffer + len, "%d: %s%s\n", i, audio_devs[i]->name,
- audio_devs[i]->flags & DMA_DUPLEX ? " (DUPLEX)" : "");
- pos = begin + len;
- if (pos < offset) {
- len = 0;
- begin = pos;
- }
- }
-
- len += sprintf(buffer + len, "\nSynth devices:\n");
- for (i = 0; (i < num_synths) && (pos <= offset + length); i++) {
- if (synth_devs[i] == NULL)
- continue;
- len += sprintf(buffer + len, "%d: %s\n", i, synth_devs[i]->info->name);
- pos = begin + len;
- if (pos < offset) {
- len = 0;
- begin = pos;
- }
- }
-
- len += sprintf(buffer + len, "\nMidi devices:\n");
- for (i = 0; (i < num_midis) && (pos <= offset + length); i++) {
- if (midi_devs[i] == NULL)
- continue;
- len += sprintf(buffer + len, "%d: %s\n", i, midi_devs[i]->info.name);
- pos = begin + len;
- if (pos < offset) {
- len = 0;
- begin = pos;
- }
- }
-
- len += sprintf(buffer + len, "\nTimers:\n");
-
- for (i = 0; (i < num_sound_timers) && (pos <= offset + length); i++) {
- if (sound_timer_devs[i] == NULL)
- continue;
- len += sprintf(buffer + len, "%d: %s\n", i, sound_timer_devs[i]->info.name);
- pos = begin + len;
- if (pos < offset) {
- len = 0;
- begin = pos;
- }
- }
-
- len += sprintf(buffer + len, "\nMixers:\n");
- for (i = 0; (i < num_mixers) && (pos <= offset + length); i++) {
- if (mixer_devs[i] == NULL)
- continue;
- len += sprintf(buffer + len, "%d: %s\n", i, mixer_devs[i]->name);
- pos = begin + len;
- if (pos < offset) {
- len = 0;
- begin = pos;
- }
- }
- *start = buffer + (offset - begin);
- len -= (offset - begin);
- if (len > length)
- len = length;
- return len;
-}
-
#ifndef MIN
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
@@ -297,67 +159,6 @@ static int sound_proc_get_info(char *buffer, char **start, off_t offset, int len
/* 4K page size but our output routines use some slack for overruns */
#define PROC_BLOCK_SIZE (3*1024)
-/*
- * basically copied from fs/proc/generic.c:proc_file_read
- * should be removed sometime in the future together with /dev/sndstat
- * (a symlink /dev/sndstat -> /proc/sound will do as well)
- */
-static ssize_t sndstat_file_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
-{
- char *page;
- ssize_t retval=0;
- int eof=0;
- ssize_t n, count;
- char *start;
-
- if (!(page = (char*) __get_free_page(GFP_KERNEL)))
- return -ENOMEM;
-
- while ((nbytes > 0) && !eof)
- {
- count = MIN(PROC_BLOCK_SIZE, nbytes);
-
- start = NULL;
- n = sound_proc_get_info(page, &start, *ppos, count);
- if (n < count)
- eof = 1;
-
- if (!start) {
- /*
- * For proc files that are less than 4k
- */
- start = page + *ppos;
- n -= *ppos;
- if (n <= 0)
- break;
- if (n > count)
- n = count;
- }
- if (n == 0)
- break; /* End of file */
- if (n < 0) {
- if (retval == 0)
- retval = n;
- break;
- }
-
- n -= copy_to_user(buf, start, n); /* BUG ??? */
- if (n == 0) {
- if (retval == 0)
- retval = -EFAULT;
- break;
- }
-
- *ppos += n; /* Move down the file */
- nbytes -= n;
- buf += n;
- retval += n;
- }
- free_page((unsigned long) page);
- return retval;
-}
-
-
static ssize_t sound_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{
int dev = MINOR(file->f_dentry->d_inode->i_rdev);
@@ -373,10 +174,6 @@ static ssize_t sound_read(struct file *file, char *buf, size_t count, loff_t *pp
DEB(printk("sound_read(dev=%d, count=%d)\n", dev, count));
switch (dev & 0x0f) {
- case SND_DEV_STATUS:
- ret = sndstat_file_read(file, buf, count, ppos);
- break;
-
case SND_DEV_DSP:
case SND_DEV_DSP16:
case SND_DEV_AUDIO:
@@ -484,10 +281,8 @@ static int sound_open(struct inode *inode, struct file *file)
}
in_use++;
-#ifdef CONFIG_MODULES
notifier_call_chain(&sound_locker, 1, 0);
lock_depth++;
-#endif
return 0;
}
@@ -522,10 +317,8 @@ static int sound_release(struct inode *inode, struct file *file)
}
in_use--;
-#ifdef CONFIG_MODULES
notifier_call_chain(&sound_locker, 0, 0);
lock_depth--;
-#endif
return 0;
}
@@ -844,22 +637,13 @@ soundcard_init(void)
soundcard_configured = 1;
- sndtable_init(); /* Initialize call tables and detect cards */
-
-
-#ifdef FIXME
- if (sndtable_get_cardcount() == 0)
- return; /* No cards detected */
+#if defined(CONFIG_LOWLEVEL_SOUND) && !defined(MODULE)
+ sound_preinit_lowlevel_drivers();
+ sound_init_lowlevel_drivers();
#endif
- if (num_audiodevs || modular) /* Audio devices present */
- {
- audio_init_devices();
- }
-#ifdef CONFIG_PROC_FS
- if (!create_proc_info_entry("sound", 0, NULL, sound_proc_get_info))
- printk(KERN_ERR "sound: registering /proc/sound failed\n");
-#endif
+ audio_init_devices();
+
soundcard_register_devfs(1); /* register after we know # of devices */
}
@@ -876,7 +660,6 @@ static int sound[20] = {
0
};
-int traceinit = 0;
static int dmabuf = 0;
static int dmabug = 0;
@@ -892,8 +675,6 @@ int init_module(void)
int i;
#endif
- trace_init=traceinit;
-
#ifdef HAS_BRIDGE_BUGGY_FUNC
if(dmabug)
isa_dma_bridge_buggy = dmabug;
@@ -956,7 +737,6 @@ void cleanup_module(void)
sound_unload_lowlevel_drivers();
}
#endif
- sound_unload_drivers();
sequencer_unload();
for (i = 0; i < MAX_DMA_CHANNELS; i++)
@@ -1075,9 +855,8 @@ void sound_stop_timer(void)
void conf_printf(char *name, struct address_info *hw_config)
{
- if (!trace_init)
+ if (!traceinit)
return;
-
printk("<%s> at 0x%03x", name, hw_config->io_base);
if (hw_config->irq)
@@ -1094,7 +873,7 @@ void conf_printf(char *name, struct address_info *hw_config)
void conf_printf2(char *name, int base, int irq, int dma, int dma2)
{
- if (!trace_init)
+ if (!traceinit)
return;
printk("<%s> at 0x%03x", name, base);