Merge branch 'topic/misc' into for-linus

This commit is contained in:
Takashi Iwai 2010-08-05 11:17:04 +02:00
commit 74bf40f079
56 changed files with 1071 additions and 692 deletions

View File

@ -280,19 +280,12 @@ and is between 256 and 4096 characters. It is defined in the file
no: ACPI OperationRegions are not marked as reserved,
no further checks are performed.
ad1848= [HW,OSS]
Format: <io>,<irq>,<dma>,<dma2>,<type>
add_efi_memmap [EFI; X86] Include EFI memory map in
kernel's map of available physical RAM.
advansys= [HW,SCSI]
See header of drivers/scsi/advansys.c.
aedsp16= [HW,OSS] Audio Excel DSP 16
Format: <io>,<irq>,<dma>,<mss_io>,<mpu_io>,<mpu_irq>
See also header of sound/oss/aedsp16.c.
agp= [AGP]
{ off | try_unsupported }
off: disable AGP support
@ -311,6 +304,9 @@ and is between 256 and 4096 characters. It is defined in the file
aic79xx= [HW,SCSI]
See Documentation/scsi/aic79xx.txt.
ALSA [HW,ALSA]
See Documentation/sound/alsa/alsa-parameters.txt
alignment= [KNL,ARM]
Allow the default userspace alignment fault handler
behaviour to be specified. Bit 0 enables warnings,
@ -655,8 +651,6 @@ and is between 256 and 4096 characters. It is defined in the file
Disable PIN 1 of APIC timer
Can be useful to work around chipset bugs.
dmasound= [HW,OSS] Sound subsystem buffers
dma_debug=off If the kernel is compiled with DMA_API_DEBUG support,
this option disables the debugging code at boot.
@ -1523,9 +1517,6 @@ and is between 256 and 4096 characters. It is defined in the file
that the amount of memory usable for all allocations
is not too small.
mpu401= [HW,OSS]
Format: <io>,<irq>
MTD_Partition= [MTD]
Format: <name>,<region-number>,<size>,<offset>
@ -1849,9 +1840,6 @@ and is between 256 and 4096 characters. It is defined in the file
For example, to override I2C bus2:
omap_mux=i2c2_scl.i2c2_scl=0x100,i2c2_sda.i2c2_sda=0x100
opl3= [HW,OSS]
Format: <io>
oprofile.timer= [HW]
Use timer interrupt instead of performance counters
@ -1863,6 +1851,9 @@ and is between 256 and 4096 characters. It is defined in the file
perfmon on Intel CPUs instead of the
CPU specific event set.
OSS [HW,OSS]
See Documentation/sound/oss/oss-parameters.txt
osst= [HW,SCSI] SCSI Tape Driver
Format: <buffer_size>,<write_threshold>
See also Documentation/scsi/st.txt.
@ -1899,9 +1890,6 @@ and is between 256 and 4096 characters. It is defined in the file
Currently this function knows 686a and 8231 chips.
Format: [spp|ps2|epp|ecp|ecpepp]
pas2= [HW,OSS] Format:
<io>,<irq>,<dma>,<dma16>,<sb_io>,<sb_irq>,<sb_dma>,<sb_dma16>
pas16= [HW,SCSI]
See header of drivers/scsi/pas16.c.
@ -2171,10 +2159,6 @@ and is between 256 and 4096 characters. It is defined in the file
[HW,MOUSE] Controls Logitech smartscroll autorepeat.
0 = disabled, 1 = enabled (default).
pss= [HW,OSS] Personal Sound System (ECHO ESC614)
Format:
<io>,<mss_io>,<mss_irq>,<mss_dma>,<mpu_io>,<mpu_irq>
pt. [PARIDE]
See Documentation/blockdev/paride.txt.
@ -2383,128 +2367,6 @@ and is between 256 and 4096 characters. It is defined in the file
1: Fast pin select (default)
2: ATC IRMode
snd-ad1816a= [HW,ALSA]
snd-ad1848= [HW,ALSA]
snd-ali5451= [HW,ALSA]
snd-als100= [HW,ALSA]
snd-als4000= [HW,ALSA]
snd-azt2320= [HW,ALSA]
snd-cmi8330= [HW,ALSA]
snd-cmipci= [HW,ALSA]
snd-cs4231= [HW,ALSA]
snd-cs4232= [HW,ALSA]
snd-cs4236= [HW,ALSA]
snd-cs4281= [HW,ALSA]
snd-cs46xx= [HW,ALSA]
snd-dt019x= [HW,ALSA]
snd-dummy= [HW,ALSA]
snd-emu10k1= [HW,ALSA]
snd-ens1370= [HW,ALSA]
snd-ens1371= [HW,ALSA]
snd-es968= [HW,ALSA]
snd-es1688= [HW,ALSA]
snd-es18xx= [HW,ALSA]
snd-es1938= [HW,ALSA]
snd-es1968= [HW,ALSA]
snd-fm801= [HW,ALSA]
snd-gusclassic= [HW,ALSA]
snd-gusextreme= [HW,ALSA]
snd-gusmax= [HW,ALSA]
snd-hdsp= [HW,ALSA]
snd-ice1712= [HW,ALSA]
snd-intel8x0= [HW,ALSA]
snd-interwave= [HW,ALSA]
snd-interwave-stb=
[HW,ALSA]
snd-korg1212= [HW,ALSA]
snd-maestro3= [HW,ALSA]
snd-mpu401= [HW,ALSA]
snd-mtpav= [HW,ALSA]
snd-nm256= [HW,ALSA]
snd-opl3sa2= [HW,ALSA]
snd-opti92x-ad1848=
[HW,ALSA]
snd-opti92x-cs4231=
[HW,ALSA]
snd-opti93x= [HW,ALSA]
snd-pmac= [HW,ALSA]
snd-rme32= [HW,ALSA]
snd-rme96= [HW,ALSA]
snd-rme9652= [HW,ALSA]
snd-sb8= [HW,ALSA]
snd-sb16= [HW,ALSA]
snd-sbawe= [HW,ALSA]
snd-serial= [HW,ALSA]
snd-sgalaxy= [HW,ALSA]
snd-sonicvibes= [HW,ALSA]
snd-sun-amd7930=
[HW,ALSA]
snd-sun-cs4231= [HW,ALSA]
snd-trident= [HW,ALSA]
snd-usb-audio= [HW,ALSA,USB]
snd-via82xx= [HW,ALSA]
snd-virmidi= [HW,ALSA]
snd-wavefront= [HW,ALSA]
snd-ymfpci= [HW,ALSA]
softlockup_panic=
[KNL] Should the soft-lockup detector generate panics.
@ -2519,9 +2381,6 @@ and is between 256 and 4096 characters. It is defined in the file
spia_pedr=
spia_peddr=
sscape= [HW,OSS]
Format: <io>,<irq>,<dma>,<mpu_io>,<mpu_irq>
st= [HW,SCSI] SCSI tape parameters (buffers, etc.)
See Documentation/scsi/st.txt.
@ -2661,10 +2520,6 @@ and is between 256 and 4096 characters. It is defined in the file
to facilitate early boot debugging.
See also Documentation/trace/events.txt
trix= [HW,OSS] MediaTrix AudioTrix Pro
Format:
<io>,<irq>,<dma>,<dma2>,<sb_io>,<sb_irq>,<sb_dma>,<mpu_io>,<mpu_irq>
tsc= Disable clocksource-must-verify flag for TSC.
Format: <string>
[x86] reliable: mark tsc clocksource as reliable, this
@ -2681,12 +2536,6 @@ and is between 256 and 4096 characters. It is defined in the file
u14-34f= [HW,SCSI] UltraStor 14F/34F SCSI host adapter
See header of drivers/scsi/u14-34f.c.
uart401= [HW,OSS]
Format: <io>,<irq>
uart6850= [HW,OSS]
Format: <io>,<irq>
uhash_entries= [KNL,NET]
Set number of hash buckets for UDP/UDP-Lite connections
@ -2852,9 +2701,6 @@ and is between 256 and 4096 characters. It is defined in the file
overridden by individual drivers. 0 will hide
cursors, 1 will display them.
waveartist= [HW,OSS]
Format: <io>,<irq>,<dma>,<dma2>
wd33c93= [HW,SCSI]
See header of drivers/scsi/wd33c93.c.
@ -2887,5 +2733,4 @@ ______________________________________________________________________
TODO:
Add documentation for ALSA options.
Add more DRM drivers.

View File

@ -103,6 +103,8 @@ card*/pcm*/xrun_debug
bit 2 = Enable additional jiffies check
bit 3 = Log hwptr update at each period interrupt
bit 4 = Log hwptr update at each snd_pcm_update_hw_ptr()
bit 5 = Show last 10 positions on error
bit 6 = Do above only once
When the bit 0 is set, the driver will show the messages to
kernel log when an xrun is detected. The debug message is
@ -122,6 +124,12 @@ card*/pcm*/xrun_debug
Bits 3 and 4 are for logging the hwptr records. Note that
these will give flood of kernel messages.
When bit 5 is set, the driver logs the last 10 xrun errors and
the proc file shows each jiffies, position, period_size,
buffer_size, old_hw_ptr, and hw_ptr_base values.
When bit 6 is set, the full xrun log is shown only once.
card*/pcm*/sub*/info
The general information of this PCM sub-stream.

View File

@ -0,0 +1,135 @@
ALSA Kernel Parameters
~~~~~~~~~~~~~~~~~~~~~~
See Documentation/kernel-parameters.txt for general information on
specifying module parameters.
This document may not be entirely up to date and comprehensive. The command
"modinfo -p ${modulename}" shows a current list of all parameters of a loadable
module. Loadable modules, after being loaded into the running kernel, also
reveal their parameters in /sys/module/${modulename}/parameters/. Some of these
parameters may be changed at runtime by the command
"echo -n ${value} > /sys/module/${modulename}/parameters/${parm}".
snd-ad1816a= [HW,ALSA]
snd-ad1848= [HW,ALSA]
snd-ali5451= [HW,ALSA]
snd-als100= [HW,ALSA]
snd-als4000= [HW,ALSA]
snd-azt2320= [HW,ALSA]
snd-cmi8330= [HW,ALSA]
snd-cmipci= [HW,ALSA]
snd-cs4231= [HW,ALSA]
snd-cs4232= [HW,ALSA]
snd-cs4236= [HW,ALSA]
snd-cs4281= [HW,ALSA]
snd-cs46xx= [HW,ALSA]
snd-dt019x= [HW,ALSA]
snd-dummy= [HW,ALSA]
snd-emu10k1= [HW,ALSA]
snd-ens1370= [HW,ALSA]
snd-ens1371= [HW,ALSA]
snd-es968= [HW,ALSA]
snd-es1688= [HW,ALSA]
snd-es18xx= [HW,ALSA]
snd-es1938= [HW,ALSA]
snd-es1968= [HW,ALSA]
snd-fm801= [HW,ALSA]
snd-gusclassic= [HW,ALSA]
snd-gusextreme= [HW,ALSA]
snd-gusmax= [HW,ALSA]
snd-hdsp= [HW,ALSA]
snd-ice1712= [HW,ALSA]
snd-intel8x0= [HW,ALSA]
snd-interwave= [HW,ALSA]
snd-interwave-stb=
[HW,ALSA]
snd-korg1212= [HW,ALSA]
snd-maestro3= [HW,ALSA]
snd-mpu401= [HW,ALSA]
snd-mtpav= [HW,ALSA]
snd-nm256= [HW,ALSA]
snd-opl3sa2= [HW,ALSA]
snd-opti92x-ad1848=
[HW,ALSA]
snd-opti92x-cs4231=
[HW,ALSA]
snd-opti93x= [HW,ALSA]
snd-pmac= [HW,ALSA]
snd-rme32= [HW,ALSA]
snd-rme96= [HW,ALSA]
snd-rme9652= [HW,ALSA]
snd-sb8= [HW,ALSA]
snd-sb16= [HW,ALSA]
snd-sbawe= [HW,ALSA]
snd-serial= [HW,ALSA]
snd-sgalaxy= [HW,ALSA]
snd-sonicvibes= [HW,ALSA]
snd-sun-amd7930=
[HW,ALSA]
snd-sun-cs4231= [HW,ALSA]
snd-trident= [HW,ALSA]
snd-usb-audio= [HW,ALSA,USB]
snd-via82xx= [HW,ALSA]
snd-virmidi= [HW,ALSA]
snd-wavefront= [HW,ALSA]
snd-ymfpci= [HW,ALSA]

View File

@ -0,0 +1,51 @@
OSS Kernel Parameters
~~~~~~~~~~~~~~~~~~~~~
See Documentation/kernel-parameters.txt for general information on
specifying module parameters.
This document may not be entirely up to date and comprehensive. The command
"modinfo -p ${modulename}" shows a current list of all parameters of a loadable
module. Loadable modules, after being loaded into the running kernel, also
reveal their parameters in /sys/module/${modulename}/parameters/. Some of these
parameters may be changed at runtime by the command
"echo -n ${value} > /sys/module/${modulename}/parameters/${parm}".
ad1848= [HW,OSS]
Format: <io>,<irq>,<dma>,<dma2>,<type>
aedsp16= [HW,OSS] Audio Excel DSP 16
Format: <io>,<irq>,<dma>,<mss_io>,<mpu_io>,<mpu_irq>
See also header of sound/oss/aedsp16.c.
dmasound= [HW,OSS] Sound subsystem buffers
mpu401= [HW,OSS]
Format: <io>,<irq>
opl3= [HW,OSS]
Format: <io>
pas2= [HW,OSS] Format:
<io>,<irq>,<dma>,<dma16>,<sb_io>,<sb_irq>,<sb_dma>,<sb_dma16>
pss= [HW,OSS] Personal Sound System (ECHO ESC614)
Format:
<io>,<mss_io>,<mss_irq>,<mss_dma>,<mpu_io>,<mpu_irq>
sscape= [HW,OSS]
Format: <io>,<irq>,<dma>,<mpu_io>,<mpu_irq>
trix= [HW,OSS] MediaTrix AudioTrix Pro
Format:
<io>,<irq>,<dma>,<dma2>,<sb_io>,<sb_irq>,<sb_dma>,<mpu_io>,<mpu_irq>
uart401= [HW,OSS]
Format: <io>,<irq>
uart6850= [HW,OSS]
Format: <io>,<irq>
waveartist= [HW,OSS]
Format: <io>,<irq>,<dma>,<dma2>

View File

@ -8,6 +8,7 @@
#include "linux/slab.h"
#include "linux/sound.h"
#include "linux/soundcard.h"
#include "linux/smp_lock.h"
#include "asm/uaccess.h"
#include "init.h"
#include "os.h"
@ -198,7 +199,10 @@ static int hostaudio_open(struct inode *inode, struct file *file)
if (file->f_mode & FMODE_WRITE)
w = 1;
lock_kernel();
ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
unlock_kernel();
if (ret < 0) {
kfree(state);
return ret;
@ -254,7 +258,9 @@ static int hostmixer_open_mixdev(struct inode *inode, struct file *file)
if (file->f_mode & FMODE_WRITE)
w = 1;
lock_kernel();
ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0);
unlock_kernel();
if (ret < 0) {
printk(KERN_ERR "hostaudio_open_mixdev failed to open '%s', "

View File

@ -61,7 +61,7 @@ DECLARE_UAC_AC_HEADER_DESCRIPTOR(2);
#define UAC_DT_TOTAL_LENGTH (UAC_DT_AC_HEADER_LENGTH + UAC_DT_INPUT_TERMINAL_SIZE \
+ UAC_DT_OUTPUT_TERMINAL_SIZE + UAC_DT_FEATURE_UNIT_SIZE(0))
/* B.3.2 Class-Specific AC Interface Descriptor */
static struct uac_ac_header_descriptor_v1_2 ac_header_desc = {
static struct uac1_ac_header_descriptor_2 ac_header_desc = {
.bLength = UAC_DT_AC_HEADER_LENGTH,
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubtype = UAC_HEADER,
@ -125,7 +125,7 @@ static struct usb_audio_control_selector feature_unit = {
};
#define OUTPUT_TERMINAL_ID 3
static struct uac_output_terminal_descriptor_v1 output_terminal_desc = {
static struct uac1_output_terminal_descriptor output_terminal_desc = {
.bLength = UAC_DT_OUTPUT_TERMINAL_SIZE,
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubtype = UAC_OUTPUT_TERMINAL,
@ -155,7 +155,7 @@ static struct usb_interface_descriptor as_interface_alt_1_desc = {
};
/* B.4.2 Class-Specific AS Interface Descriptor */
static struct uac_as_header_descriptor_v1 as_header_desc = {
static struct uac1_as_header_descriptor as_header_desc = {
.bLength = UAC_DT_AS_HEADER_SIZE,
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubtype = UAC_AS_GENERAL,

View File

@ -238,7 +238,7 @@ static const struct usb_interface_descriptor ac_interface_desc = {
};
/* B.3.2 Class-Specific AC Interface Descriptor */
static const struct uac_ac_header_descriptor_v1_1 ac_header_desc = {
static const struct uac1_ac_header_descriptor_1 ac_header_desc = {
.bLength = UAC_DT_AC_HEADER_SIZE(1),
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubtype = USB_MS_HEADER,

View File

@ -18,6 +18,21 @@
/* v1.0 and v2.0 of this standard have many things in common. For the rest
* of the definitions, please refer to audio.h */
/*
* bmControl field decoders
*
* From the USB Audio spec v2.0:
*
* bmaControls() is a (ch+1)-element array of 4-byte bitmaps,
* each containing a set of bit pairs. If a Control is present,
* it must be Host readable. If a certain Control is not
* present then the bit pair must be set to 0b00.
* If a Control is present but read-only, the bit pair must be
* set to 0b01. If a Control is also Host programmable, the bit
* pair must be set to 0b11. The value 0b10 is not allowed.
*
*/
static inline bool uac2_control_is_readable(u32 bmControls, u8 control)
{
return (bmControls >> (control * 2)) & 0x1;
@ -121,7 +136,7 @@ struct uac2_feature_unit_descriptor {
/* 4.9.2 Class-Specific AS Interface Descriptor */
struct uac_as_header_descriptor_v2 {
struct uac2_as_header_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubtype;

View File

@ -39,8 +39,8 @@
#define UAC_MIXER_UNIT 0x04
#define UAC_SELECTOR_UNIT 0x05
#define UAC_FEATURE_UNIT 0x06
#define UAC_PROCESSING_UNIT_V1 0x07
#define UAC_EXTENSION_UNIT_V1 0x08
#define UAC1_PROCESSING_UNIT 0x07
#define UAC1_EXTENSION_UNIT 0x08
/* A.6 Audio Class-Specific AS Interface Descriptor Subtypes */
#define UAC_AS_GENERAL 0x01
@ -151,7 +151,7 @@
/* Terminal Control Selectors */
/* 4.3.2 Class-Specific AC Interface Descriptor */
struct uac_ac_header_descriptor_v1 {
struct uac1_ac_header_descriptor {
__u8 bLength; /* 8 + n */
__u8 bDescriptorType; /* USB_DT_CS_INTERFACE */
__u8 bDescriptorSubtype; /* UAC_MS_HEADER */
@ -165,7 +165,7 @@ struct uac_ac_header_descriptor_v1 {
/* As above, but more useful for defining your own descriptors: */
#define DECLARE_UAC_AC_HEADER_DESCRIPTOR(n) \
struct uac_ac_header_descriptor_v1_##n { \
struct uac1_ac_header_descriptor_##n { \
__u8 bLength; \
__u8 bDescriptorType; \
__u8 bDescriptorSubtype; \
@ -205,7 +205,7 @@ struct uac_input_terminal_descriptor {
#define UAC_TERMINAL_CS_COPY_PROTECT_CONTROL 0x01
/* 4.3.2.2 Output Terminal Descriptor */
struct uac_output_terminal_descriptor_v1 {
struct uac1_output_terminal_descriptor {
__u8 bLength; /* in bytes: 9 */
__u8 bDescriptorType; /* CS_INTERFACE descriptor type */
__u8 bDescriptorSubtype; /* OUTPUT_TERMINAL descriptor subtype */
@ -395,7 +395,7 @@ static inline __u8 *uac_processing_unit_specific(struct uac_processing_unit_desc
}
/* 4.5.2 Class-Specific AS Interface Descriptor */
struct uac_as_header_descriptor_v1 {
struct uac1_as_header_descriptor {
__u8 bLength; /* in bytes: 7 */
__u8 bDescriptorType; /* USB_DT_CS_INTERFACE */
__u8 bDescriptorSubtype; /* AS_GENERAL */

View File

@ -212,7 +212,11 @@ typedef int __bitwise snd_pcm_format_t;
#define SNDRV_PCM_FORMAT_S18_3BE ((__force snd_pcm_format_t) 41) /* in three bytes */
#define SNDRV_PCM_FORMAT_U18_3LE ((__force snd_pcm_format_t) 42) /* in three bytes */
#define SNDRV_PCM_FORMAT_U18_3BE ((__force snd_pcm_format_t) 43) /* in three bytes */
#define SNDRV_PCM_FORMAT_LAST SNDRV_PCM_FORMAT_U18_3BE
#define SNDRV_PCM_FORMAT_G723_24 ((__force snd_pcm_format_t) 44) /* 8 samples in 3 bytes */
#define SNDRV_PCM_FORMAT_G723_24_1B ((__force snd_pcm_format_t) 45) /* 1 sample in 1 byte */
#define SNDRV_PCM_FORMAT_G723_40 ((__force snd_pcm_format_t) 46) /* 8 Samples in 5 bytes */
#define SNDRV_PCM_FORMAT_G723_40_1B ((__force snd_pcm_format_t) 47) /* 1 sample in 1 byte */
#define SNDRV_PCM_FORMAT_LAST SNDRV_PCM_FORMAT_G723_40_1B
#ifdef SNDRV_LITTLE_ENDIAN
#define SNDRV_PCM_FORMAT_S16 SNDRV_PCM_FORMAT_S16_LE

View File

@ -174,6 +174,10 @@ struct snd_pcm_ops {
#define SNDRV_PCM_FMTBIT_U18_3LE (1ULL << SNDRV_PCM_FORMAT_U18_3LE)
#define SNDRV_PCM_FMTBIT_S18_3BE (1ULL << SNDRV_PCM_FORMAT_S18_3BE)
#define SNDRV_PCM_FMTBIT_U18_3BE (1ULL << SNDRV_PCM_FORMAT_U18_3BE)
#define SNDRV_PCM_FMTBIT_G723_24 (1ULL << SNDRV_PCM_FORMAT_G723_24)
#define SNDRV_PCM_FMTBIT_G723_24_1B (1ULL << SNDRV_PCM_FORMAT_G723_24_1B)
#define SNDRV_PCM_FMTBIT_G723_40 (1ULL << SNDRV_PCM_FORMAT_G723_40)
#define SNDRV_PCM_FMTBIT_G723_40_1B (1ULL << SNDRV_PCM_FORMAT_G723_40_1B)
#ifdef SNDRV_LITTLE_ENDIAN
#define SNDRV_PCM_FMTBIT_S16 SNDRV_PCM_FMTBIT_S16_LE
@ -313,7 +317,7 @@ struct snd_pcm_runtime {
struct snd_pcm_mmap_control *control;
/* -- locking / scheduling -- */
unsigned int twake: 1; /* do transfer (!poll) wakeup */
snd_pcm_uframes_t twake; /* do transfer (!poll) wakeup if non-zero */
wait_queue_head_t sleep; /* poll sleep */
wait_queue_head_t tsleep; /* transfer sleep */
struct fasync_struct *fasync;

View File

@ -67,6 +67,8 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
} else {
if (new_hw_ptr == ULONG_MAX) { /* initialization */
snd_pcm_sframes_t avail = snd_pcm_playback_hw_avail(runtime);
if (avail > runtime->buffer_size)
avail = runtime->buffer_size;
runtime->silence_filled = avail > 0 ? avail : 0;
runtime->silence_start = (runtime->status->hw_ptr +
runtime->silence_filled) %
@ -287,8 +289,11 @@ int snd_pcm_update_state(struct snd_pcm_substream *substream,
return -EPIPE;
}
}
if (avail >= runtime->control->avail_min)
wake_up(runtime->twake ? &runtime->tsleep : &runtime->sleep);
if (runtime->twake) {
if (avail >= runtime->twake)
wake_up(&runtime->tsleep);
} else if (avail >= runtime->control->avail_min)
wake_up(&runtime->sleep);
return 0;
}
@ -1707,7 +1712,7 @@ EXPORT_SYMBOL(snd_pcm_period_elapsed);
* The available space is stored on availp. When err = 0 and avail = 0
* on the capture stream, it indicates the stream is in DRAINING state.
*/
static int wait_for_avail_min(struct snd_pcm_substream *substream,
static int wait_for_avail(struct snd_pcm_substream *substream,
snd_pcm_uframes_t *availp)
{
struct snd_pcm_runtime *runtime = substream->runtime;
@ -1757,7 +1762,7 @@ static int wait_for_avail_min(struct snd_pcm_substream *substream,
avail = snd_pcm_playback_avail(runtime);
else
avail = snd_pcm_capture_avail(runtime);
if (avail >= runtime->control->avail_min)
if (avail >= runtime->twake)
break;
}
_endloop:
@ -1820,7 +1825,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
goto _end_unlock;
}
runtime->twake = 1;
runtime->twake = runtime->control->avail_min ? : 1;
while (size > 0) {
snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
snd_pcm_uframes_t avail;
@ -1833,7 +1838,9 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
err = -EAGAIN;
goto _end_unlock;
}
err = wait_for_avail_min(substream, &avail);
runtime->twake = min_t(snd_pcm_uframes_t, size,
runtime->control->avail_min ? : 1);
err = wait_for_avail(substream, &avail);
if (err < 0)
goto _end_unlock;
}
@ -2042,7 +2049,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
goto _end_unlock;
}
runtime->twake = 1;
runtime->twake = runtime->control->avail_min ? : 1;
while (size > 0) {
snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
snd_pcm_uframes_t avail;
@ -2060,7 +2067,9 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
err = -EAGAIN;
goto _end_unlock;
}
err = wait_for_avail_min(substream, &avail);
runtime->twake = min_t(snd_pcm_uframes_t, size,
runtime->control->avail_min ? : 1);
err = wait_for_avail(substream, &avail);
if (err < 0)
goto _end_unlock;
if (!avail)

View File

@ -128,6 +128,14 @@ static struct pcm_format_data pcm_formats[SNDRV_PCM_FORMAT_LAST+1] = {
.width = 4, .phys = 4, .le = -1, .signd = -1,
.silence = {},
},
[SNDRV_PCM_FORMAT_G723_24] = {
.width = 3, .phys = 3, .le = -1, .signd = -1,
.silence = {},
},
[SNDRV_PCM_FORMAT_G723_40] = {
.width = 5, .phys = 5, .le = -1, .signd = -1,
.silence = {},
},
/* FIXME: the following three formats are not defined properly yet */
[SNDRV_PCM_FORMAT_MPEG] = {
.le = -1, .signd = -1,
@ -186,6 +194,14 @@ static struct pcm_format_data pcm_formats[SNDRV_PCM_FORMAT_LAST+1] = {
.width = 18, .phys = 24, .le = 0, .signd = 0,
.silence = { 0x02, 0x00, 0x00 },
},
[SNDRV_PCM_FORMAT_G723_24_1B] = {
.width = 3, .phys = 8, .le = -1, .signd = -1,
.silence = {},
},
[SNDRV_PCM_FORMAT_G723_40_1B] = {
.width = 5, .phys = 8, .le = -1, .signd = -1,
.silence = {},
},
};

View File

@ -170,9 +170,25 @@ config SND_AC97_POWER_SAVE
AC97 codecs. In this mode, the power-mode is dynamically
controlled at each open/close.
The mode is activated by passing power_save=1 option to
snd-ac97-codec driver. You can toggle it dynamically over
sysfs, too.
The mode is activated by passing 'power_save=X' to the
snd-ac97-codec driver module, where 'X' is the time-out
value, a nonnegative integer that specifies how many
seconds of idle time the driver must count before it may
put the AC97 into power-save mode; a value of 0 (zero)
disables the use of this power-save mode.
After the snd-ac97-codec driver module has been loaded,
the 'power_save' parameter can be set via sysfs as follows:
echo 10 > /sys/module/snd_ac97_codec/parameters/power_save
In this case, the time-out is set to 10 seconds; setting
the time-out to 1 second (the minimum activation value)
isn't recommended because many applications try to reopen
the device frequently. A value of 10 seconds would be a
good choice for normal operations.
See Documentation/sound/alsa/powersave.txt for more details.
config SND_AC97_POWER_SAVE_DEFAULT
int "Default time-out for AC97 power-save mode"
@ -182,4 +198,6 @@ config SND_AC97_POWER_SAVE_DEFAULT
The default time-out value in seconds for AC97 automatic
power-save mode. 0 means to disable the power-save mode.
See SND_AC97_POWER_SAVE for more details.
endif # SND_DRIVERS

View File

@ -549,7 +549,10 @@ static int __devinit snd_msnd_attach(struct snd_card *card)
printk(KERN_ERR LOGNAME ": Couldn't grab IRQ %d\n", chip->irq);
return err;
}
request_region(chip->io, DSP_NUMIO, card->shortname);
if (request_region(chip->io, DSP_NUMIO, card->shortname) == NULL) {
free_irq(chip->irq, chip);
return -EBUSY;
}
if (!request_mem_region(chip->base, BUFFSIZE, card->shortname)) {
printk(KERN_ERR LOGNAME

View File

@ -433,7 +433,8 @@ static int emu8k_transfer_block(struct snd_emu8000 *emu, int offset, unsigned sh
while (count > 0) {
unsigned short sval;
CHECK_SCHEDULER();
get_user(sval, buf);
if (get_user(sval, buf))
return -EFAULT;
EMU8000_SMLD_WRITE(emu, sval);
buf++;
count--;
@ -525,12 +526,14 @@ static int emu8k_pcm_copy(struct snd_pcm_substream *subs,
while (count-- > 0) {
unsigned short sval;
CHECK_SCHEDULER();
get_user(sval, buf);
if (get_user(sval, buf))
return -EFAULT;
EMU8000_SMLD_WRITE(emu, sval);
buf++;
if (rec->voices > 1) {
CHECK_SCHEDULER();
get_user(sval, buf);
if (get_user(sval, buf))
return -EFAULT;
EMU8000_SMRD_WRITE(emu, sval);
buf++;
}

View File

@ -43,6 +43,7 @@
#include <linux/sound.h>
#include <linux/slab.h>
#include <linux/soundcard.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
@ -162,19 +163,10 @@ ld2(unsigned int x)
static void
au1550_delay(int msec)
{
unsigned long tmo;
signed long tmo2;
if (in_interrupt())
return;
tmo = jiffies + (msec * HZ) / 1000;
for (;;) {
tmo2 = tmo - jiffies;
if (tmo2 <= 0)
break;
schedule_timeout(tmo2);
}
schedule_timeout_uninterruptible(msecs_to_jiffies(msec));
}
static u16
@ -807,7 +799,9 @@ au1550_llseek(struct file *file, loff_t offset, int origin)
static int
au1550_open_mixdev(struct inode *inode, struct file *file)
{
lock_kernel();
file->private_data = &au1550_state;
unlock_kernel();
return 0;
}
@ -824,22 +818,26 @@ mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd,
return codec->mixer_ioctl(codec, cmd, arg);
}
static int
au1550_ioctl_mixdev(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
static long
au1550_ioctl_mixdev(struct file *file, unsigned int cmd, unsigned long arg)
{
struct au1550_state *s = (struct au1550_state *)file->private_data;
struct ac97_codec *codec = s->codec;
int ret;
return mixdev_ioctl(codec, cmd, arg);
lock_kernel();
ret = mixdev_ioctl(codec, cmd, arg);
unlock_kernel();
return ret;
}
static /*const */ struct file_operations au1550_mixer_fops = {
owner:THIS_MODULE,
llseek:au1550_llseek,
ioctl:au1550_ioctl_mixdev,
open:au1550_open_mixdev,
release:au1550_release_mixdev,
.owner = THIS_MODULE,
.llseek = au1550_llseek,
.unlocked_ioctl = au1550_ioctl_mixdev,
.open = au1550_open_mixdev,
.release = au1550_release_mixdev,
};
static int
@ -1343,8 +1341,7 @@ dma_count_done(struct dmabuf *db)
static int
au1550_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
au1550_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct au1550_state *s = (struct au1550_state *)file->private_data;
unsigned long flags;
@ -1780,6 +1777,17 @@ au1550_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
return mixdev_ioctl(s->codec, cmd, arg);
}
static long
au1550_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
int ret;
lock_kernel();
ret = au1550_ioctl(file, cmd, arg);
unlock_kernel();
return ret;
}
static int
au1550_open(struct inode *inode, struct file *file)
@ -1797,21 +1805,22 @@ au1550_open(struct inode *inode, struct file *file)
#endif
file->private_data = s;
lock_kernel();
/* wait for device to become free */
mutex_lock(&s->open_mutex);
while (s->open_mode & file->f_mode) {
if (file->f_flags & O_NONBLOCK) {
mutex_unlock(&s->open_mutex);
return -EBUSY;
}
ret = -EBUSY;
if (file->f_flags & O_NONBLOCK)
goto out;
add_wait_queue(&s->open_wait, &wait);
__set_current_state(TASK_INTERRUPTIBLE);
mutex_unlock(&s->open_mutex);
schedule();
remove_wait_queue(&s->open_wait, &wait);
set_current_state(TASK_RUNNING);
ret = -ERESTARTSYS;
if (signal_pending(current))
return -ERESTARTSYS;
goto out2;
mutex_lock(&s->open_mutex);
}
@ -1840,17 +1849,21 @@ au1550_open(struct inode *inode, struct file *file)
if (file->f_mode & FMODE_READ) {
if ((ret = prog_dmabuf_adc(s)))
return ret;
goto out;
}
if (file->f_mode & FMODE_WRITE) {
if ((ret = prog_dmabuf_dac(s)))
return ret;
goto out;
}
s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
mutex_unlock(&s->open_mutex);
mutex_init(&s->sem);
return 0;
ret = 0;
out:
mutex_unlock(&s->open_mutex);
out2:
unlock_kernel();
return ret;
}
static int
@ -1885,15 +1898,15 @@ au1550_release(struct inode *inode, struct file *file)
}
static /*const */ struct file_operations au1550_audio_fops = {
owner: THIS_MODULE,
llseek: au1550_llseek,
read: au1550_read,
write: au1550_write,
poll: au1550_poll,
ioctl: au1550_ioctl,
mmap: au1550_mmap,
open: au1550_open,
release: au1550_release,
.owner = THIS_MODULE,
.llseek = au1550_llseek,
.read = au1550_read,
.write = au1550_write,
.poll = au1550_poll,
.unlocked_ioctl = au1550_unlocked_ioctl,
.mmap = au1550_mmap,
.open = au1550_open,
.release = au1550_release,
};
MODULE_AUTHOR("Advanced Micro Devices (AMD), dan@embeddededge.com");

View File

@ -323,9 +323,13 @@ static struct {
static int mixer_open(struct inode *inode, struct file *file)
{
if (!try_module_get(dmasound.mach.owner))
lock_kernel();
if (!try_module_get(dmasound.mach.owner)) {
unlock_kernel();
return -ENODEV;
}
mixer.busy = 1;
unlock_kernel();
return 0;
}
@ -337,8 +341,8 @@ static int mixer_release(struct inode *inode, struct file *file)
unlock_kernel();
return 0;
}
static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd,
u_long arg)
static int mixer_ioctl(struct file *file, u_int cmd, u_long arg)
{
if (_SIOC_DIR(cmd) & _SIOC_WRITE)
mixer.modify_counter++;
@ -362,11 +366,22 @@ static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd,
return -EINVAL;
}
static long mixer_unlocked_ioctl(struct file *file, u_int cmd, u_long arg)
{
int ret;
lock_kernel();
ret = mixer_ioctl(file, cmd, arg);
unlock_kernel();
return ret;
}
static const struct file_operations mixer_fops =
{
.owner = THIS_MODULE,
.llseek = no_llseek,
.ioctl = mixer_ioctl,
.unlocked_ioctl = mixer_unlocked_ioctl,
.open = mixer_open,
.release = mixer_release,
};
@ -737,8 +752,11 @@ static int sq_open(struct inode *inode, struct file *file)
{
int rc;
if (!try_module_get(dmasound.mach.owner))
lock_kernel();
if (!try_module_get(dmasound.mach.owner)) {
unlock_kernel();
return -ENODEV;
}
rc = write_sq_open(file); /* checks the f_mode */
if (rc)
@ -781,10 +799,11 @@ static int sq_open(struct inode *inode, struct file *file)
sound_set_format(AFMT_MU_LAW);
}
#endif
unlock_kernel();
return 0;
out:
module_put(dmasound.mach.owner);
unlock_kernel();
return rc;
}
@ -955,8 +974,7 @@ printk("dmasound_core: tried to set_queue_frags on a locked queue\n") ;
return 0 ;
}
static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd,
u_long arg)
static int sq_ioctl(struct file *file, u_int cmd, u_long arg)
{
int val, result;
u_long fmt;
@ -1114,18 +1132,29 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd,
return IOCTL_OUT(arg,val);
default:
return mixer_ioctl(inode, file, cmd, arg);
return mixer_ioctl(file, cmd, arg);
}
return -EINVAL;
}
static long sq_unlocked_ioctl(struct file *file, u_int cmd, u_long arg)
{
int ret;
lock_kernel();
ret = sq_ioctl(file, cmd, arg);
unlock_kernel();
return ret;
}
static const struct file_operations sq_fops =
{
.owner = THIS_MODULE,
.llseek = no_llseek,
.write = sq_write,
.poll = sq_poll,
.ioctl = sq_ioctl,
.unlocked_ioctl = sq_unlocked_ioctl,
.open = sq_open,
.release = sq_release,
};
@ -1226,12 +1255,17 @@ static int state_open(struct inode *inode, struct file *file)
{
char *buffer = state.buf;
int len = 0;
int ret;
lock_kernel();
ret = -EBUSY;
if (state.busy)
return -EBUSY;
goto out;
ret = -ENODEV;
if (!try_module_get(dmasound.mach.owner))
return -ENODEV;
goto out;
state.ptr = 0;
state.busy = 1;
@ -1293,7 +1327,10 @@ printk("dmasound: stat buffer used %d bytes\n", len) ;
printk(KERN_ERR "dmasound_core: stat buffer overflowed!\n");
state.len = len;
return 0;
ret = 0;
out:
unlock_kernel();
return ret;
}
static int state_release(struct inode *inode, struct file *file)

View File

@ -523,7 +523,9 @@ midi_synth_load_patch(int dev, int format, const char __user *addr,
{
unsigned char data;
get_user(*(unsigned char *) &data, (unsigned char __user *) &((addr)[hdr_size + i]));
if (get_user(data,
(unsigned char __user *)(addr + hdr_size + i)))
return -EFAULT;
eox_seen = (i > 0 && data & 0x80); /* End of sysex */

View File

@ -639,21 +639,26 @@ static int mixer_ioctl(unsigned int cmd, unsigned long arg)
return -EINVAL;
}
static int dev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
static long dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
int minor = iminor(inode);
int minor = iminor(file->f_path.dentry->d_inode);
int ret;
if (cmd == OSS_GETVERSION) {
int sound_version = SOUND_VERSION;
return put_user(sound_version, (int __user *)arg);
}
if (minor == dev.dsp_minor)
return dsp_ioctl(file, cmd, arg);
else if (minor == dev.mixer_minor)
return mixer_ioctl(cmd, arg);
ret = -EINVAL;
return -EINVAL;
lock_kernel();
if (minor == dev.dsp_minor)
ret = dsp_ioctl(file, cmd, arg);
else if (minor == dev.mixer_minor)
ret = mixer_ioctl(cmd, arg);
unlock_kernel();
return ret;
}
static void dsp_write_flush(void)
@ -756,12 +761,15 @@ static int dev_open(struct inode *inode, struct file *file)
int minor = iminor(inode);
int err = 0;
lock_kernel();
if (minor == dev.dsp_minor) {
if ((file->f_mode & FMODE_WRITE &&
test_bit(F_AUDIO_WRITE_INUSE, &dev.flags)) ||
(file->f_mode & FMODE_READ &&
test_bit(F_AUDIO_READ_INUSE, &dev.flags)))
return -EBUSY;
test_bit(F_AUDIO_READ_INUSE, &dev.flags))) {
err = -EBUSY;
goto out;
}
if ((err = dsp_open(file)) >= 0) {
dev.nresets = 0;
@ -782,7 +790,8 @@ static int dev_open(struct inode *inode, struct file *file)
/* nothing */
} else
err = -EINVAL;
out:
unlock_kernel();
return err;
}
@ -1105,7 +1114,7 @@ static const struct file_operations dev_fileops = {
.owner = THIS_MODULE,
.read = dev_read,
.write = dev_write,
.ioctl = dev_ioctl,
.unlocked_ioctl = dev_ioctl,
.open = dev_open,
.release = dev_release,
};
@ -1391,9 +1400,13 @@ static int __init attach_multisound(void)
printk(KERN_ERR LOGNAME ": Couldn't grab IRQ %d\n", dev.irq);
return err;
}
request_region(dev.io, dev.numio, dev.name);
if (request_region(dev.io, dev.numio, dev.name) == NULL) {
free_irq(dev.irq, &dev);
return -EBUSY;
}
if ((err = dsp_full_reset()) < 0) {
err = dsp_full_reset();
if (err < 0) {
release_region(dev.io, dev.numio);
free_irq(dev.irq, &dev);
return err;

View File

@ -15,7 +15,9 @@
#include <linux/linkage.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/smp_lock.h>
#include <linux/sound.h>
#include <linux/smp_lock.h>
#include <linux/soundcard.h>
#include <linux/interrupt.h>
#include <linux/hrtimer.h>
@ -92,7 +94,7 @@ static void dac_audio_set_rate(void)
wakeups_per_second = ktime_set(0, 1000000000 / rate);
}
static int dac_audio_ioctl(struct inode *inode, struct file *file,
static int dac_audio_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
int val;
@ -158,6 +160,17 @@ static int dac_audio_ioctl(struct inode *inode, struct file *file,
return -EINVAL;
}
static long dac_audio_unlocked_ioctl(struct file *file, u_int cmd, u_long arg)
{
int ret;
lock_kernel();
ret = dac_audio_ioctl(file, cmd, arg);
unlock_kernel();
return ret;
}
static ssize_t dac_audio_write(struct file *file, const char *buf, size_t count,
loff_t * ppos)
{
@ -216,13 +229,17 @@ static int dac_audio_open(struct inode *inode, struct file *file)
{
if (file->f_mode & FMODE_READ)
return -ENODEV;
if (in_use)
lock_kernel();
if (in_use) {
unlock_kernel();
return -EBUSY;
}
in_use = 1;
dac_audio_start();
unlock_kernel();
return 0;
}
@ -238,7 +255,7 @@ static int dac_audio_release(struct inode *inode, struct file *file)
const struct file_operations dac_audio_fops = {
.read = dac_audio_read,
.write = dac_audio_write,
.ioctl = dac_audio_ioctl,
.unlocked_ioctl = dac_audio_unlocked_ioctl,
.open = dac_audio_open,
.release = dac_audio_release,
};

View File

@ -210,42 +210,44 @@ static int sound_open(struct inode *inode, struct file *file)
printk(KERN_ERR "Invalid minor device %d\n", dev);
return -ENXIO;
}
lock_kernel();
switch (dev & 0x0f) {
case SND_DEV_CTL:
dev >>= 4;
if (dev >= 0 && dev < MAX_MIXER_DEV && mixer_devs[dev] == NULL) {
request_module("mixer%d", dev);
}
retval = -ENXIO;
if (dev && (dev >= num_mixers || mixer_devs[dev] == NULL))
return -ENXIO;
break;
if (!try_module_get(mixer_devs[dev]->owner))
return -ENXIO;
break;
retval = 0;
break;
case SND_DEV_SEQ:
case SND_DEV_SEQ2:
if ((retval = sequencer_open(dev, file)) < 0)
return retval;
retval = sequencer_open(dev, file);
break;
case SND_DEV_MIDIN:
if ((retval = MIDIbuf_open(dev, file)) < 0)
return retval;
retval = MIDIbuf_open(dev, file);
break;
case SND_DEV_DSP:
case SND_DEV_DSP16:
case SND_DEV_AUDIO:
if ((retval = audio_open(dev, file)) < 0)
return retval;
retval = audio_open(dev, file);
break;
default:
printk(KERN_ERR "Invalid minor device %d\n", dev);
return -ENXIO;
retval = -ENXIO;
}
unlock_kernel();
return 0;
}

View File

@ -68,6 +68,7 @@
#include <linux/delay.h>
#include <linux/sound.h>
#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/soundcard.h>
#include <linux/ac97_codec.h>
#include <linux/pci.h>
@ -1534,6 +1535,7 @@ static int cs4297a_open_mixdev(struct inode *inode, struct file *file)
CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4,
printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()+\n"));
lock_kernel();
list_for_each(entry, &cs4297a_devs)
{
s = list_entry(entry, struct cs4297a_state, list);
@ -1544,6 +1546,8 @@ static int cs4297a_open_mixdev(struct inode *inode, struct file *file)
{
CS_DBGOUT(CS_FUNCTION | CS_OPEN | CS_ERROR, 2,
printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()- -ENODEV\n"));
unlock_kernel();
return -ENODEV;
}
VALIDATE_STATE(s);
@ -1551,6 +1555,7 @@ static int cs4297a_open_mixdev(struct inode *inode, struct file *file)
CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4,
printk(KERN_INFO "cs4297a: cs4297a_open_mixdev()- 0\n"));
unlock_kernel();
return nonseekable_open(inode, file);
}
@ -1566,11 +1571,15 @@ static int cs4297a_release_mixdev(struct inode *inode, struct file *file)
}
static int cs4297a_ioctl_mixdev(struct inode *inode, struct file *file,
static int cs4297a_ioctl_mixdev(struct file *file,
unsigned int cmd, unsigned long arg)
{
return mixer_ioctl((struct cs4297a_state *) file->private_data, cmd,
int ret;
lock_kernel();
ret = mixer_ioctl((struct cs4297a_state *) file->private_data, cmd,
arg);
unlock_kernel();
return ret;
}
@ -1580,7 +1589,7 @@ static int cs4297a_ioctl_mixdev(struct inode *inode, struct file *file,
static const struct file_operations cs4297a_mixer_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.ioctl = cs4297a_ioctl_mixdev,
.unlocked_ioctl = cs4297a_ioctl_mixdev,
.open = cs4297a_open_mixdev,
.release = cs4297a_release_mixdev,
};
@ -1944,7 +1953,7 @@ static int cs4297a_mmap(struct file *file, struct vm_area_struct *vma)
}
static int cs4297a_ioctl(struct inode *inode, struct file *file,
static int cs4297a_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
struct cs4297a_state *s =
@ -2337,6 +2346,16 @@ static int cs4297a_ioctl(struct inode *inode, struct file *file,
return mixer_ioctl(s, cmd, arg);
}
static long cs4297a_unlocked_ioctl(struct file *file, u_int cmd, u_long arg)
{
int ret;
lock_kernel();
ret = cs4297a_ioctl(file, cmd, arg);
unlock_kernel();
return ret;
}
static int cs4297a_release(struct inode *inode, struct file *file)
{
@ -2369,7 +2388,7 @@ static int cs4297a_release(struct inode *inode, struct file *file)
return 0;
}
static int cs4297a_open(struct inode *inode, struct file *file)
static int cs4297a_locked_open(struct inode *inode, struct file *file)
{
int minor = iminor(inode);
struct cs4297a_state *s=NULL;
@ -2486,6 +2505,16 @@ static int cs4297a_open(struct inode *inode, struct file *file)
return nonseekable_open(inode, file);
}
static int cs4297a_open(struct inode *inode, struct file *file)
{
int ret;
lock_kernel();
ret = cs4297a_open(inode, file);
unlock_kernel();
return ret;
}
// ******************************************************************************************
// Wave (audio) file operations struct.
@ -2496,7 +2525,7 @@ static const struct file_operations cs4297a_audio_fops = {
.read = cs4297a_read,
.write = cs4297a_write,
.poll = cs4297a_poll,
.ioctl = cs4297a_ioctl,
.unlocked_ioctl = cs4297a_unlocked_ioctl,
.mmap = cs4297a_mmap,
.open = cs4297a_open,
.release = cs4297a_release,

View File

@ -491,9 +491,6 @@ static void __init attach_vidc(struct address_info *hw_config)
vidc_adev = adev;
vidc_mixer_set(SOUND_MIXER_VOLUME, (85 | 85 << 8));
#if defined(CONFIG_SOUND_SOFTOSS) || defined(CONFIG_SOUND_SOFTOSS_MODULE)
softoss_dev = adev;
#endif
return;
irq_failed:

View File

@ -2429,8 +2429,7 @@ static unsigned int vwsnd_audio_poll(struct file *file,
return mask;
}
static int vwsnd_audio_do_ioctl(struct inode *inode,
struct file *file,
static int vwsnd_audio_do_ioctl(struct file *file,
unsigned int cmd,
unsigned long arg)
{
@ -2446,8 +2445,8 @@ static int vwsnd_audio_do_ioctl(struct inode *inode,
int ival;
DBGEV("(inode=0x%p, file=0x%p, cmd=0x%x, arg=0x%lx)\n",
inode, file, cmd, arg);
DBGEV("(file=0x%p, cmd=0x%x, arg=0x%lx)\n",
file, cmd, arg);
switch (cmd) {
case OSS_GETVERSION: /* _SIOR ('M', 118, int) */
DBGX("OSS_GETVERSION\n");
@ -2885,17 +2884,19 @@ static int vwsnd_audio_do_ioctl(struct inode *inode,
return -EINVAL;
}
static int vwsnd_audio_ioctl(struct inode *inode,
struct file *file,
static long vwsnd_audio_ioctl(struct file *file,
unsigned int cmd,
unsigned long arg)
{
vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data;
int ret;
lock_kernel();
mutex_lock(&devc->io_mutex);
ret = vwsnd_audio_do_ioctl(inode, file, cmd, arg);
ret = vwsnd_audio_do_ioctl(file, cmd, arg);
mutex_unlock(&devc->io_mutex);
unlock_kernel();
return ret;
}
@ -2921,6 +2922,7 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
DBGE("(inode=0x%p, file=0x%p)\n", inode, file);
lock_kernel();
INC_USE_COUNT;
for (devc = vwsnd_dev_list; devc; devc = devc->next_dev)
if ((devc->audio_minor & ~0x0F) == (minor & ~0x0F))
@ -2928,6 +2930,7 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
if (devc == NULL) {
DEC_USE_COUNT;
unlock_kernel();
return -ENODEV;
}
@ -2936,11 +2939,13 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
mutex_unlock(&devc->open_mutex);
if (file->f_flags & O_NONBLOCK) {
DEC_USE_COUNT;
unlock_kernel();
return -EBUSY;
}
interruptible_sleep_on(&devc->open_wait);
if (signal_pending(current)) {
DEC_USE_COUNT;
unlock_kernel();
return -ERESTARTSYS;
}
mutex_lock(&devc->open_mutex);
@ -2993,6 +2998,7 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
file->private_data = devc;
DBGRV();
unlock_kernel();
return 0;
}
@ -3044,7 +3050,7 @@ static const struct file_operations vwsnd_audio_fops = {
.read = vwsnd_audio_read,
.write = vwsnd_audio_write,
.poll = vwsnd_audio_poll,
.ioctl = vwsnd_audio_ioctl,
.unlocked_ioctl = vwsnd_audio_ioctl,
.mmap = vwsnd_audio_mmap,
.open = vwsnd_audio_open,
.release = vwsnd_audio_release,
@ -3062,15 +3068,18 @@ static int vwsnd_mixer_open(struct inode *inode, struct file *file)
DBGEV("(inode=0x%p, file=0x%p)\n", inode, file);
INC_USE_COUNT;
lock_kernel();
for (devc = vwsnd_dev_list; devc; devc = devc->next_dev)
if (devc->mixer_minor == iminor(inode))
break;
if (devc == NULL) {
DEC_USE_COUNT;
unlock_kernel();
return -ENODEV;
}
file->private_data = devc;
unlock_kernel();
return 0;
}
@ -3203,8 +3212,7 @@ static int mixer_write_ioctl(vwsnd_dev_t *devc, unsigned int nr, void __user *ar
/* This is the ioctl entry to the mixer driver. */
static int vwsnd_mixer_ioctl(struct inode *ioctl,
struct file *file,
static long vwsnd_mixer_ioctl(struct file *file,
unsigned int cmd,
unsigned long arg)
{
@ -3215,6 +3223,7 @@ static int vwsnd_mixer_ioctl(struct inode *ioctl,
DBGEV("(devc=0x%p, cmd=0x%x, arg=0x%lx)\n", devc, cmd, arg);
lock_kernel();
mutex_lock(&devc->mix_mutex);
{
if ((cmd & ~nrmask) == MIXER_READ(0))
@ -3225,13 +3234,14 @@ static int vwsnd_mixer_ioctl(struct inode *ioctl,
retval = -EINVAL;
}
mutex_unlock(&devc->mix_mutex);
unlock_kernel();
return retval;
}
static const struct file_operations vwsnd_mixer_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.ioctl = vwsnd_mixer_ioctl,
.unlocked_ioctl = vwsnd_mixer_ioctl,
.open = vwsnd_mixer_open,
.release = vwsnd_mixer_release,
};

View File

@ -184,14 +184,8 @@ waveartist_iack(wavnc_info *devc)
static inline int
waveartist_sleep(int timeout_ms)
{
unsigned int timeout = timeout_ms * 10 * HZ / 100;
do {
set_current_state(TASK_INTERRUPTIBLE);
timeout = schedule_timeout(timeout);
} while (timeout);
return 0;
unsigned int timeout = msecs_to_jiffies(timeout_ms*100);
return schedule_timeout_interruptible(timeout);
}
static int

View File

@ -763,9 +763,9 @@ static void snd_als4000_configure(struct snd_sb *chip)
/* SPECS_PAGE: 39 */
for (i = ALS4K_GCR91_DMA0_ADDR; i <= ALS4K_GCR96_DMA3_MODE_COUNT; ++i)
snd_als4k_gcr_write(chip, i, 0);
/* enable burst mode to prevent dropouts during high PCI bus usage */
snd_als4k_gcr_write(chip, ALS4K_GCR99_DMA_EMULATION_CTRL,
snd_als4k_gcr_read(chip, ALS4K_GCR99_DMA_EMULATION_CTRL));
(snd_als4k_gcr_read(chip, ALS4K_GCR99_DMA_EMULATION_CTRL) & ~0x07) | 0x04);
spin_unlock_irq(&chip->reg_lock);
}

View File

@ -460,6 +460,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
int err;
u16 format;
int width;
unsigned int bytes_per_sec;
print_hwparams(params);
@ -512,9 +513,10 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
dpcm->hpi_buffer_attached);
}
bytes_per_sec = params_rate(params) * params_channels(params);
bytes_per_sec *= snd_pcm_format_width(params_format(params));
width = snd_pcm_format_width(params_format(params));
bytes_per_sec *= width;
bytes_per_sec /= 8;
if (bytes_per_sec <= 0)
if (width < 0 || bytes_per_sec == 0)
return -EINVAL;
dpcm->bytes_per_sec = bytes_per_sec;
@ -1383,7 +1385,7 @@ static char *asihpi_src_names[] =
compile_time_assert(
(ARRAY_SIZE(asihpi_src_names) ==
(HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_BASE+1)),
(HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_NONE+1)),
assert_src_names_size);
#if ASI_STYLE_NAMES
@ -1414,7 +1416,7 @@ static char *asihpi_dst_names[] =
compile_time_assert(
(ARRAY_SIZE(asihpi_dst_names) ==
(HPI_DESTNODE_LAST_INDEX-HPI_DESTNODE_BASE+1)),
(HPI_DESTNODE_LAST_INDEX-HPI_DESTNODE_NONE+1)),
assert_dst_names_size);
static inline int ctl_add(struct snd_card *card, struct snd_kcontrol_new *ctl,
@ -2171,7 +2173,7 @@ static int snd_asihpi_mux_info(struct snd_kcontrol *kcontrol,
&src_node_type, &src_node_index);
sprintf(uinfo->value.enumerated.name, "%s %d",
asihpi_src_names[src_node_type - HPI_SOURCENODE_BASE],
asihpi_src_names[src_node_type - HPI_SOURCENODE_NONE],
src_node_index);
return 0;
}
@ -2603,8 +2605,8 @@ static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
}
hpi_ctl.src_node_type -= HPI_SOURCENODE_BASE;
hpi_ctl.dst_node_type -= HPI_DESTNODE_BASE;
hpi_ctl.src_node_type -= HPI_SOURCENODE_NONE;
hpi_ctl.dst_node_type -= HPI_DESTNODE_NONE;
/* ASI50xx in SSX mode has multiple meters on the same node.
Use subindex to create distinct ALSA controls

View File

@ -50,7 +50,8 @@ i.e 3.05.02 is a development version
#define HPI_VER_RELEASE(v) ((int)(v & 0xFF))
/* Use single digits for versions less that 10 to avoid octal. */
#define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 3, 25)
#define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 4, 1)
#define HPI_VER_STRING "4.04.01"
/* Library version as documented in hpi-api-versions.txt */
#define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(9, 0, 0)
@ -203,8 +204,6 @@ enum HPI_SOURCENODES {
exists on a destination node can be searched for using a source
node value of either 0, or HPI_SOURCENODE_NONE */
HPI_SOURCENODE_NONE = 100,
/** \deprecated Use HPI_SOURCENODE_NONE instead. */
HPI_SOURCENODE_BASE = 100,
/** Out Stream (Play) node. */
HPI_SOURCENODE_OSTREAM = 101,
/** Line in node - could be analog, AES/EBU or network. */
@ -235,8 +234,6 @@ enum HPI_DESTNODES {
exists on a source node can be searched for using a destination
node value of either 0, or HPI_DESTNODE_NONE */
HPI_DESTNODE_NONE = 200,
/** \deprecated Use HPI_DESTNODE_NONE instead. */
HPI_DESTNODE_BASE = 200,
/** In Stream (Record) node. */
HPI_DESTNODE_ISTREAM = 201,
HPI_DESTNODE_LINEOUT = 202, /**< line out node. */
@ -432,7 +429,18 @@ Property 2 - adapter can do stream grouping (supports SSX2)
Property 1 - adapter can do samplerate conversion (MRX)
Property 2 - adapter can do timestretch (TSX)
*/
HPI_ADAPTER_PROPERTY_CAPS2 = 269
HPI_ADAPTER_PROPERTY_CAPS2 = 269,
/** Readonly adapter sync header connection count.
*/
HPI_ADAPTER_PROPERTY_SYNC_HEADER_CONNECTIONS = 270,
/** Readonly supports SSX2 property.
Indicates the adapter supports SSX2 in some mode setting. The
return value is true (1) or false (0). If the current adapter
mode is MONO SSX2 is disabled, even though this property will
return true.
*/
HPI_ADAPTER_PROPERTY_SUPPORTS_SSX2 = 271
};
/** Adapter mode commands
@ -813,8 +821,6 @@ enum HPI_SAMPLECLOCK_SOURCES {
/** The sampleclock output is derived from its local samplerate generator.
The local samplerate may be set using HPI_SampleClock_SetLocalRate(). */
HPI_SAMPLECLOCK_SOURCE_LOCAL = 1,
/** \deprecated Use HPI_SAMPLECLOCK_SOURCE_LOCAL instead */
HPI_SAMPLECLOCK_SOURCE_ADAPTER = 1,
/** The adapter is clocked from a dedicated AES/EBU SampleClock input.*/
HPI_SAMPLECLOCK_SOURCE_AESEBU_SYNC = 2,
/** From external wordclock connector */
@ -825,10 +831,6 @@ enum HPI_SAMPLECLOCK_SOURCES {
HPI_SAMPLECLOCK_SOURCE_SMPTE = 5,
/** One of the aesebu inputs */
HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT = 6,
/** \deprecated The first aesebu input with a valid signal
Superseded by separate Auto enable flag
*/
HPI_SAMPLECLOCK_SOURCE_AESEBU_AUTO = 7,
/** From a network interface e.g. Cobranet or Livewire at either 48 or 96kHz */
HPI_SAMPLECLOCK_SOURCE_NETWORK = 8,
/** From previous adjacent module (ASI2416 only)*/
@ -1015,8 +1017,6 @@ enum HPI_ERROR_CODES {
HPI_ERROR_CONTROL_DISABLED = 404,
/** I2C transaction failed due to a missing ACK. */
HPI_ERROR_CONTROL_I2C_MISSING_ACK = 405,
/** Control attribute is valid, but not supported by this hardware. */
HPI_ERROR_UNSUPPORTED_CONTROL_ATTRIBUTE = 406,
/** Control is busy, or coming out of
reset and cannot be accessed at this time. */
HPI_ERROR_CONTROL_NOT_READY = 407,
@ -1827,13 +1827,41 @@ u16 hpi_parametricEQ__get_coeffs(const struct hpi_hsubsys *ph_subsys,
Compressor Expander control
*******************************/
u16 hpi_compander_set(const struct hpi_hsubsys *ph_subsys, u32 h_control,
u16 attack, u16 decay, short ratio100, short threshold0_01dB,
short makeup_gain0_01dB);
u16 hpi_compander_set_enable(const struct hpi_hsubsys *ph_subsys,
u32 h_control, u32 on);
u16 hpi_compander_get(const struct hpi_hsubsys *ph_subsys, u32 h_control,
u16 *pw_attack, u16 *pw_decay, short *pw_ratio100,
short *pn_threshold0_01dB, short *pn_makeup_gain0_01dB);
u16 hpi_compander_get_enable(const struct hpi_hsubsys *ph_subsys,
u32 h_control, u32 *pon);
u16 hpi_compander_set_makeup_gain(const struct hpi_hsubsys *ph_subsys,
u32 h_control, short makeup_gain0_01dB);
u16 hpi_compander_get_makeup_gain(const struct hpi_hsubsys *ph_subsys,
u32 h_control, short *pn_makeup_gain0_01dB);
u16 hpi_compander_set_attack_time_constant(const struct hpi_hsubsys
*ph_subsys, u32 h_control, u32 index, u32 attack);
u16 hpi_compander_get_attack_time_constant(const struct hpi_hsubsys
*ph_subsys, u32 h_control, u32 index, u32 *pw_attack);
u16 hpi_compander_set_decay_time_constant(const struct hpi_hsubsys *ph_subsys,
u32 h_control, u32 index, u32 decay);
u16 hpi_compander_get_decay_time_constant(const struct hpi_hsubsys *ph_subsys,
u32 h_control, u32 index, u32 *pw_decay);
u16 hpi_compander_set_threshold(const struct hpi_hsubsys *ph_subsys,
u32 h_control, u32 index, short threshold0_01dB);
u16 hpi_compander_get_threshold(const struct hpi_hsubsys *ph_subsys,
u32 h_control, u32 index, short *pn_threshold0_01dB);
u16 hpi_compander_set_ratio(const struct hpi_hsubsys *ph_subsys,
u32 h_control, u32 index, u32 ratio100);
u16 hpi_compander_get_ratio(const struct hpi_hsubsys *ph_subsys,
u32 h_control, u32 index, u32 *pw_ratio100);
/*******************************
Cobranet HMI control

View File

@ -687,6 +687,7 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
switch (pao->pci.subsys_device_id) {
case 0x5100:
case 0x5110: /* ASI5100 revB or higher with C6711D */
case 0x5200: /* ASI5200 PC_ie version of ASI5100 */
case 0x6100:
case 0x6200:
boot_load_family = HPI_ADAPTER_FAMILY_ASI(0x6200);
@ -1133,6 +1134,12 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
subsys_device_id) ==
HPI_ADAPTER_FAMILY_ASI(0x5100))
mask = 0x00000000L;
/* ASI5200 uses AX6 code, */
/* but has no PLD r/w register to test */
if (HPI_ADAPTER_FAMILY_ASI(pao->pci.
subsys_device_id) ==
HPI_ADAPTER_FAMILY_ASI(0x5200))
mask = 0x00000000L;
break;
case HPI_ADAPTER_FAMILY_ASI(0x8800):
/* ASI8800 has 16bit path to FPGA */

View File

@ -104,9 +104,9 @@ typedef void hpi_handler_func(struct hpi_message *, struct hpi_response *);
#define STR_ROLE_FIELD_MAX 255U
struct hpi_entity_str {
uint16_t size;
uint8_t type;
uint8_t role;
u16 size;
u8 type;
u8 role;
};
#if defined(_MSC_VER)
@ -119,11 +119,11 @@ struct hpi_entity {
#if ! defined(HPI_OS_DSP_C6000) || (defined(HPI_OS_DSP_C6000) && (__TI_COMPILER_VERSION__ > 6000008))
/* DSP C6000 compiler v6.0.8 and lower
do not support flexible array member */
uint8_t value[];
u8 value[];
#else
/* NOTE! Using sizeof(struct hpi_entity) will give erroneous results */
#define HPI_INTERNAL_WARN_ABOUT_ENTITY_VALUE
uint8_t value[1];
u8 value[1];
#endif
};
@ -148,6 +148,9 @@ enum HPI_BUSES {
/* Get the sub-index of the attribute for a control type */
#define HPI_CTL_ATTR_INDEX(i) (i&0xff)
/* Extract the control from the control attribute */
#define HPI_CTL_ATTR_CONTROL(i) (i>>8)
/* Generic control attributes. */
/** Enable a control.
@ -311,8 +314,7 @@ Used for HPI_ChannelModeSet/Get()
/* Microphone control attributes */
#define HPI_MICROPHONE_PHANTOM_POWER HPI_CTL_ATTR(MICROPHONE, 1)
/** Equalizer control attributes
*/
/** Equalizer control attributes */
/** Used to get number of filters in an EQ. (Can't set) */
#define HPI_EQUALIZER_NUM_FILTERS HPI_CTL_ATTR(EQUALIZER, 1)
/** Set/get the filter by type, freq, Q, gain */
@ -320,13 +322,15 @@ Used for HPI_ChannelModeSet/Get()
/** Get the biquad coefficients */
#define HPI_EQUALIZER_COEFFICIENTS HPI_CTL_ATTR(EQUALIZER, 3)
/* Note compander also uses HPI_GENERIC_ENABLE */
#define HPI_COMPANDER_PARAMS HPI_CTL_ATTR(COMPANDER, 1)
#define HPI_COMPANDER_MAKEUPGAIN HPI_CTL_ATTR(COMPANDER, 2)
#define HPI_COMPANDER_THRESHOLD HPI_CTL_ATTR(COMPANDER, 3)
#define HPI_COMPANDER_RATIO HPI_CTL_ATTR(COMPANDER, 4)
#define HPI_COMPANDER_ATTACK HPI_CTL_ATTR(COMPANDER, 5)
#define HPI_COMPANDER_DECAY HPI_CTL_ATTR(COMPANDER, 6)
/* Cobranet control attributes.
MUST be distinct from all other control attributes.
This is so that host side processing can easily identify a Cobranet control
and apply additional host side operations (like copying data) as required.
*/
/* Cobranet control attributes. */
#define HPI_COBRANET_SET HPI_CTL_ATTR(COBRANET, 1)
#define HPI_COBRANET_GET HPI_CTL_ATTR(COBRANET, 2)
#define HPI_COBRANET_SET_DATA HPI_CTL_ATTR(COBRANET, 3)
@ -1512,11 +1516,11 @@ struct hpi_control_cache_single {
struct hpi_control_cache_info i;
union {
struct { /* volume */
u16 an_log[2];
short an_log[2];
} v;
struct { /* peak meter */
u16 an_log_peak[2];
u16 an_logRMS[2];
short an_log_peak[2];
short an_logRMS[2];
} p;
struct { /* channel mode */
u16 mode;
@ -1526,7 +1530,7 @@ struct hpi_control_cache_single {
u16 source_node_index;
} x;
struct { /* level/trim */
u16 an_log[2];
short an_log[2];
} l;
struct { /* tuner - partial caching.
some attributes go to the DSP. */

View File

@ -353,6 +353,11 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
phr->u.c.param1 = pC->u.t.band;
else if ((phm->u.c.attribute == HPI_TUNER_LEVEL)
&& (phm->u.c.param1 == HPI_TUNER_LEVEL_AVERAGE))
if (pC->u.t.level == HPI_ERROR_ILLEGAL_CACHE_VALUE) {
phr->u.c.param1 = 0;
phr->error =
HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
} else
phr->u.c.param1 = pC->u.t.level;
else
found = 0;
@ -397,7 +402,8 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
if (pC->u.clk.source_index ==
HPI_ERROR_ILLEGAL_CACHE_VALUE) {
phr->u.c.param1 = 0;
phr->error = HPI_ERROR_INVALID_OPERATION;
phr->error =
HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
} else
phr->u.c.param1 = pC->u.clk.source_index;
} else if (phm->u.c.attribute == HPI_SAMPLECLOCK_SAMPLERATE)

View File

@ -111,7 +111,7 @@ make_treenode_from_array(hpi_control_type_strings, HPI_CONTROL_TYPE_STRINGS)
&hpi_profile_strings,\
&hpi_control_strings, \
&hpi_asyncevent_strings \
};
}
make_treenode_from_array(hpi_function_strings, HPI_FUNCTION_STRINGS)
compile_time_assert(HPI_OBJ_MAXINDEX == 14, obj_list_doesnt_match);

View File

@ -356,7 +356,7 @@ compile_time_assert((HPI_CONTROL_LAST_INDEX + 1 == 27),
"HPI_SOURCENODE_ADAPTER" \
}
compile_time_assert((HPI_SOURCENODE_LAST_INDEX - HPI_SOURCENODE_BASE + 1) ==
compile_time_assert((HPI_SOURCENODE_LAST_INDEX - HPI_SOURCENODE_NONE + 1) ==
(12), sourcenode_strings_match_defs);
#define HPI_DESTNODE_STRINGS \
@ -370,7 +370,7 @@ compile_time_assert((HPI_SOURCENODE_LAST_INDEX - HPI_SOURCENODE_BASE + 1) ==
"HPI_DESTNODE_COBRANET", \
"HPI_DESTNODE_ANALOG" \
}
compile_time_assert((HPI_DESTNODE_LAST_INDEX - HPI_DESTNODE_BASE + 1) == (8),
compile_time_assert((HPI_DESTNODE_LAST_INDEX - HPI_DESTNODE_NONE + 1) == (8),
destnode_strings_match_defs);
#define HPI_CONTROL_CHANNEL_MODE_STRINGS \

View File

@ -96,8 +96,7 @@ void hpi_stream_response_to_legacy(struct hpi_stream_res *pSR)
static struct hpi_hsubsys gh_subsys;
struct hpi_hsubsys *hpi_subsys_create(void
)
struct hpi_hsubsys *hpi_subsys_create(void)
{
struct hpi_message hm;
struct hpi_response hr;
@ -302,6 +301,7 @@ u16 hpi_adapter_set_mode_ex(const struct hpi_hsubsys *ph_subsys,
{
struct hpi_message hm;
struct hpi_response hr;
hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER,
HPI_ADAPTER_SET_MODE);
hm.adapter_index = adapter_index;
@ -510,7 +510,7 @@ u16 hpi_adapter_debug_read(const struct hpi_hsubsys *ph_subsys,
hm.adapter_index = adapter_index;
hm.u.ax.debug_read.dsp_address = dsp_address;
if (*count_bytes > sizeof(hr.u.bytes))
if (*count_bytes > (int)sizeof(hr.u.bytes))
*count_bytes = sizeof(hr.u.bytes);
hm.u.ax.debug_read.count_bytes = *count_bytes;
@ -976,6 +976,7 @@ u16 hpi_outstream_ancillary_read(const struct hpi_hsubsys *ph_subsys,
{
struct hpi_message hm;
struct hpi_response hr;
hpi_init_message_response(&hm, &hr, HPI_OBJ_OSTREAM,
HPI_OSTREAM_ANC_READ);
u32TOINDEXES(h_outstream, &hm.adapter_index, &hm.obj_index);
@ -1581,6 +1582,7 @@ u16 hpi_control_param_set(const struct hpi_hsubsys *ph_subsys,
{
struct hpi_message hm;
struct hpi_response hr;
hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
HPI_CONTROL_SET_STATE);
u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@ -1591,6 +1593,22 @@ u16 hpi_control_param_set(const struct hpi_hsubsys *ph_subsys,
return hr.error;
}
static u16 hpi_control_log_set2(u32 h_control, u16 attrib, short sv0,
short sv1)
{
struct hpi_message hm;
struct hpi_response hr;
hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
HPI_CONTROL_SET_STATE);
u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
hm.u.c.attribute = attrib;
hm.u.c.an_log_value[0] = sv0;
hm.u.c.an_log_value[1] = sv1;
hpi_send_recv(&hm, &hr);
return hr.error;
}
static
u16 hpi_control_param_get(const struct hpi_hsubsys *ph_subsys,
const u32 h_control, const u16 attrib, u32 param1, u32 param2,
@ -1598,6 +1616,7 @@ u16 hpi_control_param_get(const struct hpi_hsubsys *ph_subsys,
{
struct hpi_message hm;
struct hpi_response hr;
hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
HPI_CONTROL_GET_STATE);
u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@ -1605,7 +1624,7 @@ u16 hpi_control_param_get(const struct hpi_hsubsys *ph_subsys,
hm.u.c.param1 = param1;
hm.u.c.param2 = param2;
hpi_send_recv(&hm, &hr);
if (pparam1)
*pparam1 = hr.u.c.param1;
if (pparam2)
*pparam2 = hr.u.c.param2;
@ -1617,10 +1636,23 @@ u16 hpi_control_param_get(const struct hpi_hsubsys *ph_subsys,
hpi_control_param_get(s, h, a, 0, 0, p1, NULL)
#define hpi_control_param2_get(s, h, a, p1, p2) \
hpi_control_param_get(s, h, a, 0, 0, p1, p2)
#define hpi_control_ex_param1_get(s, h, a, p1) \
hpi_control_ex_param_get(s, h, a, 0, 0, p1, NULL)
#define hpi_control_ex_param2_get(s, h, a, p1, p2) \
hpi_control_ex_param_get(s, h, a, 0, 0, p1, p2)
static u16 hpi_control_log_get2(const struct hpi_hsubsys *ph_subsys,
u32 h_control, u16 attrib, short *sv0, short *sv1)
{
struct hpi_message hm;
struct hpi_response hr;
hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
HPI_CONTROL_GET_STATE);
u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
hm.u.c.attribute = attrib;
hpi_send_recv(&hm, &hr);
*sv0 = hr.u.c.an_log_value[0];
if (sv1)
*sv1 = hr.u.c.an_log_value[1];
return hr.error;
}
static
u16 hpi_control_query(const struct hpi_hsubsys *ph_subsys,
@ -1629,6 +1661,7 @@ u16 hpi_control_query(const struct hpi_hsubsys *ph_subsys,
{
struct hpi_message hm;
struct hpi_response hr;
hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
HPI_CONTROL_GET_INFO);
u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@ -1643,9 +1676,8 @@ u16 hpi_control_query(const struct hpi_hsubsys *ph_subsys,
return hr.error;
}
static u16 hpi_control_get_string(const struct hpi_hsubsys *ph_subsys,
const u32 h_control, const u16 attribute, char *psz_string,
const u32 string_length)
static u16 hpi_control_get_string(const u32 h_control, const u16 attribute,
char *psz_string, const u32 string_length)
{
unsigned int sub_string_index = 0, j = 0;
char c = 0;
@ -1916,6 +1948,7 @@ u16 hpi_cobranet_hmi_write(const struct hpi_hsubsys *ph_subsys, u32 h_control,
{
struct hpi_message hm;
struct hpi_response hr;
hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
HPI_CONTROL_SET_STATE);
u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@ -1941,6 +1974,7 @@ u16 hpi_cobranet_hmi_read(const struct hpi_hsubsys *ph_subsys, u32 h_control,
{
struct hpi_message hm;
struct hpi_response hr;
hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
HPI_CONTROL_GET_STATE);
u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@ -1980,6 +2014,7 @@ u16 hpi_cobranet_hmi_get_status(const struct hpi_hsubsys *ph_subsys,
{
struct hpi_message hm;
struct hpi_response hr;
hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
HPI_CONTROL_GET_STATE);
u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@ -2006,6 +2041,7 @@ u16 hpi_cobranet_getI_paddress(const struct hpi_hsubsys *ph_subsys,
u32 byte_count;
u32 iP;
u16 error;
error = hpi_cobranet_hmi_read(ph_subsys, h_control,
HPI_COBRANET_HMI_cobra_ip_mon_currentIP, 4, &byte_count,
(u8 *)&iP);
@ -2082,6 +2118,7 @@ u16 hpi_cobranet_getMA_caddress(const struct hpi_hsubsys *ph_subsys,
u32 byte_count;
u16 error;
u32 mAC;
error = hpi_cobranet_hmi_read(ph_subsys, h_control,
HPI_COBRANET_HMI_cobra_if_phy_address, 4, &byte_count,
(u8 *)&mAC);
@ -2103,60 +2140,119 @@ u16 hpi_cobranet_getMA_caddress(const struct hpi_hsubsys *ph_subsys,
return error;
}
u16 hpi_compander_set(const struct hpi_hsubsys *ph_subsys, u32 h_control,
u16 attack, u16 decay, short ratio100, short threshold0_01dB,
short makeup_gain0_01dB)
u16 hpi_compander_set_enable(const struct hpi_hsubsys *ph_subsys,
u32 h_control, u32 enable)
{
return hpi_control_param_set(ph_subsys, h_control, HPI_GENERIC_ENABLE,
enable, 0);
}
u16 hpi_compander_get_enable(const struct hpi_hsubsys *ph_subsys,
u32 h_control, u32 *enable)
{
return hpi_control_param1_get(ph_subsys, h_control,
HPI_GENERIC_ENABLE, enable);
}
u16 hpi_compander_set_makeup_gain(const struct hpi_hsubsys *ph_subsys,
u32 h_control, short makeup_gain0_01dB)
{
return hpi_control_log_set2(h_control, HPI_COMPANDER_MAKEUPGAIN,
makeup_gain0_01dB, 0);
}
u16 hpi_compander_get_makeup_gain(const struct hpi_hsubsys *ph_subsys,
u32 h_control, short *makeup_gain0_01dB)
{
return hpi_control_log_get2(ph_subsys, h_control,
HPI_COMPANDER_MAKEUPGAIN, makeup_gain0_01dB, NULL);
}
u16 hpi_compander_set_attack_time_constant(const struct hpi_hsubsys
*ph_subsys, u32 h_control, unsigned int index, u32 attack)
{
return hpi_control_param_set(ph_subsys, h_control,
HPI_COMPANDER_ATTACK, attack, index);
}
u16 hpi_compander_get_attack_time_constant(const struct hpi_hsubsys
*ph_subsys, u32 h_control, unsigned int index, u32 *attack)
{
return hpi_control_param_get(ph_subsys, h_control,
HPI_COMPANDER_ATTACK, 0, index, attack, NULL);
}
u16 hpi_compander_set_decay_time_constant(const struct hpi_hsubsys *ph_subsys,
u32 h_control, unsigned int index, u32 decay)
{
return hpi_control_param_set(ph_subsys, h_control,
HPI_COMPANDER_DECAY, decay, index);
}
u16 hpi_compander_get_decay_time_constant(const struct hpi_hsubsys *ph_subsys,
u32 h_control, unsigned int index, u32 *decay)
{
return hpi_control_param_get(ph_subsys, h_control,
HPI_COMPANDER_DECAY, 0, index, decay, NULL);
}
u16 hpi_compander_set_threshold(const struct hpi_hsubsys *ph_subsys,
u32 h_control, unsigned int index, short threshold0_01dB)
{
struct hpi_message hm;
struct hpi_response hr;
hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
HPI_CONTROL_SET_STATE);
u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
hm.u.c.param1 = attack + ((u32)ratio100 << 16);
hm.u.c.param2 = (decay & 0xFFFFL);
hm.u.c.attribute = HPI_COMPANDER_THRESHOLD;
hm.u.c.param2 = index;
hm.u.c.an_log_value[0] = threshold0_01dB;
hm.u.c.an_log_value[1] = makeup_gain0_01dB;
hm.u.c.attribute = HPI_COMPANDER_PARAMS;
hpi_send_recv(&hm, &hr);
return hr.error;
}
u16 hpi_compander_get(const struct hpi_hsubsys *ph_subsys, u32 h_control,
u16 *pw_attack, u16 *pw_decay, short *pw_ratio100,
short *pn_threshold0_01dB, short *pn_makeup_gain0_01dB)
u16 hpi_compander_get_threshold(const struct hpi_hsubsys *ph_subsys,
u32 h_control, unsigned int index, short *threshold0_01dB)
{
struct hpi_message hm;
struct hpi_response hr;
hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
HPI_CONTROL_GET_STATE);
u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
hm.u.c.attribute = HPI_COMPANDER_PARAMS;
hm.u.c.attribute = HPI_COMPANDER_THRESHOLD;
hm.u.c.param2 = index;
hpi_send_recv(&hm, &hr);
if (pw_attack)
*pw_attack = (short)(hr.u.c.param1 & 0xFFFF);
if (pw_decay)
*pw_decay = (short)(hr.u.c.param2 & 0xFFFF);
if (pw_ratio100)
*pw_ratio100 = (short)(hr.u.c.param1 >> 16);
if (pn_threshold0_01dB)
*pn_threshold0_01dB = hr.u.c.an_log_value[0];
if (pn_makeup_gain0_01dB)
*pn_makeup_gain0_01dB = hr.u.c.an_log_value[1];
*threshold0_01dB = hr.u.c.an_log_value[0];
return hr.error;
}
u16 hpi_compander_set_ratio(const struct hpi_hsubsys *ph_subsys,
u32 h_control, u32 index, u32 ratio100)
{
return hpi_control_param_set(ph_subsys, h_control,
HPI_COMPANDER_RATIO, ratio100, index);
}
u16 hpi_compander_get_ratio(const struct hpi_hsubsys *ph_subsys,
u32 h_control, u32 index, u32 *ratio100)
{
return hpi_control_param_get(ph_subsys, h_control,
HPI_COMPANDER_RATIO, 0, index, ratio100, NULL);
}
u16 hpi_level_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control,
short *min_gain_01dB, short *max_gain_01dB, short *step_gain_01dB)
{
struct hpi_message hm;
struct hpi_response hr;
hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
HPI_CONTROL_GET_STATE);
u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@ -2181,37 +2277,16 @@ u16 hpi_level_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
short an_gain0_01dB[HPI_MAX_CHANNELS]
)
{
struct hpi_message hm;
struct hpi_response hr;
hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
HPI_CONTROL_SET_STATE);
u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
memcpy(hm.u.c.an_log_value, an_gain0_01dB,
sizeof(short) * HPI_MAX_CHANNELS);
hm.u.c.attribute = HPI_LEVEL_GAIN;
hpi_send_recv(&hm, &hr);
return hr.error;
return hpi_control_log_set2(h_control, HPI_LEVEL_GAIN,
an_gain0_01dB[0], an_gain0_01dB[1]);
}
u16 hpi_level_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
short an_gain0_01dB[HPI_MAX_CHANNELS]
)
{
struct hpi_message hm;
struct hpi_response hr;
hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
HPI_CONTROL_GET_STATE);
u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
hm.u.c.attribute = HPI_LEVEL_GAIN;
hpi_send_recv(&hm, &hr);
memcpy(an_gain0_01dB, hr.u.c.an_log_value,
sizeof(short) * HPI_MAX_CHANNELS);
return hr.error;
return hpi_control_log_get2(ph_subsys, h_control, HPI_LEVEL_GAIN,
&an_gain0_01dB[0], &an_gain0_01dB[1]);
}
u16 hpi_meter_query_channels(const struct hpi_hsubsys *ph_subsys,
@ -2413,6 +2488,7 @@ u16 hpi_parametricEQ__get_band(const struct hpi_hsubsys *ph_subsys,
{
struct hpi_message hm;
struct hpi_response hr;
hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
HPI_CONTROL_GET_STATE);
u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@ -2439,6 +2515,7 @@ u16 hpi_parametricEQ__set_band(const struct hpi_hsubsys *ph_subsys,
{
struct hpi_message hm;
struct hpi_response hr;
hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
HPI_CONTROL_SET_STATE);
u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@ -2460,6 +2537,7 @@ u16 hpi_parametricEQ__get_coeffs(const struct hpi_hsubsys *ph_subsys,
{
struct hpi_message hm;
struct hpi_response hr;
hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
HPI_CONTROL_GET_STATE);
u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@ -2623,8 +2701,8 @@ u16 hpi_tone_detector_get_frequency(const struct hpi_hsubsys *ph_subsys,
u16 hpi_tone_detector_get_state(const struct hpi_hsubsys *ph_subsys,
u32 h_control, u32 *state)
{
return hpi_control_param_get(ph_subsys, h_control,
HPI_TONEDETECTOR_STATE, 0, 0, (u32 *)state, NULL);
return hpi_control_param1_get(ph_subsys, h_control,
HPI_TONEDETECTOR_STATE, state);
}
u16 hpi_tone_detector_set_enable(const struct hpi_hsubsys *ph_subsys,
@ -2637,8 +2715,8 @@ u16 hpi_tone_detector_set_enable(const struct hpi_hsubsys *ph_subsys,
u16 hpi_tone_detector_get_enable(const struct hpi_hsubsys *ph_subsys,
u32 h_control, u32 *enable)
{
return hpi_control_param_get(ph_subsys, h_control, HPI_GENERIC_ENABLE,
0, 0, (u32 *)enable, NULL);
return hpi_control_param1_get(ph_subsys, h_control,
HPI_GENERIC_ENABLE, enable);
}
u16 hpi_tone_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys,
@ -2651,8 +2729,8 @@ u16 hpi_tone_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys,
u16 hpi_tone_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys,
u32 h_control, u32 *event_enable)
{
return hpi_control_param_get(ph_subsys, h_control,
HPI_GENERIC_EVENT_ENABLE, 0, 0, (u32 *)event_enable, NULL);
return hpi_control_param1_get(ph_subsys, h_control,
HPI_GENERIC_EVENT_ENABLE, event_enable);
}
u16 hpi_tone_detector_set_threshold(const struct hpi_hsubsys *ph_subsys,
@ -2665,15 +2743,15 @@ u16 hpi_tone_detector_set_threshold(const struct hpi_hsubsys *ph_subsys,
u16 hpi_tone_detector_get_threshold(const struct hpi_hsubsys *ph_subsys,
u32 h_control, int *threshold)
{
return hpi_control_param_get(ph_subsys, h_control,
HPI_TONEDETECTOR_THRESHOLD, 0, 0, (u32 *)threshold, NULL);
return hpi_control_param1_get(ph_subsys, h_control,
HPI_TONEDETECTOR_THRESHOLD, (u32 *)threshold);
}
u16 hpi_silence_detector_get_state(const struct hpi_hsubsys *ph_subsys,
u32 h_control, u32 *state)
{
return hpi_control_param_get(ph_subsys, h_control,
HPI_SILENCEDETECTOR_STATE, 0, 0, (u32 *)state, NULL);
return hpi_control_param1_get(ph_subsys, h_control,
HPI_SILENCEDETECTOR_STATE, state);
}
u16 hpi_silence_detector_set_enable(const struct hpi_hsubsys *ph_subsys,
@ -2686,50 +2764,50 @@ u16 hpi_silence_detector_set_enable(const struct hpi_hsubsys *ph_subsys,
u16 hpi_silence_detector_get_enable(const struct hpi_hsubsys *ph_subsys,
u32 h_control, u32 *enable)
{
return hpi_control_param_get(ph_subsys, h_control, HPI_GENERIC_ENABLE,
0, 0, (u32 *)enable, NULL);
return hpi_control_param1_get(ph_subsys, h_control,
HPI_GENERIC_ENABLE, enable);
}
u16 hpi_silence_detector_set_event_enable(const struct hpi_hsubsys *ph_subsys,
u32 h_control, u32 event_enable)
{
return hpi_control_param_set(ph_subsys, h_control,
HPI_GENERIC_EVENT_ENABLE, (u32)event_enable, 0);
HPI_GENERIC_EVENT_ENABLE, event_enable, 0);
}
u16 hpi_silence_detector_get_event_enable(const struct hpi_hsubsys *ph_subsys,
u32 h_control, u32 *event_enable)
{
return hpi_control_param_get(ph_subsys, h_control,
HPI_GENERIC_EVENT_ENABLE, 0, 0, (u32 *)event_enable, NULL);
return hpi_control_param1_get(ph_subsys, h_control,
HPI_GENERIC_EVENT_ENABLE, event_enable);
}
u16 hpi_silence_detector_set_delay(const struct hpi_hsubsys *ph_subsys,
u32 h_control, u32 delay)
{
return hpi_control_param_set(ph_subsys, h_control,
HPI_SILENCEDETECTOR_DELAY, (u32)delay, 0);
HPI_SILENCEDETECTOR_DELAY, delay, 0);
}
u16 hpi_silence_detector_get_delay(const struct hpi_hsubsys *ph_subsys,
u32 h_control, u32 *delay)
{
return hpi_control_param_get(ph_subsys, h_control,
HPI_SILENCEDETECTOR_DELAY, 0, 0, (u32 *)delay, NULL);
return hpi_control_param1_get(ph_subsys, h_control,
HPI_SILENCEDETECTOR_DELAY, delay);
}
u16 hpi_silence_detector_set_threshold(const struct hpi_hsubsys *ph_subsys,
u32 h_control, int threshold)
{
return hpi_control_param_set(ph_subsys, h_control,
HPI_SILENCEDETECTOR_THRESHOLD, (u32)threshold, 0);
HPI_SILENCEDETECTOR_THRESHOLD, threshold, 0);
}
u16 hpi_silence_detector_get_threshold(const struct hpi_hsubsys *ph_subsys,
u32 h_control, int *threshold)
{
return hpi_control_param_get(ph_subsys, h_control,
HPI_SILENCEDETECTOR_THRESHOLD, 0, 0, (u32 *)threshold, NULL);
return hpi_control_param1_get(ph_subsys, h_control,
HPI_SILENCEDETECTOR_THRESHOLD, (u32 *)threshold);
}
u16 hpi_tuner_query_band(const struct hpi_hsubsys *ph_subsys,
@ -2822,6 +2900,7 @@ u16 hpi_tuner_getRF_level(const struct hpi_hsubsys *ph_subsys, u32 h_control,
{
struct hpi_message hm;
struct hpi_response hr;
hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
HPI_CONTROL_GET_STATE);
u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@ -2838,6 +2917,7 @@ u16 hpi_tuner_get_rawRF_level(const struct hpi_hsubsys *ph_subsys,
{
struct hpi_message hm;
struct hpi_response hr;
hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
HPI_CONTROL_GET_STATE);
u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@ -2894,14 +2974,14 @@ u16 hpi_tuner_get_program(const struct hpi_hsubsys *ph_subsys, u32 h_control,
u16 hpi_tuner_get_hd_radio_dsp_version(const struct hpi_hsubsys *ph_subsys,
u32 h_control, char *psz_dsp_version, const u32 string_size)
{
return hpi_control_get_string(ph_subsys, h_control,
return hpi_control_get_string(h_control,
HPI_TUNER_HDRADIO_DSP_VERSION, psz_dsp_version, string_size);
}
u16 hpi_tuner_get_hd_radio_sdk_version(const struct hpi_hsubsys *ph_subsys,
u32 h_control, char *psz_sdk_version, const u32 string_size)
{
return hpi_control_get_string(ph_subsys, h_control,
return hpi_control_get_string(h_control,
HPI_TUNER_HDRADIO_SDK_VERSION, psz_sdk_version, string_size);
}
@ -2942,15 +3022,15 @@ u16 hpi_tuner_get_mode(const struct hpi_hsubsys *ph_subsys, u32 h_control,
u16 hpi_tuner_get_hd_radio_signal_quality(const struct hpi_hsubsys *ph_subsys,
u32 h_control, u32 *pquality)
{
return hpi_control_param_get(ph_subsys, h_control,
HPI_TUNER_HDRADIO_SIGNAL_QUALITY, 0, 0, pquality, NULL);
return hpi_control_param1_get(ph_subsys, h_control,
HPI_TUNER_HDRADIO_SIGNAL_QUALITY, pquality);
}
u16 hpi_tuner_get_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys,
u32 h_control, u32 *pblend)
{
return hpi_control_param_get(ph_subsys, h_control,
HPI_TUNER_HDRADIO_BLEND, 0, 0, pblend, NULL);
return hpi_control_param1_get(ph_subsys, h_control,
HPI_TUNER_HDRADIO_BLEND, pblend);
}
u16 hpi_tuner_set_hd_radio_signal_blend(const struct hpi_hsubsys *ph_subsys,
@ -2965,6 +3045,7 @@ u16 hpi_tuner_getRDS(const struct hpi_hsubsys *ph_subsys, u32 h_control,
{
struct hpi_message hm;
struct hpi_response hr;
hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
HPI_CONTROL_GET_STATE);
u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@ -2981,43 +3062,43 @@ u16 hpi_tuner_getRDS(const struct hpi_hsubsys *ph_subsys, u32 h_control,
u16 HPI_PAD__get_channel_name(const struct hpi_hsubsys *ph_subsys,
u32 h_control, char *psz_string, const u32 data_length)
{
return hpi_control_get_string(ph_subsys, h_control,
HPI_PAD_CHANNEL_NAME, psz_string, data_length);
return hpi_control_get_string(h_control, HPI_PAD_CHANNEL_NAME,
psz_string, data_length);
}
u16 HPI_PAD__get_artist(const struct hpi_hsubsys *ph_subsys, u32 h_control,
char *psz_string, const u32 data_length)
{
return hpi_control_get_string(ph_subsys, h_control, HPI_PAD_ARTIST,
psz_string, data_length);
return hpi_control_get_string(h_control, HPI_PAD_ARTIST, psz_string,
data_length);
}
u16 HPI_PAD__get_title(const struct hpi_hsubsys *ph_subsys, u32 h_control,
char *psz_string, const u32 data_length)
{
return hpi_control_get_string(ph_subsys, h_control, HPI_PAD_TITLE,
psz_string, data_length);
return hpi_control_get_string(h_control, HPI_PAD_TITLE, psz_string,
data_length);
}
u16 HPI_PAD__get_comment(const struct hpi_hsubsys *ph_subsys, u32 h_control,
char *psz_string, const u32 data_length)
{
return hpi_control_get_string(ph_subsys, h_control, HPI_PAD_COMMENT,
psz_string, data_length);
return hpi_control_get_string(h_control, HPI_PAD_COMMENT, psz_string,
data_length);
}
u16 HPI_PAD__get_program_type(const struct hpi_hsubsys *ph_subsys,
u32 h_control, u32 *ppTY)
{
return hpi_control_param_get(ph_subsys, h_control,
HPI_PAD_PROGRAM_TYPE, 0, 0, ppTY, NULL);
return hpi_control_param1_get(ph_subsys, h_control,
HPI_PAD_PROGRAM_TYPE, ppTY);
}
u16 HPI_PAD__get_rdsPI(const struct hpi_hsubsys *ph_subsys, u32 h_control,
u32 *ppI)
{
return hpi_control_param_get(ph_subsys, h_control, HPI_PAD_PROGRAM_ID,
0, 0, ppI, NULL);
return hpi_control_param1_get(ph_subsys, h_control,
HPI_PAD_PROGRAM_ID, ppI);
}
u16 hpi_volume_query_channels(const struct hpi_hsubsys *ph_subsys,
@ -3031,36 +3112,16 @@ u16 hpi_volume_set_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
short an_log_gain[HPI_MAX_CHANNELS]
)
{
struct hpi_message hm;
struct hpi_response hr;
hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
HPI_CONTROL_SET_STATE);
u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
memcpy(hm.u.c.an_log_value, an_log_gain,
sizeof(short) * HPI_MAX_CHANNELS);
hm.u.c.attribute = HPI_VOLUME_GAIN;
hpi_send_recv(&hm, &hr);
return hr.error;
return hpi_control_log_set2(h_control, HPI_VOLUME_GAIN,
an_log_gain[0], an_log_gain[1]);
}
u16 hpi_volume_get_gain(const struct hpi_hsubsys *ph_subsys, u32 h_control,
short an_log_gain[HPI_MAX_CHANNELS]
)
{
struct hpi_message hm;
struct hpi_response hr;
hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
HPI_CONTROL_GET_STATE);
u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
hm.u.c.attribute = HPI_VOLUME_GAIN;
hpi_send_recv(&hm, &hr);
memcpy(an_log_gain, hr.u.c.an_log_value,
sizeof(short) * HPI_MAX_CHANNELS);
return hr.error;
return hpi_control_log_get2(ph_subsys, h_control, HPI_VOLUME_GAIN,
&an_log_gain[0], &an_log_gain[1]);
}
u16 hpi_volume_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control,
@ -3068,6 +3129,7 @@ u16 hpi_volume_query_range(const struct hpi_hsubsys *ph_subsys, u32 h_control,
{
struct hpi_message hm;
struct hpi_response hr;
hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
HPI_CONTROL_GET_STATE);
u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@ -3094,6 +3156,7 @@ u16 hpi_volume_auto_fade_profile(const struct hpi_hsubsys *ph_subsys,
{
struct hpi_message hm;
struct hpi_response hr;
hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
HPI_CONTROL_SET_STATE);
u32TOINDEXES(h_control, &hm.adapter_index, &hm.obj_index);
@ -3170,43 +3233,42 @@ static size_t entity_type_to_size[LAST_ENTITY_TYPE] = {
6 * sizeof(char),
};
inline size_t hpi_entity_size(struct hpi_entity *entity_ptr)
static inline size_t hpi_entity_size(struct hpi_entity *entity_ptr)
{
return entity_ptr->header.size;
}
inline size_t hpi_entity_header_size(struct hpi_entity *entity_ptr)
static inline size_t hpi_entity_header_size(struct hpi_entity *entity_ptr)
{
return sizeof(entity_ptr->header);
}
inline size_t hpi_entity_value_size(struct hpi_entity *entity_ptr)
static inline size_t hpi_entity_value_size(struct hpi_entity *entity_ptr)
{
return hpi_entity_size(entity_ptr) -
hpi_entity_header_size(entity_ptr);
}
inline size_t hpi_entity_item_count(struct hpi_entity *entity_ptr)
static inline size_t hpi_entity_item_count(struct hpi_entity *entity_ptr)
{
return hpi_entity_value_size(entity_ptr) /
entity_type_to_size[entity_ptr->header.type];
}
inline struct hpi_entity *hpi_entity_ptr_to_next(struct hpi_entity
static inline struct hpi_entity *hpi_entity_ptr_to_next(struct hpi_entity
*entity_ptr)
{
return (void *)(((uint8_t *) entity_ptr) +
hpi_entity_size(entity_ptr));
return (void *)(((u8 *)entity_ptr) + hpi_entity_size(entity_ptr));
}
inline u16 hpi_entity_check_type(const enum e_entity_type t)
static inline u16 hpi_entity_check_type(const enum e_entity_type t)
{
if (t >= 0 && t < STR_TYPE_FIELD_MAX)
return 0;
return HPI_ERROR_ENTITY_TYPE_INVALID;
}
inline u16 hpi_entity_check_role(const enum e_entity_role r)
static inline u16 hpi_entity_check_role(const enum e_entity_role r)
{
if (r >= 0 && r < STR_ROLE_FIELD_MAX)
return 0;
@ -3624,6 +3686,7 @@ u16 hpi_async_event_wait(const struct hpi_hsubsys *ph_subsys, u32 h_async,
u16 maximum_events, struct hpi_async_event *p_events,
u16 *pw_number_returned)
{
return 0;
}

View File

@ -741,7 +741,7 @@ static void HPIMSGX__reset(u16 adapter_index)
hpi_init_response(&hr, HPI_OBJ_SUBSYSTEM,
HPI_SUBSYS_FIND_ADAPTERS, 0);
memcpy(&gRESP_HPI_SUBSYS_FIND_ADAPTERS, &hr,
sizeof(&gRESP_HPI_SUBSYS_FIND_ADAPTERS));
sizeof(gRESP_HPI_SUBSYS_FIND_ADAPTERS));
for (adapter = 0; adapter < HPI_MAX_ADAPTERS; adapter++) {

View File

@ -121,11 +121,17 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
phpi_ioctl_data = (struct hpi_ioctl_linux __user *)arg;
/* Read the message and response pointers from user space. */
get_user(puhm, &phpi_ioctl_data->phm);
get_user(puhr, &phpi_ioctl_data->phr);
if (get_user(puhm, &phpi_ioctl_data->phm) ||
get_user(puhr, &phpi_ioctl_data->phr)) {
err = -EFAULT;
goto out;
}
/* Now read the message size and data from user space. */
get_user(hm->h.size, (u16 __user *)puhm);
if (get_user(hm->h.size, (u16 __user *)puhm)) {
err = -EFAULT;
goto out;
}
if (hm->h.size > sizeof(*hm))
hm->h.size = sizeof(*hm);
@ -138,7 +144,10 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
goto out;
}
get_user(res_max_size, (u16 __user *)puhr);
if (get_user(res_max_size, (u16 __user *)puhr)) {
err = -EFAULT;
goto out;
}
/* printk(KERN_INFO "user response size %d\n", res_max_size); */
if (res_max_size < sizeof(struct hpi_response_header)) {
HPI_DEBUG_LOG(WARNING, "small res size %d\n", res_max_size);
@ -464,9 +473,7 @@ void __init asihpi_init(void)
memset(adapters, 0, sizeof(adapters));
printk(KERN_INFO "ASIHPI driver %d.%02d.%02d\n",
HPI_VER_MAJOR(HPI_VER), HPI_VER_MINOR(HPI_VER),
HPI_VER_RELEASE(HPI_VER));
printk(KERN_INFO "ASIHPI driver " HPI_VER_STRING "\n");
hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
HPI_SUBSYS_DRIVER_LOAD);

View File

@ -2250,6 +2250,8 @@ static int snd_echo_resume(struct pci_dev *pci)
DE_INIT(("resume start\n"));
pci_restore_state(pci);
commpage_bak = kmalloc(sizeof(struct echoaudio), GFP_KERNEL);
if (commpage_bak == NULL)
return -ENOMEM;
commpage = chip->comm_page;
memcpy(commpage_bak, commpage, sizeof(struct comm_page));

View File

@ -733,15 +733,17 @@ static void /*__devinit*/ setup_fg_nodes(struct hda_codec *codec)
total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid);
for (i = 0; i < total_nodes; i++, nid++) {
function_id = snd_hda_param_read(codec, nid,
AC_PAR_FUNCTION_TYPE) & 0xff;
switch (function_id) {
AC_PAR_FUNCTION_TYPE);
switch (function_id & 0xff) {
case AC_GRP_AUDIO_FUNCTION:
codec->afg = nid;
codec->function_id = function_id;
codec->afg_function_id = function_id & 0xff;
codec->afg_unsol = (function_id >> 8) & 1;
break;
case AC_GRP_MODEM_FUNCTION:
codec->mfg = nid;
codec->function_id = function_id;
codec->mfg_function_id = function_id & 0xff;
codec->mfg_unsol = (function_id >> 8) & 1;
break;
default:
break;

View File

@ -784,7 +784,10 @@ struct hda_codec {
hda_nid_t mfg; /* MFG node id */
/* ids */
u32 function_id;
u8 afg_function_id;
u8 mfg_function_id;
u8 afg_unsol;
u8 mfg_unsol;
u32 vendor_id;
u32 subsystem_id;
u32 revision_id;

View File

@ -557,7 +557,12 @@ static void print_codec_info(struct snd_info_entry *entry,
else
snd_iprintf(buffer, "Not Set\n");
snd_iprintf(buffer, "Address: %d\n", codec->addr);
snd_iprintf(buffer, "Function Id: 0x%x\n", codec->function_id);
if (codec->afg)
snd_iprintf(buffer, "AFG Function Id: 0x%x (unsol %u)\n",
codec->afg_function_id, codec->afg_unsol);
if (codec->mfg)
snd_iprintf(buffer, "MFG Function Id: 0x%x (unsol %u)\n",
codec->mfg_function_id, codec->mfg_unsol);
snd_iprintf(buffer, "Vendor Id: 0x%08x\n", codec->vendor_id);
snd_iprintf(buffer, "Subsystem Id: 0x%08x\n", codec->subsystem_id);
snd_iprintf(buffer, "Revision Id: 0x%x\n", codec->revision_id);

View File

@ -97,6 +97,7 @@
#include <linux/gameport.h>
#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/kernel.h>
#include <asm/io.h>
#include <sound/core.h>
#include <sound/info.h>
@ -667,13 +668,12 @@ static u32 atoh(const unsigned char *in, unsigned int len)
unsigned char c;
while (len) {
int value;
c = in[len - 1];
if ((c >= '0') && (c <= '9'))
sum += mult * (c - '0');
else if ((c >= 'A') && (c <= 'F'))
sum += mult * (c - ('A' - 10));
else if ((c >= 'a') && (c <= 'f'))
sum += mult * (c - ('a' - 10));
value = hex_to_bin(c);
if (value >= 0)
sum += mult * value;
mult *= 16;
--len;
}
@ -1615,7 +1615,10 @@ static int snd_riptide_playback_open(struct snd_pcm_substream *substream)
chip->playback_substream[sub_num] = substream;
runtime->hw = snd_riptide_playback;
data = kzalloc(sizeof(struct pcmhw), GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
data->paths = lbus_play_paths[sub_num];
data->id = play_ids[sub_num];
data->source = play_sources[sub_num];
@ -1635,7 +1638,10 @@ static int snd_riptide_capture_open(struct snd_pcm_substream *substream)
chip->capture_substream = substream;
runtime->hw = snd_riptide_capture;
data = kzalloc(sizeof(struct pcmhw), GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
data->paths = lbus_rec_path;
data->id = PADC;
data->source = ACLNK2PADC;

View File

@ -264,11 +264,13 @@ static void sis_update_voice(struct voice *voice)
* if using small periods.
*
* If we're less than 9 samples behind, we're on target.
* Otherwise, shorten the next vperiod by the amount we've
* been delayed.
*/
if (sync > -9)
voice->vperiod = voice->sync_period_size + 1;
else
voice->vperiod = voice->sync_period_size - 4;
voice->vperiod = voice->sync_period_size + sync + 10;
if (voice->vperiod < voice->buffer_size) {
sis_update_sso(voice, voice->vperiod);
@ -736,7 +738,7 @@ static void sis_prepare_timing_voice(struct voice *voice,
period_size = buffer_size;
/* Initially, we want to interrupt just a bit behind the end of
* the period we're clocking out. 10 samples seems to give a good
* the period we're clocking out. 12 samples seems to give a good
* delay.
*
* We want to spread our interrupts throughout the virtual period,
@ -747,7 +749,7 @@ static void sis_prepare_timing_voice(struct voice *voice,
*
* This is all moot if we don't need to use virtual periods.
*/
vperiod = runtime->period_size + 10;
vperiod = runtime->period_size + 12;
if (vperiod > period_size) {
u16 tail = vperiod % period_size;
u16 quarter_period = period_size / 4;
@ -776,7 +778,7 @@ static void sis_prepare_timing_voice(struct voice *voice,
*/
timing->flags |= VOICE_SYNC_TIMING;
timing->sync_base = voice->ctrl_base;
timing->sync_cso = runtime->period_size - 1;
timing->sync_cso = runtime->period_size;
timing->sync_period_size = runtime->period_size;
timing->sync_buffer_size = runtime->buffer_size;
timing->period_size = period_size;
@ -1047,7 +1049,7 @@ static int sis_chip_free(struct sis7019 *sis)
/* Reset the chip, and disable all interrputs.
*/
outl(SIS_GCR_SOFTWARE_RESET, sis->ioport + SIS_GCR);
udelay(10);
udelay(25);
outl(0, sis->ioport + SIS_GCR);
outl(0, sis->ioport + SIS_GIER);
@ -1083,7 +1085,7 @@ static int sis_chip_init(struct sis7019 *sis)
/* Reset the audio controller
*/
outl(SIS_GCR_SOFTWARE_RESET, io + SIS_GCR);
udelay(10);
udelay(25);
outl(0, io + SIS_GCR);
/* Get the AC-link semaphore, and reset the codecs
@ -1096,7 +1098,7 @@ static int sis_chip_init(struct sis7019 *sis)
return -EIO;
outl(SIS_AC97_CMD_CODEC_COLD_RESET, io + SIS_AC97_CMD);
udelay(10);
udelay(250);
count = 0xffff;
while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count)

View File

@ -85,6 +85,7 @@ static int joystick;
static int ac97_clock = 48000;
static char *ac97_quirk;
static int dxs_support;
static int dxs_init_volume = 31;
static int nodelay;
module_param(index, int, 0444);
@ -103,6 +104,8 @@ module_param(ac97_quirk, charp, 0444);
MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
module_param(dxs_support, int, 0444);
MODULE_PARM_DESC(dxs_support, "Support for DXS channels (0 = auto, 1 = enable, 2 = disable, 3 = 48k only, 4 = no VRA, 5 = enable any sample rate)");
module_param(dxs_init_volume, int, 0644);
MODULE_PARM_DESC(dxs_init_volume, "initial DXS volume (0-31)");
module_param(nodelay, int, 0444);
MODULE_PARM_DESC(nodelay, "Disable 500ms init delay");
@ -1245,8 +1248,10 @@ static int snd_via8233_playback_open(struct snd_pcm_substream *substream)
return err;
stream = viadev->reg_offset / 0x10;
if (chip->dxs_controls[stream]) {
chip->playback_volume[stream][0] = 0;
chip->playback_volume[stream][1] = 0;
chip->playback_volume[stream][0] =
VIA_DXS_MAX_VOLUME - (dxs_init_volume & 31);
chip->playback_volume[stream][1] =
VIA_DXS_MAX_VOLUME - (dxs_init_volume & 31);
chip->dxs_controls[stream]->vd[0].access &=
~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE |

View File

@ -576,8 +576,6 @@ static int soundcore_open(struct inode *inode, struct file *file)
struct sound_unit *s;
const struct file_operations *new_fops = NULL;
lock_kernel ();
chain=unit&0x0F;
if(chain==4 || chain==5) /* dsp/audio/dsp16 */
{
@ -630,18 +628,19 @@ static int soundcore_open(struct inode *inode, struct file *file)
const struct file_operations *old_fops = file->f_op;
file->f_op = new_fops;
spin_unlock(&sound_loader_lock);
if (file->f_op->open)
err = file->f_op->open(inode,file);
if (err) {
fops_put(file->f_op);
file->f_op = fops_get(old_fops);
}
fops_put(old_fops);
unlock_kernel();
return err;
}
spin_unlock(&sound_loader_lock);
unlock_kernel();
return -ENODEV;
}

View File

@ -217,7 +217,7 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
switch (protocol) {
case UAC_VERSION_1: {
struct uac_ac_header_descriptor_v1 *h1 = control_header;
struct uac1_ac_header_descriptor *h1 = control_header;
if (!h1->bInCollection) {
snd_printk(KERN_INFO "skipping empty audio interface (v1)\n");

View File

@ -19,33 +19,19 @@
#include <linux/bitops.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/usb.h>
#include <linux/moduleparam.h>
#include <linux/mutex.h>
#include <linux/usb/audio.h>
#include <linux/usb/audio-v2.h>
#include <sound/core.h>
#include <sound/info.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/initval.h>
#include "usbaudio.h"
#include "card.h"
#include "midi.h"
#include "mixer.h"
#include "proc.h"
#include "quirks.h"
#include "endpoint.h"
#include "helper.h"
#include "debug.h"
#include "pcm.h"
#include "urb.h"
#include "format.h"
#include "clock.h"
static struct uac_clock_source_descriptor *
snd_usb_find_clock_source(struct usb_host_interface *ctrl_iface,
@ -134,10 +120,7 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id)
return !!data;
}
/* Try to find the clock source ID of a given clock entity */
static int __uac_clock_find_source(struct snd_usb_audio *chip,
struct usb_host_interface *host_iface,
int entity_id, unsigned long *visited)
{
struct uac_clock_source_descriptor *source;
@ -154,11 +137,11 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
}
/* first, see if the ID we're looking for is a clock source already */
source = snd_usb_find_clock_source(host_iface, entity_id);
source = snd_usb_find_clock_source(chip->ctrl_intf, entity_id);
if (source)
return source->bClockID;
selector = snd_usb_find_clock_selector(host_iface, entity_id);
selector = snd_usb_find_clock_selector(chip->ctrl_intf, entity_id);
if (selector) {
int ret;
@ -168,6 +151,8 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
if (ret < 0)
return ret;
/* Selector values are one-based */
if (ret > selector->bNrInPins || ret < 1) {
printk(KERN_ERR
"%s(): selector reported illegal value, id %d, ret %d\n",
@ -176,27 +161,35 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
return -EINVAL;
}
return __uac_clock_find_source(chip, host_iface,
selector->baCSourceID[ret-1],
return __uac_clock_find_source(chip, selector->baCSourceID[ret-1],
visited);
}
/* FIXME: multipliers only act as pass-thru element for now */
multiplier = snd_usb_find_clock_multiplier(host_iface, entity_id);
multiplier = snd_usb_find_clock_multiplier(chip->ctrl_intf, entity_id);
if (multiplier)
return __uac_clock_find_source(chip, host_iface,
multiplier->bCSourceID, visited);
return __uac_clock_find_source(chip, multiplier->bCSourceID,
visited);
return -EINVAL;
}
int snd_usb_clock_find_source(struct snd_usb_audio *chip,
struct usb_host_interface *host_iface,
int entity_id)
/*
* For all kinds of sample rate settings and other device queries,
* the clock source (end-leaf) must be used. However, clock selectors,
* clock multipliers and sample rate converters may be specified as
* clock source input to terminal. This functions walks the clock path
* to its end and tries to find the source.
*
* The 'visited' bitfield is used internally to detect recursive loops.
*
* Returns the clock source UnitID (>=0) on success, or an error.
*/
int snd_usb_clock_find_source(struct snd_usb_audio *chip, int entity_id)
{
DECLARE_BITMAP(visited, 256);
memset(visited, 0, sizeof(visited));
return __uac_clock_find_source(chip, host_iface, entity_id, visited);
return __uac_clock_find_source(chip, entity_id, visited);
}
static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
@ -211,11 +204,8 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
ep = get_endpoint(alts, 0)->bEndpointAddress;
/* if endpoint doesn't have sampling rate control, bail out */
if (!(fmt->attributes & UAC_EP_CS_ATTR_SAMPLE_RATE)) {
snd_printk(KERN_WARNING "%d:%d:%d: endpoint lacks sample rate attribute bit, cannot set.\n",
dev->devnum, iface, fmt->altsetting);
if (!(fmt->attributes & UAC_EP_CS_ATTR_SAMPLE_RATE))
return 0;
}
data[0] = rate;
data[1] = rate >> 8;
@ -254,12 +244,13 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
struct usb_device *dev = chip->dev;
unsigned char data[4];
int err, crate;
int clock = snd_usb_clock_find_source(chip, chip->ctrl_intf, fmt->clock);
int clock = snd_usb_clock_find_source(chip, fmt->clock);
if (clock < 0)
return clock;
if (!uac_clock_source_is_valid(chip, clock)) {
/* TODO: should we try to find valid clock setups by ourself? */
snd_printk(KERN_ERR "%d:%d:%d: clock source %d is not valid, cannot use\n",
dev->devnum, iface, fmt->altsetting, clock);
return -ENXIO;

View File

@ -5,8 +5,6 @@ int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,
struct usb_host_interface *alts,
struct audioformat *fmt, int rate);
int snd_usb_clock_find_source(struct snd_usb_audio *chip,
struct usb_host_interface *host_iface,
int entity_id);
int snd_usb_clock_find_source(struct snd_usb_audio *chip, int entity_id);
#endif /* __USBAUDIO_CLOCK_H */

View File

@ -33,6 +33,7 @@
#include "pcm.h"
#include "helper.h"
#include "format.h"
#include "clock.h"
/*
* free a substream
@ -275,7 +276,7 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
/* get audio formats */
switch (protocol) {
case UAC_VERSION_1: {
struct uac_as_header_descriptor_v1 *as =
struct uac1_as_header_descriptor *as =
snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
if (!as) {
@ -297,7 +298,7 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
case UAC_VERSION_2: {
struct uac2_input_terminal_descriptor *input_term;
struct uac2_output_terminal_descriptor *output_term;
struct uac_as_header_descriptor_v2 *as =
struct uac2_as_header_descriptor *as =
snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL);
if (!as) {

View File

@ -264,13 +264,12 @@ static int parse_uac2_sample_rate_range(struct audioformat *fp, int nr_triplets,
* on the audioformat table (audio class v2).
*/
static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
struct audioformat *fp,
struct usb_host_interface *iface)
struct audioformat *fp)
{
struct usb_device *dev = chip->dev;
unsigned char tmp[2], *data;
int nr_triplets, data_size, ret = 0;
int clock = snd_usb_clock_find_source(chip, chip->ctrl_intf, fp->clock);
int clock = snd_usb_clock_find_source(chip, fp->clock);
if (clock < 0) {
snd_printk(KERN_ERR "%s(): unable to find clock source (clock %d)\n",
@ -391,7 +390,7 @@ static int parse_audio_format_i(struct snd_usb_audio *chip,
break;
case UAC_VERSION_2:
/* fp->channels is already set in this case */
ret = parse_audio_format_rates_v2(chip, fp, iface);
ret = parse_audio_format_rates_v2(chip, fp);
break;
}
@ -450,7 +449,7 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip,
framesize = le16_to_cpu(fmt->wSamplesPerFrame);
snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);
fp->frame_size = framesize;
ret = parse_audio_format_rates_v2(chip, fp, iface);
ret = parse_audio_format_rates_v2(chip, fp);
break;
}
}

View File

@ -26,6 +26,22 @@
*
*/
/*
* TODOs, for both the mixer and the streaming interfaces:
*
* - support for UAC2 effect units
* - support for graphical equalizers
* - RANGE and MEM set commands (UAC2)
* - RANGE and MEM interrupt dispatchers (UAC2)
* - audio channel clustering (UAC2)
* - audio sample rate converter units (UAC2)
* - proper handling of clock multipliers (UAC2)
* - dispatch clock change notifications (UAC2)
* - stop PCM streams which use a clock that became invalid
* - stop PCM streams which use a clock selector that has changed
* - parse available sample rates again when clock sources changed
*/
#include <linux/bitops.h>
#include <linux/init.h>
#include <linux/list.h>
@ -275,28 +291,28 @@ static int get_abs_value(struct usb_mixer_elem_info *cval, int val)
static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
{
struct snd_usb_audio *chip = cval->mixer->chip;
unsigned char buf[2];
int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
int timeout = 10;
while (timeout-- > 0) {
if (snd_usb_ctl_msg(cval->mixer->chip->dev,
usb_rcvctrlpipe(cval->mixer->chip->dev, 0),
request,
if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request,
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
validx, cval->mixer->ctrlif | (cval->id << 8),
validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
buf, val_len, 100) >= val_len) {
*value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len));
return 0;
}
}
snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
request, validx, cval->mixer->ctrlif | (cval->id << 8), cval->val_type);
request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type);
return -EINVAL;
}
static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
{
struct snd_usb_audio *chip = cval->mixer->chip;
unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */
unsigned char *val;
int ret, size;
@ -312,16 +328,14 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v
memset(buf, 0, sizeof(buf));
ret = snd_usb_ctl_msg(cval->mixer->chip->dev,
usb_rcvctrlpipe(cval->mixer->chip->dev, 0),
bRequest,
ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest,
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
validx, cval->mixer->ctrlif | (cval->id << 8),
validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
buf, size, 1000);
if (ret < 0) {
snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
request, validx, cval->mixer->ctrlif | (cval->id << 8), cval->val_type);
request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type);
return ret;
}
@ -397,6 +411,7 @@ static int get_cur_mix_value(struct usb_mixer_elem_info *cval,
int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
int request, int validx, int value_set)
{
struct snd_usb_audio *chip = cval->mixer->chip;
unsigned char buf[2];
int val_len, timeout = 10;
@ -419,15 +434,14 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval,
buf[0] = value_set & 0xff;
buf[1] = (value_set >> 8) & 0xff;
while (timeout-- > 0)
if (snd_usb_ctl_msg(cval->mixer->chip->dev,
usb_sndctrlpipe(cval->mixer->chip->dev, 0),
request,
if (snd_usb_ctl_msg(chip->dev,
usb_sndctrlpipe(chip->dev, 0), request,
USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
validx, cval->mixer->ctrlif | (cval->id << 8),
validx, snd_usb_ctrl_intf(chip) | (cval->id << 8),
buf, val_len, 100) >= 0)
return 0;
snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n",
request, validx, cval->mixer->ctrlif | (cval->id << 8), cval->val_type, buf[0], buf[1]);
request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type, buf[0], buf[1]);
return -EINVAL;
}
@ -582,9 +596,9 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm
switch (iterm->type >> 16) {
case UAC_SELECTOR_UNIT:
strcpy(name, "Selector"); return 8;
case UAC_PROCESSING_UNIT_V1:
case UAC1_PROCESSING_UNIT:
strcpy(name, "Process Unit"); return 12;
case UAC_EXTENSION_UNIT_V1:
case UAC1_EXTENSION_UNIT:
strcpy(name, "Ext Unit"); return 8;
case UAC_MIXER_UNIT:
strcpy(name, "Mixer"); return 5;
@ -672,8 +686,8 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_
term->name = uac_selector_unit_iSelector(d);
return 0;
}
case UAC_PROCESSING_UNIT_V1:
case UAC_EXTENSION_UNIT_V1: {
case UAC1_PROCESSING_UNIT:
case UAC1_EXTENSION_UNIT: {
struct uac_processing_unit_descriptor *d = p1;
if (d->bNrInPins) {
id = d->baSourceID[0];
@ -745,6 +759,8 @@ static void usb_mixer_elem_free(struct snd_kcontrol *kctl)
*/
static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
{
struct snd_usb_audio *chip = cval->mixer->chip;
/* for failsafe */
cval->min = default_min;
cval->max = cval->min + 1;
@ -767,7 +783,7 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
if (get_ctl_value(cval, UAC_GET_MAX, (cval->control << 8) | minchn, &cval->max) < 0 ||
get_ctl_value(cval, UAC_GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) {
snd_printd(KERN_ERR "%d:%d: cannot get min/max values for control %d (id %d)\n",
cval->id, cval->mixer->ctrlif, cval->control, cval->id);
cval->id, snd_usb_ctrl_intf(chip), cval->control, cval->id);
return -EINVAL;
}
if (get_ctl_value(cval, UAC_GET_RES, (cval->control << 8) | minchn, &cval->res) < 0) {
@ -1199,14 +1215,6 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
}
} else { /* UAC_VERSION_2 */
for (i = 0; i < 30/2; i++) {
/* From the USB Audio spec v2.0:
bmaControls() is a (ch+1)-element array of 4-byte bitmaps,
each containing a set of bit pairs. If a Control is present,
it must be Host readable. If a certain Control is not
present then the bit pair must be set to 0b00.
If a Control is present but read-only, the bit pair must be
set to 0b01. If a Control is also Host programmable, the bit
pair must be set to 0b11. The value 0b10 is not allowed. */
unsigned int ch_bits = 0;
unsigned int ch_read_only = 0;
@ -1855,13 +1863,13 @@ static int parse_audio_unit(struct mixer_build *state, int unitid)
return parse_audio_selector_unit(state, unitid, p1);
case UAC_FEATURE_UNIT:
return parse_audio_feature_unit(state, unitid, p1);
case UAC_PROCESSING_UNIT_V1:
case UAC1_PROCESSING_UNIT:
/* UAC2_EFFECT_UNIT has the same value */
if (state->mixer->protocol == UAC_VERSION_1)
return parse_audio_processing_unit(state, unitid, p1);
else
return 0; /* FIXME - effect units not implemented yet */
case UAC_EXTENSION_UNIT_V1:
case UAC1_EXTENSION_UNIT:
/* UAC2_PROCESSING_UNIT_V2 has the same value */
if (state->mixer->protocol == UAC_VERSION_1)
return parse_audio_extension_unit(state, unitid, p1);
@ -1905,7 +1913,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
struct usb_host_interface *hostif;
void *p;
hostif = &usb_ifnum_to_if(mixer->chip->dev, mixer->ctrlif)->altsetting[0];
hostif = mixer->chip->ctrl_intf;
memset(&state, 0, sizeof(state));
state.chip = mixer->chip;
state.mixer = mixer;
@ -1925,7 +1933,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
p = NULL;
while ((p = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, p, UAC_OUTPUT_TERMINAL)) != NULL) {
if (mixer->protocol == UAC_VERSION_1) {
struct uac_output_terminal_descriptor_v1 *desc = p;
struct uac1_output_terminal_descriptor *desc = p;
if (desc->bLength < sizeof(*desc))
continue; /* invalid descriptor? */
@ -1997,7 +2005,7 @@ static void snd_usb_mixer_proc_read(struct snd_info_entry *entry,
list_for_each_entry(mixer, &chip->mixer_list, list) {
snd_iprintf(buffer,
"USB Mixer: usb_id=0x%08x, ctrlif=%i, ctlerr=%i\n",
chip->usb_id, mixer->ctrlif,
chip->usb_id, snd_usb_ctrl_intf(chip),
mixer->ignore_ctl_error);
snd_iprintf(buffer, "Card: %s\n", chip->card->longname);
for (unitid = 0; unitid < MAX_ID_ELEMS; unitid++) {
@ -2115,7 +2123,7 @@ static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer)
int buffer_length;
unsigned int epnum;
hostif = &usb_ifnum_to_if(mixer->chip->dev, mixer->ctrlif)->altsetting[0];
hostif = mixer->chip->ctrl_intf;
/* we need one interrupt input endpoint */
if (get_iface_desc(hostif)->bNumEndpoints < 1)
return 0;
@ -2158,7 +2166,6 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
if (!mixer)
return -ENOMEM;
mixer->chip = chip;
mixer->ctrlif = ctrlif;
mixer->ignore_ctl_error = ignore_error;
mixer->id_elems = kcalloc(MAX_ID_ELEMS, sizeof(*mixer->id_elems),
GFP_KERNEL);

View File

@ -3,7 +3,6 @@
struct usb_mixer_interface {
struct snd_usb_audio *chip;
unsigned int ctrlif;
struct list_head list;
unsigned int ignore_ctl_error;
struct urb *urb;

View File

@ -7,8 +7,5 @@ int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface,
struct usb_host_interface *alts,
struct audioformat *fmt);
int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,
struct usb_host_interface *alts,
struct audioformat *fmt, int rate);
#endif /* __USBAUDIO_PCM_H */

View File

@ -2152,91 +2152,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
{
USB_DEVICE_VENDOR_SPEC(0x2040, 0x7201),
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
USB_DEVICE_ID_MATCH_INT_CLASS |
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
.bInterfaceClass = USB_CLASS_AUDIO,
.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
.vendor_name = "Hauppauge",
.product_name = "HVR-950Q",
.ifnum = QUIRK_ANY_INTERFACE,
.type = QUIRK_AUDIO_ALIGN_TRANSFER,
}
},
{
USB_DEVICE_VENDOR_SPEC(0x2040, 0x7202),
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
USB_DEVICE_ID_MATCH_INT_CLASS |
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
.bInterfaceClass = USB_CLASS_AUDIO,
.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
.vendor_name = "Hauppauge",
.product_name = "HVR-950Q",
.ifnum = QUIRK_ANY_INTERFACE,
.type = QUIRK_AUDIO_ALIGN_TRANSFER,
}
},
{
USB_DEVICE_VENDOR_SPEC(0x2040, 0x7203),
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
USB_DEVICE_ID_MATCH_INT_CLASS |
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
.bInterfaceClass = USB_CLASS_AUDIO,
.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
.vendor_name = "Hauppauge",
.product_name = "HVR-950Q",
.ifnum = QUIRK_ANY_INTERFACE,
.type = QUIRK_AUDIO_ALIGN_TRANSFER,
}
},
{
USB_DEVICE_VENDOR_SPEC(0x2040, 0x7204),
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
USB_DEVICE_ID_MATCH_INT_CLASS |
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
.bInterfaceClass = USB_CLASS_AUDIO,
.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
.vendor_name = "Hauppauge",
.product_name = "HVR-950Q",
.ifnum = QUIRK_ANY_INTERFACE,
.type = QUIRK_AUDIO_ALIGN_TRANSFER,
}
},
{
USB_DEVICE_VENDOR_SPEC(0x2040, 0x7205),
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
USB_DEVICE_ID_MATCH_INT_CLASS |
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
.bInterfaceClass = USB_CLASS_AUDIO,
.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
.vendor_name = "Hauppauge",
.product_name = "HVR-950Q",
.ifnum = QUIRK_ANY_INTERFACE,
.type = QUIRK_AUDIO_ALIGN_TRANSFER,
}
},
{
USB_DEVICE_VENDOR_SPEC(0x2040, 0x7250),
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
USB_DEVICE_ID_MATCH_INT_CLASS |
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
.bInterfaceClass = USB_CLASS_AUDIO,
.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
.vendor_name = "Hauppauge",
.product_name = "HVR-950Q",
.ifnum = QUIRK_ANY_INTERFACE,
.type = QUIRK_AUDIO_ALIGN_TRANSFER,
}
},
{
USB_DEVICE_VENDOR_SPEC(0x2040, 0x7230),
USB_DEVICE_VENDOR_SPEC(0x2040, 0x7240),
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
USB_DEVICE_ID_MATCH_INT_CLASS |
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
@ -2249,6 +2165,104 @@ YAMAHA_DEVICE(0x7010, "UB99"),
.type = QUIRK_AUDIO_ALIGN_TRANSFER,
}
},
{
USB_DEVICE_VENDOR_SPEC(0x2040, 0x7210),
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
USB_DEVICE_ID_MATCH_INT_CLASS |
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
.bInterfaceClass = USB_CLASS_AUDIO,
.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
.vendor_name = "Hauppauge",
.product_name = "HVR-950Q",
.ifnum = QUIRK_ANY_INTERFACE,
.type = QUIRK_AUDIO_ALIGN_TRANSFER,
}
},
{
USB_DEVICE_VENDOR_SPEC(0x2040, 0x7217),
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
USB_DEVICE_ID_MATCH_INT_CLASS |
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
.bInterfaceClass = USB_CLASS_AUDIO,
.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
.vendor_name = "Hauppauge",
.product_name = "HVR-950Q",
.ifnum = QUIRK_ANY_INTERFACE,
.type = QUIRK_AUDIO_ALIGN_TRANSFER,
}
},
{
USB_DEVICE_VENDOR_SPEC(0x2040, 0x721b),
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
USB_DEVICE_ID_MATCH_INT_CLASS |
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
.bInterfaceClass = USB_CLASS_AUDIO,
.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
.vendor_name = "Hauppauge",
.product_name = "HVR-950Q",
.ifnum = QUIRK_ANY_INTERFACE,
.type = QUIRK_AUDIO_ALIGN_TRANSFER,
}
},
{
USB_DEVICE_VENDOR_SPEC(0x2040, 0x721e),
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
USB_DEVICE_ID_MATCH_INT_CLASS |
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
.bInterfaceClass = USB_CLASS_AUDIO,
.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
.vendor_name = "Hauppauge",
.product_name = "HVR-950Q",
.ifnum = QUIRK_ANY_INTERFACE,
.type = QUIRK_AUDIO_ALIGN_TRANSFER,
}
},
{
USB_DEVICE_VENDOR_SPEC(0x2040, 0x721f),
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
USB_DEVICE_ID_MATCH_INT_CLASS |
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
.bInterfaceClass = USB_CLASS_AUDIO,
.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
.vendor_name = "Hauppauge",
.product_name = "HVR-950Q",
.ifnum = QUIRK_ANY_INTERFACE,
.type = QUIRK_AUDIO_ALIGN_TRANSFER,
}
},
{
USB_DEVICE_VENDOR_SPEC(0x2040, 0x7280),
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
USB_DEVICE_ID_MATCH_INT_CLASS |
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
.bInterfaceClass = USB_CLASS_AUDIO,
.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
.vendor_name = "Hauppauge",
.product_name = "HVR-950Q",
.ifnum = QUIRK_ANY_INTERFACE,
.type = QUIRK_AUDIO_ALIGN_TRANSFER,
}
},
{
USB_DEVICE_VENDOR_SPEC(0x0fd9, 0x0008),
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
USB_DEVICE_ID_MATCH_INT_CLASS |
USB_DEVICE_ID_MATCH_INT_SUBCLASS,
.bInterfaceClass = USB_CLASS_AUDIO,
.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
.vendor_name = "Hauppauge",
.product_name = "HVR-950Q",
.ifnum = QUIRK_ANY_INTERFACE,
.type = QUIRK_AUDIO_ALIGN_TRANSFER,
}
},
/* Digidesign Mbox */
{

View File

@ -32,6 +32,7 @@
#include "helper.h"
#include "endpoint.h"
#include "pcm.h"
#include "clock.h"
/*
* handle the quirks for the contained interfaces