Commit f453e20d authored by Jaroslav Kysela's avatar Jaroslav Kysela

ALSA update 0.9.3a

  - PCM - recoded link group locking
  - MPU401 - replaced RX_LOOP and TX_LOOP bits with atomic_t variables
  - ICE17xx - moved ak4xxx routines to separate module (snd-ak4xxx-adda)
  - CS8427 - fixed initialization, added Q-subcode control
  - AC97 - added more patches for Wolfson codecs
  - CMIPCI - added 24-bit sample support for S/PDIF
  - maestro3 - fixes
  - via82xx - workaround for Award BIOS, dxs_support module parameter
  - ymfpci - fixed initialization
  - intel8x0 - code cleanups, recoded inialization of pcm streams
  - sa11xx-uda1341 - removed debug code and other cleanups
  - irqreturn_t cleanups
parent d4fdd3ff
......@@ -945,19 +945,34 @@ Module parameters
Module snd-via82xx
------------------
Module for AC'97 motherboards based on VIA 82C686A/686B, 8233
(south) bridge.
Module for AC'97 motherboards based on VIA 82C686A/686B, 8233,
8233A, 8233C, 8235 (south) bridge.
mpu_port - 0x300,0x310,0x320,0x330, otherwise obtain BIOS setup
[VIA686A/686B only]
ac97_clock - AC'97 codec clock base (default 48000Hz)
dxs_support - support DXS channels,
0 = auto (default), 1 = enable, 2 = disable,
3 = 48k only
[VIA8233/C,8235 only]
Module supports autoprobe and multiple bus-master chips (max 8).
Note: on some SMP motherboards like MSI 694D the interrupts might
not be generated properly. In such a case, please try to
set the SMP (or MPS) version on BIOS to 1.1 instead of
default value 1.4. Then the interrupt number will be
assigned under 15. You might also upgrade your BIOS.
Note: VIA8233/5 (not VIA8233A) can support DXS (direct sound)
channels as the first PCM. With this device, up to 4
streams can be played at the same time. If the playback on
this PCM is noisy, try to specify dxs_channels option to 2
or 3.
Note: for the MPU401 on VIA823x, use snd-mpu401 driver
additonally.
Module snd-virmidi
------------------
......
......@@ -249,7 +249,7 @@ control. In fact, the controls with "XXX [Playback|Capture]
[Volume|Switch]" will be checked in addition.
The current assignment of these mixer elements is listed in the proc
file, /proc/asound/cardX/mixer_oss, which will be like the following
file, /proc/asound/cardX/oss_mixer, which will be like the following
VOLUME "Master" 0
BASS "" 0
......@@ -267,7 +267,7 @@ For changing the assignment, you can write the configuration to this
proc file. For example, to map "Wave Playback" to the PCM volume,
send the command like the following:
% echo 'VOLUME "Wave Playback" 0' > /proc/asound/card0/mixer_oss
% echo 'VOLUME "Wave Playback" 0' > /proc/asound/card0/oss_mixer
The command is exactly as same as listed in the proc file. You can
change one or more elements, one volume per line. In the last
......
#ifndef __SOUND_AK4XXX_ADDA_H
#define __SOUND_AK4XXX_ADDA_H
/*
* ALSA driver for AK4524 / AK4528 / AK4529 / AK4355 / AK4381
* AD and DA converters
*
* Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
*
* This program is free software; 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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
*
*/
#ifndef AK4XXX_MAX_CHIPS
#define AK4XXX_MAX_CHIPS 4
#endif
typedef struct snd_akm4xxx akm4xxx_t;
struct snd_ak4xxx_ops {
void (*lock)(akm4xxx_t *ak, int chip);
void (*unlock)(akm4xxx_t *ak, int chip);
void (*write)(akm4xxx_t *ak, int chip, unsigned char reg, unsigned char val);
// unsigned char (*read)(akm4xxx_t *ak, int chip, unsigned char reg);
void (*set_rate_val)(akm4xxx_t *ak, unsigned int rate);
};
struct snd_akm4xxx {
snd_card_t *card;
unsigned int num_adcs; /* AK4524 or AK4528 ADCs */
unsigned int num_dacs; /* AK4524 or AK4528 DACs */
unsigned char images[AK4XXX_MAX_CHIPS][16]; /* saved register image */
unsigned char ipga_gain[AK4XXX_MAX_CHIPS][2]; /* saved register image for IPGA (AK4528) */
unsigned long private_value[AK4XXX_MAX_CHIPS]; /* helper for driver */
void *private_data[AK4XXX_MAX_CHIPS]; /* helper for driver */
/* template should fill the following fields */
unsigned int idx_offset; /* control index offset */
enum {
SND_AK4524, SND_AK4528, SND_AK4529, SND_AK4355, SND_AK4381
} type;
struct snd_ak4xxx_ops ops;
};
void snd_akm4xxx_write(akm4xxx_t *ak, int chip, unsigned char reg, unsigned char val);
void snd_akm4xxx_reset(akm4xxx_t *ak, int state);
void snd_akm4xxx_init(akm4xxx_t *ak);
int snd_akm4xxx_build_controls(akm4xxx_t *ak);
#endif /* __SOUND_AK4XXX_ADDA_H */
......@@ -184,7 +184,7 @@ static inline void snd_power_unlock(snd_card_t *card)
up(&card->power_lock);
}
void snd_power_wait(snd_card_t *card);
int snd_power_wait(snd_card_t *card, unsigned int power_state, struct file *file);
static inline unsigned int snd_power_get_state(snd_card_t *card)
{
......@@ -199,7 +199,7 @@ static inline void snd_power_change_state(snd_card_t *card, unsigned int state)
#else
#define snd_power_lock(card) do { (void)(card); } while (0)
#define snd_power_unlock(card) do { (void)(card); } while (0)
#define snd_power_wait(card) do { (void)(card); } while (0)
static inline int snd_power_wait(snd_card_t *card, unsigned int state, struct file *file) { return 0; }
#define snd_power_get_state(card) SNDRV_CTL_POWER_D0
#define snd_power_change_state(card, state) do { (void)(card); } while (0)
#endif
......
......@@ -48,7 +48,7 @@
#define CS8427_REG_UDATABUF 0x13
#define CS8427_REG_QSUBCODE 0x14 /* 0x14-0x1d (10 bytes) */
#define CS8427_REG_OMCKRMCKRATIO 0x1e
#define CS8427_REG_CORU_DATABUF 0x20
#define CS8427_REG_CORU_DATABUF 0x20 /* 24 byte buffer area */
#define CS8427_REG_ID_AND_VER 0x7f
/* CS8427_REG_CONTROL1 bits */
......@@ -188,6 +188,7 @@
int snd_cs8427_detect(snd_i2c_bus_t *bus, unsigned char addr);
int snd_cs8427_create(snd_i2c_bus_t *bus, unsigned char addr, snd_i2c_device_t **r_cs8427);
void snd_cs8427_reset(snd_i2c_device_t *cs8427);
int snd_cs8427_iec958_build(snd_i2c_device_t *cs8427, snd_pcm_substream_t *playback_substream, snd_pcm_substream_t *capture_substream);
int snd_cs8427_iec958_active(snd_i2c_device_t *cs8427, int active);
int snd_cs8427_iec958_pcm(snd_i2c_device_t *cs8427, unsigned int rate);
......
......@@ -22,7 +22,6 @@
*
*/
#include <linux/interrupt.h>
#include "rawmidi.h"
#include <linux/interrupt.h>
......@@ -50,8 +49,6 @@
#define MPU401_MODE_BIT_OUTPUT 1
#define MPU401_MODE_BIT_INPUT_TRIGGER 2
#define MPU401_MODE_BIT_OUTPUT_TRIGGER 3
#define MPU401_MODE_BIT_RX_LOOP 4
#define MPU401_MODE_BIT_TX_LOOP 5
#define MPU401_MODE_INPUT (1<<MPU401_MODE_BIT_INPUT)
#define MPU401_MODE_OUTPUT (1<<MPU401_MODE_BIT_OUTPUT)
......@@ -89,6 +86,9 @@ struct _snd_mpu401 {
spinlock_t output_lock;
spinlock_t timer_lock;
atomic_t rx_loop;
atomic_t tx_loop;
struct timer_list timer;
void (*write) (mpu401_t * mpu, unsigned char data, unsigned long addr);
......
......@@ -328,7 +328,6 @@ struct _snd_pcm_runtime {
atomic_t mmap_count;
/* -- locking / scheduling -- */
spinlock_t lock;
wait_queue_head_t sleep;
struct timer_list tick_timer;
struct fasync_struct *fasync;
......@@ -360,6 +359,11 @@ struct _snd_pcm_runtime {
#endif
};
typedef struct _snd_pcm_group { /* keep linked substreams */
spinlock_t lock;
struct list_head substreams;
} snd_pcm_group_t;
struct _snd_pcm_substream {
snd_pcm_t *pcm;
snd_pcm_str_t *pstr;
......@@ -383,8 +387,10 @@ struct _snd_pcm_substream {
/* -- next substream -- */
snd_pcm_substream_t *next;
/* -- linked substreams -- */
snd_pcm_substream_t *link_next;
snd_pcm_substream_t *link_prev;
struct list_head link_list; /* linked list member */
snd_pcm_group_t self_group; /* fake group for non linked substream (with substream lock inside) */
snd_pcm_group_t *group; /* pointer to current group */
/* -- assigned files -- */
snd_pcm_file_t *file;
struct file *ffile;
#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
......@@ -468,6 +474,8 @@ int snd_pcm_notify(snd_pcm_notify_t *notify, int nfree);
* Native I/O
*/
extern rwlock_t snd_pcm_link_rwlock;
int snd_pcm_info(snd_pcm_substream_t * substream, snd_pcm_info_t *info);
int snd_pcm_info_user(snd_pcm_substream_t * substream, snd_pcm_info_t *info);
int snd_pcm_status(snd_pcm_substream_t * substream, snd_pcm_status_t *status);
......@@ -568,6 +576,53 @@ static inline void div64_32(u_int64_t *n, u_int32_t div, u_int32_t *rem)
* PCM library
*/
static inline int snd_pcm_stream_linked(snd_pcm_substream_t *substream)
{
return substream->group != &substream->self_group;
}
static inline void snd_pcm_stream_lock(snd_pcm_substream_t *substream)
{
read_lock(&snd_pcm_link_rwlock);
spin_lock(&substream->self_group.lock);
}
static inline void snd_pcm_stream_unlock(snd_pcm_substream_t *substream)
{
spin_unlock(&substream->self_group.lock);
read_unlock(&snd_pcm_link_rwlock);
}
static inline void snd_pcm_stream_lock_irq(snd_pcm_substream_t *substream)
{
read_lock_irq(&snd_pcm_link_rwlock);
spin_lock(&substream->self_group.lock);
}
static inline void snd_pcm_stream_unlock_irq(snd_pcm_substream_t *substream)
{
spin_unlock(&substream->self_group.lock);
read_unlock_irq(&snd_pcm_link_rwlock);
}
#define snd_pcm_stream_lock_irqsave(substream, flags) \
do { \
read_lock_irqsave(&snd_pcm_link_rwlock, (flags)); \
spin_lock(&substream->self_group.lock); \
} while (0)
#define snd_pcm_stream_unlock_irqrestore(substream, flags) \
do { \
spin_unlock(&substream->self_group.lock); \
read_unlock_irqrestore(&snd_pcm_link_rwlock, (flags)); \
} while (0)
#define snd_pcm_group_for_each(pos, substream) \
list_for_each(pos, &substream->group->substreams)
#define snd_pcm_group_substream_entry(pos) \
list_entry(pos, snd_pcm_substream_t, link_list)
static inline int snd_pcm_running(snd_pcm_substream_t *substream)
{
return (substream->runtime->status->state == SNDRV_PCM_STATE_RUNNING ||
......
......@@ -295,13 +295,13 @@ int snd_sbmixer_new(sb_t *chip);
/* sb8_init.c */
int snd_sb8dsp_pcm(sb_t *chip, int device, snd_pcm_t ** rpcm);
/* sb8.c */
void snd_sb8dsp_interrupt(sb_t *chip);
irqreturn_t snd_sb8dsp_interrupt(sb_t *chip);
int snd_sb8_playback_open(snd_pcm_substream_t *substream);
int snd_sb8_capture_open(snd_pcm_substream_t *substream);
int snd_sb8_playback_close(snd_pcm_substream_t *substream);
int snd_sb8_capture_close(snd_pcm_substream_t *substream);
/* midi8.c */
void snd_sb8dsp_midi_interrupt(sb_t *chip);
irqreturn_t snd_sb8dsp_midi_interrupt(sb_t *chip);
int snd_sb8dsp_midi(sb_t *chip, int device, snd_rawmidi_t ** rrawmidi);
/* sb16_init.c */
......
......@@ -57,14 +57,8 @@
/* Trident chipsets have 1GB memory limit */
#ifdef __alpha__
#define TRIDENT_DMA_TYPE SNDRV_DMA_TYPE_PCI_16MB
#define TRIDENT_GFP_FLAGS GFP_DMA
#else
#define TRIDENT_DMA_TYPE SNDRV_DMA_TYPE_PCI
#if defined(__i386__) && !defined(CONFIG_1GB)
#define TRIDENT_GFP_FLAGS GFP_DMA
#else
#define TRIDENT_GFP_FLAGS 0
#endif
#endif
#define SNDRV_SEQ_DEV_ID_TRIDENT "trident-synth"
......
......@@ -15,7 +15,7 @@
* features support
*/
/* $Id: uda1341.h,v 1.4 2003/02/25 12:48:16 perex Exp $ */
/* $Id: uda1341.h,v 1.5 2003/04/19 13:34:32 perex Exp $ */
#define UDA1341_ALSA_NAME "snd-uda1341"
......@@ -210,6 +210,10 @@ enum uda1341_config {
CMD_IG,
CMD_AGC_TIME,
CMD_AGC_LEVEL,
#ifdef CONFIG_PM
CMD_SUSPEND,
CMD_RESUME,
#endif
CMD_LAST,
};
......@@ -221,19 +225,6 @@ enum write_through {
};
int __init snd_chip_uda1341_mixer_new(snd_card_t *card, struct l3_client **clnt);
void __init snd_chip_uda1341_mixer_del(snd_card_t *card);
#ifdef DEBUG_MODE
#define DEBUG(format, args...) do{printk(format, ##args);}while(0)
#else
#define DEBUG(format, args...) /* nothing */
#endif
#ifdef DEBUG_FUNCTION_NAMES
#define DEBUG_NAME(format, args...) do{printk(format, ##args);}while(0)
#else
#define DEBUG_NAME(format, args...) /* nothing */
#endif
/*
* Local variables:
......
/* include/version.h. Generated by configure. */
#define CONFIG_SND_VERSION "0.9.2"
#define CONFIG_SND_DATE " (Fri Apr 11 07:44:21 2003 UTC)"
#define CONFIG_SND_VERSION "0.9.3a"
#define CONFIG_SND_DATE " (Thu May 08 07:41:58 2003 UTC)"
This diff is collapsed.
......@@ -78,6 +78,7 @@ obj-$(CONFIG_SND_ES1938) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-hwd
obj-$(CONFIG_SND_ES1968) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o
obj-$(CONFIG_SND_FM801) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
obj-$(CONFIG_SND_ICE1712) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o
obj-$(CONFIG_SND_ICE1724) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o
obj-$(CONFIG_SND_INTEL8X0) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o
obj-$(CONFIG_SND_MAESTRO3) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o
obj-$(CONFIG_SND_RME32) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o
......
......@@ -396,10 +396,6 @@ static snd_kcontrol_t *_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id)
continue;
if (kctl->id.index + kctl->count <= id->index)
continue;
if (kctl->id.index != id->index) {
printk("BOOOR: %i, %i, %i\n", kctl->id.index, kctl->count, id->index);
continue;
}
return kctl;
}
return NULL;
......
......@@ -252,6 +252,10 @@ int snd_card_free(snd_card_t * card)
snd_cards_count--;
write_unlock(&snd_card_rwlock);
#ifdef CONFIG_PM
wake_up(&card->power_sleep);
#endif
/* wait, until all devices are ready for the free operation */
wait_event(card->shutdown_sleep, card->files == NULL);
......@@ -662,21 +666,35 @@ int snd_card_file_remove(snd_card_t *card, struct file *file)
/**
* snd_power_wait - wait until the power-state is changed.
* @card: soundcard structure
* @power_state: expected power state
* @file: file structure for the O_NONBLOCK check (optional)
*
* Waits until the power-state is changed.
*
* Note: the power lock must be active before call.
*/
void snd_power_wait(snd_card_t *card)
int snd_power_wait(snd_card_t *card, unsigned int power_state, struct file *file)
{
wait_queue_t wait;
/* fastpath */
if (snd_power_get_state(card) == power_state)
return 0;
init_waitqueue_entry(&wait, current);
add_wait_queue(&card->power_sleep, &wait);
while (1) {
if (card->shutdown)
return -ENODEV;
if (snd_power_get_state(card) == power_state) {
remove_wait_queue(&card->power_sleep, &wait);
return 0;
}
if (file && (file->f_flags & O_NONBLOCK))
return -EAGAIN;
snd_power_unlock(card);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(30 * HZ);
remove_wait_queue(&card->power_sleep, &wait);
snd_power_lock(card);
}
}
#endif /* CONFIG_PM */
......@@ -21,7 +21,6 @@
#include <sound/driver.h>
#include <linux/time.h>
#include <linux/slab.h>
#include <linux/compat.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include "ioctl32.h"
......@@ -137,10 +136,15 @@ struct sndrv_pcm_channel_info32 {
COPY(step);\
}
struct timeval32 {
s32 tv_sec;
s32 tv_usec;
} __attribute__((packed));
struct sndrv_pcm_status32 {
s32 state;
struct compat_timespec trigger_tstamp;
struct compat_timespec tstamp;
struct timeval32 trigger_tstamp;
struct timeval32 tstamp;
u32 appl_ptr;
u32 hw_ptr;
s32 delay;
......@@ -155,9 +159,9 @@ struct sndrv_pcm_status32 {
{\
COPY(state);\
COPY(trigger_tstamp.tv_sec);\
COPY(trigger_tstamp.tv_nsec);\
COPY(trigger_tstamp.tv_usec);\
COPY(tstamp.tv_sec);\
COPY(tstamp.tv_nsec);\
COPY(tstamp.tv_usec);\
COPY(appl_ptr);\
COPY(hw_ptr);\
COPY(delay);\
......
......@@ -21,7 +21,6 @@
#include <sound/driver.h>
#include <linux/time.h>
#include <linux/fs.h>
#include <linux/compat.h>
#include <sound/core.h>
#include <sound/rawmidi.h>
#include <asm/uaccess.h>
......@@ -43,9 +42,14 @@ struct sndrv_rawmidi_params32 {
COPY(no_active_sensing);\
}
struct timeval32 {
s32 tv_sec;
s32 tv_usec;
} __attribute__((packed));
struct sndrv_rawmidi_status32 {
s32 stream;
struct compat_timespec tstamp;
struct timeval32 tstamp;
u32 avail;
u32 xruns;
unsigned char reserved[16];
......@@ -55,7 +59,7 @@ struct sndrv_rawmidi_status32 {
{\
COPY(stream);\
COPY(tstamp.tv_sec);\
COPY(tstamp.tv_nsec);\
COPY(tstamp.tv_usec);\
COPY(avail);\
COPY(xruns);\
}
......
......@@ -21,7 +21,6 @@
#include <sound/driver.h>
#include <linux/time.h>
#include <linux/fs.h>
#include <linux/compat.h>
#include <sound/core.h>
#include <sound/timer.h>
#include <asm/uaccess.h>
......@@ -32,7 +31,7 @@ struct sndrv_timer_info32 {
s32 card;
unsigned char id[64];
unsigned char name[80];
u32 reserved0;
u32 ticks;
u32 resolution;
unsigned char reserved[64];
};
......@@ -43,11 +42,17 @@ struct sndrv_timer_info32 {
COPY(card);\
memcpy(dst->id, src->id, sizeof(src->id));\
memcpy(dst->name, src->name, sizeof(src->name));\
COPY(ticks);\
COPY(resolution);\
}
struct timeval32 {
s32 tv_sec;
s32 tv_usec;
};
struct sndrv_timer_status32 {
struct compat_timespec tstamp;
struct timeval32 tstamp;
u32 resolution;
u32 lost;
u32 overrun;
......@@ -58,7 +63,7 @@ struct sndrv_timer_status32 {
#define CVT_sndrv_timer_status()\
{\
COPY(tstamp.tv_sec);\
COPY(tstamp.tv_nsec);\
COPY(tstamp.tv_usec);\
COPY(resolution);\
COPY(lost);\
COPY(overrun);\
......
......@@ -27,6 +27,7 @@
#include <linux/proc_fs.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <asm/semaphore.h>
#include <sound/memalloc.h>
......@@ -97,7 +98,7 @@ struct snd_mem_list {
* again.
*/
void *snd_pci_hack_alloc_consistent(struct pci_dev *hwdev, size_t size,
static void *snd_pci_hack_alloc_consistent(struct pci_dev *hwdev, size_t size,
dma_addr_t *dma_handle)
{
void *ret;
......
......@@ -1477,10 +1477,10 @@ static int snd_pcm_oss_release_file(snd_pcm_oss_file_t *pcm_oss_file)
continue;
runtime = substream->runtime;
spin_lock_irq(&runtime->lock);
snd_pcm_stream_lock_irq(substream);
if (snd_pcm_running(substream))
snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
spin_unlock_irq(&runtime->lock);
snd_pcm_stream_unlock_irq(substream);
if (substream->open_flag) {
if (substream->ops->hw_free != NULL)
substream->ops->hw_free(substream);
......@@ -1918,21 +1918,21 @@ static unsigned int snd_pcm_oss_poll(struct file *file, poll_table * wait)
if (psubstream != NULL) {
snd_pcm_runtime_t *runtime = psubstream->runtime;
poll_wait(file, &runtime->sleep, wait);
spin_lock_irq(&runtime->lock);
snd_pcm_stream_lock_irq(psubstream);
if (runtime->status->state != SNDRV_PCM_STATE_DRAINING &&
(runtime->status->state != SNDRV_PCM_STATE_RUNNING ||
snd_pcm_oss_playback_ready(psubstream)))
mask |= POLLOUT | POLLWRNORM;
spin_unlock_irq(&runtime->lock);
snd_pcm_stream_unlock_irq(psubstream);
}
if (csubstream != NULL) {
snd_pcm_runtime_t *runtime = csubstream->runtime;
poll_wait(file, &runtime->sleep, wait);
spin_lock_irq(&runtime->lock);
snd_pcm_stream_lock_irq(csubstream);
if (runtime->status->state != SNDRV_PCM_STATE_RUNNING ||
snd_pcm_oss_capture_ready(csubstream))
mask |= POLLIN | POLLRDNORM;
spin_unlock_irq(&runtime->lock);
snd_pcm_stream_unlock_irq(csubstream);
}
return mask;
......
......@@ -317,10 +317,10 @@ static void snd_pcm_substream_proc_hw_params_read(snd_info_entry_t *entry, snd_i
snd_iprintf(buffer, "closed\n");
return;
}
spin_lock_irq(&runtime->lock);
snd_pcm_stream_lock_irq(substream);
if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
snd_iprintf(buffer, "no setup\n");
spin_unlock_irq(&runtime->lock);
snd_pcm_stream_unlock_irq(substream);
return;
}
snd_iprintf(buffer, "access: %s\n", snd_pcm_access_name(runtime->access));
......@@ -340,7 +340,7 @@ static void snd_pcm_substream_proc_hw_params_read(snd_info_entry_t *entry, snd_i
snd_iprintf(buffer, "OSS periods: %u\n", runtime->oss.periods);
}
#endif
spin_unlock_irq(&runtime->lock);
snd_pcm_stream_unlock_irq(substream);
}
static void snd_pcm_substream_proc_sw_params_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
......@@ -351,10 +351,10 @@ static void snd_pcm_substream_proc_sw_params_read(snd_info_entry_t *entry, snd_i
snd_iprintf(buffer, "closed\n");
return;
}
spin_lock_irq(&runtime->lock);
snd_pcm_stream_lock_irq(substream);
if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
snd_iprintf(buffer, "no setup\n");
spin_unlock_irq(&runtime->lock);
snd_pcm_stream_unlock_irq(substream);
return;
}
snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode));
......@@ -367,7 +367,7 @@ static void snd_pcm_substream_proc_sw_params_read(snd_info_entry_t *entry, snd_i
snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold);
snd_iprintf(buffer, "silence_size: %lu\n", runtime->silence_size);
snd_iprintf(buffer, "boundary: %lu\n", runtime->boundary);
spin_unlock_irq(&runtime->lock);
snd_pcm_stream_unlock_irq(substream);
}
static void snd_pcm_substream_proc_status_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
......@@ -588,13 +588,15 @@ int snd_pcm_new_stream(snd_pcm_t *pcm, int stream, int substream_count)
pstr->substream = substream;
else
prev->next = substream;
substream->link_next = substream;
substream->link_prev = substream;
err = snd_pcm_substream_proc_init(substream);
if (err < 0) {
snd_magic_kfree(substream);
return err;
}
substream->group = &substream->self_group;
spin_lock_init(&substream->self_group.lock);
INIT_LIST_HEAD(&substream->self_group.substreams);
list_add_tail(&substream->link_list, &substream->self_group.substreams);
spin_lock_init(&substream->timer_lock);
prev = substream;
}
......@@ -793,7 +795,6 @@ int snd_pcm_open_substream(snd_pcm_t *pcm, int stream,
memset((void*)runtime->control, 0, size);
init_waitqueue_head(&runtime->sleep);
spin_lock_init(&runtime->lock);
atomic_set(&runtime->mmap_count, 0);
init_timer(&runtime->tick_timer);
runtime->tick_timer.function = snd_pcm_tick_timer_func;
......@@ -1022,6 +1023,7 @@ EXPORT_SYMBOL(snd_pcm_release_substream);
EXPORT_SYMBOL(snd_pcm_format_name);
EXPORT_SYMBOL(snd_pcm_subformat_name);
/* pcm_native.c */
EXPORT_SYMBOL(snd_pcm_link_rwlock);
EXPORT_SYMBOL(snd_pcm_start);
#ifdef CONFIG_PM
EXPORT_SYMBOL(snd_pcm_suspend);
......
......@@ -126,7 +126,7 @@ void snd_pcm_playback_silence(snd_pcm_substream_t *substream, snd_pcm_uframes_t
}
}
int snd_pcm_update_hw_ptr_interrupt(snd_pcm_substream_t *substream)
static inline int snd_pcm_update_hw_ptr_interrupt(snd_pcm_substream_t *substream)
{
snd_pcm_runtime_t *runtime = substream->runtime;
snd_pcm_uframes_t pos;
......@@ -1976,18 +1976,20 @@ void snd_pcm_tick_prepare(snd_pcm_substream_t *substream)
void snd_pcm_tick_elapsed(snd_pcm_substream_t *substream)
{
snd_pcm_runtime_t *runtime;
unsigned long flags;
snd_assert(substream != NULL, return);
runtime = substream->runtime;
snd_assert(runtime != NULL, return);
spin_lock_irq(&runtime->lock);
snd_pcm_stream_lock_irqsave(substream, flags);
if (!snd_pcm_running(substream) ||
snd_pcm_update_hw_ptr(substream) < 0)
goto _end;
if (runtime->sleep_min)
snd_pcm_tick_prepare(substream);
_end:
spin_unlock_irq(&runtime->lock);
snd_pcm_stream_unlock_irqrestore(substream, flags);
}
/**
......@@ -2004,6 +2006,8 @@ void snd_pcm_tick_elapsed(snd_pcm_substream_t *substream)
void snd_pcm_period_elapsed(snd_pcm_substream_t *substream)
{
snd_pcm_runtime_t *runtime;
unsigned long flags;
snd_assert(substream != NULL, return);
runtime = substream->runtime;
snd_assert(runtime != NULL, return);
......@@ -2011,7 +2015,7 @@ void snd_pcm_period_elapsed(snd_pcm_substream_t *substream)
if (runtime->transfer_ack_begin)
runtime->transfer_ack_begin(substream);
spin_lock(&runtime->lock);
snd_pcm_stream_lock_irqsave(substream, flags);
if (!snd_pcm_running(substream) ||
snd_pcm_update_hw_ptr_interrupt(substream) < 0)
goto _end;
......@@ -2021,7 +2025,7 @@ void snd_pcm_period_elapsed(snd_pcm_substream_t *substream)
if (runtime->sleep_min)
snd_pcm_tick_prepare(substream);
_end:
spin_unlock(&runtime->lock);
snd_pcm_stream_unlock_irqrestore(substream, flags);
if (runtime->transfer_ack_end)
runtime->transfer_ack_end(substream);
kill_fasync(&runtime->fasync, SIGIO, POLL_IN);
......@@ -2065,7 +2069,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(snd_pcm_substream_t *substream,
if (size > runtime->xfer_align)
size -= size % runtime->xfer_align;
spin_lock_irq(&runtime->lock);
snd_pcm_stream_lock_irq(substream);
switch (runtime->status->state) {
case SNDRV_PCM_STATE_PREPARED:
case SNDRV_PCM_STATE_RUNNING:
......@@ -2107,16 +2111,16 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(snd_pcm_substream_t *substream,
state = SIGNALED;
break;
}
spin_unlock_irq(&runtime->lock);
snd_pcm_stream_unlock_irq(substream);
if (schedule_timeout(10 * HZ) == 0) {
spin_lock_irq(&runtime->lock);
snd_pcm_stream_lock_irq(substream);
if (runtime->status->state != SNDRV_PCM_STATE_PREPARED &&
runtime->status->state != SNDRV_PCM_STATE_PAUSED) {
state = runtime->status->state == SNDRV_PCM_STATE_SUSPENDED ? SUSPENDED : EXPIRED;
break;
}
}
spin_lock_irq(&runtime->lock);
snd_pcm_stream_lock_irq(substream);
switch (runtime->status->state) {
case SNDRV_PCM_STATE_XRUN:
case SNDRV_PCM_STATE_DRAINING:
......@@ -2162,15 +2166,13 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(snd_pcm_substream_t *substream,
cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size;
if (frames > cont)
frames = cont;
snd_assert(frames != 0,
spin_unlock_irq(&runtime->lock);
return -EINVAL);
snd_assert(frames != 0, snd_pcm_stream_unlock_irq(substream); return -EINVAL);
appl_ptr = runtime->control->appl_ptr;
appl_ofs = appl_ptr % runtime->buffer_size;
spin_unlock_irq(&runtime->lock);
snd_pcm_stream_unlock_irq(substream);
if ((err = transfer(substream, appl_ofs, (void *)data, offset, frames)) < 0)
goto _end;
spin_lock_irq(&runtime->lock);
snd_pcm_stream_lock_irq(substream);
switch (runtime->status->state) {
case SNDRV_PCM_STATE_XRUN:
err = -EPIPE;
......@@ -2204,7 +2206,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(snd_pcm_substream_t *substream,
snd_pcm_tick_prepare(substream);
}
_end_unlock:
spin_unlock_irq(&runtime->lock);
snd_pcm_stream_unlock_irq(substream);
_end:
return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
}
......@@ -2348,7 +2350,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(snd_pcm_substream_t *substream, void
if (size > runtime->xfer_align)
size -= size % runtime->xfer_align;
spin_lock_irq(&runtime->lock);
snd_pcm_stream_lock_irq(substream);
switch (runtime->status->state) {
case SNDRV_PCM_STATE_PREPARED:
if (size >= runtime->start_threshold) {
......@@ -2403,16 +2405,16 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(snd_pcm_substream_t *substream, void
state = SIGNALED;
break;
}
spin_unlock_irq(&runtime->lock);
snd_pcm_stream_unlock_irq(substream);
if (schedule_timeout(10 * HZ) == 0) {
spin_lock_irq(&runtime->lock);
snd_pcm_stream_lock_irq(substream);
if (runtime->status->state != SNDRV_PCM_STATE_PREPARED &&
runtime->status->state != SNDRV_PCM_STATE_PAUSED) {
state = runtime->status->state == SNDRV_PCM_STATE_SUSPENDED ? SUSPENDED : EXPIRED;
break;
}
}
spin_lock_irq(&runtime->lock);
snd_pcm_stream_lock_irq(substream);
switch (runtime->status->state) {
case SNDRV_PCM_STATE_XRUN:
state = ERROR;
......@@ -2459,15 +2461,13 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(snd_pcm_substream_t *substream, void
cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size;
if (frames > cont)
frames = cont;
snd_assert(frames != 0,
spin_unlock_irq(&runtime->lock);
return -EINVAL);
snd_assert(frames != 0, snd_pcm_stream_unlock_irq(substream); return -EINVAL);
appl_ptr = runtime->control->appl_ptr;
appl_ofs = appl_ptr % runtime->buffer_size;
spin_unlock_irq(&runtime->lock);
snd_pcm_stream_unlock_irq(substream);
if ((err = transfer(substream, appl_ofs, (void *)data, offset, frames)) < 0)
goto _end;
spin_lock_irq(&runtime->lock);
snd_pcm_stream_lock_irq(substream);
switch (runtime->status->state) {
case SNDRV_PCM_STATE_XRUN:
err = -EPIPE;
......@@ -2495,7 +2495,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(snd_pcm_substream_t *substream, void
snd_pcm_tick_prepare(substream);
}
_end_unlock:
spin_unlock_irq(&runtime->lock);
snd_pcm_stream_unlock_irq(substream);
_end:
return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
}
......
This diff is collapsed.
......@@ -74,6 +74,7 @@ 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_ICE1724)) += $(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)
......
......@@ -20,9 +20,9 @@
*/
#include <linux/config.h>
#include <linux/version.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <sound/memalloc.h>
......
......@@ -342,6 +342,7 @@ static int __init alsa_sound_init(void)
devfs_mk_dir("snd");
if (register_chrdev(major, "alsa", &snd_fops)) {
snd_printk(KERN_ERR "unable to register native major device number %d\n", major);
devfs_remove("snd");
return -EIO;
}
#ifdef CONFIG_SND_DEBUG_MEMORY
......@@ -351,6 +352,8 @@ static int __init alsa_sound_init(void)
#ifdef CONFIG_SND_DEBUG_MEMORY
snd_memory_done();
#endif
unregister_chrdev(major, "alsa");
devfs_remove("snd");
return -ENOMEM;
}
#ifdef CONFIG_SND_OSSEMUL
......
......@@ -31,6 +31,7 @@ obj-$(CONFIG_SND_ES1938) += snd-mpu401-uart.o
obj-$(CONFIG_SND_ES1968) += snd-mpu401-uart.o
obj-$(CONFIG_SND_FM801) += snd-mpu401-uart.o
obj-$(CONFIG_SND_ICE1712) += snd-mpu401-uart.o
obj-$(CONFIG_SND_ICE1724) += snd-mpu401-uart.o
obj-$(CONFIG_SND_INTEL8X0) += snd-mpu401-uart.o
obj-$(CONFIG_SND_SONICVIBES) += snd-mpu401-uart.o
obj-$(CONFIG_SND_VIA82XX) += snd-mpu401-uart.o
......
......@@ -90,27 +90,27 @@ static void snd_mpu401_uart_clear_rx(mpu401_t *mpu)
#endif
}
static irqreturn_t _snd_mpu401_uart_interrupt(mpu401_t *mpu)
static void _snd_mpu401_uart_interrupt(mpu401_t *mpu)
{
if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) {
if (! test_and_set_bit(MPU401_MODE_BIT_RX_LOOP, &mpu->mode)) {
spin_lock(&mpu->input_lock);
if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) {
atomic_dec(&mpu->rx_loop);
snd_mpu401_uart_input_read(mpu);
spin_unlock(&mpu->input_lock);
clear_bit(MPU401_MODE_BIT_RX_LOOP, &mpu->mode);
}
} else
atomic_inc(&mpu->rx_loop);
} else {
snd_mpu401_uart_clear_rx(mpu);
}
spin_unlock(&mpu->input_lock);
/* ok. for better Tx performance try do some output when input is done */
if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) &&
test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) {
spin_lock(&mpu->output_lock);
if (spin_trylock(&mpu->output_lock)) {
atomic_dec(&mpu->tx_loop);
snd_mpu401_uart_output_write(mpu);
atomic_inc(&mpu->tx_loop);
spin_unlock(&mpu->output_lock);
}
/* FIXME! This should really check whether the irq was for us */
return IRQ_HANDLED;
}
}
/**
......@@ -127,7 +127,8 @@ irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id, struct pt_regs *reg
if (mpu == NULL)
return IRQ_NONE;
return _snd_mpu401_uart_interrupt(mpu);
_snd_mpu401_uart_interrupt(mpu);
return IRQ_HANDLED;
}
/*
......@@ -242,6 +243,7 @@ static int snd_mpu401_uart_input_open(snd_rawmidi_substream_t * substream)
snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1);
}
mpu->substream_input = substream;
atomic_set(&mpu->rx_loop, 1);
set_bit(MPU401_MODE_BIT_INPUT, &mpu->mode);
return 0;
}
......@@ -259,6 +261,7 @@ static int snd_mpu401_uart_output_open(snd_rawmidi_substream_t * substream)
snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1);
}
mpu->substream_output = substream;
atomic_set(&mpu->tx_loop, 1);
set_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode);
return 0;
}
......@@ -312,12 +315,15 @@ static void snd_mpu401_uart_input_trigger(snd_rawmidi_substream_t * substream, i
/* read data in advance */
/* prevent double enter via rawmidi->event callback */
if (! test_and_set_bit(MPU401_MODE_BIT_RX_LOOP, &mpu->mode)) {
spin_lock_irqsave(&mpu->input_lock, flags);
if (atomic_dec_and_test(&mpu->rx_loop)) {
local_irq_save(flags);
if (spin_trylock(&mpu->input_lock)) {
snd_mpu401_uart_input_read(mpu);
spin_unlock_irqrestore(&mpu->input_lock, flags);
clear_bit(MPU401_MODE_BIT_RX_LOOP, &mpu->mode);
spin_unlock(&mpu->input_lock);
}
local_irq_restore(flags);
}
atomic_inc(&mpu->rx_loop);
} else {
if (mpu->irq < 0)
snd_mpu401_uart_remove_timer(mpu, 1);
......@@ -371,9 +377,11 @@ static void snd_mpu401_uart_output_write(mpu401_t * mpu)
break;
}
}
if (timeout == 0)
break; /* Tx FIFO full - try again later */
} else {
snd_mpu401_uart_remove_timer (mpu, 0);
max = 1; /* no other data - leave the tx loop */
break; /* no other data - leave the tx loop */
}
} while (--max > 0);
}
......@@ -389,6 +397,7 @@ static void snd_mpu401_uart_output_trigger(snd_rawmidi_substream_t * substream,
mpu = snd_magic_cast(mpu401_t, substream->rmidi->private_data, return);
if (up) {
set_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode);
/* try to add the timer at each output trigger,
* since the output timer might have been removed in
* snd_mpu401_uart_output_write().
......@@ -397,12 +406,15 @@ static void snd_mpu401_uart_output_trigger(snd_rawmidi_substream_t * substream,
/* output pending data */
/* prevent double enter via rawmidi->event callback */
if (! test_and_set_bit(MPU401_MODE_BIT_TX_LOOP, &mpu->mode)) {
spin_lock_irqsave(&mpu->output_lock, flags);
if (atomic_dec_and_test(&mpu->tx_loop)) {
local_irq_save(flags);
if (spin_trylock(&mpu->output_lock)) {
snd_mpu401_uart_output_write(mpu);
spin_unlock_irqrestore(&mpu->output_lock, flags);
clear_bit(MPU401_MODE_BIT_TX_LOOP, &mpu->mode);
spin_unlock(&mpu->output_lock);
}
local_irq_restore(flags);
}
atomic_inc(&mpu->tx_loop);
} else {
snd_mpu401_uart_remove_timer(mpu, 0);
clear_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode);
......
......@@ -160,18 +160,12 @@ static int snd_opl3_detect(opl3_t * opl3)
opl3->hardware = OPL3_HW_OPL2;
} else {
/*
* Detect availability of OPL4. Unfortunately, the OPL4
* port of the chip may not be connected to the PC bus.
* If we had an OPL4 chip, opl3->hardware would have been set
* by the OPL4 driver; so we can assume OPL3 here.
*/
snd_assert(opl3->r_port != 0, return -ENODEV);
opl3->command(opl3, OPL3_RIGHT | OPL3_REG_MODE, OPL3_OPL3_ENABLE | OPL3_OPL4_ENABLE);
/* All OPL4 registers are readable. */
if (inb(opl3->r_port + 1) == (OPL3_OPL3_ENABLE | OPL3_OPL4_ENABLE)) {
opl3->hardware = OPL3_HW_OPL4;
} else {
opl3->hardware = OPL3_HW_OPL3;
}
}
return 0;
}
......
......@@ -11,6 +11,8 @@ ifeq ($(subst m,y,$(CONFIG_L3)),y)
obj-$(CONFIG_L3) += l3/
endif
obj-$(CONFIG_SND) += other/
# Toplevel Module Dependency
obj-$(CONFIG_SND_INTERWAVE_STB) += snd-tea6330t.o snd-i2c.o
obj-$(CONFIG_SND_ICE1712) += snd-cs8427.o snd-i2c.o
This diff is collapsed.
This diff is collapsed.
#
# Makefile for ALSA
# Copyright (c) 2003 by Jaroslav Kysela <perex@suse.cz>
#
snd-ak4xxx-adda-objs := ak4xxx-adda.o
# Module Dependency
obj-$(CONFIG_SND_ICE1712) += snd-ak4xxx-adda.o
obj-$(CONFIG_SND_ICE1724) += snd-ak4xxx-adda.o
This diff is collapsed.
......@@ -41,7 +41,7 @@ config SND_CS4236
config SND_PC98_CS4232
tristate "NEC PC9800 CS4232 driver"
depends on SND && PC9800
depends on SND && X86_PC9800
help
Say 'Y' or 'M' to include support for NEC PC-9801/PC-9821 on-board
soundchip based on CS4232.
......
......@@ -448,6 +448,7 @@ static int snd_cs4231_trigger(snd_pcm_substream_t *substream,
cs4231_t *chip = snd_pcm_substream_chip(substream);
int result = 0;
unsigned int what;
struct list_head *pos;
snd_pcm_substream_t *s;
int do_start;
......@@ -467,8 +468,8 @@ static int snd_cs4231_trigger(snd_pcm_substream_t *substream,
}
what = 0;
s = substream;
do {
snd_pcm_group_for_each(pos, substream) {
s = snd_pcm_group_substream_entry(pos);
if (s == chip->playback_substream) {
what |= CS4231_PLAYBACK_ENABLE;
snd_pcm_trigger_done(s, substream);
......@@ -476,8 +477,7 @@ static int snd_cs4231_trigger(snd_pcm_substream_t *substream,
what |= CS4231_RECORD_ENABLE;
snd_pcm_trigger_done(s, substream);
}
s = s->link_next;
} while (s != substream);
}
spin_lock(&chip->reg_lock);
if (do_start) {
chip->image[CS4231_IFACE_CTRL] |= what;
......
......@@ -32,8 +32,7 @@
irqreturn_t snd_gus_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
snd_gus_card_t * gus = snd_magic_cast(snd_gus_card_t,
dev_id, return IRQ_NONE);
snd_gus_card_t * gus = snd_magic_cast(snd_gus_card_t, dev_id, return IRQ_NONE);
unsigned char status;
int loop = 100;
int handled = 0;
......
......@@ -969,8 +969,10 @@ static int snd_opti93x_trigger(snd_pcm_substream_t *substream,
case SNDRV_PCM_TRIGGER_STOP:
{
unsigned int what = 0;
snd_pcm_substream_t *s = substream;
do {
struct list_head *pos;
snd_pcm_substream_t *s;
snd_pcm_group_for_each(pos, substream) {
s = snd_pcm_group_substream_entry(pos);
if (s == chip->playback_substream) {
what |= OPTi93X_PLAYBACK_ENABLE;
snd_pcm_trigger_done(s, substream);
......@@ -978,8 +980,7 @@ static int snd_opti93x_trigger(snd_pcm_substream_t *substream,
what |= OPTi93X_CAPTURE_ENABLE;
snd_pcm_trigger_done(s, substream);
}
s = s->link_next;
} while (s != substream);
}
spin_lock(&chip->lock);
if (cmd == SNDRV_PCM_TRIGGER_START) {
snd_opti93x_out_mask(chip, OPTi93X_IFACE_CONF, what, what);
......
......@@ -84,11 +84,10 @@ static irqreturn_t snd_card_es968_interrupt(int irq, void *dev_id,
sb_t *chip = snd_magic_cast(sb_t, dev_id, return IRQ_NONE);
if (chip->open & SB_OPEN_PCM) {
snd_sb8dsp_interrupt(chip);
return snd_sb8dsp_interrupt(chip);
} else {
snd_sb8dsp_midi_interrupt(chip);
return snd_sb8dsp_midi_interrupt(chip);
}
return IRQ_HANDLED;
}
static int __devinit snd_card_es968_pnp(int dev, struct snd_card_es968 *acard,
......
......@@ -75,11 +75,10 @@ static irqreturn_t snd_sb8_interrupt(int irq, void *dev_id, struct pt_regs *regs
sb_t *chip = snd_magic_cast(sb_t, dev_id, return IRQ_NONE);
if (chip->open & SB_OPEN_PCM) {
snd_sb8dsp_interrupt(chip);
return snd_sb8dsp_interrupt(chip);
} else {
snd_sb8dsp_midi_interrupt(chip);
return snd_sb8dsp_midi_interrupt(chip);
}
return IRQ_HANDLED;
}
static void snd_sb8_free(snd_card_t *card)
......
......@@ -331,7 +331,7 @@ static int snd_sb8_capture_trigger(snd_pcm_substream_t * substream,
return 0;
}
void snd_sb8dsp_interrupt(sb_t *chip)
irqreturn_t snd_sb8dsp_interrupt(sb_t *chip)
{
snd_pcm_substream_t *substream;
snd_pcm_runtime_t *runtime;
......@@ -356,6 +356,7 @@ void snd_sb8dsp_interrupt(sb_t *chip)
snd_pcm_period_elapsed(substream);
break;
}
return IRQ_HANDLED;
}
static snd_pcm_uframes_t snd_sb8_playback_pointer(snd_pcm_substream_t * substream)
......
......@@ -33,7 +33,7 @@
*/
void snd_sb8dsp_midi_interrupt(sb_t * chip)
irqreturn_t snd_sb8dsp_midi_interrupt(sb_t * chip)
{
snd_rawmidi_t *rmidi;
int max = 64;
......@@ -41,7 +41,7 @@ void snd_sb8dsp_midi_interrupt(sb_t * chip)
if (chip == NULL || (rmidi = chip->rmidi) == NULL) {
inb(SBP(chip, READ)); /* ack interrupt */
return;
return IRQ_NONE;
}
while (max-- > 0) {
spin_lock(&chip->midi_input_lock);
......@@ -53,6 +53,7 @@ void snd_sb8dsp_midi_interrupt(sb_t * chip)
spin_unlock(&chip->midi_input_lock);
}
}
return IRQ_HANDLED;
}
/*
......
......@@ -13,6 +13,7 @@ obj-$(CONFIG_SND_ENS1371) += snd-ac97-codec.o
obj-$(CONFIG_SND_ES1968) += snd-ac97-codec.o
obj-$(CONFIG_SND_FM801) += snd-ac97-codec.o
obj-$(CONFIG_SND_ICE1712) += snd-ac97-codec.o
obj-$(CONFIG_SND_ICE1724) += snd-ac97-codec.o
obj-$(CONFIG_SND_INTEL8X0) += snd-ac97-codec.o
obj-$(CONFIG_SND_MAESTRO3) += snd-ac97-codec.o
obj-$(CONFIG_SND_VIA82XX) += snd-ac97-codec.o
......
......@@ -143,10 +143,12 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = {
{ 0x54584e20, 0xffffffff, "TLC320AD9xC", NULL, NULL },
{ 0x56494161, 0xffffffff, "VIA1612A", NULL, NULL }, // modified ICE1232 with S/PDIF
{ 0x57454301, 0xffffffff, "W83971D", NULL, NULL },
{ 0x574d4c00, 0xffffffff, "WM9701A", patch_wolfson00,NULL },
{ 0x574d4c03, 0xffffffff, "WM9703/9707", patch_wolfson03,NULL },
{ 0x574d4c04, 0xffffffff, "WM9704/quad", patch_wolfson04,NULL },
{ 0x574d4c05, 0xffffffff, "WM9705", NULL, NULL }, // patch?
{ 0x574d4c00, 0xffffffff, "WM9701A", NULL, NULL },
{ 0x574d4C03, 0xffffffff, "WM9703/WM9707/WM9708/WM9717", patch_wolfson03, NULL},
{ 0x574d4C04, 0xffffffff, "WM9704M/WM9704Q", patch_wolfson04, NULL},
{ 0x574d4C05, 0xffffffff, "WM9705/WM9710", patch_wolfson05, NULL},
{ 0x574d4C09, 0xffffffff, "WM9709", NULL, NULL},
{ 0x574d4C12, 0xffffffff, "WM9711/WM9712", patch_wolfson11, NULL},
{ 0x594d4800, 0xffffffff, "YMF743", NULL, NULL },
{ 0x594d4802, 0xffffffff, "YMF752", NULL, NULL },
{ 0x594d4803, 0xffffffff, "YMF753", patch_yamaha_ymf753, NULL },
......
......@@ -51,55 +51,63 @@ int patch_yamaha_ymf753(ac97_t * ac97)
return 0;
}
int patch_wolfson00(ac97_t * ac97)
{
/* This sequence is suspect because it was designed for
the WM9704, and is known to fail when applied to the
WM9707. If you're having trouble initializing a
WM9700, this is the place to start looking.
Randolph Bentson <bentson@holmsjoen.com> */
// WM9701A
snd_ac97_write_cache(ac97, 0x72, 0x0808);
snd_ac97_write_cache(ac97, 0x74, 0x0808);
// patch for DVD noise
snd_ac97_write_cache(ac97, 0x5a, 0x0200);
// init vol
snd_ac97_write_cache(ac97, 0x70, 0x0808);
/*
* May 2, 2003 Liam Girdwood <liam.girdwood@wolfsonmicro.com>
* removed broken wolfson00 patch.
* added support for WM9705,WM9708,WM9709,WM9710,WM9711,WM9712 and WM9717.
*/
snd_ac97_write_cache(ac97, AC97_SURROUND_MASTER, 0x0000);
return 0;
}
#define AC97_WM97XX_FMIXER_VOL 0x72
#define AC97_WM9704_RMIXER_VOL 0x74
#define AC97_WM9704_TEST 0x5a
#define AC97_WM9704_RPCM_VOL 0x70
#define AC97_WM9711_OUT3VOL 0x16
int patch_wolfson03(ac97_t * ac97)
{
/* This is known to work for the ViewSonic ViewPad 1000
Randolph Bentson <bentson@holmsjoen.com> */
// WM9703/9707
snd_ac97_write_cache(ac97, 0x72, 0x0808);
snd_ac97_write_cache(ac97, 0x20, 0x8000);
// WM9703/9707/9708/9717
snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808);
snd_ac97_write_cache(ac97, AC97_GENERAL_PURPOSE, 0x8000);
return 0;
}
int patch_wolfson04(ac97_t * ac97)
{
// WM9704
snd_ac97_write_cache(ac97, 0x72, 0x0808);
snd_ac97_write_cache(ac97, 0x74, 0x0808);
// WM9704M/9704Q
// set front and rear mixer volume
snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808);
snd_ac97_write_cache(ac97, AC97_WM9704_RMIXER_VOL, 0x0808);
// patch for DVD noise
snd_ac97_write_cache(ac97, 0x5a, 0x0200);
snd_ac97_write_cache(ac97, AC97_WM9704_TEST, 0x0200);
// init vol
snd_ac97_write_cache(ac97, 0x70, 0x0808);
snd_ac97_write_cache(ac97, AC97_WM9704_RPCM_VOL, 0x0808);
// set rear surround volume
snd_ac97_write_cache(ac97, AC97_SURROUND_MASTER, 0x0000);
return 0;
}
int patch_wolfson05(ac97_t * ac97)
{
// WM9705, WM9710
// set front mixer volume
snd_ac97_write_cache(ac97, AC97_WM97XX_FMIXER_VOL, 0x0808);
return 0;
}
int patch_wolfson11(ac97_t * ac97)
{
// WM9711, WM9712
// set out3 volume
snd_ac97_write_cache(ac97, AC97_WM9711_OUT3VOL, 0x0808);
return 0;
}
int patch_tritech_tr28028(ac97_t * ac97)
{
snd_ac97_write_cache(ac97, 0x26, 0x0300);
......
......@@ -26,6 +26,8 @@ int patch_yamaha_ymf753(ac97_t * ac97);
int patch_wolfson00(ac97_t * ac97);
int patch_wolfson03(ac97_t * ac97);
int patch_wolfson04(ac97_t * ac97);
int patch_wolfson05(ac97_t * ac97);
int patch_wolfson11(ac97_t * ac97);
int patch_tritech_tr28028(ac97_t * ac97);
int patch_sigmatel_stac9708(ac97_t * ac97);
int patch_sigmatel_stac9721(ac97_t * ac97);
......
......@@ -1211,6 +1211,7 @@ static int snd_ali_trigger(snd_pcm_substream_t *substream,
{
ali_t *codec = snd_pcm_substream_chip(substream);
struct list_head *pos;
snd_pcm_substream_t *s;
unsigned int what, whati, capture_flag;
snd_ali_voice_t *pvoice = NULL, *evoice = NULL;
......@@ -1229,8 +1230,8 @@ static int snd_ali_trigger(snd_pcm_substream_t *substream,
}
what = whati = capture_flag = 0;
s = substream;
do {
snd_pcm_group_for_each(pos, substream) {
s = snd_pcm_group_substream_entry(pos);
if ((ali_t *) _snd_pcm_chip(s->pcm) == codec) {
pvoice = (snd_ali_voice_t *) s->runtime->private_data;
evoice = pvoice->extra;
......@@ -1254,8 +1255,7 @@ static int snd_ali_trigger(snd_pcm_substream_t *substream,
if (pvoice->mode)
capture_flag = 1;
}
s = s->link_next;
} while (s != substream);
}
spin_lock(&codec->reg_lock);
if (! do_start) {
outl(what, ALI_REG(codec, ALI_STOP));
......
......@@ -1496,6 +1496,7 @@ static void setup_ac3(cmipci_t *cm, snd_pcm_substream_t *subs, int do_ac3, int r
/* SPD24SEL for 037, 0x02 */
/* SPD24SEL for 039, 0x20, but cannot be set */
snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_SPD24SEL);
snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
} else { /* can_ac3_sw */
#ifdef DO_SOFT_AC3
/* FIXME: ugly hack! */
......@@ -1519,7 +1520,14 @@ static void setup_ac3(cmipci_t *cm, snd_pcm_substream_t *subs, int do_ac3, int r
snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_AC3EN2);
if (cm->can_ac3_hw) {
/* chip model >= 37 */
if (snd_pcm_format_width(subs->runtime->format) > 16) {
snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_SPD24SEL);
} else {
snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_SPD24SEL);
}
} else {
#ifdef DO_SOFT_AC3
snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
......@@ -1669,7 +1677,6 @@ static irqreturn_t snd_cmipci_interrupt(int irq, void *dev_id, struct pt_regs *r
if ((status & CM_CHINT1) && cm->channel[1].running)
snd_pcm_period_elapsed(cm->channel[1].substream);
}
return IRQ_HANDLED;
}
......@@ -1742,7 +1749,7 @@ static snd_pcm_hardware_t snd_cmipci_playback_spdif =
{
.info = (SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE),
.formats = SNDRV_PCM_FMTBIT_S16_LE /*| SNDRV_PCM_FMTBIT_S32_LE*/,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
.rate_min = 44100,
.rate_max = 48000,
......@@ -1897,6 +1904,8 @@ static int snd_cmipci_playback_spdif_open(snd_pcm_substream_t *substream)
if (cm->can_ac3_hw)
#endif
runtime->hw.info |= SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID;
if (cm->chip_version >= 37)
runtime->hw.formats |= SNDRV_PCM_FMTBIT_S32_LE;
snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x40000);
cm->dig_pcm_status = cm->dig_status;
return 0;
......
......@@ -33,22 +33,24 @@
irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
emu10k1_t *emu = snd_magic_cast(emu10k1_t, dev_id, return IRQ_NONE);
unsigned int status;
unsigned int status, orig_status;
int handled = 0;
while ((status = inl(emu->port + IPR)) != 0) {
// printk("irq - status = 0x%x\n", status);
orig_status = status;
handled = 1;
if (status & IPR_PCIERROR) {
snd_printk("interrupt: PCI error\n");
snd_emu10k1_intr_disable(emu, INTE_PCIERRORENABLE);
status &= ~IPR_PCIERROR;
}
if (status & (IPR_VOLINCR|IPR_VOLDECR|IPR_MUTE)) {
if (emu->hwvol_interrupt)
emu->hwvol_interrupt(emu, status);
else
snd_emu10k1_intr_disable(emu, INTE_VOLINCRENABLE|INTE_VOLDECRENABLE|INTE_MUTEENABLE);
outl(status & (IPR_VOLINCR|IPR_VOLDECR|IPR_MUTE), emu->port + IPR);
status &= ~(IPR_VOLINCR|IPR_VOLDECR|IPR_MUTE);
}
if (status & IPR_CHANNELLOOP) {
int voice;
......@@ -88,64 +90,69 @@ irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
pvoice++;
}
}
outl(IPR_CHANNELLOOP | (status & IPR_CHANNELNUMBERMASK), emu->port + IPR);
status &= ~IPR_CHANNELLOOP;
}
status &= ~IPR_CHANNELNUMBERMASK;
if (status & (IPR_ADCBUFFULL|IPR_ADCBUFHALFFULL)) {
if (emu->capture_interrupt)
emu->capture_interrupt(emu, status);
else
snd_emu10k1_intr_disable(emu, INTE_ADCBUFENABLE);
outl(status & (IPR_ADCBUFFULL|IPR_ADCBUFHALFFULL), emu->port + IPR);
status &= ~(IPR_ADCBUFFULL|IPR_ADCBUFHALFFULL);
}
if (status & (IPR_MICBUFFULL|IPR_MICBUFHALFFULL)) {
if (emu->capture_mic_interrupt)
emu->capture_mic_interrupt(emu, status);
else
snd_emu10k1_intr_disable(emu, INTE_MICBUFENABLE);
outl(status & (IPR_MICBUFFULL|IPR_MICBUFHALFFULL), emu->port + IPR);
status &= ~(IPR_MICBUFFULL|IPR_MICBUFHALFFULL);
}
if (status & (IPR_EFXBUFFULL|IPR_EFXBUFHALFFULL)) {
if (emu->capture_efx_interrupt)
emu->capture_efx_interrupt(emu, status);
else
snd_emu10k1_intr_disable(emu, INTE_EFXBUFENABLE);
outl(status & (IPR_EFXBUFFULL|IPR_EFXBUFHALFFULL), emu->port + IPR);
status &= ~(IPR_EFXBUFFULL|IPR_EFXBUFHALFFULL);
}
if (status & (IPR_MIDITRANSBUFEMPTY|IPR_MIDIRECVBUFEMPTY)) {
if (emu->midi.interrupt)
emu->midi.interrupt(emu, status);
else
snd_emu10k1_intr_disable(emu, INTE_MIDITXENABLE|INTE_MIDIRXENABLE);
outl(status & (IPR_MIDITRANSBUFEMPTY|IPR_MIDIRECVBUFEMPTY), emu->port + IPR);
status &= ~(IPR_MIDITRANSBUFEMPTY|IPR_MIDIRECVBUFEMPTY);
}
if (status & (IPR_A_MIDITRANSBUFEMPTY2|IPR_A_MIDIRECVBUFEMPTY2)) {
if (emu->midi2.interrupt)
emu->midi2.interrupt(emu, status);
else
snd_emu10k1_intr_disable(emu, INTE_A_MIDITXENABLE2|INTE_A_MIDIRXENABLE2);
outl(status & (IPR_A_MIDITRANSBUFEMPTY2|IPR_A_MIDIRECVBUFEMPTY2), emu->port + IPR);
status &= ~(IPR_A_MIDITRANSBUFEMPTY2|IPR_A_MIDIRECVBUFEMPTY2);
}
if (status & IPR_INTERVALTIMER) {
if (emu->timer_interrupt)
emu->timer_interrupt(emu);
else
snd_emu10k1_intr_disable(emu, INTE_INTERVALTIMERENB);
outl(IPR_INTERVALTIMER, emu->port + IPR);
status &= ~IPR_INTERVALTIMER;
}
if (status & (IPR_GPSPDIFSTATUSCHANGE|IPR_CDROMSTATUSCHANGE)) {
if (emu->spdif_interrupt)
emu->spdif_interrupt(emu, status);
else
snd_emu10k1_intr_disable(emu, INTE_GPSPDIFENABLE|INTE_CDSPDIFENABLE);
outl(status & (IPR_GPSPDIFSTATUSCHANGE|IPR_CDROMSTATUSCHANGE), emu->port + IPR);
status &= ~(IPR_GPSPDIFSTATUSCHANGE|IPR_CDROMSTATUSCHANGE);
}
if (status & IPR_FXDSP) {
if (emu->dsp_interrupt)
emu->dsp_interrupt(emu);
else
snd_emu10k1_intr_disable(emu, INTE_FXDSPENABLE);
outl(IPR_FXDSP, emu->port + IPR);
status &= ~IPR_FXDSP;
}
if (status) {
snd_printd(KERN_WARNING "emu10k1: unhandled interrupt: 0x%08x\n", status);
}
outl(orig_status, emu->port + IPR); /* ack */
}
return IRQ_RETVAL(handled);
}
......@@ -111,8 +111,11 @@ MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
#define ES_REG_CONTROL 0x00 /* R/W: Interrupt/Chip select control register */
#define ES_1370_ADC_STOP (1<<31) /* disable capture buffer transfers */
#define ES_1370_XCTL1 (1<<30) /* general purpose output bit */
#define ES_1373_TEST_BIT (1<<29) /* should be set to 0 for normal operation */
#define ES_1373_RECEN_B (1<<28) /* mix record with playback for I2S/SPDIF out */
#define ES_1373_BYPASS_P1 (1<<31) /* bypass SRC for PB1 */
#define ES_1373_BYPASS_P2 (1<<30) /* bypass SRC for PB2 */
#define ES_1373_BYPASS_R (1<<29) /* bypass SRC for REC */
#define ES_1373_TEST_BIT (1<<28) /* should be set to 0 for normal operation */
#define ES_1373_RECEN_B (1<<27) /* mix record with playback for I2S/SPDIF out */
#define ES_1373_SPDIF_THRU (1<<26) /* 0 = SPDIF thru mode, 1 = SPDIF == dig out */
#define ES_1371_JOY_ASEL(o) (((o)&0x03)<<24)/* joystick port mapping */
#define ES_1371_JOY_ASELM (0x03<<24) /* mask for above */
......@@ -739,8 +742,10 @@ static int snd_ensoniq_trigger(snd_pcm_substream_t *substream, int cmd)
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
{
unsigned int what = 0;
snd_pcm_substream_t *s = substream;
do {
struct list_head *pos;
snd_pcm_substream_t *s;
snd_pcm_group_for_each(pos, substream) {
s = snd_pcm_group_substream_entry(pos);
if (s == ensoniq->playback1_substream) {
what |= ES_P1_PAUSE;
snd_pcm_trigger_done(s, substream);
......@@ -749,8 +754,7 @@ static int snd_ensoniq_trigger(snd_pcm_substream_t *substream, int cmd)
snd_pcm_trigger_done(s, substream);
} else if (s == ensoniq->capture_substream)
return -EINVAL;
s = s->link_next;
} while (s != substream);
}
spin_lock(&ensoniq->reg_lock);
if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
ensoniq->sctrl |= what;
......@@ -764,8 +768,10 @@ static int snd_ensoniq_trigger(snd_pcm_substream_t *substream, int cmd)
case SNDRV_PCM_TRIGGER_STOP:
{
unsigned int what = 0;
snd_pcm_substream_t *s = substream;
do {
struct list_head *pos;
snd_pcm_substream_t *s;
snd_pcm_group_for_each(pos, substream) {
s = snd_pcm_group_substream_entry(pos);
if (s == ensoniq->playback1_substream) {
what |= ES_DAC1_EN;
snd_pcm_trigger_done(s, substream);
......@@ -776,8 +782,7 @@ static int snd_ensoniq_trigger(snd_pcm_substream_t *substream, int cmd)
what |= ES_ADC_EN;
snd_pcm_trigger_done(s, substream);
}
s = s->link_next;
} while (s != substream);
}
spin_lock(&ensoniq->reg_lock);
if (cmd == SNDRV_PCM_TRIGGER_START)
ensoniq->ctrl |= what;
......
......@@ -3,8 +3,8 @@
# Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
#
snd-ice1712-objs := ice1712.o ak4524.o delta.o hoontech.o ews.o
snd-ice1724-objs := ice1724.o ak4524.o amp.o revo.o
snd-ice1712-objs := ice1712.o delta.o hoontech.o ews.o
snd-ice1724-objs := ice1724.o amp.o revo.o
# Toplevel Module Dependency
obj-$(CONFIG_SND_ICE1712) += snd-ice1712.o
......
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.
......@@ -1136,8 +1136,7 @@ static void snd_korg1212_OnDSPDownloadComplete(korg1212_t *korg1212)
static irqreturn_t snd_korg1212_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
u32 doorbellValue;
korg1212_t *korg1212 = snd_magic_cast(korg1212_t, dev_id,
return IRQ_NONE);
korg1212_t *korg1212 = snd_magic_cast(korg1212_t, dev_id, return IRQ_NONE);
if(irq != korg1212->irq)
return IRQ_NONE;
......
This diff is collapsed.
......@@ -1042,7 +1042,7 @@ snd_nm256_interrupt(int irq, void *dev_id, struct pt_regs *dummy)
static irqreturn_t
snd_nm256_interrupt_zx(int irq, void *dev_id, struct pt_regs *dummy)
{
nm256_t *chip = snd_magic_cast(nm256_t, dev_id, return);
nm256_t *chip = snd_magic_cast(nm256_t, dev_id, return IRQ_NONE);
u32 status;
u8 cbyte;
......
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