Commit 2a257ccb authored by Linus Torvalds's avatar Linus Torvalds

Merge http://linux-sound.bkbits.net/linux-sound

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 96b24143 671ffdc8
......@@ -748,7 +748,8 @@ Module parameters
Module snd-rme32
----------------
Module for RME Digi32, Digi32/8 and Digi32 PRO soundcards.
Module for RME Digi32, Digi32 Pro and Digi32/8 (Sek'd Prodif32,
Prodif96 and Prodif Gold) soundcards.
Module supports up to 8 cards.
......
......@@ -82,9 +82,15 @@ as you like and set the format S16LE. For example, for playback with
and use the interleaved 4 channel data.
There is a control switch, "Line-In As Bass". As you can imagine from
its name, the line-in jack is used for the bass (5th and 6th channels)
output.
There are some control switchs affecting to the speaker connections:
"Line-In As Rear" - As mentioned above, the line-in jack is used
for the rear (3th and 4th channels) output.
"Line-In As Bass" - The line-in jack is used for the bass (5th
and 6th channels) output.
"Mic As Center/LFE" - The mic jack is used for the bass output.
If this switch is on, you cannot use a microphone as a capture
source, of course.
Digital I/O
......@@ -134,8 +140,7 @@ Additionally there are relevant control switches:
(see the next section).
"IEC958 In Select" - Select SPDIF input, the internal CD-in (false)
and the external input (true). This switch appears only on
the chip models 039 or later.
and the external input (true).
"IEC958 Loop" - SPDIF input data is loop back into SPDIF
output (aka bypass)
......
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
<book>
<?dbhtml filename="index.html">
<!-- ****************************************************** -->
<!-- Header -->
<!-- ****************************************************** -->
<bookinfo>
<title>The ALSA Driver API</title>
<legalnotice>
<para>
This document is free; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
</para>
<para>
This document is distributed in the hope that it will be useful,
but <emphasis>WITHOUT ANY WARRANTY</emphasis>; without even the
implied warranty of <emphasis>MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE</emphasis>. See the GNU General Public License
for more details.
</para>
<para>
You should have received a copy of the GNU General Public
License along with this program; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA
</para>
</legalnotice>
</bookinfo>
<chapter><title>Management of Cards and Devices</title>
<sect1><title>Card Managment</title>
!Esound/core/init.c
</sect1>
<sect1><title>Device Components</title>
!Esound/core/device.c
</sect1>
<sect1><title>KMOD and Device File Entries</title>
!Esound/core/sound.c
</sect1>
<sect1><title>Memory Management Helpers</title>
!Esound/core/memory.c
!Iinclude/sound/sndmagic.h
</sect1>
</chapter>
<chapter><title>PCM API</title>
<sect1><title>PCM Core</title>
!Esound/core/pcm.c
!Esound/core/pcm_lib.c
!Esound/core/pcm_native.c
</sect1>
<sect1><title>PCM Format Helpers</title>
!Esound/core/pcm_misc.c
</sect1>
<sect1><title>PCM Memory Managment</title>
!Esound/core/pcm_memory.c
</sect1>
<sect1><title>SG-Buffer Helpers</title>
!Esound/core/pcm_sgbuf.c
</sect1>
</chapter>
<chapter><title>Control/Mixer API</title>
<sect1><title>General Control Interface</title>
!Esound/core/control.c
</sect1>
<sect1><title>AC97 Codec API</title>
!Esound/pci/ac97/ac97_codec.c
</sect1>
</chapter>
<chapter><title>MIDI API</title>
<sect1><title>Raw MIDI API</title>
!Esound/core/rawmidi.c
</sect1>
<sect1><title>MPU401-UART API</title>
!Esound/drivers/mpu401/mpu401_uart.c
</sect1>
</chapter>
<chapter><title>Proc Info API</title>
<sect1><title>Proc Info Interface</title>
!Esound/core/info.c
</sect1>
</chapter>
<chapter><title>Miscellaneous Functions</title>
<sect1><title>Hardware-Dependent Devices API</title>
!Esound/core/hwdep.c
</sect1>
<sect1><title>ISA DMA Helpers</title>
!Esound/core/isadma.c
</sect1>
<sect1><title>Other Helper Macros</title>
!Iinclude/sound/core.h
</sect1>
</chapter>
</book>
This diff is collapsed.
This diff is collapsed.
......@@ -196,6 +196,8 @@
#define AC97_CXR_SPDIF_AC3 0x2
/* specific - ALC */
#define AC97_ALC650_SURR_DAC_VOL 0x64
#define AC97_ALC650_LFE_DAC_VOL 0x66
#define AC97_ALC650_MULTICH 0x6a
#define AC97_ALC650_CLOCK 0x7a
......@@ -235,8 +237,6 @@ struct _snd_ac97 {
unsigned short (*read) (ac97_t *ac97, unsigned short reg);
void (*wait) (ac97_t *ac97);
void (*init) (ac97_t *ac97);
snd_info_entry_t *proc_entry;
snd_info_entry_t *proc_regs_entry;
void *private_data;
void (*private_free) (ac97_t *ac97);
/* --- */
......
......@@ -22,7 +22,6 @@
*
*/
#include "control.h"
#include "pcm.h"
/* IO ports */
......@@ -162,28 +161,44 @@ int snd_ad1848_create(snd_card_t * card,
ad1848_t ** chip);
int snd_ad1848_pcm(ad1848_t * chip, int device, snd_pcm_t **rpcm);
const snd_pcm_ops_t *snd_ad1848_get_pcm_ops(int direction);
int snd_ad1848_mixer(ad1848_t * chip);
void snd_ad1848_interrupt(int irq, void *dev_id, struct pt_regs *regs);
#define AD1848_SINGLE(xname, xindex, reg, shift, mask, invert) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
.info = snd_ad1848_info_single, \
.get = snd_ad1848_get_single, .put = snd_ad1848_put_single, \
.private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
/* exported mixer stuffs */
enum { AD1848_MIX_SINGLE, AD1848_MIX_DOUBLE, AD1848_MIX_CAPTURE };
#define AD1848_MIXVAL_SINGLE(reg, shift, mask, invert) \
((reg) | ((shift) << 8) | ((mask) << 16) | ((invert) << 24))
#define AD1848_MIXVAL_DOUBLE(left_reg, right_reg, shift_left, shift_right, mask, invert) \
((left_reg) | ((right_reg) << 8) | ((shift_left) << 16) | ((shift_right) << 19) | ((mask) << 24) | ((invert) << 22))
int snd_ad1848_add_ctl(ad1848_t *chip, const char *name, int index, int type, unsigned long value);
int snd_ad1848_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo);
int snd_ad1848_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
int snd_ad1848_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
/* for ease of use */
struct ad1848_mix_elem {
const char *name;
int index;
int type;
unsigned long private_value;
};
#define AD1848_SINGLE(xname, xindex, reg, shift, mask, invert) \
{ .name = xname, \
.index = xindex, \
.type = AD1848_MIX_SINGLE, \
.private_value = AD1848_MIXVAL_SINGLE(reg, shift, mask, invert) }
#define AD1848_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
.info = snd_ad1848_info_double, \
.get = snd_ad1848_get_double, .put = snd_ad1848_put_double, \
.private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
int snd_ad1848_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo);
int snd_ad1848_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
int snd_ad1848_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
{ .name = xname, \
.index = xindex, \
.type = AD1848_MIX_DOUBLE, \
.private_value = AD1848_MIXVAL_DOUBLE(left_reg, right_reg, shift_left, shift_right, mask, invert) }
static inline int snd_ad1848_add_ctl_elem(ad1848_t *chip, const struct ad1848_mix_elem *c)
{
return snd_ad1848_add_ctl(chip, c->name, c->index, c->type, c->private_value);
}
#ifdef CONFIG_SND_DEBUG
void snd_ad1848_debug(ad1848_t *chip);
......
......@@ -68,7 +68,6 @@ typedef struct _snd_ak4531 ak4531_t;
struct _snd_ak4531 {
void (*write) (ak4531_t *ak4531, unsigned short reg, unsigned short val);
snd_info_entry_t *proc_entry;
void *private_data;
void (*private_free) (ak4531_t *ak4531);
/* --- */
......
......@@ -55,6 +55,7 @@ typedef enum {
SNDRV_DEV_TIMER,
SNDRV_DEV_SEQUENCER,
SNDRV_DEV_HWDEP,
SNDRV_DEV_INFO,
SNDRV_DEV_LOWLEVEL = (2*SNDRV_DEV_TYPE_RANGE_SIZE)
} snd_device_type_t;
......@@ -281,6 +282,8 @@ void snd_free_pages(void *ptr, unsigned long size);
void *snd_malloc_pci_pages(struct pci_dev *pci, unsigned long size, dma_addr_t *dma_addr);
void *snd_malloc_pci_pages_fallback(struct pci_dev *pci, unsigned long size, dma_addr_t *dma_addr, unsigned long *res_size);
void snd_free_pci_pages(struct pci_dev *pci, unsigned long size, void *ptr, dma_addr_t dma_addr);
void *snd_malloc_pci_page(struct pci_dev *pci, dma_addr_t *dma_addr);
#define snd_free_pci_page(pci,ptr,addr) snd_free_pci_pages(pci,PAGE_SIZE,ptr,addr)
#endif
#ifdef CONFIG_SBUS
void *snd_malloc_sbus_pages(struct sbus_dev *sdev, unsigned long size, dma_addr_t *dma_addr);
......@@ -354,13 +357,17 @@ void snd_verbose_printk(const char *file, int line, const char *format, ...);
#if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_VERBOSE_PRINTK)
void snd_verbose_printd(const char *file, int line, const char *format, ...);
#endif
#if defined(CONFIG_SND_DEBUG) && !defined(CONFIG_SND_VERBOSE_PRINTK)
void snd_printd(const char *format, ...);
#endif
/* --- */
#ifdef CONFIG_SND_VERBOSE_PRINTK
/**
* snd_printk - printk wrapper
* @fmt: format string
*
* Works like print() but prints the file and the line of the caller
* when configured with CONFIG_SND_VERBOSE_PRINTK.
*/
#define snd_printk(fmt, args...) \
snd_verbose_printk(__FILE__, __LINE__, fmt ,##args)
#else
......@@ -373,15 +380,45 @@ void snd_printd(const char *format, ...);
#define __ASTRING__(x) #x
#ifdef CONFIG_SND_VERBOSE_PRINTK
/**
* snd_printd - debug printk
* @format: format string
*
* Compiled only when Works like snd_printk() for debugging purpose.
* Ignored when CONFIG_SND_DEBUG is not set.
*/
#define snd_printd(fmt, args...) \
snd_verbose_printd(__FILE__, __LINE__, fmt ,##args)
#else
#define snd_printd(fmt, args...) \
printk(fmt ,##args)
#endif
/**
* snd_assert - run-time assersion macro
* @expr: expression
* @args...: the action
*
* This macro checks the expression in run-time and invokes the commands
* given in the rest arguments if the assertion is failed.
* When CONFIG_SND_DEBUG is not set, the expression is executed but
* not checked.
*/
#define snd_assert(expr, args...) do {\
if (!(expr)) {\
snd_printk("BUG? (%s) (called from %p)\n", __ASTRING__(expr), __builtin_return_address(0));\
args;\
}\
} while (0)
/**
* snd_runtime_check - run-time assersion macro
* @expr: expression
* @args...: the action
*
* This macro checks the expression in run-time and invokes the commands
* given in the rest arguments if the assertion is failed.
* Unlike snd_assert(), the action commands are executed even if
* CONFIG_SND_DEBUG is not set but without any error messages.
*/
#define snd_runtime_check(expr, args...) do {\
if (!(expr)) {\
snd_printk("ERROR (%s) (called from %p)\n", __ASTRING__(expr), __builtin_return_address(0));\
......@@ -398,6 +435,13 @@ void snd_printd(const char *format, ...);
#endif /* CONFIG_SND_DEBUG */
#ifdef CONFIG_SND_DEBUG_DETECT
/**
* snd_printdd - debug printk
* @format: format string
*
* Compiled only when Works like snd_printk() for debugging purpose.
* Ignored when CONFIG_SND_DEBUG_DETECT is not set.
*/
#define snd_printdd(format, args...) snd_printk(format, ##args)
#else
#define snd_printdd(format, args...) /* nothing */
......
......@@ -1673,7 +1673,6 @@ typedef struct {
unsigned long remap_addr;
unsigned long size;
struct resource *resource;
void *proc_entry;
} snd_cs46xx_region_t;
struct _snd_cs46xx {
......@@ -1726,7 +1725,6 @@ struct _snd_cs46xx {
spinlock_t reg_lock;
unsigned int midcr;
unsigned int uartm;
snd_info_entry_t *proc_entry;
int amplifier;
void (*amplifier_ctrl)(cs46xx_t *, int);
......
......@@ -25,12 +25,11 @@
#ifdef __KERNEL__
#include "pcm.h"
#include "pcm_sgbuf.h"
#include "rawmidi.h"
#include "hwdep.h"
#include "ac97_codec.h"
#include "util_mem.h"
#include <sound/pcm.h>
#include <sound/rawmidi.h>
#include <sound/hwdep.h>
#include <sound/ac97_codec.h>
#include <sound/util_mem.h>
#include <asm/io.h>
#ifndef PCI_VENDOR_ID_CREATIVE
......@@ -232,7 +231,7 @@
#define A_IOCFG 0x18 /* GPIO on Audigy card (16bits) */
#define A_GPINPUT_MASK 0xff00
#define A_GPOUTPUT_MASK 0x00ff
#define A_IOCFG_GPOUT0 0x0040 /* analog/digital? */
#define A_IOCFG_GPOUT0 0x0044 /* analog/digital? */
#define TIMER 0x1a /* Timer terminal count register */
/* NOTE: After the rate is changed, a maximum */
......@@ -993,13 +992,6 @@ struct _snd_emu10k1 {
emu10k1_midi_t midi2; /* for audigy */
unsigned int efx_voices_mask[2];
snd_info_entry_t *proc_entry;
snd_info_entry_t *proc_entry_fx8010_gpr;
snd_info_entry_t *proc_entry_fx8010_tram_data;
snd_info_entry_t *proc_entry_fx8010_tram_addr;
snd_info_entry_t *proc_entry_fx8010_code;
snd_info_entry_t *proc_entry_fx8010_iblocks;
};
int snd_emu10k1_create(snd_card_t * card,
......@@ -1045,7 +1037,7 @@ unsigned int snd_emu10k1_rate_to_pitch(unsigned int rate);
unsigned char snd_emu10k1_sum_vol_attn(unsigned int value);
/* memory allocation */
snd_util_memblk_t *snd_emu10k1_alloc_pages(emu10k1_t *emu, struct snd_sg_buf *sgbuf);
snd_util_memblk_t *snd_emu10k1_alloc_pages(emu10k1_t *emu, snd_pcm_substream_t *substream);
int snd_emu10k1_free_pages(emu10k1_t *emu, snd_util_memblk_t *blk);
snd_util_memblk_t *snd_emu10k1_synth_alloc(emu10k1_t *emu, unsigned int size);
int snd_emu10k1_synth_free(emu10k1_t *emu, snd_util_memblk_t *blk);
......@@ -1063,7 +1055,6 @@ int snd_emu10k1_audigy_midi(emu10k1_t * emu);
/* proc interface */
int snd_emu10k1_proc_init(emu10k1_t * emu);
int snd_emu10k1_proc_done(emu10k1_t * emu);
#endif /* __KERNEL__ */
......
......@@ -210,7 +210,6 @@ typedef struct _snd_gf1_mem {
snd_gf1_bank_info_t banks_16[4];
snd_gf1_mem_block_t *first;
snd_gf1_mem_block_t *last;
snd_info_entry_t *info_entry;
struct semaphore memory_mutex;
} snd_gf1_mem_t;
......@@ -332,8 +331,6 @@ struct _snd_gf1 {
unsigned int rom_banks; /* GUS's ROM banks */
snd_gf1_mem_t mem_alloc;
snd_info_entry_t *ram_entries[4];
snd_info_entry_t *rom_entries[4];
/* registers */
unsigned short reg_page;
......@@ -452,9 +449,6 @@ struct _snd_gus_card {
int timer_dev; /* timer device */
struct _snd_gf1 gf1; /* gf1 specific variables */
#ifdef CONFIG_SND_DEBUG
snd_info_entry_t *irq_entry;
#endif
snd_pcm_t *pcm;
snd_pcm_substream_t *pcm_cap_substream;
unsigned int c_dma_size;
......@@ -601,7 +595,6 @@ int snd_gf1_mem_done(snd_gus_card_t * gus);
/* gus_mem_proc.c */
int snd_gf1_mem_proc_init(snd_gus_card_t * gus);
int snd_gf1_mem_proc_done(snd_gus_card_t * gus);
/* gus_dma.c */
......@@ -676,7 +669,6 @@ int snd_gus_initialize(snd_gus_card_t * gus);
void snd_gus_interrupt(int irq, void *dev_id, struct pt_regs *regs);
#ifdef CONFIG_SND_DEBUG
void snd_gus_irq_profile_init(snd_gus_card_t *gus);
void snd_gus_irq_profile_done(snd_gus_card_t *gus);
#endif
/* gus_uart.c */
......
......@@ -141,6 +141,19 @@ struct proc_dir_entry *snd_create_proc_entry(const char *name, mode_t mode,
void snd_remove_proc_entry(struct proc_dir_entry *parent,
struct proc_dir_entry *de);
/* for card drivers */
int snd_card_proc_new(snd_card_t *card, const char *name, snd_info_entry_t **entryp);
inline static void snd_info_set_text_ops(snd_info_entry_t *entry,
void *private_data,
void (*read)(snd_info_entry_t *, snd_info_buffer_t *))
{
entry->private_data = private_data;
entry->c.text.read_size = 1024;
entry->c.text.read = read;
}
#else
#define snd_seq_root NULL
......@@ -160,8 +173,9 @@ static inline snd_info_entry_t *snd_info_create_device(const char *name,
unsigned int mode) { return NULL; }
static inline void snd_info_free_device(snd_info_entry_t * entry) { ; }
static inline int snd_info_card_create(snd_card_t * card) { return 0; }
static inline int snd_info_card_register(snd_card_t * card) { return 0; }
static inline int snd_info_card_unregister(snd_card_t * card) { return 0; }
static inline int snd_info_card_free(snd_card_t * card) { return 0; }
static inline int snd_info_register(snd_info_entry_t * entry) { return 0; }
static inline int snd_info_unregister(snd_info_entry_t * entry) { return 0; }
......@@ -169,6 +183,9 @@ static inline struct proc_dir_entry *snd_create_proc_entry(const char *name, mod
static inline void snd_remove_proc_entry(struct proc_dir_entry *parent,
struct proc_dir_entry *de) { ; }
#define snd_card_proc_new(card,name,entryp) 0 /* always success */
#define snd_info_set_text_ops(entry,private_data,read) /*NOP*/
#endif
/*
......
......@@ -50,7 +50,7 @@ typedef struct sndrv_pcm_mmap_status snd_pcm_mmap_status_t;
typedef struct sndrv_pcm_mmap_control snd_pcm_mmap_control_t;
typedef struct sndrv_mask snd_mask_t;
#define _snd_pcm_substream_chip(substream) ((substream)->pcm->private_data)
#define _snd_pcm_substream_chip(substream) ((substream)->private_data)
#define snd_pcm_substream_chip(substream) snd_magic_cast1(chip_t, _snd_pcm_substream_chip(substream), return -ENXIO)
#define _snd_pcm_chip(pcm) ((pcm)->private_data)
#define snd_pcm_chip(pcm) snd_magic_cast1(chip_t, _snd_pcm_chip(pcm), return -ENXIO)
......@@ -120,10 +120,12 @@ typedef struct _snd_pcm_ops {
#define SNDRV_PCM_TRIGGER_SUSPEND 5
#define SNDRV_PCM_TRIGGER_RESUME 6
#define SNDRV_PCM_DMA_TYPE_CONTINUOUS 0 /* continuous no-DMA memory */
#define SNDRV_PCM_DMA_TYPE_ISA 1 /* ISA continuous */
#define SNDRV_PCM_DMA_TYPE_PCI 2 /* PCI continuous */
#define SNDRV_PCM_DMA_TYPE_SBUS 3 /* SBUS continuous */
#define SNDRV_PCM_DMA_TYPE_UNKNOWN 0 /* not defined */
#define SNDRV_PCM_DMA_TYPE_CONTINUOUS 1 /* continuous no-DMA memory */
#define SNDRV_PCM_DMA_TYPE_ISA 2 /* ISA continuous */
#define SNDRV_PCM_DMA_TYPE_PCI 3 /* PCI continuous */
#define SNDRV_PCM_DMA_TYPE_SBUS 4 /* SBUS continuous */
#define SNDRV_PCM_DMA_TYPE_PCI_SG 5 /* PCI SG-buffer */
/* If you change this don't forget to change rates[] table in pcm_native.c */
#define SNDRV_PCM_RATE_5512 (1<<0) /* 5512Hz */
......@@ -363,6 +365,7 @@ struct _snd_pcm_runtime {
struct _snd_pcm_substream {
snd_pcm_t *pcm;
snd_pcm_str_t *pstr;
void *private_data; /* copied from pcm->private_data */
int number;
char name[32]; /* substream name */
int stream; /* stream (direction) */
......@@ -741,6 +744,10 @@ int snd_pcm_hw_param_near(snd_pcm_substream_t *substream,
snd_pcm_hw_params_t *params,
snd_pcm_hw_param_t var,
unsigned int val, int *dir);
int snd_pcm_hw_param_set(snd_pcm_substream_t *pcm,
snd_pcm_hw_params_t *params,
snd_pcm_hw_param_t var,
unsigned int val, int dir);
int snd_pcm_hw_params_choose(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *params);
int snd_pcm_hw_refine(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *params);
......
......@@ -32,6 +32,7 @@ struct snd_sg_buf {
int pages; /* allocated pages */
int tblsize; /* allocated table size */
struct snd_sg_page *table;
struct page **page_table;
struct pci_dev *pci;
};
......@@ -53,15 +54,17 @@ static inline dma_addr_t snd_pcm_sgbuf_get_addr(struct snd_sg_buf *sgbuf, size_t
return sgbuf->table[offset >> PAGE_SHIFT].addr + offset % PAGE_SIZE;
}
int snd_pcm_sgbuf_init(snd_pcm_substream_t *substream, struct pci_dev *pci, int tblsize);
int snd_pcm_sgbuf_delete(snd_pcm_substream_t *substream);
int snd_pcm_sgbuf_alloc(snd_pcm_substream_t *substream, size_t size);
int snd_pcm_sgbuf_free(snd_pcm_substream_t *substream);
struct snd_sg_buf *snd_pcm_sgbuf_init(struct pci_dev *pci);
void snd_pcm_sgbuf_delete(struct snd_sg_buf *sgbuf);
void *snd_pcm_sgbuf_alloc_pages(struct snd_sg_buf *sgbuf, size_t size);
int snd_pcm_sgbuf_free_pages(struct snd_sg_buf *sgbuf, void *vmaddr);
int snd_pcm_sgbuf_ops_copy_playback(snd_pcm_substream_t *substream, int channel, snd_pcm_uframes_t hwoff, void *buf, snd_pcm_uframes_t count);
int snd_pcm_sgbuf_ops_copy_capture(snd_pcm_substream_t *substream, int channel, snd_pcm_uframes_t hwoff, void *buf, snd_pcm_uframes_t count);
int snd_pcm_sgbuf_ops_silence(snd_pcm_substream_t *substream, int channel, snd_pcm_uframes_t hwoff, snd_pcm_uframes_t count);
struct page *snd_pcm_sgbuf_ops_page(snd_pcm_substream_t *substream, unsigned long offset);
int snd_pcm_lib_preallocate_sg_pages(struct pci_dev *pci, snd_pcm_substream_t *substream);
int snd_pcm_lib_preallocate_sg_pages_for_all(struct pci_dev *pci, snd_pcm_t *pcm);
#define _snd_pcm_substream_sgbuf(substream) ((substream)->dma_private)
#define snd_pcm_substream_sgbuf(substream) snd_magic_cast(snd_pcm_sgbuf_t, _snd_pcm_substream_sgbuf(substream), return -ENXIO)
struct page *snd_pcm_sgbuf_ops_page(snd_pcm_substream_t *substream, unsigned long offset);
#endif /* __SOUND_PCM_SGBUF_H */
......@@ -305,6 +305,7 @@ int snd_sb8dsp_midi(sb_t *chip, int device, snd_rawmidi_t ** rrawmidi);
/* sb16_init.c */
int snd_sb16dsp_pcm(sb_t *chip, int device, snd_pcm_t ** rpcm);
const snd_pcm_ops_t *snd_sb16dsp_get_pcm_ops(int direction);
int snd_sb16dsp_configure(sb_t *chip);
/* sb16.c */
void snd_sb16dsp_interrupt(int irq, void *dev_id, struct pt_regs *regs);
......@@ -313,4 +314,49 @@ int snd_sb16_capture_open(snd_pcm_substream_t *substream);
int snd_sb16_playback_close(snd_pcm_substream_t *substream);
int snd_sb16_capture_close(snd_pcm_substream_t *substream);
/* exported mixer stuffs */
enum {
SB_MIX_SINGLE,
SB_MIX_DOUBLE,
SB_MIX_INPUT_SW,
SB_MIX_CAPTURE_PRO,
SB_MIX_CAPTURE_DT019X
};
#define SB_MIXVAL_DOUBLE(left_reg, right_reg, left_shift, right_shift, mask) \
((left_reg) | ((right_reg) << 8) | ((left_shift) << 16) | ((right_shift) << 19) | ((mask) << 24))
#define SB_MIXVAL_SINGLE(reg, shift, mask) \
((reg) | ((shift) << 16) | ((mask) << 24))
#define SB_MIXVAL_INPUT_SW(reg1, reg2, left_shift, right_shift) \
((reg1) | ((reg2) << 8) | ((left_shift) << 16) | ((right_shift) << 24))
int snd_sbmixer_add_ctl(sb_t *chip, const char *name, int index, int type, unsigned long value);
/* for ease of use */
struct sbmix_elem {
const char *name;
int type;
unsigned long private_value;
};
#define SB_SINGLE(xname, reg, shift, mask) \
{ .name = xname, \
.type = SB_MIX_SINGLE, \
.private_value = SB_MIXVAL_SINGLE(reg, shift, mask) }
#define SB_DOUBLE(xname, left_reg, right_reg, left_shift, right_shift, mask) \
{ .name = xname, \
.type = SB_MIX_DOUBLE, \
.private_value = SB_MIXVAL_DOUBLE(left_reg, right_reg, left_shift, right_shift, mask) }
#define SB16_INPUT_SW(xname, reg1, reg2, left_shift, right_shift) \
{ .name = xname, \
.type = SB_MIX_INPUT_SW, \
.private_value = SB_MIXVAL_INPUT_SW(reg1, reg2, left_shift, right_shift) }
static inline int snd_sbmixer_add_ctl_elem(sb_t *chip, const struct sbmix_elem *c)
{
return snd_sbmixer_add_ctl(chip, c->name, 0, c->type, c->private_value);
}
#endif /* __SOUND_SB_H */
......@@ -159,7 +159,6 @@ struct snd_sb_csp {
snd_kcontrol_t *qsound_space;
struct semaphore access_mutex; /* locking */
snd_info_entry_t *proc; /* proc interface */
};
int snd_sb_csp_new(sb_t *chip, int device, snd_hwdep_t ** rhwdep);
......
......@@ -27,10 +27,45 @@
void *_snd_magic_kcalloc(unsigned long magic, size_t size, int flags);
void *_snd_magic_kmalloc(unsigned long magic, size_t size, int flags);
void snd_magic_kfree(void *ptr);
#define snd_magic_kcalloc(type, extra, flags) (type *) _snd_magic_kcalloc(type##_magic, sizeof(type) + extra, flags)
#define snd_magic_kmalloc(type, extra, flags) (type *) _snd_magic_kmalloc(type##_magic, sizeof(type) + extra, flags)
/**
* snd_magic_kmalloc - allocate a record with a magic-prefix
* @type: the type to allocate a record (like xxx_t)
* @extra: the extra size to allocate in bytes
* @flags: the allocation condition (GFP_XXX)
*
* Allocates a record of the given type with the extra space and
* returns its pointer. The allocated record has a secret magic-key
* to be checked via snd_magic_cast() for safe casts.
*
* The allocated pointer must be released via snd_magic_kfree().
*
* The "struct xxx" style cannot be used as the type argument
* because the magic-key constant is generated from the type-name
* string.
*/
#define snd_magic_kmalloc(type, extra, flags) \
(type *) _snd_magic_kmalloc(type##_magic, sizeof(type) + extra, flags)
/**
* snd_magic_kcalloc - allocate a record with a magic-prefix and initialize
* @type: the type to allocate a record (like xxx_t)
* @extra: the extra size to allocate in bytes
* @flags: the allocation condition (GFP_XXX)
*
* Works like snd_magic_kmalloc() but this clears the area with zero
* automatically.
*/
#define snd_magic_kcalloc(type, extra, flags) \
(type *) _snd_magic_kcalloc(type##_magic, sizeof(type) + extra, flags)
/**
* snd_magic_kfree - release the allocated area
* @ptr: the pointer allocated via snd_magic_kmalloc() or snd_magic_kcalloc()
*
* Releases the memory area allocated via snd_magic_kmalloc() or
* snd_magic_kcalloc() function.
*/
void snd_magic_kfree(void *ptr);
static inline unsigned long _snd_magic_value(void *obj)
{
......@@ -44,7 +79,19 @@ static inline int _snd_magic_bad(void *obj, unsigned long magic)
#define snd_magic_cast1(t, expr, cmd) snd_magic_cast(t, expr, cmd)
#define snd_magic_cast(type, ptr, action...) (type *) ({\
/**
* snd_magic_cast - check and cast the magic-allocated pointer
* @type: the type of record to cast
* @ptr: the magic-allocated pointer
* @action...: the action to do if failed
*
* This macro provides a safe cast for the given type, which was
* allocated via snd_magic_kmalloc() or snd_magic_kcallc().
* If the pointer is invalid, i.e. the cast-type doesn't match,
* the action arguments are called with a debug message.
*/
#define snd_magic_cast(type, ptr, action...) \
(type *) ({\
void *__ptr = ptr;\
unsigned long __magic = _snd_magic_value(__ptr);\
if (__magic != type##_magic) {\
......@@ -64,6 +111,7 @@ static inline int _snd_magic_bad(void *obj, unsigned long magic)
#define snd_pcm_sgbuf_t_magic 0xa15a0107
#define snd_info_private_data_t_magic 0xa15a0201
#define snd_info_entry_t_magic 0xa15a0202
#define snd_ctl_file_t_magic 0xa15a0301
#define snd_kcontrol_t_magic 0xa15a0302
#define snd_rawmidi_t_magic 0xa15a0401
......
......@@ -431,7 +431,8 @@ struct _snd_trident {
int ChanPCM; /* max number of PCM channels */
int ChanPCMcnt; /* actual number of PCM channels */
int ac97_detect; /* 1 = AC97 in detection phase */
unsigned int ac97_detect: 1; /* 1 = AC97 in detection phase */
unsigned int in_suspend: 1; /* 1 during suspend/resume */
struct _snd_4dwave synth; /* synth specific variables */
......@@ -452,7 +453,6 @@ struct _snd_trident {
snd_trident_pcm_mixer_t pcm_mixer[32];
spinlock_t reg_lock;
snd_info_entry_t *proc_entry;
struct snd_trident_gameport *gameport;
};
......@@ -479,7 +479,7 @@ void snd_trident_write_voice_regs(trident_t * trident, snd_trident_voice_t *voic
void snd_trident_clear_voices(trident_t * trident, unsigned short v_min, unsigned short v_max);
/* TLB memory allocation */
snd_util_memblk_t *snd_trident_alloc_pages(trident_t *trident, void *pages, dma_addr_t addr, unsigned long size);
snd_util_memblk_t *snd_trident_alloc_pages(trident_t *trident, snd_pcm_substream_t *substream);
int snd_trident_free_pages(trident_t *trident, snd_util_memblk_t *blk);
snd_util_memblk_t *snd_trident_synth_alloc(trident_t *trident, unsigned int size);
int snd_trident_synth_free(trident_t *trident, snd_util_memblk_t *blk);
......
/* include/version.h. Generated automatically by configure. */
#define CONFIG_SND_VERSION "0.9.0rc6"
#define CONFIG_SND_DATE " (Tue Dec 17 19:01:13 2002 UTC)"
#define CONFIG_SND_DATE " (Tue Jan 28 12:17:23 2003 UTC)"
......@@ -48,9 +48,6 @@ static int snd_ctl_open(struct inode *inode, struct file *file)
snd_ctl_file_t *ctl;
int err;
#ifdef LINUX_2_2
MOD_INC_USE_COUNT;
#endif
card = snd_cards[cardnum];
if (!card) {
err = -ENODEV;
......@@ -86,9 +83,6 @@ static int snd_ctl_open(struct inode *inode, struct file *file)
__error2:
snd_card_file_remove(card, file);
__error1:
#ifdef LINUX_2_2
MOD_DEC_USE_COUNT;
#endif
return err;
}
......@@ -131,9 +125,6 @@ static int snd_ctl_release(struct inode *inode, struct file *file)
snd_magic_kfree(ctl);
module_put(card->module);
snd_card_file_remove(card, file);
#ifdef LINUX_2_2
MOD_DEC_USE_COUNT;
#endif
return 0;
}
......@@ -178,6 +169,15 @@ void snd_ctl_notify(snd_card_t *card, unsigned int mask, snd_ctl_elem_id_t *id)
read_unlock(&card->ctl_files_rwlock);
}
/**
* snd_ctl_new - create a control instance from the template
* @control: the control template
*
* Allocates a new snd_kcontrol_t instance and copies the given template
* to the new instance.
*
* Returns the pointer of the new instance, or NULL on failure.
*/
snd_kcontrol_t *snd_ctl_new(snd_kcontrol_t * control)
{
snd_kcontrol_t *kctl;
......@@ -190,6 +190,17 @@ snd_kcontrol_t *snd_ctl_new(snd_kcontrol_t * control)
return kctl;
}
/**
* snd_ctl_new1 - create a control instance from the template
* @ncontrol: the initialization record
* @private_data: the private data to set
*
* Allocates a new snd_kcontrol_t instance and initialize from the given
* template. When the access field of ncontrol is 0, it's assumed as
* READWRITE access.
*
* Returns the pointer of the newly generated instance, or NULL on failure.
*/
snd_kcontrol_t *snd_ctl_new1(snd_kcontrol_new_t * ncontrol, void *private_data)
{
snd_kcontrol_t kctl;
......@@ -200,6 +211,7 @@ snd_kcontrol_t *snd_ctl_new1(snd_kcontrol_new_t * ncontrol, void *private_data)
kctl.id.iface = ncontrol->iface;
kctl.id.device = ncontrol->device;
kctl.id.subdevice = ncontrol->subdevice;
if (ncontrol->name)
strncpy(kctl.id.name, ncontrol->name, sizeof(kctl.id.name)-1);
kctl.id.index = ncontrol->index;
kctl.access = ncontrol->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
......@@ -212,6 +224,14 @@ snd_kcontrol_t *snd_ctl_new1(snd_kcontrol_new_t * ncontrol, void *private_data)
return snd_ctl_new(&kctl);
}
/**
* snd_ctl_free_one - release the control instance
* @kcontrol: the control instance
*
* Releases the control instance created via snd_ctl_new()
* or snd_ctl_new1().
* Don't call this after the control was added to the card.
*/
void snd_ctl_free_one(snd_kcontrol_t * kcontrol)
{
if (kcontrol) {
......@@ -221,6 +241,16 @@ void snd_ctl_free_one(snd_kcontrol_t * kcontrol)
}
}
/**
* snd_ctl_add - add the control instance to the card
* @card: the card instance
* @kcontrol: the control instance to add
*
* Adds the control instance created via snd_ctl_new() or
* snd_ctl_new1() to the given card.
*
* Returns zero if successful, or a negative error code on failure.
*/
int snd_ctl_add(snd_card_t * card, snd_kcontrol_t * kcontrol)
{
snd_runtime_check(card != NULL && kcontrol != NULL, return -EINVAL);
......@@ -236,6 +266,16 @@ int snd_ctl_add(snd_card_t * card, snd_kcontrol_t * kcontrol)
return 0;
}
/**
* snd_ctl_remove - remove the control from the card and release it
* @card: the card instance
* @kcontrol: the control instance to remove
*
* Removes the control from the card and then releases the instance.
* You don't need to call snd_ctl_free_one().
*
* Returns 0 if successful, or a negative error code on failure.
*/
int snd_ctl_remove(snd_card_t * card, snd_kcontrol_t * kcontrol)
{
snd_runtime_check(card != NULL && kcontrol != NULL, return -EINVAL);
......@@ -248,6 +288,16 @@ int snd_ctl_remove(snd_card_t * card, snd_kcontrol_t * kcontrol)
return 0;
}
/**
* snd_ctl_remove_id - remove the control of the given id and release it
* @card: the card instance
* @id: the control id to remove
*
* Finds the control instance with the given id, removes it from the
* card list and releases it.
*
* Returns 0 if successful, or a negative error code on failure.
*/
int snd_ctl_remove_id(snd_card_t * card, snd_ctl_elem_id_t *id)
{
snd_kcontrol_t *kctl;
......@@ -260,6 +310,17 @@ int snd_ctl_remove_id(snd_card_t * card, snd_ctl_elem_id_t *id)
static snd_kcontrol_t *_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id); /* w/o lock */
/**
* snd_ctl_rename_id - replace the id of a control on the card
* @card: the card instance
* @src_id: the old id
* @dst_id: the new id
*
* Finds the control with the old id from the card, and replaces the
* id with the new one.
*
* Returns zero if successful, or a negative error code on failure.
*/
int snd_ctl_rename_id(snd_card_t * card, snd_ctl_elem_id_t *src_id, snd_ctl_elem_id_t *dst_id)
{
snd_kcontrol_t *kctl;
......@@ -315,7 +376,15 @@ static snd_kcontrol_t *_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id)
return NULL;
}
/* exported: with read lock */
/**
* snd_ctl_find_id - find the control instance with the given id
* @card: the card instance
* @id: the id to search
*
* Finds the control instance with the given id from the card.
*
* Returns the pointer of the instance if found, or NULL if not.
*/
snd_kcontrol_t *snd_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id)
{
snd_kcontrol_t *kctl;
......@@ -325,7 +394,15 @@ snd_kcontrol_t *snd_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id)
return kctl;
}
/* exported: with read lock */
/**
* snd_ctl_find_numid - find the control instance with the given number-id
* @card: the card instance
* @numid: the number-id to search
*
* Finds the control instance with the given number-id from the card.
*
* Returns the pointer of the instance if found, or NULL if not.
*/
snd_kcontrol_t *snd_ctl_find_numid(snd_card_t * card, unsigned int numid)
{
snd_kcontrol_t *kctl;
......@@ -637,13 +714,15 @@ static int snd_ctl_ioctl(struct inode *inode, struct file *file,
return -EFAULT;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
err = -ENOPROTOOPT;
#ifdef CONFIG_PM
if (card->set_power_state == NULL)
return -ENOPROTOOPT;
return card->set_power_state(card, err);
#else
return -ENOPROTOOPT;
if (card->set_power_state) {
snd_power_lock(card);
err = card->set_power_state(card, err);
snd_power_unlock(card);
}
#endif
return err;
case SNDRV_CTL_IOCTL_POWER_STATE:
#ifdef CONFIG_PM
return put_user(card->power_state, (int *)arg) ? -EFAULT : 0;
......@@ -736,6 +815,10 @@ static unsigned int snd_ctl_poll(struct file *file, poll_table * wait)
return mask;
}
/*
* register the device-specific control-ioctls.
* called from each device manager like pcm.c, hwdep.c, etc.
*/
int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn)
{
snd_kctl_ioctl_t *pn;
......@@ -751,6 +834,9 @@ int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn)
return 0;
}
/*
* de-register the device-specific control-ioctls.
*/
int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn)
{
struct list_head *list;
......@@ -806,6 +892,10 @@ static snd_minor_t snd_ctl_reg =
.f_ops = &snd_ctl_f_ops,
};
/*
* registration of the control device:
* called from init.c
*/
int snd_ctl_register(snd_card_t *card)
{
int err, cardnum;
......@@ -821,6 +911,10 @@ int snd_ctl_register(snd_card_t *card)
return 0;
}
/*
* disconnection of the control device:
* called from init.c
*/
int snd_ctl_disconnect(snd_card_t *card)
{
struct list_head *flist;
......@@ -836,6 +930,10 @@ int snd_ctl_disconnect(snd_card_t *card)
return 0;
}
/*
* de-registration of the control device:
* called from init.c
*/
int snd_ctl_unregister(snd_card_t *card)
{
int err, cardnum;
......
......@@ -25,6 +25,22 @@
#include <linux/errno.h>
#include <sound/core.h>
/**
* snd_device_new - create an ALSA device component
* @card: the card instance
* @type: the device type, SNDRV_DEV_TYPE_XXX
* @device_data: the data pointer of this device
* @ops: the operator table
*
* Creates a new device component for the given data pointer.
* The device will be assigned to the card and managed together
* by the card.
*
* The data pointer plays a role as the identifier, too, so the
* pointer address must be unique and unchanged.
*
* Returns zero if successful, or a negative error code on failure.
*/
int snd_device_new(snd_card_t *card, snd_device_type_t type,
void *device_data, snd_device_ops_t *ops)
{
......@@ -43,6 +59,18 @@ int snd_device_new(snd_card_t *card, snd_device_type_t type,
return 0;
}
/**
* snd_device_free - release the device from the card
* @card: the card instance
* @device_data: the data pointer to release
*
* Removes the device from the list on the card and invokes the
* callback, dev_unregister or dev_free, corresponding to the state.
* Then release the device.
*
* Returns zero if successful, or a negative error code on failure or if the
* device not found.
*/
int snd_device_free(snd_card_t *card, void *device_data)
{
struct list_head *list;
......@@ -73,6 +101,19 @@ int snd_device_free(snd_card_t *card, void *device_data)
return -ENXIO;
}
/**
* snd_device_free - disconnect the device
* @card: the card instance
* @device_data: the data pointer to disconnect
*
* Turns the device into the disconnection state, invoking
* dev_disconnect callback, if the device was already registered.
*
* Usually called from snd_card_disconnect().
*
* Returns zero if successful, or a negative error code on failure or if the
* device not found.
*/
int snd_device_disconnect(snd_card_t *card, void *device_data)
{
struct list_head *list;
......@@ -95,6 +136,19 @@ int snd_device_disconnect(snd_card_t *card, void *device_data)
return -ENXIO;
}
/**
* snd_device_register - register the device
* @card: the card instance
* @device_data: the data pointer to register
*
* Registers the device which was already created via
* snd_device_new(). Usually this is called from snd_card_register(),
* but it can be called later if any new devices are created after
* invokation of snd_card_register().
*
* Returns zero if successful, or a negative error code on failure or if the
* device not found.
*/
int snd_device_register(snd_card_t *card, void *device_data)
{
struct list_head *list;
......@@ -118,6 +172,10 @@ int snd_device_register(snd_card_t *card, void *device_data)
return -ENXIO;
}
/*
* register all the devices on the card.
* called from init.c
*/
int snd_device_register_all(snd_card_t *card)
{
struct list_head *list;
......@@ -136,6 +194,10 @@ int snd_device_register_all(snd_card_t *card)
return 0;
}
/*
* disconnect all the devices on the card.
* called from init.c
*/
int snd_device_disconnect_all(snd_card_t *card)
{
snd_device_t *dev;
......@@ -151,6 +213,10 @@ int snd_device_disconnect_all(snd_card_t *card)
return err;
}
/*
* release all the devices on the card.
* called from init.c
*/
int snd_device_free_all(snd_card_t *card, snd_device_cmd_t cmd)
{
snd_device_t *dev;
......
......@@ -256,6 +256,19 @@ static snd_minor_t snd_hwdep_reg =
.f_ops = &snd_hwdep_f_ops,
};
/**
* snd_hwdep_new - create a new hwdep instance
* @card: the card instance
* @id: the id string
* @device: the device index (zero-based)
* @rhwdep: the pointer to store the new hwdep instance
*
* Creates a new hwdep instance with the given index on the card.
* The callbacks (hwdep->ops) must be set on the returned instance
* after this call manually by the caller.
*
* Returns zero if successful, or a negative error code on failure.
*/
int snd_hwdep_new(snd_card_t * card, char *id, int device, snd_hwdep_t ** rhwdep)
{
snd_hwdep_t *hwdep;
......
......@@ -83,10 +83,16 @@ typedef struct _snd_info_private_data {
static int snd_info_version_init(void);
static int snd_info_version_done(void);
/*
/**
* snd_iprintf - printf on the procfs buffer
* @buffer: the procfs buffer
* @fmt: the printf format
*
* Outputs the string on the procfs buffer just like printf().
*
* Returns the size of output string.
*/
int snd_iprintf(snd_info_buffer_t * buffer, char *fmt,...)
{
va_list args;
......@@ -293,9 +299,6 @@ static int snd_info_entry_open(struct inode *inode, struct file *file)
up(&info_mutex);
return -ENODEV;
}
#ifdef LINUX_2_2
MOD_INC_USE_COUNT;
#endif
if (!try_module_get(entry->module)) {
err = -EFAULT;
goto __error1;
......@@ -403,9 +406,6 @@ static int snd_info_entry_open(struct inode *inode, struct file *file)
__error:
module_put(entry->module);
__error1:
#ifdef LINUX_2_2
MOD_DEC_USE_COUNT;
#endif
up(&info_mutex);
return err;
}
......@@ -445,9 +445,6 @@ static int snd_info_entry_release(struct inode *inode, struct file *file)
break;
}
module_put(entry->module);
#ifdef LINUX_2_2
MOD_DEC_USE_COUNT;
#endif
snd_magic_kfree(data);
return 0;
}
......@@ -600,6 +597,17 @@ struct inode_operations snd_info_card_link_inode_operations =
.follow_link = snd_info_card_followlink,
};
/**
* snd_create_proc_entry - create a procfs entry
* @name: the name of the proc file
* @mode: the file permission bits, S_Ixxx
* @parent: the parent proc-directory entry
*
* Creates a new proc file entry with the given name and permission
* on the given directory.
*
* Returns the pointer of new instance or NULL on failure.
*/
struct proc_dir_entry *snd_create_proc_entry(const char *name, mode_t mode,
struct proc_dir_entry *parent)
{
......@@ -691,6 +699,10 @@ int __exit snd_info_done(void)
*/
/*
* create a card proc file
* called from init.c
*/
int snd_info_card_create(snd_card_t * card)
{
char str[8];
......@@ -710,6 +722,10 @@ int snd_info_card_create(snd_card_t * card)
return 0;
}
/*
* register the card proc file
* called from init.c
*/
int snd_info_card_register(snd_card_t * card)
{
char *s;
......@@ -737,6 +753,10 @@ int snd_info_card_register(snd_card_t * card)
return 0;
}
/*
* de-register the card proc file
* called from init.c
*/
int snd_info_card_free(snd_card_t * card)
{
void *data;
......@@ -756,10 +776,17 @@ int snd_info_card_free(snd_card_t * card)
return 0;
}
/*
/**
* snd_info_get_line - read one line from the procfs buffer
* @buffer: the procfs buffer
* @line: the buffer to store
* @len: the max. buffer size - 1
*
* Reads one line from the buffer and stores the string.
*
* Returns zero if successful, or 1 if error or EOF.
*/
int snd_info_get_line(snd_info_buffer_t * buffer, char *line, int len)
{
int c = -1;
......@@ -790,6 +817,18 @@ int snd_info_get_line(snd_info_buffer_t * buffer, char *line, int len)
return 0;
}
/**
* snd_info_get_line - parse a string token
* @dest: the buffer to store the string token
* @src: the original string
* @len: the max. length of token - 1
*
* Parses the original string and copy a token to the given
* string buffer.
*
* Returns the updated pointer of the original string so that
* it can be used for the next call.
*/
char *snd_info_get_str(char *dest, char *src, int len)
{
int c;
......@@ -814,15 +853,27 @@ char *snd_info_get_str(char *dest, char *src, int len)
return src;
}
/**
* snd_info_create_entry - create an info entry
* @name: the proc file name
*
* Creates an info entry with the given file name and initializes as
* the default state.
*
* Usually called from other functions such as
* snd_info_create_card_entry().
*
* Returns the pointer of the new instance, or NULL on failure.
*/
static snd_info_entry_t *snd_info_create_entry(const char *name)
{
snd_info_entry_t *entry;
entry = (snd_info_entry_t *) snd_kcalloc(sizeof(snd_info_entry_t), GFP_KERNEL);
entry = snd_magic_kcalloc(snd_info_entry_t, 0, GFP_KERNEL);
if (entry == NULL)
return NULL;
entry->name = snd_kmalloc_strdup(name, GFP_KERNEL);
if (entry->name == NULL) {
kfree(entry);
snd_magic_kfree(entry);
return NULL;
}
entry->mode = S_IFREG | S_IRUGO;
......@@ -831,6 +882,16 @@ static snd_info_entry_t *snd_info_create_entry(const char *name)
return entry;
}
/**
* snd_info_create_module_entry - create an info entry for the given module
* @module: the module pointer
* @name: the file name
* @parent: the parent directory
*
* Creates a new info entry and assigns it to the given module.
*
* Returns the pointer of the new instance, or NULL on failure.
*/
snd_info_entry_t *snd_info_create_module_entry(struct module * module,
const char *name,
snd_info_entry_t *parent)
......@@ -843,6 +904,16 @@ snd_info_entry_t *snd_info_create_module_entry(struct module * module,
return entry;
}
/**
* snd_info_create_card_entry - create an info entry for the given card
* @card: the card instance
* @name: the file name
* @parent: the parent directory
*
* Creates a new info entry and assigns it to the given card.
*
* Returns the pointer of the new instance, or NULL on failure.
*/
snd_info_entry_t *snd_info_create_card_entry(snd_card_t * card,
const char *name,
snd_info_entry_t * parent)
......@@ -856,6 +927,75 @@ snd_info_entry_t *snd_info_create_card_entry(snd_card_t * card,
return entry;
}
static int snd_info_dev_free_entry(snd_device_t *device)
{
snd_info_entry_t *entry = snd_magic_cast(snd_info_entry_t, device->device_data, return -ENXIO);
snd_info_free_entry(entry);
return 0;
}
static int snd_info_dev_register_entry(snd_device_t *device)
{
snd_info_entry_t *entry = snd_magic_cast(snd_info_entry_t, device->device_data, return -ENXIO);
return snd_info_register(entry);
}
static int snd_info_dev_unregister_entry(snd_device_t *device)
{
snd_info_entry_t *entry = snd_magic_cast(snd_info_entry_t, device->device_data, return -ENXIO);
return snd_info_unregister(entry);
}
/**
* snd_card_proc_new - create an info entry for the given card
* @card: the card instance
* @name: the file name
* @entryp: the pointer to store the new info entry
*
* Creates a new info entry and assigns it to the given card.
* Unlike snd_info_create_card_entry(), this function registers the
* info entry as an ALSA device component, so that it can be
* unregistered/released without explicit call.
* Also, you don't have to register this entry via snd_info_register(),
* since this will be registered by snd_card_register() automatically.
*
* The parent is assumed as card->proc_root.
*
* For releasing this entry, use snd_device_free() instead of
* snd_info_free_entry().
*
* Returns zero if successful, or a negative error code on failure.
*/
int snd_card_proc_new(snd_card_t *card, const char *name,
snd_info_entry_t **entryp)
{
static snd_device_ops_t ops = {
.dev_free = snd_info_dev_free_entry,
.dev_register = snd_info_dev_register_entry,
// .dev_disconnect = snd_info_dev_disconnect_entry,
.dev_unregister = snd_info_dev_unregister_entry
};
snd_info_entry_t *entry;
int err;
entry = snd_info_create_card_entry(card, name, card->proc_root);
if (! entry)
return -ENOMEM;
if ((err = snd_device_new(card, SNDRV_DEV_INFO, entry, &ops)) < 0) {
snd_info_free_entry(entry);
return err;
}
if (entryp)
*entryp = entry;
return 0;
}
/**
* snd_info_free_entry - release the info entry
* @entry: the info entry
*
* Releases the info entry. Don't call this after registered.
*/
void snd_info_free_entry(snd_info_entry_t * entry)
{
if (entry == NULL)
......@@ -864,7 +1004,7 @@ void snd_info_free_entry(snd_info_entry_t * entry)
kfree((char *)entry->name);
if (entry->private_free)
entry->private_free(entry);
kfree(entry);
snd_magic_kfree(entry);
}
#ifdef LINUX_2_2
......@@ -901,11 +1041,11 @@ static inline void snd_info_device_entry_prepare(struct proc_dir_entry *de, snd_
}
#endif /* LINUX_2_2 */
/*
* create a procfs device file
*/
snd_info_entry_t *snd_info_create_device(const char *name, unsigned int number, unsigned int mode)
{
#ifdef CONFIG_DEVFS_FS
char dname[32];
#endif
unsigned short _major = number >> 16;
unsigned short minor = (unsigned short) number;
snd_info_entry_t *entry;
......@@ -921,7 +1061,7 @@ snd_info_entry_t *snd_info_create_device(const char *name, unsigned int number,
return NULL;
entry->content = SNDRV_INFO_CONTENT_DEVICE;
entry->mode = mode;
entry->c.device.major = major;
entry->c.device.major = _major;
entry->c.device.minor = minor;
down(&info_mutex);
p = create_proc_entry(entry->name, entry->mode, snd_proc_dev);
......@@ -942,15 +1082,19 @@ snd_info_entry_t *snd_info_create_device(const char *name, unsigned int number,
up(&info_mutex);
#ifdef CONFIG_DEVFS_FS
if (strncmp(name, "controlC", 8)) { /* created in sound.c */
char dname[32];
sprintf(dname, "snd/%s", name);
devfs_register(NULL, dname, DEVFS_FL_DEFAULT,
major, minor, mode,
_major, minor, mode,
&snd_fops, NULL);
}
#endif
return entry;
}
/*
* release a procfs device file
*/
void snd_info_free_device(snd_info_entry_t * entry)
{
snd_runtime_check(entry, return);
......@@ -962,6 +1106,14 @@ void snd_info_free_device(snd_info_entry_t * entry)
snd_info_free_entry(entry);
}
/**
* snd_info_register - register the info entry
* @entry: the info entry
*
* Registers the proc info entry.
*
* Returns zero if successful, or a negative error code on failure.
*/
int snd_info_register(snd_info_entry_t * entry)
{
struct proc_dir_entry *root, *p = NULL;
......@@ -991,6 +1143,14 @@ int snd_info_register(snd_info_entry_t * entry)
return 0;
}
/**
* snd_info_unregister - de-register the info entry
* @entry: the info entry
*
* De-registers the info entry and releases the instance.
*
* Returns zero if successful, or a negative error code on failure.
*/
int snd_info_unregister(snd_info_entry_t * entry)
{
struct proc_dir_entry *root;
......
......@@ -51,14 +51,16 @@ static void snd_card_id_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer
}
/**
* snd_card_new: create and initialize a soundcard structure
* snd_card_new - create and initialize a soundcard structure
* @idx: card index (address) [0 ... (SNDRV_CARDS-1)]
* @xid: card identification (ASCII string)
* @module: top level module for locking
* @extra_size: allocate this extra size after the main soundcard structure
*
* Creates and initializes a soundcard structure.
*
* Returns kmallocated snd_card_t structure. Creates the ALSA control interface
* (which is blocked until #snd_card_register function is called).
* (which is blocked until snd_card_register function is called).
*/
snd_card_t *snd_card_new(int idx, const char *xid,
struct module *module, int extra_size)
......@@ -84,11 +86,19 @@ snd_card_t *snd_card_new(int idx, const char *xid,
idx = idx2;
break;
}
if (idx < 0 && snd_ecards_limit < SNDRV_CARDS)
/* for dynamically additional devices like hotplug:
* increment the limit if still free slot exists.
*/
idx = snd_ecards_limit++;
} else if (idx < snd_ecards_limit) {
if (snd_cards_lock & (1 << idx))
idx = -1; /* invalid */
}
if (idx < 0 || idx >= snd_ecards_limit) {
} else if (idx < SNDRV_CARDS)
snd_ecards_limit = idx + 1; /* increase the limit */
else
idx = -1;
if (idx < 0) {
write_unlock(&snd_card_rwlock);
if (idx >= snd_ecards_limit)
snd_printk(KERN_ERR "card %i is out of range (0-%i)\n", idx, snd_ecards_limit-1);
......@@ -136,10 +146,12 @@ static unsigned int snd_disconnect_poll(struct file * file, poll_table * wait)
}
/**
* snd_card_disconnect: disconnect all APIs from the file-operations (user space)
* snd_card_disconnect - disconnect all APIs from the file-operations (user space)
* @card: soundcard structure
*
* Returns - zero, otherwise a negative error code.
* Disconnects all APIs from the file-operations (user space).
*
* Returns zero, otherwise a negative error code.
*
* Note: The current implementation replaces all active file->f_op with special
* dummy file operations (they do nothing except release).
......@@ -219,19 +231,18 @@ int snd_card_disconnect(snd_card_t * card)
}
/**
* snd_card_free: frees given soundcard structure
* snd_card_free - frees given soundcard structure
* @card: soundcard structure
*
* This function releases the soundcard structure and the all assigned
* devices automatically. That is, you don't have to release the devices
* by yourself.
*
* Returns - zero. Frees all associated devices and frees the control
* Returns zero. Frees all associated devices and frees the control
* interface associated to given soundcard.
*/
int snd_card_free(snd_card_t * card)
{
wait_queue_t wait;
struct snd_shutdown_f_ops *s_f_ops;
if (card == NULL)
......@@ -242,13 +253,7 @@ int snd_card_free(snd_card_t * card)
write_unlock(&snd_card_rwlock);
/* wait, until all devices are ready for the free operation */
init_waitqueue_entry(&wait, current);
add_wait_queue(&card->shutdown_sleep, &wait);
while (card->files) {
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(30 * HZ);
}
remove_wait_queue(&card->shutdown_sleep, &wait);
wait_event(card->shutdown_sleep, card->files == NULL);
#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
if (snd_mixer_oss_notify_callback)
......@@ -292,29 +297,29 @@ int snd_card_free(snd_card_t * card)
static void snd_card_free_thread(void * __card)
{
snd_card_t *card = __card;
struct module * module;
struct module * module = card->module;
if (!try_module_get(module = card->module)) {
if (!try_module_get(module)) {
snd_printk(KERN_ERR "unable to lock toplevel module for card %i in free thread\n", card->number);
module = NULL;
}
wait_event(card->shutdown_sleep, card->files == NULL);
snd_card_free(card);
module_put(module);
}
/**
* snd_card_free_in_thread: call snd_card_free() in thread
* snd_card_free_in_thread - call snd_card_free() in thread
* @card: soundcard structure
*
* This function schedules the call of #snd_card_free function in a
* This function schedules the call of snd_card_free() function in a
* work queue. When all devices are released (non-busy), the work
* is woken up and calls #snd_card_free.
* is woken up and calls snd_card_free().
*
* When a card can be disconnected at any time by hotplug service,
* this function should be used in disconnect (or detach) callback
* instead of calling #snd_card_free directly.
* instead of calling snd_card_free() directly.
*
* Returns - zero otherwise a negative error code if the start of thread failed.
*/
......@@ -390,7 +395,7 @@ static void choose_default_id(snd_card_t * card)
}
/**
* snd_card_register: register the soundcard
* snd_card_register - register the soundcard
* @card: soundcard structure
*
* This function registers all the devices assigned to the soundcard.
......@@ -398,7 +403,7 @@ static void choose_default_id(snd_card_t * card)
* external accesses. Thus, you should call this function at the end
* of the initialization of the card.
*
* Returns - zero otherwise a negative error code if the registrain failed.
* Returns zero otherwise a negative error code if the registrain failed.
*/
int snd_card_register(snd_card_t * card)
{
......@@ -515,14 +520,14 @@ int __exit snd_card_info_done(void)
}
/**
* snd_component_add: add a component string
* snd_component_add - add a component string
* @card: soundcard structure
* @component: the component id string
*
* This function adds the component id string to the supported list.
* The component can be referred from the alsa-lib.
*
* Returns - zero otherwise a negative error code.
* Returns zero otherwise a negative error code.
*/
int snd_component_add(snd_card_t *card, const char *component)
......@@ -546,7 +551,7 @@ int snd_component_add(snd_card_t *card, const char *component)
}
/**
* snd_card_file_add: add the file to the file list of the card
* snd_card_file_add - add the file to the file list of the card
* @card: soundcard structure
* @file: file pointer
*
......@@ -578,15 +583,15 @@ int snd_card_file_add(snd_card_t *card, struct file *file)
}
/**
* snd_card_file_remove: remove the file from the file list
* snd_card_file_remove - remove the file from the file list
* @card: soundcard structure
* @file: file pointer
*
* This function removes the file formerly added to the card via
* #snd_card_file_add function.
* snd_card_file_add() function.
* If all files are removed and the release of the card is
* scheduled, it will wake up the the thread to call #snd_card_free
* (see #snd_card_free_in_thread function).
* scheduled, it will wake up the the thread to call snd_card_free()
* (see snd_card_free_in_thread() function).
*
* Returns zero or a negative error code.
*/
......@@ -621,9 +626,11 @@ int snd_card_file_remove(snd_card_t *card, struct file *file)
#ifdef CONFIG_PM
/**
* snd_power_wait: wait until the power-state is changed.
* snd_power_wait - wait until the power-state is changed.
* @card: soundcard structure
*
* Waits until the power-state is changed.
*
* Note: the power lock must be active before call.
*/
void snd_power_wait(snd_card_t *card)
......
......@@ -250,9 +250,9 @@ static int get_ctl_type(struct file *file, snd_ctl_elem_id_t *id)
ctl = snd_magic_cast(snd_ctl_file_t, file->private_data, return -ENXIO);
kctl = snd_ctl_find_id(ctl->card, id);
if (! kctl)
if (! kctl) {
return -ENXIO;
}
info.id = *id;
err = kctl->info(kctl, &info);
if (err >= 0)
......
......@@ -30,10 +30,15 @@
#include <sound/core.h>
#include <asm/dma.h>
/*
/**
* snd_dma_program - program an ISA DMA transfer
* @dma: the dma number
* @addr: the physical address of the buffer
* @size: the DMA transfer size
* @mode: the DMA transfer mode, DMA_MODE_XXX
*
* Programs an ISA DMA transfer for the given buffer.
*/
void snd_dma_program(unsigned long dma,
unsigned long addr, unsigned int size,
unsigned short mode)
......@@ -51,6 +56,12 @@ void snd_dma_program(unsigned long dma,
release_dma_lock(flags);
}
/**
* snd_dma_disable - stop the ISA DMA transfer
* @dma: the dma number
*
* Stops the ISA DMA transfer.
*/
void snd_dma_disable(unsigned long dma)
{
unsigned long flags;
......@@ -61,6 +72,12 @@ void snd_dma_disable(unsigned long dma)
release_dma_lock(flags);
}
/**
* snd_dma_residue - return the residue count of the given DMA
* @dma: the dma number
*
* Returns the residue count of the given DMA transfer.
*/
unsigned int snd_dma_residue(unsigned long dma)
{
unsigned long flags;
......
This diff is collapsed.
......@@ -56,14 +56,8 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file)
fmixer->card = card;
fmixer->mixer = card->mixer_oss;
file->private_data = fmixer;
#ifdef LINUX_2_2
MOD_INC_USE_COUNT;
#endif
if (!try_module_get(card->module)) {
kfree(fmixer);
#ifdef LINUX_2_2
MOD_DEC_USE_COUNT;
#endif
snd_card_file_remove(card, file);
return -EFAULT;
}
......@@ -77,9 +71,6 @@ static int snd_mixer_oss_release(struct inode *inode, struct file *file)
if (file->private_data) {
fmixer = (snd_mixer_oss_file_t *) file->private_data;
module_put(fmixer->card->module);
#ifdef LINUX_2_2
MOD_DEC_USE_COUNT;
#endif
snd_card_file_remove(fmixer->card, file);
kfree(fmixer);
}
......
......@@ -251,6 +251,43 @@ static int snd_pcm_oss_period_size(snd_pcm_substream_t *substream,
return 0;
}
static int choose_rate(snd_pcm_substream_t *substream,
snd_pcm_hw_params_t *params, int best_rate)
{
snd_interval_t *it;
snd_pcm_hw_params_t *save;
int rate;
save = kmalloc(sizeof(*save), GFP_KERNEL);
if (save == NULL)
return -ENOMEM;
*save = *params;
it = hw_param_interval(save, SNDRV_PCM_HW_PARAM_RATE);
/* try multiples of the best rate */
rate = best_rate;
for (;;) {
if (it->max < rate || (it->max == rate && it->openmax))
break;
if (it->min < rate || (it->min == rate && !it->openmin)) {
int ret;
ret = snd_pcm_hw_param_set(substream, params,
SNDRV_PCM_HW_PARAM_RATE,
rate, 0);
if (ret == rate) {
kfree(save);
return rate;
}
*params = *save;
}
rate += best_rate;
}
/* not found, use the nearest rate */
kfree(save);
return snd_pcm_hw_param_near(substream, params, SNDRV_PCM_HW_PARAM_RATE, best_rate, 0);
}
static int snd_pcm_oss_change_params(snd_pcm_substream_t *substream)
{
snd_pcm_runtime_t *runtime = substream->runtime;
......@@ -287,7 +324,7 @@ static int snd_pcm_oss_change_params(snd_pcm_substream_t *substream)
snd_printd("No usable accesses\n");
return -EINVAL;
}
snd_pcm_hw_param_near(substream, &sparams, SNDRV_PCM_HW_PARAM_RATE, runtime->oss.rate, 0);
choose_rate(substream, &sparams, runtime->oss.rate);
snd_pcm_hw_param_near(substream, &sparams, SNDRV_PCM_HW_PARAM_CHANNELS, runtime->oss.channels, 0);
format = snd_pcm_oss_format_from(runtime->oss.format);
......@@ -1540,9 +1577,6 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
device = SNDRV_MINOR_OSS_DEVICE(minor) == SNDRV_MINOR_OSS_PCM1 ?
adsp_map[cardnum] : dsp_map[cardnum];
#ifdef LINUX_2_2
MOD_INC_USE_COUNT;
#endif
pcm = snd_pcm_devices[(cardnum * SNDRV_PCM_DEVICES) + device];
if (pcm == NULL) {
err = -ENODEV;
......@@ -1615,9 +1649,6 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file)
__error2:
snd_card_file_remove(pcm->card, file);
__error1:
#ifdef LINUX_2_2
MOD_DEC_USE_COUNT;
#endif
return err;
}
......@@ -1640,9 +1671,6 @@ static int snd_pcm_oss_release(struct inode *inode, struct file *file)
wake_up(&pcm->open_wait);
module_put(pcm->card->module);
snd_card_file_remove(pcm->card, file);
#ifdef LINUX_2_2
MOD_DEC_USE_COUNT;
#endif
return 0;
}
......
......@@ -542,6 +542,19 @@ static int snd_pcm_substream_proc_done(snd_pcm_substream_t *substream)
return 0;
}
/**
* snd_pcm_new_stream - create a new PCM stream
* @pcm: the pcm instance
* @stream: the stream direction, SNDRV_PCM_STREAM_XXX
* @substream_count: the number of substreams
*
* Creates a new stream for the pcm.
* The corresponding stream on the pcm must have been empty before
* calling this, i.e. zero must be given to the argument of
* snd_pcm_new().
*
* Returns zero if successful, or a negative error code on failure.
*/
int snd_pcm_new_stream(snd_pcm_t *pcm, int stream, int substream_count)
{
int idx, err;
......@@ -582,7 +595,7 @@ int snd_pcm_new_stream(snd_pcm_t *pcm, int stream, int substream_count)
snd_magic_kfree(substream);
return err;
}
substream->dma_type = SNDRV_PCM_DMA_TYPE_ISA;
substream->dma_type = SNDRV_PCM_DMA_TYPE_UNKNOWN;
substream->dma_private = NULL;
spin_lock_init(&substream->timer_lock);
prev = substream;
......@@ -590,6 +603,22 @@ int snd_pcm_new_stream(snd_pcm_t *pcm, int stream, int substream_count)
return 0;
}
/**
* snd_pcm_new - create a new PCM instance
* @card: the card instance
* @id: the id string
* @device: the device index (zero based)
* @playback_count: the number of substreams for playback
* @capture_count: the number of substreams for capture
* @rpcm: the pointer to store the new pcm instance
*
* Creates a new PCM instance.
*
* The pcm operators have to be set afterwards to the new instance
* via snd_pcm_set_ops().
*
* Returns zero if successful, or a negative error code on failure.
*/
int snd_pcm_new(snd_card_t * card, char *id, int device,
int playback_count, int capture_count,
snd_pcm_t ** rpcm)
......@@ -660,6 +689,7 @@ static int snd_pcm_free(snd_pcm_t *pcm)
snd_assert(pcm != NULL, return -ENXIO);
if (pcm->private_free)
pcm->private_free(pcm);
snd_pcm_lib_preallocate_free_for_all(pcm);
snd_pcm_free_stream(&pcm->streams[SNDRV_PCM_STREAM_PLAYBACK]);
snd_pcm_free_stream(&pcm->streams[SNDRV_PCM_STREAM_CAPTURE]);
snd_magic_kfree(pcm);
......@@ -774,6 +804,7 @@ int snd_pcm_open_substream(snd_pcm_t *pcm, int stream,
runtime->status->state = SNDRV_PCM_STATE_OPEN;
substream->runtime = runtime;
substream->private_data = pcm->private_data;
pstr->substream_opened++;
*rsubstream = substream;
return 0;
......
This diff is collapsed.
This diff is collapsed.
......@@ -30,6 +30,13 @@
#define snd_enum_to_int(v) (v)
#define snd_int_to_enum(v) (v)
/**
* snd_pcm_format_signed - Check the PCM format is signed linear
* @format: the format to check
*
* Returns 1 if the given PCM format is signed linear, 0 if unsigned
* linear, and a negative error code for non-linear formats.
*/
int snd_pcm_format_signed(snd_pcm_format_t format)
{
switch (snd_enum_to_int(format)) {
......@@ -66,6 +73,13 @@ int snd_pcm_format_signed(snd_pcm_format_t format)
}
}
/**
* snd_pcm_format_unsigned - Check the PCM format is unsigned linear
* @format: the format to check
*
* Returns 1 if the given PCM format is unsigned linear, 0 if signed
* linear, and a negative error code for non-linear formats.
*/
int snd_pcm_format_unsigned(snd_pcm_format_t format)
{
int val;
......@@ -76,11 +90,24 @@ int snd_pcm_format_unsigned(snd_pcm_format_t format)
return !val;
}
/**
* snd_pcm_format_linear - Check the PCM format is linear
* @format: the format to check
*
* Returns 1 if the given PCM format is linear, 0 if not.
*/
int snd_pcm_format_linear(snd_pcm_format_t format)
{
return snd_pcm_format_signed(format) >= 0;
}
/**
* snd_pcm_format_little_endian - Check the PCM format is little-endian
* @format: the format to check
*
* Returns 1 if the given PCM format is little-endian, 0 if
* big-endian, or a negative error code if endian not specified.
*/
int snd_pcm_format_little_endian(snd_pcm_format_t format)
{
switch (snd_enum_to_int(format)) {
......@@ -121,6 +148,13 @@ int snd_pcm_format_little_endian(snd_pcm_format_t format)
}
}
/**
* snd_pcm_format_big_endian - Check the PCM format is big-endian
* @format: the format to check
*
* Returns 1 if the given PCM format is big-endian, 0 if
* little-endian, or a negative error code if endian not specified.
*/
int snd_pcm_format_big_endian(snd_pcm_format_t format)
{
int val;
......@@ -131,6 +165,13 @@ int snd_pcm_format_big_endian(snd_pcm_format_t format)
return !val;
}
/**
* snd_pcm_format_cpu_endian - Check the PCM format is CPU-endian
* @format: the format to check
*
* Returns 1 if the given PCM format is CPU-endian, 0 if
* opposite, or a negative error code if endian not specified.
*/
int snd_pcm_format_cpu_endian(snd_pcm_format_t format)
{
#ifdef SNDRV_LITTLE_ENDIAN
......@@ -140,6 +181,13 @@ int snd_pcm_format_cpu_endian(snd_pcm_format_t format)
#endif
}
/**
* snd_pcm_format_width - return the bit-width of the format
* @format: the format to check
*
* Returns the bit-width of the format, or a negative error code
* if unknown format.
*/
int snd_pcm_format_width(snd_pcm_format_t format)
{
switch (snd_enum_to_int(format)) {
......@@ -193,6 +241,13 @@ int snd_pcm_format_width(snd_pcm_format_t format)
}
}
/**
* snd_pcm_format_physical_width - return the physical bit-width of the format
* @format: the format to check
*
* Returns the physical bit-width of the format, or a negative error code
* if unknown format.
*/
int snd_pcm_format_physical_width(snd_pcm_format_t format)
{
switch (snd_enum_to_int(format)) {
......@@ -243,6 +298,13 @@ int snd_pcm_format_physical_width(snd_pcm_format_t format)
}
}
/**
* snd_pcm_format_size - return the byte size of samples on the given format
* @format: the format to check
*
* Returns the byte size of the given samples for the format, or a
* negative error code if unknown format.
*/
ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples)
{
switch (snd_enum_to_int(format)) {
......@@ -296,6 +358,12 @@ ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples)
}
}
/**
* snd_pcm_format_silence_64 - return the silent data in 64bit integer
* @format: the format to check
*
* Returns the silent data in 64bit integer for the given format.
*/
u_int64_t snd_pcm_format_silence_64(snd_pcm_format_t format)
{
switch (snd_enum_to_int(format)) {
......@@ -451,6 +519,16 @@ u_int8_t snd_pcm_format_silence(snd_pcm_format_t format)
return (u_int8_t)snd_pcm_format_silence_64(format);
}
/**
* snd_pcm_format_set_silence - set the silence data on the buffer
* @format: the PCM format
* @data: the buffer pointer
* @samples: the number of samples to set silence
*
* Sets the silence data on the buffer for the given samples.
*
* Returns zero if sucessful, or a negative error code on failure.
*/
int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int samples)
{
if (samples == 0)
......@@ -497,6 +575,7 @@ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int
#endif
}
}
break;
}
case 32: {
u_int32_t silence = snd_pcm_format_silence_64(format);
......@@ -543,6 +622,14 @@ static int linear_formats[4*2*2] = {
SNDRV_PCM_FORMAT_U32_BE
};
/**
* snd_pcm_build_linear_format - return the suitable linear format for the given condition
* @width: the bit-width
* @unsignd: 1 if unsigned, 0 if signed.
* @big_endian: 1 if big-endian, 0 if little-endian
*
* Returns the suitable linear format for the given condition.
*/
snd_pcm_format_t snd_pcm_build_linear_format(int width, int unsignd, int big_endian)
{
switch (width) {
......
......@@ -76,6 +76,8 @@ static inline void snd_leave_user(mm_segment_t fs)
set_fs(fs);
}
int snd_pcm_info(snd_pcm_substream_t * substream, snd_pcm_info_t *info)
{
snd_pcm_runtime_t * runtime;
......@@ -674,6 +676,9 @@ static inline void snd_pcm_post_start(snd_pcm_substream_t *substream, int state)
snd_pcm_tick_prepare(substream);
}
/**
* snd_pcm_sart
*/
int snd_pcm_start(snd_pcm_substream_t *substream)
{
SND_PCM_ACTION(start, substream, 0);
......@@ -703,6 +708,9 @@ static inline void snd_pcm_post_stop(snd_pcm_substream_t *substream, int state)
wake_up(&runtime->sleep);
}
/**
* snd_pcm_stop
*/
int snd_pcm_stop(snd_pcm_substream_t *substream, int state)
{
SND_PCM_ACTION(stop, substream, state);
......@@ -779,11 +787,17 @@ static inline void snd_pcm_post_suspend(snd_pcm_substream_t *substream, int stat
wake_up(&runtime->sleep);
}
/**
* snd_pcm_suspend
*/
int snd_pcm_suspend(snd_pcm_substream_t *substream)
{
SND_PCM_ACTION(suspend, substream, 0);
}
/**
* snd_pcm_suspend_all
*/
int snd_pcm_suspend_all(snd_pcm_t *pcm)
{
snd_pcm_substream_t *substream;
......@@ -976,6 +990,9 @@ static inline void snd_pcm_post_prepare(snd_pcm_substream_t * substream, int sta
runtime->status->state = SNDRV_PCM_STATE_PREPARED;
}
/**
* snd_pcm_prepare
*/
int snd_pcm_prepare(snd_pcm_substream_t *substream)
{
int res;
......@@ -1081,6 +1098,8 @@ static int snd_pcm_playback_drain(snd_pcm_substream_t * substream)
/* Fall through */
case SNDRV_PCM_STATE_SETUP:
goto _end;
default:
break;
}
if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) {
......@@ -1183,6 +1202,8 @@ static int snd_pcm_playback_drop(snd_pcm_substream_t *substream)
spin_lock_irq(&runtime->lock);
}
goto _xrun_recovery;
default:
break;
}
runtime->control->appl_ptr = runtime->status->hw_ptr;
_end:
......@@ -1236,6 +1257,8 @@ static int snd_pcm_capture_drain(snd_pcm_substream_t * substream)
spin_lock_irq(&runtime->lock);
}
goto _xrun_recovery;
default:
break;
}
_end:
spin_unlock_irq(&runtime->lock);
......@@ -1278,6 +1301,8 @@ static int snd_pcm_capture_drop(snd_pcm_substream_t * substream)
case SNDRV_PCM_STATE_XRUN:
snd_pcm_change_state(substream, SNDRV_PCM_STATE_SETUP);
break;
default:
break;
}
runtime->control->appl_ptr = runtime->status->hw_ptr;
_end:
......@@ -1779,9 +1804,6 @@ int snd_pcm_open(struct inode *inode, struct file *file)
snd_pcm_file_t *pcm_file;
wait_queue_t wait;
#ifdef LINUX_2_2
MOD_INC_USE_COUNT;
#endif
snd_runtime_check(device >= SNDRV_MINOR_PCM_PLAYBACK && device < SNDRV_MINOR_DEVICES, return -ENXIO);
pcm = snd_pcm_devices[(cardnum * SNDRV_PCM_DEVICES) + (device % SNDRV_MINOR_PCMS)];
if (pcm == NULL) {
......@@ -1829,9 +1851,6 @@ int snd_pcm_open(struct inode *inode, struct file *file)
__error2:
snd_card_file_remove(pcm->card, file);
__error1:
#ifdef LINUX_2_2
MOD_DEC_USE_COUNT;
#endif
return err;
}
......@@ -1857,9 +1876,6 @@ int snd_pcm_release(struct inode *inode, struct file *file)
wake_up(&pcm->open_wait);
module_put(pcm->card->module);
snd_card_file_remove(pcm->card, file);
#ifdef LINUX_2_2
MOD_DEC_USE_COUNT;
#endif
return 0;
}
......
This diff is collapsed.
......@@ -181,9 +181,6 @@ int snd_rawmidi_kernel_open(int cardnum, int device, int subdevice,
if (rfile)
rfile->input = rfile->output = NULL;
#ifdef LINUX_2_2
MOD_INC_USE_COUNT;
#endif
rmidi = snd_rawmidi_devices[(cardnum * SNDRV_RAWMIDI_DEVICES) + device];
if (rmidi == NULL) {
err = -ENODEV;
......@@ -342,9 +339,6 @@ int snd_rawmidi_kernel_open(int cardnum, int device, int subdevice,
module_put(rmidi->card->module);
up(&rmidi->open_mutex);
__error1:
#ifdef LINUX_2_2
MOD_DEC_USE_COUNT;
#endif
return err;
}
......@@ -499,9 +493,6 @@ int snd_rawmidi_kernel_release(snd_rawmidi_file_t * rfile)
}
up(&rmidi->open_mutex);
module_put(rmidi->card->module);
#ifdef LINUX_2_2
MOD_DEC_USE_COUNT;
#endif
return 0;
}
......@@ -824,6 +815,16 @@ int snd_rawmidi_control_ioctl(snd_card_t * card, snd_ctl_file_t * control,
return -ENOIOCTLCMD;
}
/**
* snd_rawmidi_receive - receive the input data from the device
* @substream: the rawmidi substream
* @buffer: the buffer pointer
* @count: the data size to read
*
* Reads the data from the internal buffer.
*
* Returns the size of read data, or a negative error code on failure.
*/
int snd_rawmidi_receive(snd_rawmidi_substream_t * substream, const unsigned char *buffer, int count)
{
unsigned long flags;
......@@ -968,6 +969,12 @@ static ssize_t snd_rawmidi_read(struct file *file, char *buf, size_t count, loff
return result;
}
/**
* snd_rawmidi_transmit_empty - check whether the output buffer is empty
* @substream: the rawmidi substream
*
* Returns 1 if the internal output buffer is empty, 0 if not.
*/
int snd_rawmidi_transmit_empty(snd_rawmidi_substream_t * substream)
{
snd_rawmidi_runtime_t *runtime = substream->runtime;
......@@ -986,6 +993,20 @@ int snd_rawmidi_transmit_empty(snd_rawmidi_substream_t * substream)
return result;
}
/**
* snd_rawmidi_transmit_peek - copy data from the internal buffer
* @substream: the rawmidi substream
* @buffer: the buffer pointer
* @count: data size to transfer
*
* Copies data from the internal output buffer to the given buffer.
*
* Call this in the interrupt handler when the midi output is ready,
* and call snd_rawmidi_transmit_ack() after the transmission is
* finished.
*
* Returns the size of copied data, or a negative error code on failure.
*/
int snd_rawmidi_transmit_peek(snd_rawmidi_substream_t * substream, unsigned char *buffer, int count)
{
unsigned long flags;
......@@ -1023,6 +1044,17 @@ int snd_rawmidi_transmit_peek(snd_rawmidi_substream_t * substream, unsigned char
return result;
}
/**
* snd_rawmidi_transmit_ack - acknowledge the transmission
* @substream: the rawmidi substream
* @count: the tranferred count
*
* Advances the hardware pointer for the internal output buffer with
* the given size and updates the condition.
* Call after the transmission is finished.
*
* Returns the advanced size if successful, or a negative error code on failure.
*/
int snd_rawmidi_transmit_ack(snd_rawmidi_substream_t * substream, int count)
{
unsigned long flags;
......@@ -1050,6 +1082,16 @@ int snd_rawmidi_transmit_ack(snd_rawmidi_substream_t * substream, int count)
return count;
}
/**
* snd_rawmidi_transmit - copy from the buffer to the device
* @substream: the rawmidi substream
* @buf: the buffer pointer
* @count: the data size to transfer
*
* Copies data from the buffer to the device and advances the pointer.
*
* Returns the copied size if successful, or a negative error code on failure.
*/
int snd_rawmidi_transmit(snd_rawmidi_substream_t * substream, unsigned char *buffer, int count)
{
count = snd_rawmidi_transmit_peek(substream, buffer, count);
......@@ -1313,6 +1355,20 @@ static int snd_rawmidi_alloc_substreams(snd_rawmidi_t *rmidi,
return 0;
}
/**
* snd_rawmidi_new - create a rawmidi instance
* @card: the card instance
* @id: the id string
* @device: the device index
* @output_count: the number of output streams
* @input_count: the number of input streams
* @rrawmidi: the pointer to store the new rawmidi instance
*
* Creates a new rawmidi instance.
* Use snd_rawmidi_set_ops() to set the operators to the new instance.
*
* Returns zero if successful, or a negative error code on failure.
*/
int snd_rawmidi_new(snd_card_t * card, char *id, int device,
int output_count, int input_count,
snd_rawmidi_t ** rrawmidi)
......@@ -1522,6 +1578,14 @@ static int snd_rawmidi_dev_unregister(snd_device_t *device)
return snd_rawmidi_free(rmidi);
}
/**
* snd_rawmidi_set_ops - set the rawmidi operators
* @rmidi: the rawmidi instance
* @stream: the stream direction, SNDRV_RAWMIDI_STREAM_XXX
* @ops: the operator table
*
* Sets the rawmidi operators for the given stream direction.
*/
void snd_rawmidi_set_ops(snd_rawmidi_t *rmidi, int stream, snd_rawmidi_ops_t *ops)
{
struct list_head *list;
......
......@@ -83,7 +83,6 @@ rtctimer_open(snd_timer_t *t)
if (err < 0)
return err;
t->private_data = &rtc_task;
MOD_INC_USE_COUNT;
return 0;
}
......@@ -95,7 +94,6 @@ rtctimer_close(snd_timer_t *t)
rtc_unregister(rtc);
t->private_data = NULL;
}
MOD_DEC_USE_COUNT;
return 0;
}
......
......@@ -22,6 +22,17 @@ snd-seq-instr-objs := seq_instr.o
snd-seq-dummy-objs := seq_dummy.o
snd-seq-virmidi-objs := seq_virmidi.o
RAWMIDI_OBJS = snd-seq-midi.o snd-seq-midi-event.o
OPL3_OBJS = snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
#
# this function returns:
# "m" - CONFIG_SND_SEQUENCER is m
# <empty string> - CONFIG_SND_SEQUENCER is undefined
# otherwise parameter #1 value
#
sequencer := $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),m,$(if $(CONFIG_SND_SEQUENCER),$(1)))
obj-$(CONFIG_SND_SEQUENCER) += snd-seq.o snd-seq-device.o
ifeq ($(CONFIG_SND_SEQUENCER_OSS),y)
obj-$(CONFIG_SND_SEQUENCER) += snd-seq-midi-event.o
......@@ -29,53 +40,52 @@ endif
obj-$(CONFIG_SND_SEQ_DUMMY) += snd-seq-dummy.o
# Toplevel Module Dependency
RAWMIDI_OBJS = snd-seq-midi.o snd-seq-midi-event.o
OPL3_OBJS = snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_VIRMIDI) += snd-seq-virmidi.o snd-seq-midi-event.o
obj-$(CONFIG_SND_SERIAL_U16550) += $(RAWMIDI_OBJS)
obj-$(CONFIG_SND_MTPAV) += $(RAWMIDI_OBJS)
obj-$(CONFIG_SND_MPU401) += $(RAWMIDI_OBJS)
obj-$(CONFIG_SND_ALS100) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_AZT2320) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_DT019X) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_ES18XX) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_OPL3SA2) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_AD1816A) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_CS4231) += $(RAWMIDI_OBJS)
obj-$(CONFIG_SND_CS4232) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_CS4236) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_PC98_CS4232) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_ES1688) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_GUSCLASSIC) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_GUSMAX) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_GUSEXTREME) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_INTERWAVE) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_INTERWAVE_STB) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_OPTI92X_AD1848) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_OPTI92X_CS4231) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_OPTI93X) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_SB8) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_SB16) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_SBAWE) += $(RAWMIDI_OBJS) $(OPL3_OBJS) snd-seq-virmidi.o
obj-$(CONFIG_SND_ES968) += $(RAWMIDI_OBJS)
obj-$(CONFIG_SND_WAVEFRONT) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_ALS4000) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_CMIPCI) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_CS4281) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_ENS1370) += $(RAWMIDI_OBJS)
obj-$(CONFIG_SND_ENS1371) += $(RAWMIDI_OBJS)
obj-$(CONFIG_SND_ES1938) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_ES1968) += $(RAWMIDI_OBJS)
obj-$(CONFIG_SND_FM801) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_ICE1712) += $(RAWMIDI_OBJS)
obj-$(CONFIG_SND_INTEL8X0) += $(RAWMIDI_OBJS)
obj-$(CONFIG_SND_SONICVIBES) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_VIA82XX) += $(RAWMIDI_OBJS)
obj-$(CONFIG_SND_ALI5451) += $(RAWMIDI_OBJS)
obj-$(CONFIG_SND_CS46XX) += $(RAWMIDI_OBJS)
obj-$(CONFIG_SND_EMU10K1) += $(RAWMIDI_OBJS) snd-seq-midi-emul.o snd-seq-virmidi.o
obj-$(CONFIG_SND_TRIDENT) += $(RAWMIDI_OBJS) snd-seq-midi-emul.o snd-seq-instr.o
obj-$(CONFIG_SND_YMFPCI) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(CONFIG_SND_USB_AUDIO) += $(RAWMIDI_OBJS)
obj-$(call sequencer,$(CONFIG_SND_SERIAL_U16550)) += $(RAWMIDI_OBJS)
obj-$(call sequencer,$(CONFIG_SND_MTPAV)) += $(RAWMIDI_OBJS)
obj-$(call sequencer,$(CONFIG_SND_MPU401)) += $(RAWMIDI_OBJS)
obj-$(call sequencer,$(CONFIG_SND_ALS100)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_AZT2320)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_DT019X)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_ES18XX)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_OPL3SA2)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_AD1816A)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_CS4231)) += $(RAWMIDI_OBJS)
obj-$(call sequencer,$(CONFIG_SND_CS4232)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_CS4236)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_PC98_CS4232)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_ES1688)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_GUSCLASSIC)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_GUSMAX)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_GUSEXTREME)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_INTERWAVE)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_INTERWAVE_STB)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_OPTI92X_AD1848)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_OPTI92X_CS4231)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_OPTI93X)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_SB8)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_SB16)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_SBAWE)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) snd-seq-virmidi.o
obj-$(call sequencer,$(CONFIG_SND_ES968)) += $(RAWMIDI_OBJS)
obj-$(call sequencer,$(CONFIG_SND_WAVEFRONT)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_ALS4000)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_CMIPCI)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_CS4281)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_ENS1370)) += $(RAWMIDI_OBJS)
obj-$(call sequencer,$(CONFIG_SND_ENS1371)) += $(RAWMIDI_OBJS)
obj-$(call sequencer,$(CONFIG_SND_ES1938)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_ES1968)) += $(RAWMIDI_OBJS)
obj-$(call sequencer,$(CONFIG_SND_FM801)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_ICE1712)) += $(RAWMIDI_OBJS)
obj-$(call sequencer,$(CONFIG_SND_INTEL8X0)) += $(RAWMIDI_OBJS)
obj-$(call sequencer,$(CONFIG_SND_SONICVIBES)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_VIA82XX)) += $(RAWMIDI_OBJS)
obj-$(call sequencer,$(CONFIG_SND_ALI5451)) += $(RAWMIDI_OBJS)
obj-$(call sequencer,$(CONFIG_SND_CS46XX)) += $(RAWMIDI_OBJS)
obj-$(call sequencer,$(CONFIG_SND_EMU10K1)) += $(RAWMIDI_OBJS) snd-seq-midi-emul.o snd-seq-virmidi.o
obj-$(call sequencer,$(CONFIG_SND_TRIDENT)) += $(RAWMIDI_OBJS) snd-seq-midi-emul.o snd-seq-instr.o
obj-$(call sequencer,$(CONFIG_SND_YMFPCI)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_USB_AUDIO)) += $(RAWMIDI_OBJS)
obj-$(call sequencer,$(CONFIG_SND_HDSP)) += $(RAWMIDI_OBJS)
obj-m := $(sort $(obj-m))
......@@ -10,36 +10,44 @@ snd-ainstr-simple-objs := ainstr_simple.o
snd-ainstr-gf1-objs := ainstr_gf1.o
snd-ainstr-iw-objs := ainstr_iw.o
#
# this function returns:
# "m" - CONFIG_SND_SEQUENCER is m
# <empty string> - CONFIG_SND_SEQUENCER is undefined
# otherwise parameter #1 value
#
sequencer := $(if $(subst y,,$(CONFIG_SND_SEQUENCER)),m,$(if $(CONFIG_SND_SEQUENCER),$(1)))
# Toplevel Module Dependency
obj-$(CONFIG_SND_ALS100) += snd-ainstr-fm.o
obj-$(CONFIG_SND_AZT2320) += snd-ainstr-fm.o
obj-$(CONFIG_SND_DT019X) += snd-ainstr-fm.o
obj-$(CONFIG_SND_ES18XX) += snd-ainstr-fm.o
obj-$(CONFIG_SND_OPL3SA2) += snd-ainstr-fm.o
obj-$(CONFIG_SND_AD1816A) += snd-ainstr-fm.o
obj-$(CONFIG_SND_CS4232) += snd-ainstr-fm.o
obj-$(CONFIG_SND_CS4236) += snd-ainstr-fm.o
obj-$(CONFIG_SND_PC98_CS4232) += snd-ainstr-fm.o
obj-$(CONFIG_SND_ES1688) += snd-ainstr-fm.o
obj-$(CONFIG_SND_GUSCLASSIC) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o
obj-$(CONFIG_SND_GUSMAX) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o
obj-$(CONFIG_SND_GUSEXTREME) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o snd-ainstr-fm.o
obj-$(CONFIG_SND_INTERWAVE) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o
obj-$(CONFIG_SND_INTERWAVE_STB) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o
obj-$(CONFIG_SND_OPTI92X_AD1848) += snd-ainstr-fm.o
obj-$(CONFIG_SND_OPTI92X_CS4231) += snd-ainstr-fm.o
obj-$(CONFIG_SND_OPTI93X) += snd-ainstr-fm.o
obj-$(CONFIG_SND_SB8) += snd-ainstr-fm.o
obj-$(CONFIG_SND_SB16) += snd-ainstr-fm.o
obj-$(CONFIG_SND_SBAWE) += snd-ainstr-fm.o
obj-$(CONFIG_SND_WAVEFRONT) += snd-ainstr-fm.o
obj-$(CONFIG_SND_ALS4000) += snd-ainstr-fm.o
obj-$(CONFIG_SND_CMIPCI) += snd-ainstr-fm.o
obj-$(CONFIG_SND_CS4281) += snd-ainstr-fm.o
obj-$(CONFIG_SND_ES1938) += snd-ainstr-fm.o
obj-$(CONFIG_SND_FM801) += snd-ainstr-fm.o
obj-$(CONFIG_SND_SONICVIBES) += snd-ainstr-fm.o
obj-$(CONFIG_SND_TRIDENT) += snd-ainstr-simple.o
obj-$(CONFIG_SND_YMFPCI) += snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_ALS100)) += snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_AZT2320)) += snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_DT019X)) += snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_ES18XX)) += snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_OPL3SA2)) += snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_AD1816A)) += snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_CS4232)) += snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_CS4236)) += snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_PC98_CS4232)) += snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_ES1688)) += snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_GUSCLASSIC)) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o
obj-$(call sequencer,$(CONFIG_SND_GUSMAX)) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o
obj-$(call sequencer,$(CONFIG_SND_GUSEXTREME)) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_INTERWAVE)) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o
obj-$(call sequencer,$(CONFIG_SND_INTERWAVE_STB)) += snd-ainstr-iw.o snd-ainstr-gf1.o snd-ainstr-simple.o
obj-$(call sequencer,$(CONFIG_SND_OPTI92X_AD1848)) += snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_OPTI92X_CS4231)) += snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_OPTI93X)) += snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_SB8)) += snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_SB16)) += snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_SBAWE)) += snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_WAVEFRONT)) += snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_ALS4000)) += snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_CMIPCI)) += snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_CS4281)) += snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_ES1938)) += snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_FM801)) += snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_SONICVIBES)) += snd-ainstr-fm.o
obj-$(call sequencer,$(CONFIG_SND_TRIDENT)) += snd-ainstr-simple.o
obj-$(call sequencer,$(CONFIG_SND_YMFPCI)) += snd-ainstr-fm.o
obj-m := $(sort $(obj-m))
......@@ -7,6 +7,4 @@ snd-seq-oss-objs := seq_oss.o seq_oss_init.o seq_oss_timer.o seq_oss_ioctl.o \
seq_oss_event.o seq_oss_rw.o seq_oss_synth.o \
seq_oss_midi.o seq_oss_readq.o seq_oss_writeq.o
ifeq ($(CONFIG_SND_SEQUENCER_OSS),y)
obj-$(CONFIG_SND_SEQUENCER) += snd-seq-oss.o
endif
obj-$(CONFIG_SND_SEQUENCER) += snd-seq-oss.o
......@@ -275,9 +275,6 @@ snd_seq_oss_open(struct file *file, int level)
client_table[dp->index] = dp;
num_clients++;
#ifdef LINUX_2_2
MOD_INC_USE_COUNT;
#endif
debug_printk(("open done\n"));
......@@ -434,9 +431,6 @@ snd_seq_oss_release(seq_oss_devinfo_t *dp)
if (dp->queue >= 0)
delete_seq_queue(dp);
#ifdef LINUX_2_2
MOD_DEC_USE_COUNT;
#endif
debug_printk(("release done\n"));
}
......
......@@ -217,7 +217,6 @@ snd_seq_oss_midi_check_new_port(snd_seq_port_info_t *pinfo)
midi_devs[mdev->seq_device] = mdev;
spin_unlock_irqrestore(&register_lock, flags);
/*MOD_INC_USE_COUNT;*/
return 0;
}
......
......@@ -339,10 +339,6 @@ static int snd_seq_open(struct inode *inode, struct file *file)
/* make others aware this new client */
snd_seq_system_client_ev_client_start(c);
#ifdef LINUX_2_2
MOD_INC_USE_COUNT;
#endif
return 0;
}
......@@ -358,9 +354,6 @@ static int snd_seq_release(struct inode *inode, struct file *file)
kfree(client);
}
#ifdef LINUX_2_2
MOD_DEC_USE_COUNT;
#endif
return 0;
}
......
......@@ -73,6 +73,13 @@ static devfs_handle_t devfs_handle = NULL;
#ifdef CONFIG_KMOD
/**
* snd_request_card - try to load the card module
* @card: the card number
*
* Tries to load the module "snd-card-X" for the given card number
* via KMOD. Returns immediately if already loaded.
*/
void snd_request_card(int card)
{
char str[32];
......@@ -83,7 +90,7 @@ void snd_request_card(int card)
read_unlock(&snd_card_rwlock);
if (locked)
return;
if (card < 0 || card >= snd_ecards_limit)
if (card < 0 || card >= cards_limit)
return;
sprintf(str, "snd-card-%i", card);
request_module(str);
......@@ -188,6 +195,19 @@ static int snd_kernel_minor(int type, snd_card_t * card, int dev)
return minor;
}
/**
* snd_register_device - Register the ALSA device file for the card
* @type: the device type, SNDRV_DEVICE_TYPE_XXX
* @card: the card instance
* @dev: the device index
* @reg: the snd_minor_t record
* @name: the device file name
*
* Registers an ALSA device file for the given card.
* The operators have to be set in reg parameter.
*
* Retrurns zero if successful, or a negative error code on failure.
*/
int snd_register_device(int type, snd_card_t * card, int dev, snd_minor_t * reg, const char *name)
{
int minor = snd_kernel_minor(type, card, dev);
......@@ -215,6 +235,17 @@ int snd_register_device(int type, snd_card_t * card, int dev, snd_minor_t * reg,
return 0;
}
/**
* snd_unregister_device - unregister the device on the given card
* @type: the device type, SNDRV_DEVICE_TYPE_XXX
* @card: the card instance
* @dev: the device index
*
* Unregisters the device file already registered via
* snd_register_device().
*
* Returns zero if sucecessful, or a negative error code on failure
*/
int snd_unregister_device(int type, snd_card_t * card, int dev)
{
int minor = snd_kernel_minor(type, card, dev);
......@@ -411,6 +442,7 @@ EXPORT_SYMBOL(snd_malloc_isa_pages_fallback);
#ifdef CONFIG_PCI
EXPORT_SYMBOL(snd_malloc_pci_pages);
EXPORT_SYMBOL(snd_malloc_pci_pages_fallback);
EXPORT_SYMBOL(snd_malloc_pci_page);
EXPORT_SYMBOL(snd_free_pci_pages);
#endif
#ifdef CONFIG_SBUS
......@@ -463,6 +495,7 @@ EXPORT_SYMBOL(snd_info_create_device);
EXPORT_SYMBOL(snd_info_free_device);
EXPORT_SYMBOL(snd_info_register);
EXPORT_SYMBOL(snd_info_unregister);
EXPORT_SYMBOL(snd_card_proc_new);
#endif
/* info_oss.c */
#if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS)
......
......@@ -942,9 +942,6 @@ static int snd_timer_user_open(struct inode *inode, struct file *file)
return -ENOMEM;
}
file->private_data = tu;
#ifdef LINUX_2_2
MOD_INC_USE_COUNT;
#endif
return 0;
}
......@@ -961,9 +958,6 @@ static int snd_timer_user_release(struct inode *inode, struct file *file)
kfree(tu->queue);
snd_magic_kfree(tu);
}
#ifdef LINUX_2_2
MOD_DEC_USE_COUNT;
#endif
return 0;
}
......
......@@ -40,7 +40,7 @@ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* MPU-401 port number */
static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* MPU-401 IRQ */
#ifdef CONFIG_PC9800
#ifdef CONFIG_X86_PC9800
static int pc98ii[SNDRV_CARDS]; /* PC98-II dauther board */
#endif
......@@ -59,7 +59,7 @@ MODULE_PARM_SYNTAX(port, SNDRV_PORT12_DESC);
MODULE_PARM(irq, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(irq, "IRQ # for MPU-401 device.");
MODULE_PARM_SYNTAX(irq, SNDRV_IRQ_DESC);
#ifdef CONFIG_PC9800
#ifdef CONFIG_X86_PC9800
MODULE_PARM(pc98ii, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(pc98ii, "Roland MPU-PC98II support.");
MODULE_PARM_SYNTAX(pc98ii, SNDRV_BOOLEAN_FALSE_DESC);
......@@ -85,7 +85,7 @@ static int __init snd_card_mpu401_probe(int dev)
if (card == NULL)
return -ENOMEM;
if (snd_mpu401_uart_new(card, 0,
#ifdef CONFIG_PC9800
#ifdef CONFIG_X86_PC9800
pc98ii[dev] ? MPU401_HW_PC98II :
#endif
MPU401_HW_MPU401,
......@@ -154,6 +154,9 @@ static int __init alsa_card_mpu401_setup(char *str)
(void)(get_option(&str,&enable[nr_dev]) == 2 &&
get_option(&str,&index[nr_dev]) == 2 &&
get_id(&str,&id[nr_dev]) == 2 &&
#ifdef CONFIG_X86_PC9800
get_option(&str,&pc98ii[nr_dev]) == 2 &&
#endif
get_option(&str,(int *)&port[nr_dev]) == 2 &&
get_option(&str,&irq[nr_dev]) == 2);
nr_dev++;
......
This diff is collapsed.
......@@ -322,17 +322,20 @@ static void snd_uart16550_buffer_timer(unsigned long data)
* return 0 if found
* return negative error if not found
*/
static int __init snd_uart16550_detect(unsigned int io_base)
static int __init snd_uart16550_detect(snd_uart16550_t *uart)
{
unsigned long io_base = uart->base;
int ok;
unsigned char c;
if (check_region(io_base, 8))
return -EBUSY;
/* Do some vague tests for the presence of the uart */
if (io_base == 0)
if (io_base == 0) {
return -ENODEV; /* Not configured */
}
uart->res_base = request_region(io_base, 8, "Serial MIDI");
if (uart->res_base == NULL)
return -EBUSY;
ok = 1; /* uart detected unless one of the following tests should fail */
/* 8 data-bits, 1 stop-bit, parity off, DLAB = 0 */
......@@ -766,11 +769,13 @@ static int __init snd_uart16550_create(snd_card_t * card,
uart->card = card;
spin_lock_init(&uart->open_lock);
uart->irq = -1;
if ((uart->res_base = request_region(iobase, 8, "Serial MIDI")) == NULL) {
snd_printk("unable to grab ports 0x%lx-0x%lx\n", iobase, iobase + 8 - 1);
return -EBUSY;
}
uart->base = iobase;
if ((err = snd_uart16550_detect(uart)) <= 0) {
printk(KERN_ERR "no UART detected at 0x%lx\n", iobase);
return err;
}
if (irq >= 0) {
if (request_irq(irq, snd_uart16550_interrupt,
SA_INTERRUPT, "Serial MIDI", (void *) uart)) {
......@@ -888,12 +893,6 @@ static int __init snd_serial_probe(int dev)
strcpy(card->driver, "Serial");
strcpy(card->shortname, "Serial midi (uart16550A)");
if ((err = snd_uart16550_detect(port[dev])) <= 0) {
snd_card_free(card);
printk(KERN_ERR "no UART detected at 0x%lx\n", (long)port[dev]);
return err;
}
if ((err = snd_uart16550_create(card,
port[dev],
irq[dev],
......
......@@ -16,7 +16,7 @@
* 2002-04-12 Tomas Kasparek Proc interface update, code cleanup
*/
/* $Id: uda1341.c,v 1.5 2002/11/09 13:12:19 perex Exp $ */
/* $Id: uda1341.c,v 1.6 2003/01/07 10:36:28 tiwai Exp $ */
#include <sound/driver.h>
#include <linux/module.h>
......@@ -128,9 +128,6 @@ struct uda1341{
snd_card_t *card;
snd_info_entry_t *proc_entry;
snd_info_entry_t *proc_regs_entry;
uda1341_cfg cfg;
};
......@@ -410,46 +407,10 @@ static void __devinit snd_uda1341_proc_init(snd_card_t *card, struct l3_client *
DEBUG_NAME(KERN_DEBUG "proc_init\n");
if ((entry = snd_info_create_card_entry(card, "uda1341", card->proc_root)) != NULL) {
entry->content = SNDRV_INFO_CONTENT_TEXT;
entry->private_data = clnt;
entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
entry->c.text.read_size = 512;
entry->c.text.read = snd_uda1341_proc_read;
if (snd_info_register(entry) < 0) {
snd_info_free_entry(entry);
entry = NULL;
}
}
uda->proc_entry = entry;
if ((entry = snd_info_create_card_entry(card, "uda1341-regs", card->proc_root)) != NULL) {
entry->content = SNDRV_INFO_CONTENT_TEXT;
entry->private_data = clnt;
entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
entry->c.text.read_size = 1024;
entry->c.text.read = snd_uda1341_proc_regs_read;
if (snd_info_register(entry) < 0) {
snd_info_free_entry(entry);
entry = NULL;
}
}
uda->proc_regs_entry = entry;
}
static void snd_uda1341_proc_done(struct l3_client *clnt)
{
struct uda1341 *uda = clnt->driver_data;
DEBUG_NAME(KERN_DEBUG "proc_done\n");
if (uda->proc_regs_entry) {
snd_info_unregister(uda->proc_regs_entry);
uda->proc_regs_entry = NULL;
}
if (uda->proc_entry) {
snd_info_unregister(uda->proc_entry);
uda->proc_entry = NULL;
}
if (! snd_card_proc_new(card, "uda1341", &entry))
snd_info_set_text_ops(entry, clnt, snd_uda1341_proc_read);
if (! snd_card_proc_new(card, "uda1341-regs", &entry)) {
snd_info_set_text_ops(entry, clnt, snd_uda1341_proc_regs_read);
}
/* }}} */
......@@ -731,7 +692,6 @@ void __init snd_chip_uda1341_mixer_del(snd_card_t *card)
{
DEBUG_NAME(KERN_DEBUG "uda1341 mixer_del\n");
snd_uda1341_proc_done(uda1341);
l3_detach_client(uda1341);
snd_magic_kfree(uda1341);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -41,18 +41,14 @@ static int snd_gus_init_dma_irq(snd_gus_card_t * gus, int latches);
int snd_gus_use_inc(snd_gus_card_t * gus)
{
MOD_INC_USE_COUNT;
if (!try_module_get(gus->card->module)) {
MOD_DEC_USE_COUNT;
if (!try_module_get(gus->card->module))
return 0;
}
return 1;
}
void snd_gus_use_dec(snd_gus_card_t * gus)
{
module_put(gus->card->module);
MOD_DEC_USE_COUNT;
}
static int snd_gus_joystick_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -297,6 +297,7 @@ EXPORT_SYMBOL(snd_sbdsp_create);
EXPORT_SYMBOL(snd_sbmixer_write);
EXPORT_SYMBOL(snd_sbmixer_read);
EXPORT_SYMBOL(snd_sbmixer_new);
EXPORT_SYMBOL(snd_sbmixer_add_ctl);
/*
* INIT part
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment