Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
fe6a9c21
Commit
fe6a9c21
authored
Mar 30, 2004
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
http://linux-sound.bkbits.net/linux-sound
into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents
807b9692
42628d82
Changes
28
Hide whitespace changes
Inline
Side-by-side
Showing
28 changed files
with
513 additions
and
144 deletions
+513
-144
Documentation/sound/alsa/ALSA-Configuration.txt
Documentation/sound/alsa/ALSA-Configuration.txt
+2
-0
Documentation/sound/alsa/Procfile.txt
Documentation/sound/alsa/Procfile.txt
+185
-0
include/sound/ac97_codec.h
include/sound/ac97_codec.h
+1
-1
include/sound/cs8427.h
include/sound/cs8427.h
+2
-1
include/sound/pcm.h
include/sound/pcm.h
+1
-1
include/sound/version.h
include/sound/version.h
+2
-2
sound/core/ioctl32/timer32.c
sound/core/ioctl32/timer32.c
+10
-0
sound/core/pcm.c
sound/core/pcm.c
+1
-1
sound/core/pcm_lib.c
sound/core/pcm_lib.c
+10
-3
sound/core/pcm_timer.c
sound/core/pcm_timer.c
+8
-4
sound/i2c/cs8427.c
sound/i2c/cs8427.c
+7
-2
sound/pci/ac97/ac97_codec.c
sound/pci/ac97/ac97_codec.c
+11
-6
sound/pci/ac97/ac97_patch.c
sound/pci/ac97/ac97_patch.c
+13
-5
sound/pci/ac97/ac97_pcm.c
sound/pci/ac97/ac97_pcm.c
+2
-2
sound/pci/ac97/ac97_proc.c
sound/pci/ac97/ac97_proc.c
+6
-4
sound/pci/au88x0/au88x0.h
sound/pci/au88x0/au88x0.h
+0
-17
sound/pci/cs46xx/cs46xx.c
sound/pci/cs46xx/cs46xx.c
+7
-4
sound/pci/ice1712/delta.c
sound/pci/ice1712/delta.c
+2
-0
sound/pci/ice1712/ice1712.c
sound/pci/ice1712/ice1712.c
+16
-6
sound/pci/ice1712/ice1712.h
sound/pci/ice1712/ice1712.h
+1
-0
sound/pci/intel8x0.c
sound/pci/intel8x0.c
+13
-8
sound/pcmcia/pdaudiocf/pdaudiocf.c
sound/pcmcia/pdaudiocf/pdaudiocf.c
+0
-1
sound/pcmcia/pdaudiocf/pdaudiocf_core.c
sound/pcmcia/pdaudiocf/pdaudiocf_core.c
+0
-1
sound/pcmcia/pdaudiocf/pdaudiocf_irq.c
sound/pcmcia/pdaudiocf/pdaudiocf_irq.c
+0
-1
sound/ppc/powermac.c
sound/ppc/powermac.c
+6
-4
sound/usb/usbaudio.c
sound/usb/usbaudio.c
+203
-68
sound/usb/usbaudio.h
sound/usb/usbaudio.h
+4
-1
sound/usb/usbmidi.c
sound/usb/usbmidi.c
+0
-1
No files found.
Documentation/sound/alsa/ALSA-Configuration.txt
View file @
fe6a9c21
...
...
@@ -611,6 +611,8 @@ Module parameters
* Digigram VX442
omni - Omni I/O support for MidiMan M-Audio Delta44/66
cs8427_timeout - reset timeout for the CS8427 chip (S/PDIF transciever)
in msec resolution, default value is 500 (0.5 sec)
Module supports up to 8 cards and autoprobe. Note: The consumer part
is not used with all Envy24 based cards (for example in the MidiMan Delta
...
...
Documentation/sound/alsa/Procfile.txt
0 → 100644
View file @
fe6a9c21
Proc Files of ALSA Drivers
==========================
Takashi Iwai <tiwai@suse.de>
General
-------
ALSA has its own proc tree, /proc/asound. Many useful information are
found in this tree. When you encounter a problem and need debugging,
check the files listed in the following sections.
Each card has its subtree cardX, where X is from 0 to 7. The
card-specific files are stored in the card* subdirectories.
Global Information
------------------
cards
Shows the list of currently configured ALSA drivers,
index, the id string, short and long descriptions.
version
Shows the version string and compile date.
modules
Lists the module of each card
devices
Lists the ALSA native device mappings.
meminfo
Shows the status of allocated pages via ALSA drivers.
Appears only when CONFIG_SND_DEBUG=y.
hwdep
Lists the currently available hwdep devices in format of
<card>-<device>: <name>
pcm
Lists the currently available PCM devices in format of
<card>-<device>: <id>: <name> : <sub-streams>
timer
Lists the currently available timer devices
oss/devices
Lists the OSS device mappings.
oss/sndstat
Provides the output compatible with /dev/sndstat.
You can symlink this to /dev/sndstat.
Card Specific Files
-------------------
The card-specific files are found in /proc/asound/card* directories.
Some drivers (e.g. cmipci) have their own proc entries for the
register dump, etc (e.g. /proc/asound/card*/cmipci shows the register
dump). These files would be really helpful for debugging.
When PCM devices are available on this card, you can see directories
like pcm0p or pcm1c. They hold the PCM information for each PCM
stream. The number after 'pcm' is the PCM device number from 0, and
the last 'p' or 'c' means playback or capture direction. The files in
this subtree is described later.
The status of MIDI I/O is found in midi* files. It shows the device
name and the received/transmitted bytes through the MIDI device.
When the card is equipped with AC97 codecs, there are codec97#*
subdirectories (desribed later).
When the OSS mixer emulation is enabled (and the module is loaded),
oss_mixer file appears here, too. This shows the current mapping of
OSS mixer elements to the ALSA control elements. You can change the
mapping by writing to this device. Read OSS-Emulation.txt for
details.
PCM Proc Files
--------------
card*/pcm*/info
The general information of this PCM device: card #, device #,
substreams, etc.
card*/pcm*/xrun_debug
This file appears when CONFIG_SND_DEBUG=y.
This shows the status of xrun (= buffer overrun/xrun) debug of
ALSA PCM middle layer, as an integer from 0 to 2. The value
can be changed by writing to this file, such as
# cat 2 > /proc/asound/card0/pcm0p/xrun_debug
When this value is greater than 0, the driver will show the
messages to kernel log when an xrun is detected. The debug
message is shown also when the invalid H/W pointer is detected
at the update of periods (usually called from the interrupt
handler).
When this value is greater than 1, the driver will show the
stack trace additionally. This may help the debugging.
card*/pcm*/sub*/info
The general information of this PCM sub-stream.
card*/pcm*/sub*/status
The current status of this PCM sub-stream, elapsed time,
H/W position, etc.
card*/pcm*/sub*/hw_params
The hardware parameters set for this sub-stream.
card*/pcm*/sub*/sw_params
The soft parameters set for this sub-stream.
card*/pcm*/sub*/prealloc
The buffer pre-allocation information.
AC97 Codec Information
----------------------
card*/codec97#*/ac97#?-?
Shows the general information of this AC97 codec chip, such as
name, capabilities, set up.
card*/codec97#0/ac97#?-?+regs
Shows the AC97 register dump. Useful for debugging.
Sequencer Information
---------------------
seq/drivers
Lists the currently available ALSA sequencer drivers.
seq/clients
Shows the list of currently available sequencer clinets and
ports. The connection status and the running status are shown
in this file, too.
seq/queues
Lists the currently allocated/running sequener queues.
seq/timer
Lists the currently allocated/running sequencer timers.
seq/oss
Lists the OSS-compatible sequencer stuffs.
Help For Debugging?
-------------------
When the problem is related with PCM, first try to turn on xrun_debug
mode. This will give you the kernel messages when and where xrun
happened.
If it's really a bug, report it with the following information
- the name of the driver/card, show in /proc/asound/cards
- the reigster dump, if available (e.g. card*/cmipci)
when it's a PCM problem,
- set-up of PCM, shown in hw_parms, sw_params, and status in the PCM
sub-stream directory
when it's a mixer problem,
- AC97 proc files, codec97#*/* files
for USB audio/midi,
- output of lsusb -v
- stream* files in card directory
The ALSA bug-tracking system is found at:
https://bugtrack.alsa-project.org/alsa-bug/
include/sound/ac97_codec.h
View file @
fe6a9c21
...
...
@@ -460,7 +460,7 @@ static inline int ac97_is_modem(ac97_t * ac97)
}
static
inline
int
ac97_is_rev22
(
ac97_t
*
ac97
)
{
return
(
ac97
->
ext_id
&
AC97_EI_REV_MASK
)
=
=
AC97_EI_REV_22
;
return
(
ac97
->
ext_id
&
AC97_EI_REV_MASK
)
>
=
AC97_EI_REV_22
;
}
static
inline
int
ac97_can_amap
(
ac97_t
*
ac97
)
{
...
...
include/sound/cs8427.h
View file @
fe6a9c21
...
...
@@ -187,7 +187,8 @@
#define CS8427_VER8427A 0x71
int
snd_cs8427_detect
(
snd_i2c_bus_t
*
bus
,
unsigned
char
addr
);
int
snd_cs8427_create
(
snd_i2c_bus_t
*
bus
,
unsigned
char
addr
,
snd_i2c_device_t
**
r_cs8427
);
int
snd_cs8427_create
(
snd_i2c_bus_t
*
bus
,
unsigned
char
addr
,
unsigned
int
reset_timeout
,
snd_i2c_device_t
**
r_cs8427
);
void
snd_cs8427_reset
(
snd_i2c_device_t
*
cs8427
);
int
snd_cs8427_reg_write
(
snd_i2c_device_t
*
device
,
unsigned
char
reg
,
unsigned
char
val
);
int
snd_cs8427_reg_read
(
snd_i2c_device_t
*
device
,
unsigned
char
reg
);
...
...
include/sound/pcm.h
View file @
fe6a9c21
...
...
@@ -428,7 +428,7 @@ struct _snd_pcm_str {
snd_info_entry_t
*
proc_root
;
snd_info_entry_t
*
proc_info_entry
;
#ifdef CONFIG_SND_DEBUG
unsigned
int
xrun_debug
:
1
;
unsigned
int
xrun_debug
;
/* 0 = disabled, 1 = verbose, 2 = stacktrace */
snd_info_entry_t
*
proc_xrun_debug_entry
;
#endif
};
...
...
include/sound/version.h
View file @
fe6a9c21
/* include/version.h. Generated by configure. */
#define CONFIG_SND_VERSION "1.0.
3
"
#define CONFIG_SND_DATE " (
Mon Mar 01 10:12:14
2004 UTC)"
#define CONFIG_SND_VERSION "1.0.
4rc2
"
#define CONFIG_SND_DATE " (
Tue Mar 30 08:19:30
2004 UTC)"
sound/core/ioctl32/timer32.c
View file @
fe6a9c21
...
...
@@ -88,8 +88,18 @@ struct ioctl32_mapper timer_mappers[] = {
{
SNDRV_TIMER_IOCTL_INFO32
,
AP
(
timer_info
)
},
MAP_COMPAT
(
SNDRV_TIMER_IOCTL_PARAMS
),
{
SNDRV_TIMER_IOCTL_STATUS32
,
AP
(
timer_status
)
},
#if 0
/* ** FIXME **
* The following four entries are disabled because they conflict
* with the TCOC* definitions.
* Unfortunately, the current ioctl32 wrapper uses a single
* hash table for all devices. Once when the wrapper is fixed
* with the table based on devices, they'll be back again.
*/
MAP_COMPAT(SNDRV_TIMER_IOCTL_START),
MAP_COMPAT(SNDRV_TIMER_IOCTL_STOP),
MAP_COMPAT(SNDRV_TIMER_IOCTL_CONTINUE),
MAP_COMPAT(SNDRV_TIMER_IOCTL_PAUSE),
#endif
{
0
},
};
sound/core/pcm.c
View file @
fe6a9c21
...
...
@@ -403,7 +403,7 @@ static void snd_pcm_xrun_debug_write(snd_info_entry_t *entry, snd_info_buffer_t
snd_pcm_str_t
*
pstr
=
(
snd_pcm_str_t
*
)
entry
->
private_data
;
char
line
[
64
];
if
(
!
snd_info_get_line
(
buffer
,
line
,
sizeof
(
line
)))
pstr
->
xrun_debug
=
!!
simple_strtoul
(
line
,
NULL
,
10
);
pstr
->
xrun_debug
=
simple_strtoul
(
line
,
NULL
,
10
);
}
#endif
...
...
sound/core/pcm_lib.c
View file @
fe6a9c21
...
...
@@ -167,7 +167,8 @@ static inline int snd_pcm_update_hw_ptr_post(snd_pcm_substream_t *substream,
substream
->
pcm
->
card
->
number
,
substream
->
pcm
->
device
,
substream
->
stream
?
'c'
:
'p'
);
dump_stack
();
if
(
substream
->
pstr
->
xrun_debug
>
1
)
dump_stack
();
}
#endif
return
-
EPIPE
;
...
...
@@ -194,8 +195,11 @@ static inline int snd_pcm_update_hw_ptr_interrupt(snd_pcm_substream_t *substream
if
(
delta
>
0
)
{
if
((
snd_pcm_uframes_t
)
delta
<
runtime
->
buffer_size
/
2
)
{
#ifdef CONFIG_SND_DEBUG
if
(
runtime
->
periods
>
1
)
if
(
runtime
->
periods
>
1
&&
substream
->
pstr
->
xrun_debug
)
{
snd_printd
(
KERN_ERR
"Unexpected hw_pointer value [1] (stream = %i, delta: -%ld, max jitter = %ld): wrong interrupt acknowledge?
\n
"
,
substream
->
stream
,
(
long
)
delta
,
runtime
->
buffer_size
/
2
);
if
(
substream
->
pstr
->
xrun_debug
>
1
)
dump_stack
();
}
#endif
return
0
;
}
...
...
@@ -232,8 +236,11 @@ int snd_pcm_update_hw_ptr(snd_pcm_substream_t *substream)
if
(
delta
>
0
)
{
if
((
snd_pcm_uframes_t
)
delta
<
runtime
->
buffer_size
/
2
)
{
#ifdef CONFIG_SND_DEBUG
if
(
runtime
->
periods
>
2
)
if
(
runtime
->
periods
>
2
&&
substream
->
pstr
->
xrun_debug
)
{
snd_printd
(
KERN_ERR
"Unexpected hw_pointer value [2] (stream = %i, delta: -%ld, max jitter = %ld): wrong interrupt acknowledge?
\n
"
,
substream
->
stream
,
(
long
)
delta
,
runtime
->
buffer_size
/
2
);
if
(
substream
->
pstr
->
xrun_debug
>
1
)
dump_stack
();
}
#endif
return
0
;
}
...
...
sound/core/pcm_timer.c
View file @
fe6a9c21
...
...
@@ -32,9 +32,9 @@
*/
/* Greatest common divisor */
static
int
gcd
(
int
a
,
int
b
)
static
unsigned
long
gcd
(
unsigned
long
a
,
unsigned
long
b
)
{
int
r
;
unsigned
long
r
;
if
(
a
<
b
)
{
r
=
a
;
a
=
b
;
...
...
@@ -49,7 +49,7 @@ static int gcd(int a, int b)
void
snd_pcm_timer_resolution_change
(
snd_pcm_substream_t
*
substream
)
{
unsigned
int
rate
,
mult
,
fsize
,
l
;
unsigned
long
rate
,
mult
,
fsize
,
l
;
snd_pcm_runtime_t
*
runtime
=
substream
->
runtime
;
mult
=
1000000000
;
...
...
@@ -67,7 +67,11 @@ void snd_pcm_timer_resolution_change(snd_pcm_substream_t *substream)
mult
/=
2
;
rate
/=
2
;
}
snd_assert
(
rate
!=
0
,
return
);
if
(
rate
==
0
)
{
snd_printk
(
KERN_ERR
"pcm timer resolution out of range (rate = %u, period_size = %lu)
\n
"
,
runtime
->
rate
,
runtime
->
period_size
);
runtime
->
timer_resolution
=
-
1
;
return
;
}
runtime
->
timer_resolution
=
mult
*
fsize
/
rate
;
}
...
...
sound/i2c/cs8427.c
View file @
fe6a9c21
...
...
@@ -50,6 +50,7 @@ typedef struct {
typedef
struct
{
unsigned
char
regmap
[
0x14
];
/* map of first 1 + 13 registers */
unsigned
int
rate
;
unsigned
int
reset_timeout
;
cs8427_stream_t
playback
;
cs8427_stream_t
capture
;
}
cs8427_t
;
...
...
@@ -163,6 +164,7 @@ static void snd_cs8427_free(snd_i2c_device_t *device)
int
snd_cs8427_create
(
snd_i2c_bus_t
*
bus
,
unsigned
char
addr
,
unsigned
int
reset_timeout
,
snd_i2c_device_t
**
r_cs8427
)
{
static
unsigned
char
initvals1
[]
=
{
...
...
@@ -256,6 +258,9 @@ int snd_cs8427_create(snd_i2c_bus_t *bus,
snd_i2c_unlock
(
bus
);
/* turn on run bit and rock'n'roll */
if
(
reset_timeout
<
1
)
reset_timeout
=
1
;
chip
->
reset_timeout
=
reset_timeout
;
snd_cs8427_reset
(
device
);
#if 0 // it's nice for read tests
...
...
@@ -301,7 +306,7 @@ void snd_cs8427_reset(snd_i2c_device_t *cs8427)
snd_cs8427_reg_write
(
cs8427
,
CS8427_REG_CLOCKSOURCE
,
chip
->
regmap
[
CS8427_REG_CLOCKSOURCE
]);
udelay
(
200
);
snd_i2c_unlock
(
cs8427
->
bus
);
end_time
=
jiffies
+
HZ
/
2
;
end_time
=
jiffies
+
chip
->
reset_timeout
;
while
(
time_after_eq
(
end_time
,
jiffies
))
{
snd_i2c_lock
(
cs8427
->
bus
);
data
=
snd_cs8427_reg_read
(
cs8427
,
CS8427_REG_RECVERRORS
);
...
...
@@ -309,7 +314,7 @@ void snd_cs8427_reset(snd_i2c_device_t *cs8427)
if
(
!
(
data
&
CS8427_UNLOCK
))
break
;
set_current_state
(
TASK_UNINTERRUPTIBLE
);
schedule_timeout
(
HZ
/
100
);
schedule_timeout
(
1
);
}
snd_i2c_lock
(
cs8427
->
bus
);
chip
->
regmap
[
CS8427_REG_CLOCKSOURCE
]
&=
~
CS8427_RXDMASK
;
...
...
sound/pci/ac97/ac97_codec.c
View file @
fe6a9c21
...
...
@@ -396,11 +396,14 @@ static int snd_ac97_ad18xx_update_pcm_bits(ac97_t *ac97, int codec, unsigned sho
ac97
->
spec
.
ad18xx
.
pcmreg
[
codec
]
=
new
;
spin_unlock
(
&
ac97
->
reg_lock
);
/* select single codec */
ac97
->
bus
->
write
(
ac97
,
AC97_AD_SERIAL_CFG
,
ac97
->
spec
.
ad18xx
.
unchained
[
codec
]
|
ac97
->
spec
.
ad18xx
.
chained
[
codec
]);
ac97
->
bus
->
write
(
ac97
,
AC97_AD_SERIAL_CFG
,
(
ac97
->
regs
[
AC97_AD_SERIAL_CFG
]
&
~
0x7000
)
|
ac97
->
spec
.
ad18xx
.
unchained
[
codec
]
|
ac97
->
spec
.
ad18xx
.
chained
[
codec
]);
/* update PCM bits */
ac97
->
bus
->
write
(
ac97
,
AC97_PCM
,
new
);
/* select all codecs */
ac97
->
bus
->
write
(
ac97
,
AC97_AD_SERIAL_CFG
,
0x7000
);
ac97
->
bus
->
write
(
ac97
,
AC97_AD_SERIAL_CFG
,
ac97
->
regs
[
AC97_AD_SERIAL_CFG
]
|
0x7000
);
}
else
spin_unlock
(
&
ac97
->
reg_lock
);
up
(
&
ac97
->
spec
.
ad18xx
.
mutex
);
...
...
@@ -2032,11 +2035,12 @@ void snd_ac97_resume(ac97_t *ac97)
if
(
!
ac97
->
spec
.
ad18xx
.
id
[
codec
])
continue
;
/* select single codec */
ac97
->
bus
->
write
(
ac97
,
AC97_AD_SERIAL_CFG
,
ac97
->
spec
.
ad18xx
.
unchained
[
codec
]
|
ac97
->
spec
.
ad18xx
.
chained
[
codec
]);
snd_ac97_update_bits
(
ac97
,
AC97_AD_SERIAL_CFG
,
0x7000
,
ac97
->
spec
.
ad18xx
.
unchained
[
codec
]
|
ac97
->
spec
.
ad18xx
.
chained
[
codec
]);
ac97
->
bus
->
write
(
ac97
,
AC97_AD_CODEC_CFG
,
ac97
->
spec
.
ad18xx
.
codec_cfg
[
codec
]);
}
/* select all codecs */
ac97
->
bus
->
write
(
ac97
,
AC97_AD_SERIAL_CFG
,
0x7000
);
snd_ac97_update_bits
(
ac97
,
AC97_AD_SERIAL_CFG
,
0x7000
,
0x7000
);
}
/* restore ac97 status */
...
...
@@ -2055,12 +2059,13 @@ void snd_ac97_resume(ac97_t *ac97)
if
(
!
ac97
->
spec
.
ad18xx
.
id
[
codec
])
continue
;
/* select single codec */
ac97
->
bus
->
write
(
ac97
,
AC97_AD_SERIAL_CFG
,
ac97
->
spec
.
ad18xx
.
unchained
[
codec
]
|
ac97
->
spec
.
ad18xx
.
chained
[
codec
]);
snd_ac97_update_bits
(
ac97
,
AC97_AD_SERIAL_CFG
,
0x7000
,
ac97
->
spec
.
ad18xx
.
unchained
[
codec
]
|
ac97
->
spec
.
ad18xx
.
chained
[
codec
]);
/* update PCM bits */
ac97
->
bus
->
write
(
ac97
,
AC97_PCM
,
ac97
->
spec
.
ad18xx
.
pcmreg
[
codec
]);
}
/* select all codecs */
ac97
->
bus
->
write
(
ac97
,
AC97_AD_SERIAL_CFG
,
0x7000
);
snd_ac97_update_bits
(
ac97
,
AC97_AD_SERIAL_CFG
,
0x7000
,
0x7000
);
continue
;
}
else
if
(
i
==
AC97_AD_TEST
||
i
==
AC97_AD_CODEC_CFG
||
...
...
sound/pci/ac97/ac97_patch.c
View file @
fe6a9c21
...
...
@@ -562,8 +562,11 @@ int patch_conexant(ac97_t * ac97)
*/
int
patch_ad1819
(
ac97_t
*
ac97
)
{
unsigned
short
scfg
;
// patch for Analog Devices
snd_ac97_write_cache
(
ac97
,
AC97_AD_SERIAL_CFG
,
0x7000
);
/* select all codecs */
scfg
=
snd_ac97_read
(
ac97
,
AC97_AD_SERIAL_CFG
);
snd_ac97_write_cache
(
ac97
,
AC97_AD_SERIAL_CFG
,
scfg
|
0x7000
);
/* select all codecs */
return
0
;
}
...
...
@@ -572,7 +575,7 @@ static unsigned short patch_ad1881_unchained(ac97_t * ac97, int idx, unsigned sh
unsigned
short
val
;
// test for unchained codec
snd_ac97_
write_cache
(
ac97
,
AC97_AD_SERIAL_CFG
,
mask
);
snd_ac97_
update_bits
(
ac97
,
AC97_AD_SERIAL_CFG
,
0x7000
,
mask
);
snd_ac97_write_cache
(
ac97
,
AC97_AD_CODEC_CFG
,
0x0000
);
/* ID0C, ID1C, SDIE = off */
val
=
snd_ac97_read
(
ac97
,
AC97_VENDOR_ID2
);
if
((
val
&
0xff40
)
!=
0x5340
)
...
...
@@ -588,7 +591,7 @@ static int patch_ad1881_chained1(ac97_t * ac97, int idx, unsigned short codec_bi
static
int
cfg_bits
[
3
]
=
{
1
<<
12
,
1
<<
14
,
1
<<
13
};
unsigned
short
val
;
snd_ac97_
write_cache
(
ac97
,
AC97_AD_SERIAL_CFG
,
cfg_bits
[
idx
]);
snd_ac97_
update_bits
(
ac97
,
AC97_AD_SERIAL_CFG
,
0x7000
,
cfg_bits
[
idx
]);
snd_ac97_write_cache
(
ac97
,
AC97_AD_CODEC_CFG
,
0x0004
);
// SDIE
val
=
snd_ac97_read
(
ac97
,
AC97_VENDOR_ID2
);
if
((
val
&
0xff40
)
!=
0x5340
)
...
...
@@ -611,7 +614,8 @@ static void patch_ad1881_chained(ac97_t * ac97, int unchained_idx, int cidx1, in
if
(
cidx1
<
0
&&
cidx2
<
0
)
return
;
// test for chained codecs
snd_ac97_write_cache
(
ac97
,
AC97_AD_SERIAL_CFG
,
ac97
->
spec
.
ad18xx
.
unchained
[
unchained_idx
]);
snd_ac97_update_bits
(
ac97
,
AC97_AD_SERIAL_CFG
,
0x7000
,
ac97
->
spec
.
ad18xx
.
unchained
[
unchained_idx
]);
snd_ac97_write_cache
(
ac97
,
AC97_AD_CODEC_CFG
,
0x0002
);
// ID1C
ac97
->
spec
.
ad18xx
.
codec_cfg
[
unchained_idx
]
=
0x0002
;
if
(
cidx1
>=
0
)
{
...
...
@@ -634,10 +638,13 @@ int patch_ad1881(ac97_t * ac97)
// patch for Analog Devices
unsigned
short
codecs
[
3
];
unsigned
short
val
;
int
idx
,
num
;
init_MUTEX
(
&
ac97
->
spec
.
ad18xx
.
mutex
);
val
=
snd_ac97_read
(
ac97
,
AC97_AD_SERIAL_CFG
);
snd_ac97_write_cache
(
ac97
,
AC97_AD_SERIAL_CFG
,
val
);
codecs
[
0
]
=
patch_ad1881_unchained
(
ac97
,
0
,
(
1
<<
12
));
codecs
[
1
]
=
patch_ad1881_unchained
(
ac97
,
1
,
(
1
<<
14
));
codecs
[
2
]
=
patch_ad1881_unchained
(
ac97
,
2
,
(
1
<<
13
));
...
...
@@ -659,7 +666,7 @@ int patch_ad1881(ac97_t * ac97)
__end:
/* select all codecs */
snd_ac97_
write_cache
(
ac97
,
AC97_AD_SERIAL_CFG
,
0x7000
);
snd_ac97_
update_bits
(
ac97
,
AC97_AD_SERIAL_CFG
,
0x7000
,
0x7000
);
/* check if only one codec is present */
for
(
idx
=
num
=
0
;
idx
<
3
;
idx
++
)
if
(
ac97
->
spec
.
ad18xx
.
id
[
idx
])
...
...
@@ -1003,6 +1010,7 @@ int patch_ad1985(ac97_t * ac97)
{
unsigned
short
misc
;
patch_ad1881
(
ac97
);
ac97
->
build_ops
=
&
patch_ad1985_build_ops
;
misc
=
snd_ac97_read
(
ac97
,
AC97_AD_MISC
);
/* switch front/surround line-out/hp-out */
...
...
sound/pci/ac97/ac97_pcm.c
View file @
fe6a9c21
...
...
@@ -89,7 +89,7 @@ static unsigned char rate_reg_tables[2][4][9] = {
0xff
,
/* slot 6 */
AC97_PCM_LFE_DAC_RATE
,
/* slot 7 */
AC97_PCM_LFE_DAC_RATE
,
/* slot 8 */
AC97_PCM_FRONT_DAC_RATE
,
/* slot 9 */
0xff
,
/* slot 9 */
AC97_PCM_FRONT_DAC_RATE
,
/* slot 10 */
AC97_PCM_FRONT_DAC_RATE
,
/* slot 11 */
},
...
...
@@ -140,7 +140,7 @@ static unsigned char rate_reg_tables[2][4][9] = {
0xff
,
/* slot 6 */
AC97_PCM_LFE_DAC_RATE
,
/* slot 7 */
AC97_PCM_LFE_DAC_RATE
,
/* slot 8 */
AC97_PCM_FRONT_DAC_RATE
,
/* slot 9 */
0xff
,
/* slot 9 */
AC97_PCM_FRONT_DAC_RATE
,
/* slot 10 */
AC97_PCM_FRONT_DAC_RATE
,
/* slot 11 */
}
...
...
sound/pci/ac97/ac97_proc.c
View file @
fe6a9c21
...
...
@@ -241,12 +241,13 @@ static void snd_ac97_proc_read(snd_info_entry_t *entry, snd_info_buffer_t * buff
for
(
idx
=
0
;
idx
<
3
;
idx
++
)
if
(
ac97
->
spec
.
ad18xx
.
id
[
idx
])
{
/* select single codec */
snd_ac97_write_cache
(
ac97
,
AC97_AD_SERIAL_CFG
,
ac97
->
spec
.
ad18xx
.
unchained
[
idx
]
|
ac97
->
spec
.
ad18xx
.
chained
[
idx
]);
snd_ac97_update_bits
(
ac97
,
AC97_AD_SERIAL_CFG
,
0x7000
,
ac97
->
spec
.
ad18xx
.
unchained
[
idx
]
|
ac97
->
spec
.
ad18xx
.
chained
[
idx
]);
snd_ac97_proc_read_main
(
ac97
,
buffer
,
idx
);
snd_iprintf
(
buffer
,
"
\n\n
"
);
}
/* select all codecs */
snd_ac97_
write_cache
(
ac97
,
AC97_AD_SERIAL_CFG
,
0x7000
);
snd_ac97_
update_bits
(
ac97
,
AC97_AD_SERIAL_CFG
,
0x7000
,
0x7000
);
up
(
&
ac97
->
spec
.
ad18xx
.
mutex
);
snd_iprintf
(
buffer
,
"
\n
AD18XX configuration
\n
"
);
...
...
@@ -285,11 +286,12 @@ static void snd_ac97_proc_regs_read(snd_info_entry_t *entry,
for
(
idx
=
0
;
idx
<
3
;
idx
++
)
if
(
ac97
->
spec
.
ad18xx
.
id
[
idx
])
{
/* select single codec */
snd_ac97_write_cache
(
ac97
,
AC97_AD_SERIAL_CFG
,
ac97
->
spec
.
ad18xx
.
unchained
[
idx
]
|
ac97
->
spec
.
ad18xx
.
chained
[
idx
]);
snd_ac97_update_bits
(
ac97
,
AC97_AD_SERIAL_CFG
,
0x7000
,
ac97
->
spec
.
ad18xx
.
unchained
[
idx
]
|
ac97
->
spec
.
ad18xx
.
chained
[
idx
]);
snd_ac97_proc_regs_read_main
(
ac97
,
buffer
,
idx
);
}
/* select all codecs */
snd_ac97_
write_cache
(
ac97
,
AC97_AD_SERIAL_CFG
,
0x7000
);
snd_ac97_
update_bits
(
ac97
,
AC97_AD_SERIAL_CFG
,
0x7000
,
0x7000
);
up
(
&
ac97
->
spec
.
ad18xx
.
mutex
);
}
else
{
snd_ac97_proc_regs_read_main
(
ac97
,
buffer
,
0
);
...
...
sound/pci/au88x0/au88x0.h
View file @
fe6a9c21
...
...
@@ -17,7 +17,6 @@
#ifndef __SOUND_AU88X0_H
#define __SOUND_AU88X0_H
#ifdef __KERNEL__
#include <sound/driver.h>
#include <linux/init.h>
#include <linux/pci.h>
...
...
@@ -29,22 +28,6 @@
#include <sound/hwdep.h>
#include <sound/ac97_codec.h>
#ifndef PCI_VENDOR_ID_AUREAL
#define PCI_VENDOR_ID_AUREAL 0x12eb
#endif
#ifndef PCI_DEVICE_ID_AUREAL_VORTEX
#define PCI_DEVICE_ID_AUREAL_VORTEX 0x0001
#endif
#ifndef PCI_DEVICE_ID_AUREAL_VORTEX2
#define PCI_DEVICE_ID_AUREAL_VORTEX2 0x0002
#endif
#ifndef PCI_DEVICE_ID_AUREAL_ADVANTAGE
#define PCI_DEVICE_ID_AUREAL_ADVANTAGE 0x0003
#endif
#endif
#ifndef CHIP_AU8820
#include "au88x0_eq.h"
#include "au88x0_a3d.h"
...
...
sound/pci/cs46xx/cs46xx.c
View file @
fe6a9c21
...
...
@@ -51,7 +51,7 @@ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static
int
enable
[
SNDRV_CARDS
]
=
SNDRV_DEFAULT_ENABLE_PNP
;
/* Enable this card */
static
int
external_amp
[
SNDRV_CARDS
]
=
{[
0
...
(
SNDRV_CARDS
-
1
)]
=
0
};
static
int
thinkpad
[
SNDRV_CARDS
]
=
{[
0
...
(
SNDRV_CARDS
-
1
)]
=
0
};
static
int
mmap_valid
[
SNDRV_CARDS
]
=
{[
0
...
(
SNDRV_CARDS
-
1
)]
=
0
};
static
int
mmap_valid
[
SNDRV_CARDS
]
=
{[
0
...
(
SNDRV_CARDS
-
1
)]
=
1
};
MODULE_PARM
(
index
,
"1-"
__MODULE_STRING
(
SNDRV_CARDS
)
"i"
);
MODULE_PARM_DESC
(
index
,
"Index value for the CS46xx soundcard."
);
...
...
@@ -70,7 +70,7 @@ MODULE_PARM_DESC(thinkpad, "Force to enable Thinkpad's CLKRUN control.");
MODULE_PARM_SYNTAX
(
thinkpad
,
SNDRV_ENABLED
","
SNDRV_BOOLEAN_FALSE_DESC
);
MODULE_PARM
(
mmap_valid
,
"1-"
__MODULE_STRING
(
SNDRV_CARDS
)
"i"
);
MODULE_PARM_DESC
(
mmap_valid
,
"Support OSS mmap."
);
MODULE_PARM_SYNTAX
(
mmap_valid
,
SNDRV_ENABLED
","
SNDRV_BOOLEAN_
FALS
E_DESC
);
MODULE_PARM_SYNTAX
(
mmap_valid
,
SNDRV_ENABLED
","
SNDRV_BOOLEAN_
TRU
E_DESC
);
static
struct
pci_device_id
snd_cs46xx_ids
[]
=
{
{
0x1013
,
0x6001
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0
,
0
,
0
,
},
/* CS4280 */
...
...
@@ -219,7 +219,7 @@ module_exit(alsa_card_cs46xx_exit)
#ifndef MODULE
/* format is: snd-cs46xx=enable,index,id */
/* format is: snd-cs46xx=enable,index,id
,mmap_valid,external_amp,thinkpad
*/
static
int
__init
alsa_card_cs46xx_setup
(
char
*
str
)
{
...
...
@@ -229,7 +229,10 @@ static int __init alsa_card_cs46xx_setup(char *str)
return
0
;
(
void
)(
get_option
(
&
str
,
&
enable
[
nr_dev
])
==
2
&&
get_option
(
&
str
,
&
index
[
nr_dev
])
==
2
&&
get_id
(
&
str
,
&
id
[
nr_dev
])
==
2
);
get_id
(
&
str
,
&
id
[
nr_dev
])
==
2
&&
get_option
(
&
str
,
&
mmap_valid
[
nr_dev
])
==
2
&&
get_option
(
&
str
,
&
external_amp
[
nr_dev
])
==
2
&&
get_option
(
&
str
,
&
thinkpad
[
nr_dev
])
==
2
);
nr_dev
++
;
return
1
;
}
...
...
sound/pci/ice1712/delta.c
View file @
fe6a9c21
...
...
@@ -90,6 +90,7 @@ static unsigned char ap_cs8427_codec_select(ice1712_t *ice)
tmp
|=
ICE1712_DELTA_1010LT_CCLK
|
ICE1712_DELTA_1010LT_CS_CS8427
;
break
;
case
ICE1712_SUBDEVICE_AUDIOPHILE
:
case
ICE1712_SUBDEVICE_DELTA410
:
tmp
|=
ICE1712_DELTA_AP_CCLK
|
ICE1712_DELTA_AP_CS_CODEC
;
tmp
&=
~
ICE1712_DELTA_AP_CS_DIGITAL
;
break
;
...
...
@@ -112,6 +113,7 @@ static void ap_cs8427_codec_deassert(ice1712_t *ice, unsigned char tmp)
tmp
|=
ICE1712_DELTA_1010LT_CS_NONE
;
break
;
case
ICE1712_SUBDEVICE_AUDIOPHILE
:
case
ICE1712_SUBDEVICE_DELTA410
:
tmp
|=
ICE1712_DELTA_AP_CS_DIGITAL
;
break
;
case
ICE1712_SUBDEVICE_VX442
:
...
...
sound/pci/ice1712/ice1712.c
View file @
fe6a9c21
...
...
@@ -82,6 +82,7 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static
char
*
id
[
SNDRV_CARDS
]
=
SNDRV_DEFAULT_STR
;
/* ID for this card */
static
int
enable
[
SNDRV_CARDS
]
=
SNDRV_DEFAULT_ENABLE_PNP
;
/* Enable this card */
static
int
omni
[
SNDRV_CARDS
]
=
{[
0
...
(
SNDRV_CARDS
-
1
)]
=
0
};
/* Delta44 & 66 Omni I/O support */
static
int
cs8427_timeout
[
SNDRV_CARDS
]
=
{[
0
...
(
SNDRV_CARDS
-
1
)]
=
500
};
/* CS8427 S/PDIF transciever reset timeout value in msec */
MODULE_PARM
(
index
,
"1-"
__MODULE_STRING
(
SNDRV_CARDS
)
"i"
);
MODULE_PARM_DESC
(
index
,
"Index value for ICE1712 soundcard."
);
...
...
@@ -95,6 +96,9 @@ MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC);
MODULE_PARM
(
omni
,
"1-"
__MODULE_STRING
(
SNDRV_CARDS
)
"i"
);
MODULE_PARM_DESC
(
omni
,
"Enable Midiman M-Audio Delta Omni I/O support."
);
MODULE_PARM_SYNTAX
(
omni
,
SNDRV_ENABLED
","
SNDRV_ENABLE_DESC
);
MODULE_PARM
(
cs8427_timeout
,
"1-"
__MODULE_STRING
(
SNDRV_CARDS
)
"i"
);
MODULE_PARM_DESC
(
cs8427_timeout
,
"Define reset timeout for cs8427 chip in msec resolution."
);
MODULE_PARM_SYNTAX
(
cs8427_timeout
,
SNDRV_ENABLED
", allows:{{1,1000}},default=500,skill:advanced"
);
#ifndef PCI_VENDOR_ID_ICE
#define PCI_VENDOR_ID_ICE 0x1412
...
...
@@ -386,7 +390,9 @@ int __devinit snd_ice1712_init_cs8427(ice1712_t *ice, int addr)
{
int
err
;
if
((
err
=
snd_cs8427_create
(
ice
->
i2c
,
addr
,
&
ice
->
cs8427
))
<
0
)
{
if
((
err
=
snd_cs8427_create
(
ice
->
i2c
,
addr
,
(
ice
->
cs8427_timeout
*
HZ
)
/
1000
,
&
ice
->
cs8427
))
<
0
)
{
snd_printk
(
"CS8427 initialization failed
\n
"
);
return
err
;
}
...
...
@@ -1505,10 +1511,10 @@ static void snd_ice1712_mixer_free_ac97(ac97_t *ac97)
static
int
__devinit
snd_ice1712_ac97_mixer
(
ice1712_t
*
ice
)
{
int
err
;
ac97_t
ac97
;
ac97_bus_t
bus
,
*
pbus
;
if
(
ice_has_con_ac97
(
ice
))
{
ac97_bus_t
bus
,
*
pbus
;
ac97_t
ac97
;
memset
(
&
bus
,
0
,
sizeof
(
bus
));
bus
.
write
=
snd_ice1712_ac97_write
;
bus
.
read
=
snd_ice1712_ac97_read
;
...
...
@@ -1527,8 +1533,6 @@ static int __devinit snd_ice1712_ac97_mixer(ice1712_t * ice)
}
if
(
!
(
ice
->
eeprom
.
data
[
ICE_EEP1_ACLINK
]
&
ICE1712_CFG_PRO_I2S
))
{
ac97_bus_t
bus
,
*
pbus
;
ac97_t
ac97
;
memset
(
&
bus
,
0
,
sizeof
(
bus
));
bus
.
write
=
snd_ice1712_pro_ac97_write
;
bus
.
read
=
snd_ice1712_pro_ac97_read
;
...
...
@@ -2404,6 +2408,7 @@ static int snd_ice1712_dev_free(snd_device_t *device)
static
int
__devinit
snd_ice1712_create
(
snd_card_t
*
card
,
struct
pci_dev
*
pci
,
int
omni
,
int
cs8427_timeout
,
ice1712_t
**
r_ice1712
)
{
ice1712_t
*
ice
;
...
...
@@ -2428,6 +2433,11 @@ static int __devinit snd_ice1712_create(snd_card_t * card,
if
(
ice
==
NULL
)
return
-
ENOMEM
;
ice
->
omni
=
omni
?
1
:
0
;
if
(
cs8427_timeout
<
1
)
cs8427_timeout
=
1
;
else
if
(
cs8427_timeout
>
1000
)
cs8427_timeout
=
1000
;
ice
->
cs8427_timeout
=
cs8427_timeout
;
spin_lock_init
(
&
ice
->
reg_lock
);
init_MUTEX
(
&
ice
->
gpio_mutex
);
init_MUTEX
(
&
ice
->
open_mutex
);
...
...
@@ -2547,7 +2557,7 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,
strcpy
(
card
->
driver
,
"ICE1712"
);
strcpy
(
card
->
shortname
,
"ICEnsemble ICE1712"
);
if
((
err
=
snd_ice1712_create
(
card
,
pci
,
omni
[
dev
],
&
ice
))
<
0
)
{
if
((
err
=
snd_ice1712_create
(
card
,
pci
,
omni
[
dev
],
cs8427_timeout
[
dev
],
&
ice
))
<
0
)
{
snd_card_free
(
card
);
return
err
;
}
...
...
sound/pci/ice1712/ice1712.h
View file @
fe6a9c21
...
...
@@ -346,6 +346,7 @@ struct _snd_ice1712 {
snd_i2c_bus_t
*
i2c
;
/* I2C bus */
snd_i2c_device_t
*
cs8404
;
/* CS8404A I2C device */
snd_i2c_device_t
*
cs8427
;
/* CS8427 I2C device */
unsigned
int
cs8427_timeout
;
/* CS8427 reset timeout in HZ/100 */
snd_i2c_device_t
*
i2cdevs
[
2
];
/* additional i2c devices */
struct
ice1712_gpio
{
...
...
sound/pci/intel8x0.c
View file @
fe6a9c21
...
...
@@ -96,7 +96,7 @@ MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect).");
MODULE_PARM_SYNTAX
(
ac97_clock
,
SNDRV_ENABLED
",default:0"
);
MODULE_PARM
(
ac97_quirk
,
"1-"
__MODULE_STRING
(
SNDRV_CARDS
)
"i"
);
MODULE_PARM_DESC
(
ac97_quirk
,
"AC'97 workaround for strange hardware."
);
MODULE_PARM_SYNTAX
(
ac97_quirk
,
SNDRV_ENABLED
",allows:{{-1,
3
}},dialog:list,default:-1"
);
MODULE_PARM_SYNTAX
(
ac97_quirk
,
SNDRV_ENABLED
",allows:{{-1,
4
}},dialog:list,default:-1"
);
#ifdef SUPPORT_JOYSTICK
MODULE_PARM
(
joystick
,
"1-"
__MODULE_STRING
(
SNDRV_CARDS
)
"i"
);
MODULE_PARM_DESC
(
joystick
,
"Enable joystick for Intel i8x0 soundcard."
);
...
...
@@ -824,19 +824,16 @@ static irqreturn_t snd_intel8x0_interrupt(int irq, void *dev_id, struct pt_regs
spin_lock
(
&
chip
->
reg_lock
);
status
=
igetdword
(
chip
,
chip
->
int_sta_reg
);
if
((
status
&
chip
->
int_sta_mask
)
==
0
)
{
static
int
err_count
=
10
;
if
(
status
)
{
/* ack */
iputdword
(
chip
,
chip
->
int_sta_reg
,
status
);
/* some Nforce[2] boards have problems when
IRQ_NONE is returned here.
*/
if
(
chip
->
device_type
!=
DEVICE_NFORCE
)
status
^=
igetdword
(
chip
,
chip
->
int_sta_reg
)
;
status
=
0
;
}
spin_unlock
(
&
chip
->
reg_lock
);
if
(
chip
->
device_type
!=
DEVICE_NFORCE
&&
status
&&
err_count
)
{
err_count
--
;
snd_printd
(
"intel8x0: unknown IRQ bits 0x%x (sta_mask=0x%x)
\n
"
,
status
,
chip
->
int_sta_mask
);
}
return
IRQ_RETVAL
(
status
);
}
...
...
@@ -1689,6 +1686,12 @@ static struct ac97_pcm ac97_pcm_defs[] __devinitdata = {
};
static
struct
ac97_quirk
ac97_quirks
[]
__devinitdata
=
{
{
.
vendor
=
0x0e11
,
.
device
=
0x00b8
,
.
name
=
"Compaq Evo D510C"
,
.
type
=
AC97_TUNE_HP_ONLY
},
{
.
vendor
=
0x1014
,
.
device
=
0x1f00
,
...
...
@@ -2739,6 +2742,7 @@ static int __devinit snd_intel8x0_joystick_probe(struct pci_dev *pci,
pci_read_config_word
(
pci
,
0xe6
,
&
val
);
#ifdef SUPPORT_JOYSTICK
val
&=
~
0x100
;
if
(
joystick
[
dev
])
{
if
(
!
request_region
(
ich_gameport
.
io
,
8
,
"ICH gameport"
))
{
printk
(
KERN_WARNING
"intel8x0: cannot grab gameport 0x%x
\n
"
,
ich_gameport
.
io
);
...
...
@@ -2751,6 +2755,7 @@ static int __devinit snd_intel8x0_joystick_probe(struct pci_dev *pci,
}
#endif
#ifdef SUPPORT_MIDI
val
&=
~
0x20
;
if
(
mpu_port
[
dev
]
>
0
)
{
if
(
mpu_port
[
dev
]
==
0x300
||
mpu_port
[
dev
]
==
0x330
)
{
u8
b
;
...
...
sound/pcmcia/pdaudiocf/pdaudiocf.c
View file @
fe6a9c21
...
...
@@ -25,7 +25,6 @@
#include <pcmcia/ciscode.h>
#include <pcmcia/cisreg.h>
#include "pdaudiocf.h"
#define SNDRV_GET_ID
#include <sound/initval.h>
/*
...
...
sound/pcmcia/pdaudiocf/pdaudiocf_core.c
View file @
fe6a9c21
...
...
@@ -23,7 +23,6 @@
#include <sound/core.h>
#include <sound/info.h>
#include "pdaudiocf.h"
#define SNDRV_GET_ID
#include <sound/initval.h>
/*
...
...
sound/pcmcia/pdaudiocf/pdaudiocf_irq.c
View file @
fe6a9c21
...
...
@@ -21,7 +21,6 @@
#include <sound/driver.h>
#include <sound/core.h>
#include "pdaudiocf.h"
#define SNDRV_GET_ID
#include <sound/initval.h>
/*
...
...
sound/ppc/powermac.c
View file @
fe6a9c21
...
...
@@ -36,7 +36,7 @@ MODULE_LICENSE("GPL");
static
int
index
=
SNDRV_DEFAULT_IDX1
;
/* Index 0-MAX */
static
char
*
id
=
SNDRV_DEFAULT_STR1
;
/* ID for this card */
static
int
enable
=
1
;
/* static int enable = 1; */
#ifdef PMAC_SUPPORT_PCM_BEEP
static
int
enable_beep
=
1
;
#endif
...
...
@@ -47,9 +47,9 @@ MODULE_PARM_SYNTAX(index, SNDRV_INDEX_DESC);
MODULE_PARM
(
id
,
"s"
);
MODULE_PARM_DESC
(
id
,
"ID string for "
CHIP_NAME
" soundchip."
);
MODULE_PARM_SYNTAX
(
id
,
SNDRV_ID_DESC
);
MODULE_PARM
(
enable
,
"i"
);
MODULE_PARM_DESC
(
enable
,
"Enable this soundchip."
);
MODULE_PARM_SYNTAX
(
enable
,
SNDRV_ENABLE_DESC
);
/*
MODULE_PARM(enable, "i");
MODULE_PARM_DESC(enable, "Enable this soundchip.");
MODULE_PARM_SYNTAX(enable, SNDRV_ENABLE_DESC); */
#ifdef PMAC_SUPPORT_PCM_BEEP
MODULE_PARM
(
enable_beep
,
"i"
);
MODULE_PARM_DESC
(
enable_beep
,
"Enable beep using PCM."
);
...
...
@@ -183,6 +183,8 @@ module_exit(alsa_card_pmac_exit)
static
int
__init
alsa_card_pmac_setup
(
char
*
str
)
{
int
__attribute__
((
__unused__
))
enable
=
1
;
(
void
)(
get_option
(
&
str
,
&
enable
)
==
2
&&
get_option
(
&
str
,
&
index
)
==
2
&&
get_id
(
&
str
,
&
id
)
==
2
...
...
sound/usb/usbaudio.c
View file @
fe6a9c21
...
...
@@ -104,6 +104,7 @@ MODULE_PARM_SYNTAX(async_unlink, SNDRV_BOOLEAN_TRUE_DESC);
*/
#define MAX_PACKS 10
#define MAX_PACKS_HS (MAX_PACKS * 8)
/* in high speed mode */
#define MAX_URBS 5
/* max. 20ms long packets */
#define SYNC_URBS 2
/* always two urbs for sync */
#define MIN_PACKS_URB 1
/* minimum 1 packet per urb */
...
...
@@ -161,8 +162,8 @@ struct snd_usb_substream {
unsigned
int
datapipe
;
/* the data i/o pipe */
unsigned
int
syncpipe
;
/* 1 - async out or adaptive in */
unsigned
int
syncinterval
;
/* P for adaptive mode, 0 otherwise */
unsigned
int
freqn
;
/* nominal sampling rate in
USB format, i.e. fs/1000 in Q10.14
*/
unsigned
int
freqm
;
/* momentary sampling rate in
USB format, i.e. fs/1000 in Q10.14
*/
unsigned
int
freqn
;
/* nominal sampling rate in
fs/fps in Q16.16 format
*/
unsigned
int
freqm
;
/* momentary sampling rate in
fs/fps in Q16.16 format
*/
unsigned
int
freqmax
;
/* maximum sampling rate, used for buffer management */
unsigned
int
phase
;
/* phase accumulator */
unsigned
int
maxpacksize
;
/* max packet size in bytes */
...
...
@@ -184,7 +185,7 @@ struct snd_usb_substream {
unsigned
int
nurbs
;
/* # urbs */
snd_urb_ctx_t
dataurb
[
MAX_URBS
];
/* data urb table */
snd_urb_ctx_t
syncurb
[
SYNC_URBS
];
/* sync urb table */
char
syncbuf
[
SYNC_URBS
*
MAX_PACKS
*
3
];
/* sync buffer; it's so small - let's get static */
char
syncbuf
[
SYNC_URBS
*
MAX_PACKS
*
4
];
/* sync buffer; it's so small - let's get static */
char
*
tmpbuf
;
/* temporary buffer for playback */
u64
formats
;
/* format bitmasks (all or'ed) */
...
...
@@ -218,17 +219,38 @@ static snd_usb_audio_t *usb_chip[SNDRV_CARDS];
/*
* convert a sampling rate into
USB format (fs/1000 in Q10.14
)
* this will overflow at approx
2MSPS
* convert a sampling rate into
our full speed format (fs/1000 in Q16.16
)
* this will overflow at approx
524 kHz
*/
inline
static
unsigned
get_usb_rate
(
unsigned
int
rate
)
inline
static
unsigned
get_usb_
full_speed_
rate
(
unsigned
int
rate
)
{
return
((
rate
<<
11
)
+
62
)
/
125
;
return
((
rate
<<
13
)
+
62
)
/
125
;
}
/*
* convert a sampling rate into USB high speed format (fs/8000 in Q16.16)
* this will overflow at approx 4 MHz
*/
inline
static
unsigned
get_usb_high_speed_rate
(
unsigned
int
rate
)
{
return
((
rate
<<
10
)
+
62
)
/
125
;
}
/* convert our full speed USB rate into sampling rate in Hz */
inline
static
unsigned
get_full_speed_hz
(
unsigned
int
usb_rate
)
{
return
(
usb_rate
*
125
+
(
1
<<
12
))
>>
13
;
}
/* convert our high speed USB rate into sampling rate in Hz */
inline
static
unsigned
get_high_speed_hz
(
unsigned
int
usb_rate
)
{
return
(
usb_rate
*
125
+
(
1
<<
9
))
>>
10
;
}
/*
* prepare urb for capture sync pipe
* prepare urb for
full speed
capture sync pipe
*
* fill the length and offset of each urb descriptor.
* the fixed 10.14 frequency is passed through the pipe.
...
...
@@ -243,14 +265,40 @@ static int prepare_capture_sync_urb(snd_usb_substream_t *subs,
urb
->
number_of_packets
=
ctx
->
packets
;
urb
->
dev
=
ctx
->
subs
->
dev
;
/* we need to set this at each time */
for
(
i
=
offs
=
0
;
i
<
urb
->
number_of_packets
;
i
++
,
offs
+=
3
,
cp
+=
3
)
{
for
(
i
=
offs
=
0
;
i
<
urb
->
number_of_packets
;
i
++
,
offs
+=
4
,
cp
+=
4
)
{
urb
->
iso_frame_desc
[
i
].
length
=
3
;
urb
->
iso_frame_desc
[
i
].
offset
=
offs
;
cp
[
0
]
=
subs
->
freqn
>>
2
;
cp
[
1
]
=
subs
->
freqn
>>
10
;
cp
[
2
]
=
subs
->
freqn
>>
18
;
}
return
0
;
}
/*
* prepare urb for high speed capture sync pipe
*
* fill the length and offset of each urb descriptor.
* the fixed 12.13 frequency is passed as 16.16 through the pipe.
*/
static
int
prepare_capture_sync_urb_hs
(
snd_usb_substream_t
*
subs
,
snd_pcm_runtime_t
*
runtime
,
struct
urb
*
urb
)
{
unsigned
char
*
cp
=
urb
->
transfer_buffer
;
snd_urb_ctx_t
*
ctx
=
(
snd_urb_ctx_t
*
)
urb
->
context
;
int
i
,
offs
;
urb
->
number_of_packets
=
ctx
->
packets
;
urb
->
dev
=
ctx
->
subs
->
dev
;
/* we need to set this at each time */
for
(
i
=
offs
=
0
;
i
<
urb
->
number_of_packets
;
i
++
,
offs
+=
4
,
cp
+=
4
)
{
urb
->
iso_frame_desc
[
i
].
length
=
4
;
urb
->
iso_frame_desc
[
i
].
offset
=
offs
;
cp
[
0
]
=
subs
->
freqn
;
cp
[
1
]
=
subs
->
freqn
>>
8
;
cp
[
2
]
=
subs
->
freqn
>>
16
;
cp
[
3
]
=
subs
->
freqn
>>
24
;
}
urb
->
interval
=
1
;
return
0
;
}
...
...
@@ -301,7 +349,6 @@ static int prepare_capture_urb(snd_usb_substream_t *subs,
spin_unlock_irqrestore
(
&
subs
->
lock
,
flags
);
urb
->
transfer_buffer
=
ctx
->
buf
;
urb
->
transfer_buffer_length
=
offs
;
urb
->
interval
=
1
;
#if 0 // for check
if (! urb->bandwidth) {
int bustime;
...
...
@@ -372,7 +419,7 @@ static int retire_capture_urb(snd_usb_substream_t *subs,
/*
* prepare urb for playback sync pipe
* prepare urb for
full speed
playback sync pipe
*
* set up the offset and length to receive the current frequency.
*/
...
...
@@ -386,16 +433,37 @@ static int prepare_playback_sync_urb(snd_usb_substream_t *subs,
urb
->
number_of_packets
=
ctx
->
packets
;
urb
->
dev
=
ctx
->
subs
->
dev
;
/* we need to set this at each time */
for
(
i
=
offs
=
0
;
i
<
urb
->
number_of_packets
;
i
++
,
offs
+=
3
)
{
for
(
i
=
offs
=
0
;
i
<
urb
->
number_of_packets
;
i
++
,
offs
+=
4
)
{
urb
->
iso_frame_desc
[
i
].
length
=
3
;
urb
->
iso_frame_desc
[
i
].
offset
=
offs
;
}
urb
->
interval
=
1
;
return
0
;
}
/*
* process after playback sync complete
* prepare urb for high speed playback sync pipe
*
* set up the offset and length to receive the current frequency.
*/
static
int
prepare_playback_sync_urb_hs
(
snd_usb_substream_t
*
subs
,
snd_pcm_runtime_t
*
runtime
,
struct
urb
*
urb
)
{
int
i
,
offs
;
snd_urb_ctx_t
*
ctx
=
(
snd_urb_ctx_t
*
)
urb
->
context
;
urb
->
number_of_packets
=
ctx
->
packets
;
urb
->
dev
=
ctx
->
subs
->
dev
;
/* we need to set this at each time */
for
(
i
=
offs
=
0
;
i
<
urb
->
number_of_packets
;
i
++
,
offs
+=
4
)
{
urb
->
iso_frame_desc
[
i
].
length
=
4
;
urb
->
iso_frame_desc
[
i
].
offset
=
offs
;
}
return
0
;
}
/*
* process after full speed playback sync complete
*
* retrieve the current 10.14 frequency from pipe, and set it.
* the value is referred in prepare_playback_urb().
...
...
@@ -410,11 +478,11 @@ static int retire_playback_sync_urb(snd_usb_substream_t *subs,
unsigned
long
flags
;
found
=
0
;
for
(
i
=
0
;
i
<
urb
->
number_of_packets
;
i
++
,
cp
+=
3
)
{
for
(
i
=
0
;
i
<
urb
->
number_of_packets
;
i
++
,
cp
+=
4
)
{
if
(
urb
->
iso_frame_desc
[
i
].
status
||
urb
->
iso_frame_desc
[
i
].
actual_length
<
3
)
continue
;
f
=
combine_triple
(
cp
);
f
=
combine_triple
(
cp
)
<<
2
;
#if 0
if (f < subs->freqn - (subs->freqn>>3) || f > subs->freqmax) {
snd_printd(KERN_WARNING "requested frequency %d (%u,%03uHz) out of range (current nominal %d (%u,%03uHz))\n",
...
...
@@ -434,6 +502,37 @@ static int retire_playback_sync_urb(snd_usb_substream_t *subs,
return
0
;
}
/*
* process after high speed playback sync complete
*
* retrieve the current 12.13 frequency from pipe, and set it.
* the value is referred in prepare_playback_urb().
*/
static
int
retire_playback_sync_urb_hs
(
snd_usb_substream_t
*
subs
,
snd_pcm_runtime_t
*
runtime
,
struct
urb
*
urb
)
{
int
i
;
unsigned
int
found
;
unsigned
char
*
cp
=
urb
->
transfer_buffer
;
unsigned
long
flags
;
found
=
0
;
for
(
i
=
0
;
i
<
urb
->
number_of_packets
;
i
++
,
cp
+=
4
)
{
if
(
urb
->
iso_frame_desc
[
i
].
status
||
urb
->
iso_frame_desc
[
i
].
actual_length
<
4
)
continue
;
found
=
combine_quad
(
cp
)
&
0x0fffffff
;
}
if
(
found
)
{
spin_lock_irqsave
(
&
subs
->
lock
,
flags
);
subs
->
freqm
=
found
;
spin_unlock_irqrestore
(
&
subs
->
lock
,
flags
);
}
return
0
;
}
/*
* prepare urb for playback data pipe
*
...
...
@@ -464,8 +563,8 @@ static int prepare_playback_urb(snd_usb_substream_t *subs,
if
(
subs
->
fill_max
)
counts
=
subs
->
maxframesize
;
/* fixed */
else
{
subs
->
phase
=
(
subs
->
phase
&
0x
3
fff
)
+
subs
->
freqm
;
counts
=
subs
->
phase
>>
1
4
;
subs
->
phase
=
(
subs
->
phase
&
0x
f
fff
)
+
subs
->
freqm
;
counts
=
subs
->
phase
>>
1
6
;
if
(
counts
>
subs
->
maxframesize
)
counts
=
subs
->
maxframesize
;
}
...
...
@@ -515,7 +614,6 @@ static int prepare_playback_urb(snd_usb_substream_t *subs,
spin_unlock_irqrestore
(
&
subs
->
lock
,
flags
);
urb
->
transfer_buffer_length
=
offs
*
stride
;
ctx
->
transfer
=
offs
;
urb
->
interval
=
1
;
return
0
;
}
...
...
@@ -565,6 +663,21 @@ static struct snd_urb_ops audio_urb_ops[2] = {
},
};
static
struct
snd_urb_ops
audio_urb_ops_high_speed
[
2
]
=
{
{
.
prepare
=
prepare_playback_urb
,
.
retire
=
retire_playback_urb
,
.
prepare_sync
=
prepare_playback_sync_urb_hs
,
.
retire_sync
=
retire_playback_sync_urb_hs
,
},
{
.
prepare
=
prepare_capture_urb
,
.
retire
=
retire_capture_urb
,
.
prepare_sync
=
prepare_capture_sync_urb_hs
,
.
retire_sync
=
retire_capture_sync_urb
,
},
};
/*
* complete callback from data urb
*/
...
...
@@ -822,15 +935,19 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by
{
unsigned
int
maxsize
,
n
,
i
;
int
is_playback
=
subs
->
direction
==
SNDRV_PCM_STREAM_PLAYBACK
;
unsigned
int
npacks
[
MAX_URBS
],
total_packs
;
unsigned
int
npacks
[
MAX_URBS
],
urb_packs
,
total_packs
;
/* calculate the frequency in 10.14 format */
subs
->
freqn
=
subs
->
freqm
=
get_usb_rate
(
rate
);
/* calculate the frequency in 16.16 format */
if
(
snd_usb_get_speed
(
subs
->
dev
)
==
USB_SPEED_FULL
)
subs
->
freqn
=
get_usb_full_speed_rate
(
rate
);
else
subs
->
freqn
=
get_usb_high_speed_rate
(
rate
);
subs
->
freqm
=
subs
->
freqn
;
subs
->
freqmax
=
subs
->
freqn
+
(
subs
->
freqn
>>
2
);
/* max. allowed frequency */
subs
->
phase
=
0
;
/* calculate the max. size of packet */
maxsize
=
((
subs
->
freqmax
+
0x
3fff
)
*
(
frame_bits
>>
3
))
>>
14
;
maxsize
=
((
subs
->
freqmax
+
0x
ffff
)
*
(
frame_bits
>>
3
))
>>
16
;
if
(
subs
->
maxpacksize
&&
maxsize
>
subs
->
maxpacksize
)
{
//snd_printd(KERN_DEBUG "maxsize %d is greater than defined size %d\n",
// maxsize, subs->maxpacksize);
...
...
@@ -842,9 +959,14 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by
else
subs
->
curpacksize
=
maxsize
;
if
(
snd_usb_get_speed
(
subs
->
dev
)
==
USB_SPEED_FULL
)
urb_packs
=
nrpacks
;
else
urb_packs
=
nrpacks
*
8
;
/* allocate a temporary buffer for playback */
if
(
is_playback
)
{
subs
->
tmpbuf
=
kmalloc
(
maxsize
*
nr
packs
,
GFP_KERNEL
);
subs
->
tmpbuf
=
kmalloc
(
maxsize
*
urb_
packs
,
GFP_KERNEL
);
if
(
!
subs
->
tmpbuf
)
{
snd_printk
(
KERN_ERR
"cannot malloc tmpbuf
\n
"
);
return
-
ENOMEM
;
...
...
@@ -855,16 +977,16 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by
total_packs
=
(
period_bytes
+
maxsize
-
1
)
/
maxsize
;
if
(
total_packs
<
2
*
MIN_PACKS_URB
)
total_packs
=
2
*
MIN_PACKS_URB
;
subs
->
nurbs
=
(
total_packs
+
nrpacks
-
1
)
/
nr
packs
;
subs
->
nurbs
=
(
total_packs
+
urb_packs
-
1
)
/
urb_
packs
;
if
(
subs
->
nurbs
>
MAX_URBS
)
{
/* too much... */
subs
->
nurbs
=
MAX_URBS
;
total_packs
=
MAX_URBS
*
nr
packs
;
total_packs
=
MAX_URBS
*
urb_
packs
;
}
n
=
total_packs
;
for
(
i
=
0
;
i
<
subs
->
nurbs
;
i
++
)
{
npacks
[
i
]
=
n
>
nrpacks
?
nr
packs
:
n
;
n
-=
nr
packs
;
npacks
[
i
]
=
n
>
urb_packs
?
urb_
packs
:
n
;
n
-=
urb_
packs
;
}
if
(
subs
->
nurbs
<=
1
)
{
/* too little - we need at least two packets
...
...
@@ -913,6 +1035,7 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by
u
->
urb
->
pipe
=
subs
->
datapipe
;
u
->
urb
->
transfer_flags
=
URB_ISO_ASAP
;
u
->
urb
->
number_of_packets
=
u
->
packets
;
u
->
urb
->
interval
=
1
;
u
->
urb
->
context
=
u
;
u
->
urb
->
complete
=
snd_usb_complete_callback
(
snd_complete_urb
);
}
...
...
@@ -929,12 +1052,16 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by
release_substream_urbs
(
subs
,
0
);
return
-
ENOMEM
;
}
u
->
urb
->
transfer_buffer
=
subs
->
syncbuf
+
i
*
nrpacks
*
3
;
u
->
urb
->
transfer_buffer_length
=
nrpacks
*
3
;
u
->
urb
->
transfer_buffer
=
subs
->
syncbuf
+
i
*
nrpacks
*
4
;
u
->
urb
->
transfer_buffer_length
=
nrpacks
*
4
;
u
->
urb
->
dev
=
subs
->
dev
;
u
->
urb
->
pipe
=
subs
->
syncpipe
;
u
->
urb
->
transfer_flags
=
URB_ISO_ASAP
;
u
->
urb
->
number_of_packets
=
u
->
packets
;
if
(
snd_usb_get_speed
(
subs
->
dev
)
==
USB_SPEED_HIGH
)
u
->
urb
->
interval
=
8
;
else
u
->
urb
->
interval
=
1
;
u
->
urb
->
context
=
u
;
u
->
urb
->
complete
=
snd_usb_complete_callback
(
snd_complete_sync_urb
);
}
...
...
@@ -1099,7 +1226,7 @@ static int set_format(snd_usb_substream_t *subs, struct audioformat *fmt)
/* set interface */
if
(
subs
->
interface
!=
fmt
->
iface
||
subs
->
format
!=
fmt
->
altset_idx
)
{
if
(
usb_set_interface
(
dev
,
fmt
->
iface
,
fmt
->
altset
_idx
)
<
0
)
{
if
(
usb_set_interface
(
dev
,
fmt
->
iface
,
fmt
->
altset
ting
)
<
0
)
{
snd_printk
(
KERN_ERR
"%d:%d:%d: usb_set_interface failed
\n
"
,
dev
->
devnum
,
fmt
->
iface
,
fmt
->
altsetting
);
return
-
EIO
;
...
...
@@ -1116,7 +1243,7 @@ static int set_format(snd_usb_substream_t *subs, struct audioformat *fmt)
else
subs
->
datapipe
=
usb_rcvisocpipe
(
dev
,
ep
);
subs
->
syncpipe
=
subs
->
syncinterval
=
0
;
subs
->
maxpacksize
=
get_endpoint
(
alts
,
0
)
->
wMaxPacketS
ize
;
subs
->
maxpacksize
=
fmt
->
maxpacks
ize
;
subs
->
fill_max
=
0
;
/* we need a sync pipe in async OUT or adaptive IN mode */
...
...
@@ -1836,11 +1963,10 @@ static void proc_dump_substream_status(snd_usb_substream_t *subs, snd_info_buffe
snd_iprintf
(
buffer
,
"%d "
,
subs
->
dataurb
[
i
].
packets
);
snd_iprintf
(
buffer
,
"]
\n
"
);
snd_iprintf
(
buffer
,
" Packet Size = %d
\n
"
,
subs
->
curpacksize
);
snd_iprintf
(
buffer
,
" Momentary freq = %d.%d Hz
\n
"
,
(
subs
->
freqm
*
125
)
>>
11
,
(
subs
->
freqm
>>
10
)
*
625
+
(((
subs
->
freqm
&
((
1
<<
10
)
-
1
))
*
625
)
>>
10
)
-
10
*
((
subs
->
freqm
*
125
)
>>
11
));
snd_iprintf
(
buffer
,
" Momentary freq = %u Hz
\n
"
,
snd_usb_get_speed
(
subs
->
dev
)
==
USB_SPEED_FULL
?
get_full_speed_hz
(
subs
->
freqm
)
:
get_high_speed_hz
(
subs
->
freqm
));
}
else
{
snd_iprintf
(
buffer
,
" Status: Stop
\n
"
);
}
...
...
@@ -1890,7 +2016,10 @@ static void init_substream(snd_usb_stream_t *as, int stream, struct audioformat
subs
->
stream
=
as
;
subs
->
direction
=
stream
;
subs
->
dev
=
as
->
chip
->
dev
;
subs
->
ops
=
audio_urb_ops
[
stream
];
if
(
snd_usb_get_speed
(
subs
->
dev
)
==
USB_SPEED_FULL
)
subs
->
ops
=
audio_urb_ops
[
stream
];
else
subs
->
ops
=
audio_urb_ops_high_speed
[
stream
];
snd_pcm_lib_preallocate_pages
(
as
->
pcm
->
streams
[
stream
].
substream
,
SNDRV_DMA_TYPE_CONTINUOUS
,
snd_dma_continuous_data
(
GFP_KERNEL
),
...
...
@@ -2351,6 +2480,7 @@ static int parse_audio_endpoints(snd_usb_audio_t *chip, int iface_no)
fp
->
altset_idx
=
i
;
fp
->
endpoint
=
get_endpoint
(
alts
,
0
)
->
bEndpointAddress
;
fp
->
ep_attr
=
get_endpoint
(
alts
,
0
)
->
bmAttributes
;
/* FIXME: decode wMaxPacketSize of high bandwith endpoints */
fp
->
maxpacksize
=
get_endpoint
(
alts
,
0
)
->
wMaxPacketSize
;
fp
->
attributes
=
csep
[
3
];
...
...
@@ -2405,7 +2535,7 @@ static int parse_audio_endpoints(snd_usb_audio_t *chip, int iface_no)
return
err
;
}
/* try to set the interface... */
usb_set_interface
(
chip
->
dev
,
iface_no
,
i
);
usb_set_interface
(
chip
->
dev
,
iface_no
,
altno
);
init_usb_pitch
(
chip
->
dev
,
iface_no
,
alts
,
fp
);
init_usb_sample_rate
(
chip
->
dev
,
iface_no
,
alts
,
fp
,
fp
->
rate_max
);
}
...
...
@@ -2422,7 +2552,6 @@ static void snd_usb_stream_disconnect(struct list_head *head, struct usb_driver
int
idx
;
snd_usb_stream_t
*
as
;
snd_usb_substream_t
*
subs
;
struct
list_head
*
p
;
as
=
list_entry
(
head
,
snd_usb_stream_t
,
list
);
for
(
idx
=
0
;
idx
<
2
;
idx
++
)
{
...
...
@@ -2431,11 +2560,6 @@ static void snd_usb_stream_disconnect(struct list_head *head, struct usb_driver
return
;
release_substream_urbs
(
subs
,
1
);
subs
->
interface
=
-
1
;
/* release interfaces */
list_for_each
(
p
,
&
subs
->
fmt_list
)
{
struct
audioformat
*
fp
=
list_entry
(
p
,
struct
audioformat
,
list
);
usb_driver_release_interface
(
driver
,
usb_ifnum_to_if
(
subs
->
dev
,
fp
->
iface
));
}
}
}
...
...
@@ -2587,14 +2711,13 @@ static int create_composite_quirk(snd_usb_audio_t *chip,
struct
usb_interface
*
iface
,
const
snd_usb_audio_quirk_t
*
quirk
)
{
struct
usb_host_config
*
config
=
chip
->
dev
->
actconfig
;
int
probed_ifnum
=
get_iface_desc
(
iface
->
altsetting
)
->
bInterfaceNumber
;
int
err
;
for
(
quirk
=
quirk
->
data
;
quirk
->
ifnum
>=
0
;
++
quirk
)
{
if
(
quirk
->
ifnum
>=
get_cfg_desc
(
config
)
->
bNumInterfaces
)
iface
=
usb_ifnum_to_if
(
chip
->
dev
,
quirk
->
ifnum
);
if
(
!
iface
)
continue
;
iface
=
get_iface
(
config
,
quirk
->
ifnum
);
if
(
quirk
->
ifnum
!=
probed_ifnum
&&
usb_interface_claimed
(
iface
))
continue
;
...
...
@@ -2706,9 +2829,6 @@ static void snd_usb_audio_create_proc(snd_usb_audio_t *chip)
static
int
snd_usb_audio_free
(
snd_usb_audio_t
*
chip
)
{
down
(
&
register_mutex
);
usb_chip
[
chip
->
index
]
=
NULL
;
up
(
&
register_mutex
);
snd_magic_kfree
(
chip
);
return
0
;
}
...
...
@@ -2723,10 +2843,11 @@ static int snd_usb_audio_dev_free(snd_device_t *device)
/*
* create a chip instance and set its names.
*/
static
int
snd_usb_audio_create
(
s
nd_card_t
*
card
,
struct
usb_device
*
dev
,
static
int
snd_usb_audio_create
(
s
truct
usb_device
*
dev
,
int
idx
,
const
snd_usb_audio_quirk_t
*
quirk
,
snd_usb_audio_t
**
rchip
)
{
snd_card_t
*
card
;
snd_usb_audio_t
*
chip
;
int
err
,
len
;
char
component
[
14
];
...
...
@@ -2735,10 +2856,26 @@ static int snd_usb_audio_create(snd_card_t *card, struct usb_device *dev,
};
*
rchip
=
NULL
;
if
(
snd_usb_get_speed
(
dev
)
!=
USB_SPEED_FULL
&&
snd_usb_get_speed
(
dev
)
!=
USB_SPEED_HIGH
)
{
snd_printk
(
KERN_ERR
"unknown device speed %d
\n
"
,
snd_usb_get_speed
(
dev
));
return
-
ENXIO
;
}
card
=
snd_card_new
(
index
[
idx
],
id
[
idx
],
THIS_MODULE
,
0
);
if
(
card
==
NULL
)
{
snd_printk
(
KERN_ERR
"cannot create card instance %d
\n
"
,
idx
);
return
-
ENOMEM
;
}
chip
=
snd_magic_kcalloc
(
snd_usb_audio_t
,
0
,
GFP_KERNEL
);
if
(
!
chip
)
if
(
!
chip
)
{
snd_card_free
(
card
);
return
-
ENOMEM
;
}
chip
->
index
=
idx
;
chip
->
dev
=
dev
;
chip
->
card
=
card
;
INIT_LIST_HEAD
(
&
chip
->
pcm_list
);
...
...
@@ -2746,6 +2883,7 @@ static int snd_usb_audio_create(snd_card_t *card, struct usb_device *dev,
if
((
err
=
snd_device_new
(
card
,
SNDRV_DEV_LOWLEVEL
,
chip
,
&
ops
))
<
0
)
{
snd_usb_audio_free
(
chip
);
snd_card_free
(
card
);
return
err
;
}
...
...
@@ -2788,6 +2926,10 @@ static int snd_usb_audio_create(snd_card_t *card, struct usb_device *dev,
if
(
len
<
sizeof
(
card
->
longname
))
usb_make_path
(
dev
,
card
->
longname
+
len
,
sizeof
(
card
->
longname
)
-
len
);
strlcat
(
card
->
longname
,
snd_usb_get_speed
(
dev
)
==
USB_SPEED_FULL
?
", full speed"
:
", high speed"
,
sizeof
(
card
->
longname
));
snd_usb_audio_create_proc
(
chip
);
snd_card_set_dev
(
card
,
&
dev
->
dev
);
...
...
@@ -2814,7 +2956,6 @@ static void *snd_usb_audio_probe(struct usb_device *dev,
struct
usb_host_config
*
config
=
dev
->
actconfig
;
const
snd_usb_audio_quirk_t
*
quirk
=
(
const
snd_usb_audio_quirk_t
*
)
usb_id
->
driver_info
;
int
i
,
err
;
snd_card_t
*
card
;
snd_usb_audio_t
*
chip
;
struct
usb_host_interface
*
alts
;
int
ifnum
;
...
...
@@ -2842,11 +2983,11 @@ static void *snd_usb_audio_probe(struct usb_device *dev,
down
(
&
register_mutex
);
for
(
i
=
0
;
i
<
SNDRV_CARDS
;
i
++
)
{
if
(
usb_chip
[
i
]
&&
usb_chip
[
i
]
->
dev
==
dev
)
{
chip
=
usb_chip
[
i
];
if
(
chip
->
shutdown
)
{
if
(
usb_chip
[
i
]
->
shutdown
)
{
snd_printk
(
KERN_ERR
"USB device is in the shutdown state, cannot create a card instance
\n
"
);
goto
__error
;
}
chip
=
usb_chip
[
i
];
break
;
}
}
...
...
@@ -2863,17 +3004,9 @@ static void *snd_usb_audio_probe(struct usb_device *dev,
if
(
enable
[
i
]
&&
!
usb_chip
[
i
]
&&
(
vid
[
i
]
==
-
1
||
vid
[
i
]
==
dev
->
descriptor
.
idVendor
)
&&
(
pid
[
i
]
==
-
1
||
pid
[
i
]
==
dev
->
descriptor
.
idProduct
))
{
card
=
snd_card_new
(
index
[
i
],
id
[
i
],
THIS_MODULE
,
0
);
if
(
card
==
NULL
)
{
snd_printk
(
KERN_ERR
"cannot create a card instance %d
\n
"
,
i
);
goto
__error
;
}
if
(
snd_usb_audio_create
(
card
,
dev
,
quirk
,
&
chip
)
<
0
)
{
snd_card_free
(
card
);
if
(
snd_usb_audio_create
(
dev
,
i
,
quirk
,
&
chip
)
<
0
)
{
goto
__error
;
}
chip
->
index
=
i
;
usb_chip
[
i
]
=
chip
;
break
;
}
if
(
!
chip
)
{
...
...
@@ -2899,16 +3032,17 @@ static void *snd_usb_audio_probe(struct usb_device *dev,
/* we are allowed to call snd_card_register() many times */
if
(
snd_card_register
(
chip
->
card
)
<
0
)
{
if
(
!
chip
->
num_interfaces
)
snd_card_free
(
chip
->
card
);
goto
__error
;
}
usb_chip
[
chip
->
index
]
=
chip
;
chip
->
num_interfaces
++
;
up
(
&
register_mutex
);
return
chip
;
__error:
if
(
chip
&&
!
chip
->
num_interfaces
)
snd_card_free
(
chip
->
card
);
up
(
&
register_mutex
);
__err_val:
return
NULL
;
...
...
@@ -2942,6 +3076,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr)
list_for_each
(
p
,
&
chip
->
midi_list
)
{
snd_usbmidi_disconnect
(
p
,
&
usb_audio_driver
);
}
usb_chip
[
chip
->
index
]
=
NULL
;
up
(
&
register_mutex
);
snd_card_free_in_thread
(
card
);
}
else
{
...
...
sound/usb/usbaudio.h
View file @
fe6a9c21
...
...
@@ -207,7 +207,6 @@ void snd_usbmidi_disconnect(struct list_head *p, struct usb_driver *driver);
* (conditional for compatibility with the older API)
*/
#ifndef get_iface_desc
#define get_iface(cfg, num) ((cfg)->interface[(num)])
#define get_iface_desc(iface) (&(iface)->desc)
#define get_endpoint(alt,ep) (&(alt)->endpoint[ep].desc)
#define get_ep_desc(ep) (&(ep)->desc)
...
...
@@ -222,4 +221,8 @@ void snd_usbmidi_disconnect(struct list_head *p, struct usb_driver *driver);
#define snd_usb_complete_callback(x) (x)
#endif
#ifndef snd_usb_get_speed
#define snd_usb_get_speed(dev) ((dev)->speed)
#endif
#endif
/* __USBAUDIO_H */
sound/usb/usbmidi.c
View file @
fe6a9c21
...
...
@@ -714,7 +714,6 @@ void snd_usbmidi_disconnect(struct list_head* p, struct usb_driver *driver)
if
(
ep
->
in
&&
ep
->
in
->
urb
)
usb_unlink_urb
(
ep
->
in
->
urb
);
}
usb_driver_release_interface
(
driver
,
umidi
->
iface
);
}
static
void
snd_usbmidi_rawmidi_free
(
snd_rawmidi_t
*
rmidi
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment