Commit 5b0bebdc authored by Jaroslav Kysela's avatar Jaroslav Kysela

Merge suse.cz:/home/perex/bk/linux-sound/linux-sound

into suse.cz:/home/perex/bk/linux-sound/work
parents 8edee057 1e8fff3a
......@@ -599,6 +599,37 @@ Module parameters
Module supports up to 8 cards and autoprobe.
Module snd-hda-intel
--------------------
Module for Intel HD Audio (ICH6, ICH6M, ICH7)
model - force the model name
Module supports up to 8 cards.
Each codec may have a model table for different configurations.
If your machine isn't listed there, the default (usually minimal)
configuration is set up. You can pass "model=<name>" option to
specify a certain model in such a case. There are different
models depending on the codec chip.
Model name Description
---------- -----------
ALC880
3stack 3-jack in back and a headphone out
3stack-digout 3-jack in back, a HP out and a SPDIF out
5stack 5-jack in back, 2-jack in front
5stack-digout 5-jack in back, 2-jack in front, a SPDIF out
w810 3-jack
CMI9880
minimal 3-jack in back
min_fp 3-jack in back, 2-jack in front
full 6-jack in back, 2-jack in front
full_dig 6-jack in back, 2-jack in front, SPDIF I/O
allout 5-jack in back, 2-jack in front, SPDIF out
Module snd-hdsp
---------------
......@@ -689,7 +720,7 @@ Module parameters
hp_only = use headphone control as master
swap_hp = swap headphone and master controls
swap_surround = swap master and surround controls
ad_shring = for AD1985, turn on OMS bit and use headphone
ad_sharing = for AD1985, turn on OMS bit and use headphone
alc_jack = for ALC65x, turn on the jack sense mode
inv_eapd = inverted EAPD implementation
mute_led = bind EAPD bit for turning on/off mute LED
......
......@@ -110,9 +110,9 @@
</para>
<para>
One is the the trees provided as a tarball or via cvs from the
One is the trees provided as a tarball or via cvs from the
ALSA's ftp site, and another is the 2.6 (or later) Linux kernel
tree. To synchronize both, the ALSA driver tree is split to
tree. To synchronize both, the ALSA driver tree is split into
two different trees: alsa-kernel and alsa-driver. The former
contains purely the source codes for the Linux 2.6 (or later)
tree. This tree is designed only for compilation on 2.6 or
......@@ -766,7 +766,7 @@
</para>
<para>
The ALSA interfaces like PCM or control API are define in other
The ALSA interfaces like PCM or control API are defined in other
header files as <filename>&lt;sound/xxx.h&gt;</filename>.
They have to be included after
<filename>&lt;sound/core.h&gt;</filename>.
......@@ -1103,7 +1103,7 @@
/* release the irq */
if (chip->irq >= 0)
free_irq(chip->irq, (void *)chip);
/* release the i/o ports */
/* release the i/o ports & memory */
pci_release_regions(chip->pci);
/* disable the PCI entry */
pci_disable_device(chip->pci);
......@@ -1314,6 +1314,7 @@
</para>
<para>
<!-- obsolete -->
It will reserve the i/o port region of 8 bytes of the given
PCI device. The returned value, chip-&gt;res_port, is allocated
via <function>kmalloc()</function> by
......@@ -1936,6 +1937,7 @@
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
&snd_mychip_capture_ops);
/* pre-allocation of buffers */
/* NOTE: this may fail */
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
snd_dma_pci_data(chip->pci),
64*1024, 64*1024);
......@@ -1950,7 +1952,7 @@
<section id="pcm-interface-constructor">
<title>Constructor</title>
<para>
A pcm instance is allocated <function>snd_pcm_new()</function>
A pcm instance is allocated by <function>snd_pcm_new()</function>
function. It would be better to create a constructor for pcm,
namely,
......@@ -2235,7 +2237,8 @@ struct _snd_pcm_runtime {
unsigned char *dma_area; /* DMA area */
dma_addr_t dma_addr; /* physical bus address (not accessible from main CPU) */
size_t dma_bytes; /* size of DMA area */
void *dma_private; /* private DMA data for the memory allocator */
struct snd_dma_buffer *dma_buffer_p; /* allocated buffer */
#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
/* -- OSS things -- */
......@@ -2250,7 +2253,7 @@ struct _snd_pcm_runtime {
<para>
For the operators (callbacks) of each sound driver, most of
these records are supposed to be read-only. Only the PCM
middle-layer changes / updates these info. The excpetions are
middle-layer changes / updates these info. The exceptions are
the hardware description (hw), interrupt callbacks
(transfer_ack_xxx), DMA buffer information, and the private
data. Besides, if you use the standard buffer allocation
......@@ -3250,7 +3253,7 @@ struct _snd_pcm_runtime {
<para>
There are many different constraints.
Look in <filename>sound/asound.h</filename> for a complete list.
Look in <filename>sound/pcm.h</filename> for a complete list.
You can even define your own constraint rules.
For example, let's suppose my_chip can manage a substream of 1 channel
if and only if the format is S16_LE, otherwise it supports any format
......@@ -4066,7 +4069,7 @@ struct _snd_pcm_runtime {
Both <function>snd_ac97_write()</function> and
<function>snd_ac97_update()</function> functions are used to
set a value to the given register
(<constant>AC97_XXX</constant>). The different between them is
(<constant>AC97_XXX</constant>). The difference between them is
that <function>snd_ac97_update()</function> doesn't write a
value if the given value has been already set, while
<function>snd_ac97_write()</function> always rewrites the
......@@ -4152,8 +4155,8 @@ struct _snd_pcm_runtime {
<title>Proc Files</title>
<para>
The ALSA AC97 interface will create a proc file such as
<filename>/proc/asound/card0/ac97#0</filename> and
<filename>ac97#0regs</filename>. You can refer to these files to
<filename>/proc/asound/card0/codec97#0/ac97#0-0</filename> and
<filename>ac97#0-0+regs</filename>. You can refer to these files to
see the current status and registers of the codec.
</para>
</section>
......@@ -4633,7 +4636,7 @@ struct _snd_pcm_runtime {
where <parameter>size</parameter> is the byte size to be
pre-allocated and the <parameter>max</parameter> is the maximal
size to be changed via <filename>prealloc</filename> proc file.
The allocator will try to get as the large area as possible
The allocator will try to get as large area as possible
within the given size.
</para>
......@@ -4855,7 +4858,7 @@ struct _snd_pcm_runtime {
If your hardware supports the page table like emu10k1 or the
buffer descriptors like via82xx, you can use the scatter-gather
(SG) DMA. ALSA provides an interface for handling SG-buffers.
The API is provided in <filename>&lt;sound/pcm_sgbuf.h&gt;</filename>.
The API is provided in <filename>&lt;sound/pcm.h&gt;</filename>.
</para>
<para>
......
This diff is collapsed.
......@@ -106,7 +106,7 @@
#define AK4117_DIF_24L (AK4117_DIF2) /* STDO: 24-bit, left justified */
#define AK4117_DIF_24I2S (AK4117_DIF2|AK4117_DIF0) /* STDO: I2S */
/* AK4117_REG_INT0_MASK & AK4117_INT1_MASK */
/* AK4117_REG_INT0_MASK & AK4117_REG_INT1_MASK */
#define AK4117_MULK (1<<7) /* mask enable for UNLOCK bit */
#define AK4117_MPAR (1<<6) /* mask enable for PAR bit */
#define AK4117_MAUTO (1<<5) /* mask enable for AUTO bit */
......@@ -181,8 +181,8 @@ struct ak4117 {
int snd_ak4117_create(snd_card_t *card, ak4117_read_t *read, ak4117_write_t *write,
unsigned char pgm[5], void *private_data, ak4117_t **r_ak4117);
void snd_ak4117_reg_write(ak4117_t *chip, unsigned char reg, unsigned char mask, unsigned char val);
void snd_ak4117_reinit(ak4117_t *chip);
void snd_ak4117_reg_write(ak4117_t *ak4117, unsigned char reg, unsigned char mask, unsigned char val);
void snd_ak4117_reinit(ak4117_t *ak4117);
int snd_ak4117_build(ak4117_t *ak4117, snd_pcm_substream_t *capture_substream);
int snd_ak4117_external_rate(ak4117_t *ak4117);
int snd_ak4117_check_rate_and_errors(ak4117_t *ak4117, unsigned int flags);
......
......@@ -119,6 +119,13 @@ int snd_ctl_create(snd_card_t *card);
int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn);
int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn);
#ifdef CONFIG_COMPAT
int snd_ctl_register_ioctl_compat(snd_kctl_ioctl_func_t fcn);
int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn);
#else
#define snd_ctl_register_ioctl_compat(fcn)
#define snd_ctl_unregister_ioctl_compat(fcn)
#endif
int snd_ctl_elem_read(snd_card_t *card, snd_ctl_elem_value_t *control);
int snd_ctl_elem_write(snd_card_t *card, snd_ctl_file_t *file, snd_ctl_elem_value_t *control);
......
......@@ -38,6 +38,7 @@ typedef struct _snd_hwdep_ops {
int (*release) (snd_hwdep_t * hw, struct file * file);
unsigned int (*poll) (snd_hwdep_t * hw, struct file * file, poll_table * wait);
int (*ioctl) (snd_hwdep_t * hw, struct file * file, unsigned int cmd, unsigned long arg);
int (*ioctl_compat) (snd_hwdep_t * hw, struct file * file, unsigned int cmd, unsigned long arg);
int (*mmap) (snd_hwdep_t * hw, struct file * file, struct vm_area_struct * vma);
int (*dsp_status) (snd_hwdep_t * hw, snd_hwdep_dsp_status_t * status);
int (*dsp_load) (snd_hwdep_t * hw, snd_hwdep_dsp_image_t * image);
......
......@@ -81,20 +81,6 @@ config SND_SEQUENCER_OSS
To compile this driver as a module, choose M here: the module
will be called snd-seq-oss.
config SND_BIT32_EMUL
tristate "Emulation for 32-bit applications"
depends on SND && COMPAT
select SND_PCM
select SND_RAWMIDI
select SND_TIMER
select SND_HWDEP
help
Say Y here to enable the emulation for 32-bit ALSA-native
applications.
To compile this driver as a module, choose M here: the module
will be called snd-ioctl32.
config SND_RTCTIMER
tristate "RTC Timer support"
depends on SND && RTC
......
......@@ -31,4 +31,3 @@ obj-$(CONFIG_SND_RAWMIDI) += snd-rawmidi.o
obj-$(CONFIG_SND_OSSEMUL) += oss/
obj-$(CONFIG_SND_SEQUENCER) += seq/
obj-$(CONFIG_SND_BIT32_EMUL) += ioctl32/
This diff is collapsed.
This diff is collapsed.
......@@ -232,8 +232,7 @@ static int snd_hwdep_dsp_load(snd_hwdep_t *hw, snd_hwdep_dsp_image_t __user *_in
return 0;
}
static inline int _snd_hwdep_ioctl(struct inode *inode, struct file * file,
unsigned int cmd, unsigned long arg)
static long snd_hwdep_ioctl(struct file * file, unsigned int cmd, unsigned long arg)
{
snd_hwdep_t *hw = file->private_data;
void __user *argp = (void __user *)arg;
......@@ -252,17 +251,6 @@ static inline int _snd_hwdep_ioctl(struct inode *inode, struct file * file,
return -ENOTTY;
}
/* FIXME: need to unlock BKL to allow preemption */
static int snd_hwdep_ioctl(struct inode *inode, struct file * file,
unsigned int cmd, unsigned long arg)
{
int err;
unlock_kernel();
err = _snd_hwdep_ioctl(inode, file, cmd, arg);
lock_kernel();
return err;
}
static int snd_hwdep_mmap(struct file * file, struct vm_area_struct * vma)
{
snd_hwdep_t *hw = file->private_data;
......@@ -315,6 +303,12 @@ static int snd_hwdep_control_ioctl(snd_card_t * card, snd_ctl_file_t * control,
return -ENOIOCTLCMD;
}
#ifdef CONFIG_COMPAT
#include "hwdep_compat.c"
#else
#define snd_hwdep_ioctl_compat NULL
#endif
/*
*/
......@@ -328,7 +322,8 @@ static struct file_operations snd_hwdep_f_ops =
.open = snd_hwdep_open,
.release = snd_hwdep_release,
.poll = snd_hwdep_poll,
.ioctl = snd_hwdep_ioctl,
.unlocked_ioctl = snd_hwdep_ioctl,
.compat_ioctl = snd_hwdep_ioctl_compat,
.mmap = snd_hwdep_mmap,
};
......@@ -509,12 +504,14 @@ static int __init alsa_hwdep_init(void)
}
snd_hwdep_proc_entry = entry;
snd_ctl_register_ioctl(snd_hwdep_control_ioctl);
snd_ctl_register_ioctl_compat(snd_hwdep_control_ioctl);
return 0;
}
static void __exit alsa_hwdep_exit(void)
{
snd_ctl_unregister_ioctl(snd_hwdep_control_ioctl);
snd_ctl_unregister_ioctl_compat(snd_hwdep_control_ioctl);
if (snd_hwdep_proc_entry) {
snd_info_unregister(snd_hwdep_proc_entry);
snd_hwdep_proc_entry = NULL;
......
/*
* 32bit -> 64bit ioctl wrapper for hwdep API
* Copyright (c) by Takashi Iwai <tiwai@suse.de>
*
* 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
*
*/
/* This file is included from hwdep.c */
#include <linux/compat.h>
struct sndrv_hwdep_dsp_image32 {
u32 index;
unsigned char name[64];
u32 image; /* pointer */
u32 length;
u32 driver_data;
} /* don't set packed attribute here */;
static int snd_hwdep_dsp_load_compat(snd_hwdep_t *hw,
struct sndrv_hwdep_dsp_image32 __user *src)
{
struct sndrv_hwdep_dsp_image *dst;
compat_caddr_t ptr;
u32 val;
dst = compat_alloc_user_space(sizeof(*dst));
/* index and name */
if (copy_in_user(dst, src, 4 + 64))
return -EFAULT;
if (get_user(ptr, &src->image) ||
put_user(compat_ptr(ptr), &dst->image))
return -EFAULT;
if (get_user(val, &src->length) ||
put_user(val, &dst->length))
return -EFAULT;
if (get_user(val, &src->driver_data) ||
put_user(val, &dst->driver_data))
return -EFAULT;
return snd_hwdep_dsp_load(hw, dst);
}
enum {
SNDRV_HWDEP_IOCTL_DSP_LOAD32 = _IOW('H', 0x03, struct sndrv_hwdep_dsp_image32)
};
static long snd_hwdep_ioctl_compat(struct file * file, unsigned int cmd, unsigned long arg)
{
snd_hwdep_t *hw = file->private_data;
void __user *argp = compat_ptr(arg);
switch (cmd) {
case SNDRV_HWDEP_IOCTL_PVERSION:
case SNDRV_HWDEP_IOCTL_INFO:
case SNDRV_HWDEP_IOCTL_DSP_STATUS:
return snd_hwdep_ioctl(file, cmd, (unsigned long)argp);
case SNDRV_HWDEP_IOCTL_DSP_LOAD32:
return snd_hwdep_dsp_load_compat(hw, argp);
}
if (hw->ops.ioctl_compat)
return hw->ops.ioctl_compat(hw, file, cmd, arg);
return -ENOIOCTLCMD;
}
......@@ -39,7 +39,7 @@ struct snd_shutdown_f_ops {
unsigned int snd_cards_lock = 0; /* locked for registering/using */
snd_card_t *snd_cards[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = NULL};
rwlock_t snd_card_rwlock = RW_LOCK_UNLOCKED;
DEFINE_RWLOCK(snd_card_rwlock);
#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
int (*snd_mixer_oss_notify_callback)(snd_card_t *card, int free_flag);
......
......@@ -220,6 +220,9 @@ struct sndrv_ctl_elem_value32 {
unsigned int indirect; /* bit-field causes misalignment */
union {
s32 integer[128]; /* integer and boolean need conversion */
#ifndef CONFIG_X86_64
s64 integer64[64]; /* for alignment */
#endif
unsigned char data[512]; /* others should be compatible */
} value;
unsigned char reserved[128]; /* not used */
......
......@@ -376,6 +376,7 @@ DEFINE_ALSA_IOCTL_ENTRY(pcm_status, pcm_status, SNDRV_PCM_IOCTL_STATUS);
DEFINE_ALSA_IOCTL_ENTRY(pcm_delay, pcm_sframes_str, SNDRV_PCM_IOCTL_DELAY);
DEFINE_ALSA_IOCTL_ENTRY(pcm_channel_info, pcm_channel_info, SNDRV_PCM_IOCTL_CHANNEL_INFO);
DEFINE_ALSA_IOCTL_ENTRY(pcm_rewind, pcm_uframes_str, SNDRV_PCM_IOCTL_REWIND);
DEFINE_ALSA_IOCTL_ENTRY(pcm_forward, pcm_uframes_str, SNDRV_PCM_IOCTL_FORWARD);
DEFINE_ALSA_IOCTL_ENTRY(pcm_readi, xferi, SNDRV_PCM_IOCTL_READI_FRAMES);
DEFINE_ALSA_IOCTL_ENTRY(pcm_writei, xferi, SNDRV_PCM_IOCTL_WRITEI_FRAMES);
DEFINE_ALSA_IOCTL_ENTRY(pcm_readn, xfern, SNDRV_PCM_IOCTL_READN_FRAMES);
......@@ -419,6 +420,7 @@ enum {
SNDRV_PCM_IOCTL_DELAY32 = _IOR('A', 0x21, s32),
SNDRV_PCM_IOCTL_CHANNEL_INFO32 = _IOR('A', 0x32, struct sndrv_pcm_channel_info32),
SNDRV_PCM_IOCTL_REWIND32 = _IOW('A', 0x46, u32),
SNDRV_PCM_IOCTL_FORWARD32 = _IOW('A', 0x49, u32),
SNDRV_PCM_IOCTL_WRITEI_FRAMES32 = _IOW('A', 0x50, struct sndrv_xferi32),
SNDRV_PCM_IOCTL_READI_FRAMES32 = _IOR('A', 0x51, struct sndrv_xferi32),
SNDRV_PCM_IOCTL_WRITEN_FRAMES32 = _IOW('A', 0x52, struct sndrv_xfern32),
......@@ -450,6 +452,7 @@ struct ioctl32_mapper pcm_mappers[] = {
{ SNDRV_PCM_IOCTL_REWIND32, AP(pcm_rewind) },
MAP_COMPAT(SNDRV_PCM_IOCTL_RESUME),
MAP_COMPAT(SNDRV_PCM_IOCTL_XRUN),
{ SNDRV_PCM_IOCTL_FORWARD32, AP(pcm_forward) },
{ SNDRV_PCM_IOCTL_WRITEI_FRAMES32, AP(pcm_writei) },
{ SNDRV_PCM_IOCTL_READI_FRAMES32, AP(pcm_readi) },
{ SNDRV_PCM_IOCTL_WRITEN_FRAMES32, AP(pcm_writen) },
......
......@@ -50,8 +50,8 @@ static long snd_alloc_kmalloc;
static long snd_alloc_vmalloc;
static LIST_HEAD(snd_alloc_kmalloc_list);
static LIST_HEAD(snd_alloc_vmalloc_list);
static spinlock_t snd_alloc_kmalloc_lock = SPIN_LOCK_UNLOCKED;
static spinlock_t snd_alloc_vmalloc_lock = SPIN_LOCK_UNLOCKED;
static DEFINE_SPINLOCK(snd_alloc_kmalloc_lock);
static DEFINE_SPINLOCK(snd_alloc_vmalloc_lock);
#define KMALLOC_MAGIC 0x87654321
#define VMALLOC_MAGIC 0x87654320
static snd_info_entry_t *snd_memory_info_entry;
......
......@@ -359,16 +359,9 @@ static int snd_mixer_oss_ioctl1(snd_mixer_oss_file_t *fmixer, unsigned int cmd,
return -ENXIO;
}
/* FIXME: need to unlock BKL to allow preemption */
static int snd_mixer_oss_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
static long snd_mixer_oss_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
int err;
/* FIXME: need to unlock BKL to allow preemption */
unlock_kernel();
err = snd_mixer_oss_ioctl1((snd_mixer_oss_file_t *) file->private_data, cmd, arg);
lock_kernel();
return err;
return snd_mixer_oss_ioctl1((snd_mixer_oss_file_t *) file->private_data, cmd, arg);
}
int snd_mixer_oss_ioctl_card(snd_card_t *card, unsigned int cmd, unsigned long arg)
......@@ -384,6 +377,13 @@ int snd_mixer_oss_ioctl_card(snd_card_t *card, unsigned int cmd, unsigned long a
return snd_mixer_oss_ioctl1(&fmixer, cmd, arg);
}
#ifdef CONFIG_COMPAT
/* all compatible */
#define snd_mixer_oss_ioctl_compat snd_mixer_oss_ioctl
#else
#define snd_mixer_oss_ioctl_compat NULL
#endif
/*
* REGISTRATION PART
*/
......@@ -393,7 +393,8 @@ static struct file_operations snd_mixer_oss_f_ops =
.owner = THIS_MODULE,
.open = snd_mixer_oss_open,
.release = snd_mixer_oss_release,
.ioctl = snd_mixer_oss_ioctl,
.unlocked_ioctl = snd_mixer_oss_ioctl,
.compat_ioctl = snd_mixer_oss_ioctl_compat,
};
static snd_minor_t snd_mixer_oss_reg =
......
......@@ -1913,8 +1913,7 @@ static int snd_pcm_oss_release(struct inode *inode, struct file *file)
return 0;
}
static inline int _snd_pcm_oss_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
static long snd_pcm_oss_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
snd_pcm_oss_file_t *pcm_oss_file;
int __user *p = (int __user *)arg;
......@@ -2073,16 +2072,12 @@ static inline int _snd_pcm_oss_ioctl(struct inode *inode, struct file *file,
return -EINVAL;
}
/* FIXME: need to unlock BKL to allow preemption */
static int snd_pcm_oss_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
int err;
unlock_kernel();
err = _snd_pcm_oss_ioctl(inode, file, cmd, arg);
lock_kernel();
return err;
}
#ifdef CONFIG_COMPAT
/* all compatible */
#define snd_pcm_oss_ioctl_compat snd_pcm_oss_ioctl
#else
#define snd_pcm_oss_ioctl_compat NULL
#endif
static ssize_t snd_pcm_oss_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
{
......@@ -2410,7 +2405,8 @@ static struct file_operations snd_pcm_oss_f_reg =
.open = snd_pcm_oss_open,
.release = snd_pcm_oss_release,
.poll = snd_pcm_oss_poll,
.ioctl = snd_pcm_oss_ioctl,
.unlocked_ioctl = snd_pcm_oss_ioctl,
.compat_ioctl = snd_pcm_oss_ioctl_compat,
.mmap = snd_pcm_oss_mmap,
};
......
......@@ -1004,6 +1004,7 @@ static int __init alsa_pcm_init(void)
snd_info_entry_t *entry;
snd_ctl_register_ioctl(snd_pcm_control_ioctl);
snd_ctl_register_ioctl_compat(snd_pcm_control_ioctl);
if ((entry = snd_info_create_module_entry(THIS_MODULE, "pcm", NULL)) != NULL) {
snd_info_set_text_ops(entry, NULL, SNDRV_CARDS * SNDRV_PCM_DEVICES * 128, snd_pcm_proc_read);
if (snd_info_register(entry) < 0) {
......@@ -1018,6 +1019,7 @@ static int __init alsa_pcm_init(void)
static void __exit alsa_pcm_exit(void)
{
snd_ctl_unregister_ioctl(snd_pcm_control_ioctl);
snd_ctl_unregister_ioctl_compat(snd_pcm_control_ioctl);
if (snd_pcm_proc_entry) {
snd_info_unregister(snd_pcm_proc_entry);
snd_pcm_proc_entry = NULL;
......
This diff is collapsed.
......@@ -291,7 +291,7 @@ struct page *snd_pcm_sgbuf_ops_page(snd_pcm_substream_t *substream, unsigned lon
* @substream: the substream to allocate the DMA buffer to
* @size: the requested buffer size in bytes
*
* Allocates the DMA buffer on the BUS type given by
* Allocates the DMA buffer on the BUS type given earlier to
* snd_pcm_lib_preallocate_xxx_pages().
*
* Returns 1 if the buffer is changed, 0 if not changed, or a negative
......
......@@ -65,7 +65,7 @@ static int snd_pcm_hw_params_old_user(snd_pcm_substream_t * substream, struct sn
*
*/
rwlock_t snd_pcm_link_rwlock = RW_LOCK_UNLOCKED;
DEFINE_RWLOCK(snd_pcm_link_rwlock);
static DECLARE_RWSEM(snd_pcm_link_rwsem);
......@@ -2640,40 +2640,28 @@ static int snd_pcm_capture_ioctl1(snd_pcm_substream_t *substream,
return snd_pcm_common_ioctl1(substream, cmd, arg);
}
static int snd_pcm_playback_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
static long snd_pcm_playback_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
snd_pcm_file_t *pcm_file;
int err;
pcm_file = file->private_data;
if (((cmd >> 8) & 0xff) != 'A')
return -ENOTTY;
/* FIXME: need to unlock BKL to allow preemption */
unlock_kernel();
err = snd_pcm_playback_ioctl1(pcm_file->substream, cmd, (void __user *)arg);
lock_kernel();
return err;
return snd_pcm_playback_ioctl1(pcm_file->substream, cmd, (void __user *)arg);
}
static int snd_pcm_capture_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
snd_pcm_file_t *pcm_file;
int err;
pcm_file = file->private_data;
if (((cmd >> 8) & 0xff) != 'A')
return -ENOTTY;
/* FIXME: need to unlock BKL to allow preemption */
unlock_kernel();
err = snd_pcm_capture_ioctl1(pcm_file->substream, cmd, (void __user *)arg);
lock_kernel();
return err;
return snd_pcm_capture_ioctl1(pcm_file->substream, cmd, (void __user *)arg);
}
int snd_pcm_kernel_playback_ioctl(snd_pcm_substream_t *substream,
......@@ -3197,6 +3185,15 @@ static int snd_pcm_fasync(int fd, struct file * file, int on)
return 0;
}
/*
* ioctl32 compat
*/
#ifdef CONFIG_COMPAT
#include "pcm_compat.c"
#else
#define snd_pcm_ioctl_compat NULL
#endif
/*
* To be removed helpers to keep binary compatibility
*/
......@@ -3318,7 +3315,8 @@ static struct file_operations snd_pcm_f_ops_playback = {
.open = snd_pcm_open,
.release = snd_pcm_release,
.poll = snd_pcm_playback_poll,
.ioctl = snd_pcm_playback_ioctl,
.unlocked_ioctl = snd_pcm_playback_ioctl,
.compat_ioctl = snd_pcm_ioctl_compat,
.mmap = snd_pcm_mmap,
.fasync = snd_pcm_fasync,
};
......@@ -3330,7 +3328,8 @@ static struct file_operations snd_pcm_f_ops_capture = {
.open = snd_pcm_open,
.release = snd_pcm_release,
.poll = snd_pcm_capture_poll,
.ioctl = snd_pcm_capture_ioctl,
.unlocked_ioctl = snd_pcm_capture_ioctl,
.compat_ioctl = snd_pcm_ioctl_compat,
.mmap = snd_pcm_mmap,
.fasync = snd_pcm_fasync,
};
......
......@@ -673,8 +673,7 @@ static int snd_rawmidi_input_status(snd_rawmidi_substream_t * substream,
return 0;
}
static inline int _snd_rawmidi_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
static long snd_rawmidi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
snd_rawmidi_file_t *rfile;
void __user *argp = (void __user *)arg;
......@@ -784,17 +783,6 @@ static inline int _snd_rawmidi_ioctl(struct inode *inode, struct file *file,
return -ENOTTY;
}
/* FIXME: need to unlock BKL to allow preemption */
static int snd_rawmidi_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
int err;
unlock_kernel();
err = _snd_rawmidi_ioctl(inode, file, cmd, arg);
lock_kernel();
return err;
}
static int snd_rawmidi_control_ioctl(snd_card_t * card,
snd_ctl_file_t * control,
unsigned int cmd,
......@@ -1277,6 +1265,14 @@ static unsigned int snd_rawmidi_poll(struct file *file, poll_table * wait)
return mask;
}
/*
*/
#ifdef CONFIG_COMPAT
#include "rawmidi_compat.c"
#else
#define snd_rawmidi_ioctl_compat NULL
#endif
/*
*/
......@@ -1347,7 +1343,8 @@ static struct file_operations snd_rawmidi_f_ops =
.open = snd_rawmidi_open,
.release = snd_rawmidi_release,
.poll = snd_rawmidi_poll,
.ioctl = snd_rawmidi_ioctl,
.unlocked_ioctl = snd_rawmidi_ioctl,
.compat_ioctl = snd_rawmidi_ioctl_compat,
};
static snd_minor_t snd_rawmidi_reg =
......@@ -1628,6 +1625,7 @@ static int __init alsa_rawmidi_init(void)
{
snd_ctl_register_ioctl(snd_rawmidi_control_ioctl);
snd_ctl_register_ioctl_compat(snd_rawmidi_control_ioctl);
#ifdef CONFIG_SND_OSSEMUL
{ int i;
/* check device map table */
......@@ -1649,6 +1647,7 @@ static int __init alsa_rawmidi_init(void)
static void __exit alsa_rawmidi_exit(void)
{
snd_ctl_unregister_ioctl(snd_rawmidi_control_ioctl);
snd_ctl_unregister_ioctl_compat(snd_rawmidi_control_ioctl);
}
module_init(alsa_rawmidi_init)
......
/*
* 32bit -> 64bit ioctl wrapper for raw MIDI API
* Copyright (c) by Takashi Iwai <tiwai@suse.de>
*
* 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
*
*/
/* This file included from rawmidi.c */
#include <linux/compat.h>
struct sndrv_rawmidi_params32 {
s32 stream;
u32 buffer_size;
u32 avail_min;
unsigned int no_active_sensing; /* avoid bit-field */
unsigned char reserved[16];
} __attribute__((packed));
static int snd_rawmidi_ioctl_params_compat(snd_rawmidi_file_t *rfile,
struct sndrv_rawmidi_params32 __user *src)
{
snd_rawmidi_params_t params;
unsigned int val;
if (rfile->output == NULL)
return -EINVAL;
if (get_user(params.stream, &src->stream) ||
get_user(params.buffer_size, &src->buffer_size) ||
get_user(params.avail_min, &src->avail_min) ||
get_user(val, &src->no_active_sensing))
return -EFAULT;
params.no_active_sensing = val;
switch (params.stream) {
case SNDRV_RAWMIDI_STREAM_OUTPUT:
return snd_rawmidi_output_params(rfile->output, &params);
case SNDRV_RAWMIDI_STREAM_INPUT:
return snd_rawmidi_input_params(rfile->input, &params);
}
return -EINVAL;
}
struct sndrv_rawmidi_status32 {
s32 stream;
struct compat_timespec tstamp;
u32 avail;
u32 xruns;
unsigned char reserved[16];
} __attribute__((packed));
static int snd_rawmidi_ioctl_status_compat(snd_rawmidi_file_t *rfile,
struct sndrv_rawmidi_status32 __user *src)
{
int err;
snd_rawmidi_status_t status;
if (rfile->output == NULL)
return -EINVAL;
if (get_user(status.stream, &src->stream))
return -EFAULT;
switch (status.stream) {
case SNDRV_RAWMIDI_STREAM_OUTPUT:
err = snd_rawmidi_output_status(rfile->output, &status);
break;
case SNDRV_RAWMIDI_STREAM_INPUT:
err = snd_rawmidi_input_status(rfile->input, &status);
break;
default:
return -EINVAL;
}
if (err < 0)
return err;
if (put_user(status.tstamp.tv_sec, &src->tstamp.tv_sec) ||
put_user(status.tstamp.tv_nsec, &src->tstamp.tv_nsec) ||
put_user(status.avail, &src->avail) ||
put_user(status.xruns, &src->xruns))
return -EFAULT;
return 0;
}
enum {
SNDRV_RAWMIDI_IOCTL_PARAMS32 = _IOWR('W', 0x10, struct sndrv_rawmidi_params32),
SNDRV_RAWMIDI_IOCTL_STATUS32 = _IOWR('W', 0x20, struct sndrv_rawmidi_status32),
};
static long snd_rawmidi_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
{
snd_rawmidi_file_t *rfile;
void __user *argp = compat_ptr(arg);
rfile = file->private_data;
switch (cmd) {
case SNDRV_RAWMIDI_IOCTL_PVERSION:
case SNDRV_RAWMIDI_IOCTL_INFO:
case SNDRV_RAWMIDI_IOCTL_DROP:
case SNDRV_RAWMIDI_IOCTL_DRAIN:
return snd_rawmidi_ioctl(file, cmd, (unsigned long)argp);
case SNDRV_RAWMIDI_IOCTL_PARAMS32:
return snd_rawmidi_ioctl_params_compat(rfile, argp);
case SNDRV_RAWMIDI_IOCTL_STATUS32:
return snd_rawmidi_ioctl_status_compat(rfile, argp);
}
return -ENOIOCTLCMD;
}
......@@ -59,7 +59,7 @@ static int odev_open(struct inode *inode, struct file *file);
static int odev_release(struct inode *inode, struct file *file);
static ssize_t odev_read(struct file *file, char __user *buf, size_t count, loff_t *offset);
static ssize_t odev_write(struct file *file, const char __user *buf, size_t count, loff_t *offset);
static int odev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
static long odev_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
static unsigned int odev_poll(struct file *file, poll_table * wait);
#ifdef CONFIG_PROC_FS
static void info_read(snd_info_entry_t *entry, snd_info_buffer_t *buf);
......@@ -177,20 +177,20 @@ odev_write(struct file *file, const char __user *buf, size_t count, loff_t *offs
return snd_seq_oss_write(dp, buf, count, file);
}
static int
odev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
static long
odev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
seq_oss_devinfo_t *dp;
int err;
dp = file->private_data;
snd_assert(dp != NULL, return -EIO);
/* FIXME: need to unlock BKL to allow preemption */
unlock_kernel();
err = snd_seq_oss_ioctl(dp, cmd, arg);
lock_kernel();
return err;
return snd_seq_oss_ioctl(dp, cmd, arg);
}
#ifdef CONFIG_COMPAT
#define odev_ioctl_compat odev_ioctl
#else
#define odev_ioctl_compat NULL
#endif
static unsigned int
odev_poll(struct file *file, poll_table * wait)
......@@ -213,7 +213,8 @@ static struct file_operations seq_oss_f_ops =
.open = odev_open,
.release = odev_release,
.poll = odev_poll,
.ioctl = odev_ioctl,
.unlocked_ioctl = odev_ioctl,
.compat_ioctl = odev_ioctl_compat,
};
static snd_minor_t seq_oss_reg = {
......
......@@ -56,7 +56,7 @@ struct seq_oss_midi_t {
static int max_midi_devs;
static seq_oss_midi_t *midi_devs[SNDRV_SEQ_OSS_MAX_MIDI_DEVS];
static spinlock_t register_lock = SPIN_LOCK_UNLOCKED;
static DEFINE_SPINLOCK(register_lock);
/*
* prototypes
......
......@@ -75,7 +75,7 @@ static seq_oss_synth_t midi_synth_dev = {
"MIDI", /* name */
};
static spinlock_t register_lock = SPIN_LOCK_UNLOCKED;
static DEFINE_SPINLOCK(register_lock);
/*
* prototypes
......
......@@ -51,7 +51,7 @@
#define SNDRV_SEQ_LFLG_OUTPUT 0x0002
#define SNDRV_SEQ_LFLG_OPEN (SNDRV_SEQ_LFLG_INPUT|SNDRV_SEQ_LFLG_OUTPUT)
static spinlock_t clients_lock = SPIN_LOCK_UNLOCKED;
static DEFINE_SPINLOCK(clients_lock);
static DECLARE_MUTEX(register_mutex);
/*
......@@ -2131,21 +2131,20 @@ static int snd_seq_do_ioctl(client_t *client, unsigned int cmd, void __user *arg
}
static int snd_seq_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
static long snd_seq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
client_t *client = (client_t *) file->private_data;
int err;
snd_assert(client != NULL, return -ENXIO);
/* FIXME: need to unlock BKL to allow preemption */
unlock_kernel();
err = snd_seq_do_ioctl(client, cmd, (void __user *) arg);
lock_kernel();
return err;
return snd_seq_do_ioctl(client, cmd, (void __user *) arg);
}
#ifdef CONFIG_COMPAT
#include "seq_compat.c"
#else
#define snd_seq_ioctl_compat NULL
#endif
/* -------------------------------------------------------- */
......@@ -2462,7 +2461,8 @@ static struct file_operations snd_seq_f_ops =
.open = snd_seq_open,
.release = snd_seq_release,
.poll = snd_seq_poll,
.ioctl = snd_seq_ioctl,
.unlocked_ioctl = snd_seq_ioctl,
.compat_ioctl = snd_seq_ioctl_compat,
};
static snd_minor_t snd_seq_reg =
......
/*
* 32bit -> 64bit ioctl wrapper for sequencer API
* Copyright (c) by Takashi Iwai <tiwai@suse.de>
*
* 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
*
*/
/* This file included from seq.c */
#include <linux/compat.h>
struct sndrv_seq_port_info32 {
struct sndrv_seq_addr addr; /* client/port numbers */
char name[64]; /* port name */
u32 capability; /* port capability bits */
u32 type; /* port type bits */
s32 midi_channels; /* channels per MIDI port */
s32 midi_voices; /* voices per MIDI port */
s32 synth_voices; /* voices per SYNTH port */
s32 read_use; /* R/O: subscribers for output (from this port) */
s32 write_use; /* R/O: subscribers for input (to this port) */
u32 kernel; /* reserved for kernel use (must be NULL) */
u32 flags; /* misc. conditioning */
unsigned char time_queue; /* queue # for timestamping */
char reserved[59]; /* for future use */
};
static int snd_seq_call_port_info_ioctl(client_t *client, unsigned int cmd,
struct sndrv_seq_port_info32 __user *data32)
{
int err = -EFAULT;
snd_seq_port_info_t *data;
mm_segment_t fs;
data = kmalloc(sizeof(*data), GFP_KERNEL);
if (! data)
return -ENOMEM;
if (copy_from_user(data, data32, sizeof(*data32)) ||
get_user(data->flags, &data32->flags) ||
get_user(data->time_queue, &data32->time_queue))
goto error;
data->kernel = NULL;
fs = snd_enter_user();
err = snd_seq_do_ioctl(client, cmd, data);
snd_leave_user(fs);
if (err < 0)
goto error;
if (copy_to_user(data32, data, sizeof(*data32)) ||
put_user(data->flags, &data32->flags) ||
put_user(data->time_queue, &data32->time_queue))
err = -EFAULT;
error:
kfree(data);
return err;
}
/*
*/
enum {
SNDRV_SEQ_IOCTL_CREATE_PORT32 = _IOWR('S', 0x20, struct sndrv_seq_port_info32),
SNDRV_SEQ_IOCTL_DELETE_PORT32 = _IOW ('S', 0x21, struct sndrv_seq_port_info32),
SNDRV_SEQ_IOCTL_GET_PORT_INFO32 = _IOWR('S', 0x22, struct sndrv_seq_port_info32),
SNDRV_SEQ_IOCTL_SET_PORT_INFO32 = _IOW ('S', 0x23, struct sndrv_seq_port_info32),
SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT32 = _IOWR('S', 0x52, struct sndrv_seq_port_info32),
};
static long snd_seq_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
{
client_t *client = (client_t *) file->private_data;
void __user *argp = compat_ptr(arg);
snd_assert(client != NULL, return -ENXIO);
switch (cmd) {
case SNDRV_SEQ_IOCTL_PVERSION:
case SNDRV_SEQ_IOCTL_CLIENT_ID:
case SNDRV_SEQ_IOCTL_SYSTEM_INFO:
case SNDRV_SEQ_IOCTL_GET_CLIENT_INFO:
case SNDRV_SEQ_IOCTL_SET_CLIENT_INFO:
case SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT:
case SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT:
case SNDRV_SEQ_IOCTL_CREATE_QUEUE:
case SNDRV_SEQ_IOCTL_DELETE_QUEUE:
case SNDRV_SEQ_IOCTL_GET_QUEUE_INFO:
case SNDRV_SEQ_IOCTL_SET_QUEUE_INFO:
case SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE:
case SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS:
case SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO:
case SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO:
case SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER:
case SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER:
case SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT:
case SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT:
case SNDRV_SEQ_IOCTL_GET_CLIENT_POOL:
case SNDRV_SEQ_IOCTL_SET_CLIENT_POOL:
case SNDRV_SEQ_IOCTL_REMOVE_EVENTS:
case SNDRV_SEQ_IOCTL_QUERY_SUBS:
case SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION:
case SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT:
case SNDRV_SEQ_IOCTL_RUNNING_MODE:
return snd_seq_do_ioctl(client, cmd, argp);
case SNDRV_SEQ_IOCTL_CREATE_PORT32:
return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_CREATE_PORT, argp);
case SNDRV_SEQ_IOCTL_DELETE_PORT32:
return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_DELETE_PORT, argp);
case SNDRV_SEQ_IOCTL_GET_PORT_INFO32:
return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_GET_PORT_INFO, argp);
case SNDRV_SEQ_IOCTL_SET_PORT_INFO32:
return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_SET_PORT_INFO, argp);
case SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT32:
return snd_seq_call_port_info_ioctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT, argp);
}
return -ENOIOCTLCMD;
}
......@@ -49,7 +49,7 @@
/* list of allocated queues */
static queue_t *queue_list[SNDRV_SEQ_MAX_QUEUES];
static spinlock_t queue_list_lock = SPIN_LOCK_UNLOCKED;
static DEFINE_SPINLOCK(queue_list_lock);
/* number of queues allocated */
static int num_queues;
......
......@@ -467,6 +467,10 @@ EXPORT_SYMBOL(snd_ctl_find_id);
EXPORT_SYMBOL(snd_ctl_notify);
EXPORT_SYMBOL(snd_ctl_register_ioctl);
EXPORT_SYMBOL(snd_ctl_unregister_ioctl);
#ifdef CONFIG_COMPAT
EXPORT_SYMBOL(snd_ctl_register_ioctl_compat);
EXPORT_SYMBOL(snd_ctl_unregister_ioctl_compat);
#endif
EXPORT_SYMBOL(snd_ctl_elem_read);
EXPORT_SYMBOL(snd_ctl_elem_write);
/* misc.c */
......
......@@ -76,7 +76,7 @@ static LIST_HEAD(snd_timer_list);
static LIST_HEAD(snd_timer_slave_list);
/* lock for slave active lists */
static spinlock_t slave_active_lock = SPIN_LOCK_UNLOCKED;
static DEFINE_SPINLOCK(slave_active_lock);
static DECLARE_MUTEX(register_mutex);
......@@ -1653,8 +1653,7 @@ static int snd_timer_user_continue(struct file *file)
return (err = snd_timer_continue(tu->timeri)) < 0 ? err : 0;
}
static inline int _snd_timer_user_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
snd_timer_user_t *tu;
void __user *argp = (void __user *)arg;
......@@ -1701,17 +1700,6 @@ static inline int _snd_timer_user_ioctl(struct inode *inode, struct file *file,
return -ENOTTY;
}
/* FIXME: need to unlock BKL to allow preemption */
static int snd_timer_user_ioctl(struct inode *inode, struct file * file,
unsigned int cmd, unsigned long arg)
{
int err;
unlock_kernel();
err = _snd_timer_user_ioctl(inode, file, cmd, arg);
lock_kernel();
return err;
}
static int snd_timer_user_fasync(int fd, struct file * file, int on)
{
snd_timer_user_t *tu;
......@@ -1803,6 +1791,12 @@ static unsigned int snd_timer_user_poll(struct file *file, poll_table * wait)
return mask;
}
#ifdef CONFIG_COMPAT
#include "timer_compat.c"
#else
#define snd_timer_user_ioctl_compat NULL
#endif
static struct file_operations snd_timer_f_ops =
{
.owner = THIS_MODULE,
......@@ -1810,7 +1804,8 @@ static struct file_operations snd_timer_f_ops =
.open = snd_timer_user_open,
.release = snd_timer_user_release,
.poll = snd_timer_user_poll,
.ioctl = snd_timer_user_ioctl,
.unlocked_ioctl = snd_timer_user_ioctl,
.compat_ioctl = snd_timer_user_ioctl_compat,
.fasync = snd_timer_user_fasync,
};
......
/*
* 32bit -> 64bit ioctl wrapper for timer API
* Copyright (c) by Takashi Iwai <tiwai@suse.de>
*
* 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
*
*/
/* This file included from timer.c */
#include <linux/compat.h>
struct sndrv_timer_info32 {
u32 flags;
s32 card;
unsigned char id[64];
unsigned char name[80];
u32 reserved0;
u32 resolution;
unsigned char reserved[64];
};
static int snd_timer_user_info_compat(struct file *file,
struct sndrv_timer_info32 __user *_info)
{
snd_timer_user_t *tu;
struct sndrv_timer_info32 info;
snd_timer_t *t;
tu = file->private_data;
snd_assert(tu->timeri != NULL, return -ENXIO);
t = tu->timeri->timer;
snd_assert(t != NULL, return -ENXIO);
memset(&info, 0, sizeof(info));
info.card = t->card ? t->card->number : -1;
if (t->hw.flags & SNDRV_TIMER_HW_SLAVE)
info.flags |= SNDRV_TIMER_FLG_SLAVE;
strlcpy(info.id, t->id, sizeof(info.id));
strlcpy(info.name, t->name, sizeof(info.name));
info.resolution = t->hw.resolution;
if (copy_to_user(_info, &info, sizeof(*_info)))
return -EFAULT;
return 0;
}
struct sndrv_timer_status32 {
struct compat_timespec tstamp;
u32 resolution;
u32 lost;
u32 overrun;
u32 queue;
unsigned char reserved[64];
};
static int snd_timer_user_status_compat(struct file *file,
struct sndrv_timer_status32 __user *_status)
{
snd_timer_user_t *tu;
snd_timer_status_t status;
tu = file->private_data;
snd_assert(tu->timeri != NULL, return -ENXIO);
memset(&status, 0, sizeof(status));
status.tstamp = tu->tstamp;
status.resolution = snd_timer_resolution(tu->timeri);
status.lost = tu->timeri->lost;
status.overrun = tu->overrun;
spin_lock_irq(&tu->qlock);
status.queue = tu->qused;
spin_unlock_irq(&tu->qlock);
if (copy_to_user(_status, &status, sizeof(status)))
return -EFAULT;
return 0;
}
/*
*/
enum {
SNDRV_TIMER_IOCTL_INFO32 = _IOR('T', 0x11, struct sndrv_timer_info32),
SNDRV_TIMER_IOCTL_STATUS32 = _IOW('T', 0x14, struct sndrv_timer_status32),
};
static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
{
void __user *argp = compat_ptr(arg);
switch (cmd) {
case SNDRV_TIMER_IOCTL_PVERSION:
case SNDRV_TIMER_IOCTL_TREAD:
case SNDRV_TIMER_IOCTL_GINFO:
case SNDRV_TIMER_IOCTL_GPARAMS:
case SNDRV_TIMER_IOCTL_GSTATUS:
case SNDRV_TIMER_IOCTL_SELECT:
case SNDRV_TIMER_IOCTL_PARAMS:
case SNDRV_TIMER_IOCTL_START:
case SNDRV_TIMER_IOCTL_STOP:
case SNDRV_TIMER_IOCTL_CONTINUE:
case SNDRV_TIMER_IOCTL_NEXT_DEVICE:
return snd_timer_user_ioctl(file, cmd, (unsigned long)argp);
case SNDRV_TIMER_IOCTL_INFO32:
return snd_timer_user_info_compat(file, argp);
case SNDRV_TIMER_IOCTL_STATUS32:
return snd_timer_user_status_compat(file, argp);
}
return -ENOIOCTLCMD;
}
......@@ -25,6 +25,7 @@
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/firmware.h>
#include <sound/core.h>
#include <sound/pcm.h>
......@@ -610,6 +611,10 @@ static void vx_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
static char *uer_type[] = { "Consumer", "Professional", "Not Present" };
snd_iprintf(buffer, "%s\n", chip->card->longname);
snd_iprintf(buffer, "Xilinx Firmware: %s\n",
chip->chip_status & VX_STAT_XILINX_LOADED ? "Loaded" : "No");
snd_iprintf(buffer, "Device Initialized: %s\n",
chip->chip_status & VX_STAT_DEVICE_INIT ? "Yes" : "No");
snd_iprintf(buffer, "DSP audio info:");
if (chip->audio_info & VX_AUDIO_INFO_REAL_TIME)
snd_iprintf(buffer, " realtime");
......
......@@ -21,6 +21,7 @@
*/
#include <sound/driver.h>
#include <linux/device.h>
#include <linux/firmware.h>
#include <sound/core.h>
#include <sound/hwdep.h>
......
......@@ -514,5 +514,15 @@ config SND_VX222
To compile this driver as a module, choose M here: the module
will be called snd-vx222.
endmenu
config SND_HDA_INTEL
tristate "Intel HD Audio"
depends on SND
select SND_PCM
help
Say Y here to include support for Intel "High Definition
Audio" (Azalia) motherboard devices.
To compile this driver as a module, choose M here: the module
will be called snd-hda-intel.
endmenu
......@@ -53,6 +53,7 @@ obj-$(CONFIG_SND) += \
ca0106/ \
cs46xx/ \
emu10k1/ \
hda/ \
ice1712/ \
korg1212/ \
mixart/ \
......
......@@ -438,9 +438,10 @@ static int snd_ac97_ad18xx_update_pcm_bits(ac97_t *ac97, int codec, unsigned sho
}
/*
*
* Controls
*/
/* input mux */
static int snd_ac97_info_mux(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
{
static char *texts[8] = {
......@@ -481,6 +482,7 @@ static int snd_ac97_put_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * uc
return snd_ac97_update(ac97, AC97_REC_SEL, val);
}
/* standard stereo enums */
#define AC97_ENUM_DOUBLE(xname, reg, shift, invert) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_enum_double, \
.get = snd_ac97_get_enum_double, .put = snd_ac97_put_enum_double, \
......@@ -543,6 +545,30 @@ static int snd_ac97_put_enum_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_valu
return snd_ac97_update_bits(ac97, reg, 1 << shift, val << shift);
}
/* save/restore ac97 v2.3 paging */
static int snd_ac97_page_save(ac97_t *ac97, int reg, snd_kcontrol_t *kcontrol)
{
int page_save = -1;
if ((kcontrol->private_value & (1<<25)) &&
(ac97->ext_id & AC97_EI_REV_MASK) >= AC97_EI_REV_23 &&
(reg >= 0x60 && reg < 0x70)) {
unsigned short page = (kcontrol->private_value >> 26) & 0x0f;
down(&ac97->page_mutex); /* lock paging */
page_save = snd_ac97_read(ac97, AC97_INT_PAGING) & AC97_PAGE_MASK;
snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page);
}
return page_save;
}
static void snd_ac97_page_restore(ac97_t *ac97, int page_save)
{
if (page_save >= 0) {
snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page_save);
up(&ac97->page_mutex); /* unlock paging */
}
}
/* volume and switch controls */
int snd_ac97_info_volsw(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
{
int mask = (kcontrol->private_value >> 16) & 0xff;
......@@ -564,7 +590,9 @@ int snd_ac97_get_volsw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontro
int rshift = (kcontrol->private_value >> 12) & 0x0f;
int mask = (kcontrol->private_value >> 16) & 0xff;
int invert = (kcontrol->private_value >> 24) & 0x01;
int page_save;
page_save = snd_ac97_page_save(ac97, reg, kcontrol);
ucontrol->value.integer.value[0] = (snd_ac97_read_cache(ac97, reg) >> shift) & mask;
if (shift != rshift)
ucontrol->value.integer.value[1] = (snd_ac97_read_cache(ac97, reg) >> rshift) & mask;
......@@ -573,6 +601,7 @@ int snd_ac97_get_volsw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontro
if (shift != rshift)
ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
}
snd_ac97_page_restore(ac97, page_save);
return 0;
}
......@@ -584,8 +613,10 @@ int snd_ac97_put_volsw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontro
int rshift = (kcontrol->private_value >> 12) & 0x0f;
int mask = (kcontrol->private_value >> 16) & 0xff;
int invert = (kcontrol->private_value >> 24) & 0x01;
int err, page_save;
unsigned short val, val2, val_mask;
page_save = snd_ac97_page_save(ac97, reg, kcontrol);
val = (ucontrol->value.integer.value[0] & mask);
if (invert)
val = mask - val;
......@@ -598,7 +629,9 @@ int snd_ac97_put_volsw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontro
val_mask |= mask << rshift;
val |= val2 << rshift;
}
return snd_ac97_update_bits(ac97, reg, val_mask, val);
err = snd_ac97_update_bits(ac97, reg, val_mask, val);
snd_ac97_page_restore(ac97, page_save);
return err;
}
#define AC97_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \
......@@ -606,40 +639,6 @@ int snd_ac97_put_volsw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontro
.get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
.private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) | ((mask) << 16) | ((invert) << 24) }
static int snd_ac97_getput_page(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol,
int (*func)(snd_kcontrol_t *, snd_ctl_elem_value_t *))
{
ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
int reg = kcontrol->private_value & 0xff;
int err;
if ((ac97->ext_id & AC97_EI_REV_MASK) >= AC97_EI_REV_23 &&
(reg >= 0x60 && reg < 0x70)) {
unsigned short page_save;
unsigned short page = (kcontrol->private_value >> 25) & 0x0f;
down(&ac97->page_mutex); /* lock paging */
page_save = snd_ac97_read(ac97, AC97_INT_PAGING) & AC97_PAGE_MASK;
snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page);
err = func(kcontrol, ucontrol);
snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page_save);
up(&ac97->page_mutex); /* unlock paging */
} else
err = func(kcontrol, ucontrol);
return err;
}
/* for rev2.3 paging */
int snd_ac97_page_get_volsw(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
return snd_ac97_getput_page(kcontrol, ucontrol, snd_ac97_get_volsw);
}
/* for rev2.3 paging */
int snd_ac97_page_put_volsw(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
return snd_ac97_getput_page(kcontrol, ucontrol, snd_ac97_put_volsw);
}
static const snd_kcontrol_new_t snd_ac97_controls_master_mono[2] = {
AC97_SINGLE("Master Mono Playback Switch", AC97_MASTER_MONO, 15, 1, 1),
AC97_SINGLE("Master Mono Playback Volume", AC97_MASTER_MONO, 0, 31, 1)
......
......@@ -23,14 +23,14 @@
*/
#define AC97_SINGLE_VALUE(reg,shift,mask,invert) ((reg) | ((shift) << 8) | ((shift) << 12) | ((mask) << 16) | ((invert) << 24))
#define AC97_PAGE_SINGLE_VALUE(reg,shift,mask,invert,page) (AC97_SINGLE_VALUE(reg,shift,mask,invert) | ((page) << 25))
#define AC97_PAGE_SINGLE_VALUE(reg,shift,mask,invert,page) (AC97_SINGLE_VALUE(reg,shift,mask,invert) | (1<<25) | ((page) << 26))
#define AC97_SINGLE(xname, reg, shift, mask, invert) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_volsw, \
.get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
.private_value = AC97_SINGLE_VALUE(reg, shift, mask, invert) }
#define AC97_PAGE_SINGLE(xname, reg, shift, mask, invert, page) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_volsw, \
.get = snd_ac97_page_get_volsw, .put = snd_ac97_page_put_volsw, \
.get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
.private_value = AC97_PAGE_SINGLE_VALUE(reg, shift, mask, invert, page) }
/* ac97_codec.c */
......@@ -42,8 +42,6 @@ void snd_ac97_get_name(ac97_t *ac97, unsigned int id, char *name, int modem);
int snd_ac97_info_volsw(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo);
int snd_ac97_get_volsw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
int snd_ac97_put_volsw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
int snd_ac97_page_get_volsw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
int snd_ac97_page_put_volsw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
int snd_ac97_try_bit(ac97_t * ac97, int reg, int bit);
int snd_ac97_remove_ctl(ac97_t *ac97, const char *name, const char *suffix);
int snd_ac97_rename_ctl(ac97_t *ac97, const char *src, const char *dst, const char *suffix);
......
......@@ -1107,13 +1107,26 @@ static struct snd_ac97_build_ops patch_ad1981a_build_ops = {
#endif
};
static void check_ad1981_hp_jack_sense(ac97_t *ac97)
{
u32 subid = ((u32)ac97->subsystem_vendor << 16) | ac97->subsystem_device;
switch (subid) {
case 0x103c0890: /* HP nc6000 */
case 0x103c006d: /* HP nx9105 */
case 0x17340088: /* FSC Scenic-W */
/* enable headphone jack sense */
snd_ac97_update_bits(ac97, AC97_AD_JACK_SPDIF, 1<<11, 1<<11);
break;
}
}
int patch_ad1981a(ac97_t *ac97)
{
patch_ad1881(ac97);
ac97->build_ops = &patch_ad1981a_build_ops;
snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD198X_MSPLT, AC97_AD198X_MSPLT);
ac97->flags |= AC97_STEREO_MUTES;
snd_ac97_update_bits(ac97, AC97_AD_JACK_SPDIF, 1<<11, 1<<11); /* HP jack sense */
check_ad1981_hp_jack_sense(ac97);
return 0;
}
......@@ -1144,7 +1157,7 @@ int patch_ad1981b(ac97_t *ac97)
ac97->build_ops = &patch_ad1981b_build_ops;
snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD198X_MSPLT, AC97_AD198X_MSPLT);
ac97->flags |= AC97_STEREO_MUTES;
snd_ac97_update_bits(ac97, AC97_AD_JACK_SPDIF, 1<<11, 1<<11); /* HP jack sense */
check_ad1981_hp_jack_sense(ac97);
return 0;
}
......
......@@ -1332,6 +1332,12 @@ static irqreturn_t snd_atiixp_interrupt(int irq, void *dev_id, struct pt_regs *r
*/
static struct ac97_quirk ac97_quirks[] __devinitdata = {
{
.vendor = 0x103c,
.device = 0x006b,
.name = "HP Pavilion ZV5030US",
.type = AC97_TUNE_MUTE_LED
},
{ } /* terminator */
};
......
......@@ -606,21 +606,20 @@ static snd_pcm_uframes_t snd_atiixp_pcm_pointer(snd_pcm_substream_t *substream)
snd_pcm_runtime_t *runtime = substream->runtime;
atiixp_dma_t *dma = (atiixp_dma_t *)runtime->private_data;
unsigned int curptr;
int timeout = 1000;
spin_lock(&chip->reg_lock);
curptr = readl(chip->remap_addr + dma->ops->dt_cur);
if (curptr < dma->buf_addr) {
snd_printdd("curptr = %x, base = %x\n", curptr, dma->buf_addr);
curptr = 0;
} else {
while (timeout--) {
curptr = readl(chip->remap_addr + dma->ops->dt_cur);
if (curptr < dma->buf_addr)
continue;
curptr -= dma->buf_addr;
if (curptr >= dma->buf_bytes) {
snd_printdd("curptr = %x, size = %x\n", curptr, dma->buf_bytes);
curptr = 0;
}
if (curptr >= dma->buf_bytes)
continue;
return bytes_to_frames(runtime, curptr);
}
spin_unlock(&chip->reg_lock);
return bytes_to_frames(runtime, curptr);
snd_printd("atiixp-modem: invalid DMA pointer read 0x%x (buf=%x)\n",
readl(chip->remap_addr + dma->ops->dt_cur), dma->buf_addr);
return 0;
}
/*
......
snd-hda-intel-objs := hda_intel.o
snd-hda-codec-objs := hda_codec.o hda_generic.o patch_realtek.o patch_cmedia.o
ifdef CONFIG_PROC_FS
snd-hda-codec-objs += hda_proc.o
endif
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o snd-hda-codec.o
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* Universal Interface for Intel High Definition Audio Codec
*
* Local helper functions
*
* Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
*
* 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 __SOUND_HDA_LOCAL_H
#define __SOUND_HDA_LOCAL_H
/*
* for mixer controls
*/
#define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19))
#define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
.info = snd_hda_mixer_amp_volume_info, \
.get = snd_hda_mixer_amp_volume_get, \
.put = snd_hda_mixer_amp_volume_put, \
.private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) }
#define HDA_CODEC_VOLUME_IDX(xname, xcidx, nid, xindex, direction) \
HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, 3, xindex, direction)
#define HDA_CODEC_VOLUME_MONO(xname, nid, channel, xindex, direction) \
HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, 3, xindex, direction)
#define HDA_CODEC_VOLUME(xname, nid, xindex, direction) \
HDA_CODEC_VOLUME_MONO(xname, nid, 3, xindex, direction)
#define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
.info = snd_hda_mixer_amp_switch_info, \
.get = snd_hda_mixer_amp_switch_get, \
.put = snd_hda_mixer_amp_switch_put, \
.private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) }
#define HDA_CODEC_MUTE_IDX(xname, xcidx, nid, xindex, direction) \
HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, 3, xindex, direction)
#define HDA_CODEC_MUTE_MONO(xname, nid, channel, xindex, direction) \
HDA_CODEC_MUTE_MONO_IDX(xname, 0, nid, 3, xindex, direction)
#define HDA_CODEC_MUTE(xname, nid, xindex, direction) \
HDA_CODEC_MUTE_MONO(xname, nid, 3, xindex, direction)
int snd_hda_mixer_amp_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo);
int snd_hda_mixer_amp_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
int snd_hda_mixer_amp_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
int snd_hda_mixer_amp_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo);
int snd_hda_mixer_amp_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
int snd_hda_mixer_amp_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid);
/*
* input MUX helper
*/
#define HDA_MAX_NUM_INPUTS 8
struct hda_input_mux_item {
const char *label;
unsigned int index;
};
struct hda_input_mux {
unsigned int num_items;
struct hda_input_mux_item items[HDA_MAX_NUM_INPUTS];
};
int snd_hda_input_mux_info(const struct hda_input_mux *imux, snd_ctl_elem_info_t *uinfo);
int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *imux,
snd_ctl_elem_value_t *ucontrol, hda_nid_t nid,
unsigned int *cur_val);
/*
* Multi-channel / digital-out PCM helper
*/
enum { HDA_FRONT, HDA_REAR, HDA_CLFE, HDA_SIDE }; /* index for dac_nidx */
enum { HDA_DIG_NONE, HDA_DIG_EXCLUSIVE, HDA_DIG_ANALOG_DUP }; /* dig_out_used */
struct hda_multi_out {
int num_dacs; /* # of DACs, must be more than 1 */
hda_nid_t *dac_nids; /* DAC list */
hda_nid_t hp_nid; /* optional DAC for HP, 0 when not exists */
hda_nid_t dig_out_nid; /* digital out audio widget */
int max_channels; /* currently supported analog channels */
int dig_out_used; /* current usage of digital out (HDA_DIG_XXX) */
};
int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout);
int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout);
int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout,
snd_pcm_substream_t *substream);
int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout,
unsigned int stream_tag,
unsigned int format,
snd_pcm_substream_t *substream);
int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_out *mout);
/*
* generic codec parser
*/
int snd_hda_parse_generic_codec(struct hda_codec *codec);
/*
* generic proc interface
*/
#ifdef CONFIG_PROC_FS
int snd_hda_codec_proc_new(struct hda_codec *codec);
#else
static inline int snd_hda_codec_proc_new(struct hda_codec *codec) { return 0; }
#endif
/*
* Misc
*/
struct hda_board_config {
const char *modelname;
int config;
unsigned short pci_vendor;
unsigned short pci_device;
};
int snd_hda_check_board_config(struct hda_codec *codec, struct hda_board_config *tbl);
int snd_hda_add_new_ctls(struct hda_codec *codec, snd_kcontrol_new_t *knew);
/*
* power management
*/
#ifdef CONFIG_PM
int snd_hda_resume_ctls(struct hda_codec *codec, snd_kcontrol_new_t *knew);
int snd_hda_resume_spdif_out(struct hda_codec *codec);
#endif
/*
* unsolicited event handler
*/
#define HDA_UNSOL_QUEUE_SIZE 64
struct hda_bus_unsolicited {
/* ring buffer */
u32 queue[HDA_UNSOL_QUEUE_SIZE * 2];
unsigned int rp, wp;
/* workqueue */
struct workqueue_struct *workq;
struct work_struct work;
};
#endif /* __SOUND_HDA_LOCAL_H */
/*
* HDA Patches - included by hda_codec.c
*/
/* Realtek codecs */
extern struct hda_codec_preset snd_hda_preset_realtek[];
/* C-Media codecs */
extern struct hda_codec_preset snd_hda_preset_cmedia[];
static const struct hda_codec_preset *hda_preset_tables[] = {
snd_hda_preset_realtek,
snd_hda_preset_cmedia,
NULL
};
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -101,6 +101,15 @@ struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = {
.eeprom_size = sizeof(k8x800_eeprom),
.eeprom_data = k8x800_eeprom,
},
{
.subvendor = VT1720_SUBDEVICE_9CJS,
.name = "Chaintech 9CJS",
/* identical with k8x800 */
.chip_init = k8x800_init,
.build_controls = k8x800_add_controls,
.eeprom_size = sizeof(k8x800_eeprom),
.eeprom_data = k8x800_eeprom,
},
{ } /* terminator */
};
......@@ -26,11 +26,13 @@
#define VT1720_MOBO_DEVICE_DESC "{Albatron,K8X800 Pro II},"\
"{Chaintech,ZNF3-150},"\
"{Chaintech,ZNF3-250},"
"{Chaintech,ZNF3-250},"\
"{Chaintech,9CJS},"
#define VT1720_SUBDEVICE_K8X800 0xf217052c
#define VT1720_SUBDEVICE_ZNF3_150 0x0f2741f6
#define VT1720_SUBDEVICE_ZNF3_250 0x0f2745f6
#define VT1720_SUBDEVICE_9CJS 0x0f272327
extern struct snd_ice1712_card_info snd_vt1720_mobo_cards[];
......
This diff is collapsed.
......@@ -4958,7 +4958,7 @@ static int __devinit hdsp_request_fw_loader(hdsp_t *hdsp)
#ifdef SNDRV_BIG_ENDIAN
{
int i;
u32 *src = hdsp->data;
u32 *src = (u32*)fw->data;
for (i = 0; i < ARRAY_SIZE(hdsp->firmware_cache); i++, src++)
hdsp->firmware_cache[i] = ((*src & 0x000000ff) << 16) |
((*src & 0x0000ff00) << 8) |
......
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