mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 06:02:05 +00:00
Merge branch 'topic/misc' into for-linus
This commit is contained in:
commit
74bf40f079
@ -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.
|
||||
|
@ -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.
|
||||
|
||||
|
135
Documentation/sound/alsa/alsa-parameters.txt
Normal file
135
Documentation/sound/alsa/alsa-parameters.txt
Normal 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]
|
51
Documentation/sound/oss/oss-parameters.txt
Normal file
51
Documentation/sound/oss/oss-parameters.txt
Normal 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>
|
@ -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', "
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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 = {},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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++;
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
@ -237,8 +254,8 @@ 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,
|
||||
.write = dac_audio_write,
|
||||
.unlocked_ioctl = dac_audio_unlocked_ioctl,
|
||||
.open = dac_audio_open,
|
||||
.release = dac_audio_release,
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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:
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
@ -142,12 +142,15 @@ enum HPI_BUSES {
|
||||
/******************************************* CONTROL ATTRIBUTES ****/
|
||||
/* (in order of control type ID */
|
||||
|
||||
/* This allows for 255 control types, 256 unique attributes each */
|
||||
/* This allows for 255 control types, 256 unique attributes each */
|
||||
#define HPI_CTL_ATTR(ctl, ai) (HPI_CONTROL_##ctl * 0x100 + ai)
|
||||
|
||||
/* 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)
|
||||
|
||||
#define HPI_COMPANDER_PARAMS HPI_CTL_ATTR(COMPANDER, 1)
|
||||
/* 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. */
|
||||
|
@ -353,7 +353,12 @@ 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))
|
||||
phr->u.c.param1 = pC->u.t.level;
|
||||
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;
|
||||
break;
|
||||
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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 \
|
||||
|
@ -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,8 +1624,8 @@ 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;
|
||||
|
||||
*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;
|
||||
}
|
||||
|
||||
|
@ -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++) {
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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 |
|
||||
|
@ -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)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -434,7 +434,7 @@ static void snd_usbmidi_maudio_broken_running_status_input(
|
||||
u8 cin = buffer[i] & 0x0f;
|
||||
struct usbmidi_in_port *port = &ep->ports[cable];
|
||||
int length;
|
||||
|
||||
|
||||
length = snd_usbmidi_cin_length[cin];
|
||||
if (cin == 0xf && buffer[i + 1] >= 0xf8)
|
||||
; /* realtime msg: no running status change */
|
||||
@ -628,13 +628,13 @@ static struct usb_protocol_ops snd_usbmidi_standard_ops = {
|
||||
|
||||
static struct usb_protocol_ops snd_usbmidi_midiman_ops = {
|
||||
.input = snd_usbmidi_midiman_input,
|
||||
.output = snd_usbmidi_standard_output,
|
||||
.output = snd_usbmidi_standard_output,
|
||||
.output_packet = snd_usbmidi_output_midiman_packet,
|
||||
};
|
||||
|
||||
static struct usb_protocol_ops snd_usbmidi_maudio_broken_running_status_ops = {
|
||||
.input = snd_usbmidi_maudio_broken_running_status_input,
|
||||
.output = snd_usbmidi_standard_output,
|
||||
.output = snd_usbmidi_standard_output,
|
||||
.output_packet = snd_usbmidi_output_standard_packet,
|
||||
};
|
||||
|
||||
@ -1248,7 +1248,7 @@ static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint *ep
|
||||
*/
|
||||
static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi,
|
||||
struct snd_usb_midi_endpoint_info* ep_info,
|
||||
struct snd_usb_midi_endpoint* rep)
|
||||
struct snd_usb_midi_endpoint* rep)
|
||||
{
|
||||
struct snd_usb_midi_out_endpoint* ep;
|
||||
unsigned int i;
|
||||
@ -1398,7 +1398,7 @@ static void snd_usbmidi_rawmidi_free(struct snd_rawmidi *rmidi)
|
||||
}
|
||||
|
||||
static struct snd_rawmidi_substream *snd_usbmidi_find_substream(struct snd_usb_midi* umidi,
|
||||
int stream, int number)
|
||||
int stream, int number)
|
||||
{
|
||||
struct list_head* list;
|
||||
|
||||
@ -1811,7 +1811,7 @@ static int snd_usbmidi_detect_endpoints(struct snd_usb_midi* umidi,
|
||||
snd_usbmidi_switch_roland_altsetting(umidi);
|
||||
|
||||
if (endpoint[0].out_ep || endpoint[0].in_ep)
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
intf = umidi->iface;
|
||||
if (!intf || intf->num_altsetting < 1)
|
||||
@ -1849,7 +1849,7 @@ static int snd_usbmidi_detect_per_port_endpoints(struct snd_usb_midi* umidi,
|
||||
struct snd_usb_midi_endpoint_info* endpoints)
|
||||
{
|
||||
int err, i;
|
||||
|
||||
|
||||
err = snd_usbmidi_detect_endpoints(umidi, endpoints, MIDI_MAX_ENDPOINTS);
|
||||
for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
|
||||
if (endpoints[i].out_ep)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
{
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "helper.h"
|
||||
#include "endpoint.h"
|
||||
#include "pcm.h"
|
||||
#include "clock.h"
|
||||
|
||||
/*
|
||||
* handle the quirks for the contained interfaces
|
||||
|
Loading…
Reference in New Issue
Block a user