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
e799d0bc
Commit
e799d0bc
authored
Oct 11, 2010
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote branch 'alsa/devel' into topic/misc
parents
1d2019fb
838c364f
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
114 additions
and
22 deletions
+114
-22
sound/core/oss/mixer_oss.c
sound/core/oss/mixer_oss.c
+8
-4
sound/drivers/aloop.c
sound/drivers/aloop.c
+106
-18
No files found.
sound/core/oss/mixer_oss.c
View file @
e799d0bc
...
...
@@ -618,8 +618,10 @@ static void snd_mixer_oss_put_volume1_vol(struct snd_mixer_oss_file *fmixer,
if
(
numid
==
ID_UNKNOWN
)
return
;
down_read
(
&
card
->
controls_rwsem
);
if
((
kctl
=
snd_ctl_find_numid
(
card
,
numid
))
==
NULL
)
if
((
kctl
=
snd_ctl_find_numid
(
card
,
numid
))
==
NULL
)
{
up_read
(
&
card
->
controls_rwsem
);
return
;
}
uinfo
=
kzalloc
(
sizeof
(
*
uinfo
),
GFP_KERNEL
);
uctl
=
kzalloc
(
sizeof
(
*
uctl
),
GFP_KERNEL
);
if
(
uinfo
==
NULL
||
uctl
==
NULL
)
...
...
@@ -658,7 +660,7 @@ static void snd_mixer_oss_put_volume1_sw(struct snd_mixer_oss_file *fmixer,
return
;
down_read
(
&
card
->
controls_rwsem
);
if
((
kctl
=
snd_ctl_find_numid
(
card
,
numid
))
==
NULL
)
{
up_read
(
&
fmixer
->
card
->
controls_rwsem
);
up_read
(
&
card
->
controls_rwsem
);
return
;
}
uinfo
=
kzalloc
(
sizeof
(
*
uinfo
),
GFP_KERNEL
);
...
...
@@ -797,7 +799,7 @@ static int snd_mixer_oss_get_recsrc2(struct snd_mixer_oss_file *fmixer, unsigned
uctl
=
kzalloc
(
sizeof
(
*
uctl
),
GFP_KERNEL
);
if
(
uinfo
==
NULL
||
uctl
==
NULL
)
{
err
=
-
ENOMEM
;
goto
__
unlock
;
goto
__
free_only
;
}
down_read
(
&
card
->
controls_rwsem
);
kctl
=
snd_mixer_oss_test_id
(
mixer
,
"Capture Source"
,
0
);
...
...
@@ -826,6 +828,7 @@ static int snd_mixer_oss_get_recsrc2(struct snd_mixer_oss_file *fmixer, unsigned
err
=
0
;
__unlock:
up_read
(
&
card
->
controls_rwsem
);
__free_only:
kfree
(
uctl
);
kfree
(
uinfo
);
return
err
;
...
...
@@ -847,7 +850,7 @@ static int snd_mixer_oss_put_recsrc2(struct snd_mixer_oss_file *fmixer, unsigned
uctl
=
kzalloc
(
sizeof
(
*
uctl
),
GFP_KERNEL
);
if
(
uinfo
==
NULL
||
uctl
==
NULL
)
{
err
=
-
ENOMEM
;
goto
__
unlock
;
goto
__
free_only
;
}
down_read
(
&
card
->
controls_rwsem
);
kctl
=
snd_mixer_oss_test_id
(
mixer
,
"Capture Source"
,
0
);
...
...
@@ -880,6 +883,7 @@ static int snd_mixer_oss_put_recsrc2(struct snd_mixer_oss_file *fmixer, unsigned
err
=
0
;
__unlock:
up_read
(
&
card
->
controls_rwsem
);
__free_only:
kfree
(
uctl
);
kfree
(
uinfo
);
return
err
;
...
...
sound/drivers/aloop.c
View file @
e799d0bc
...
...
@@ -188,7 +188,7 @@ static inline void loopback_timer_stop(struct loopback_pcm *dpcm)
static
int
loopback_check_format
(
struct
loopback_cable
*
cable
,
int
stream
)
{
struct
snd_pcm_runtime
*
runtime
;
struct
snd_pcm_runtime
*
runtime
,
*
cruntime
;
struct
loopback_setup
*
setup
;
struct
snd_card
*
card
;
int
check
;
...
...
@@ -200,11 +200,11 @@ static int loopback_check_format(struct loopback_cable *cable, int stream)
}
runtime
=
cable
->
streams
[
SNDRV_PCM_STREAM_PLAYBACK
]
->
substream
->
runtime
;
c
heck
=
cable
->
hw
.
formats
!=
(
1ULL
<<
runtime
->
format
)
||
cable
->
hw
.
rate_min
!=
runtime
->
rate
||
cable
->
hw
.
rate_max
!=
runtime
->
rate
||
cable
->
hw
.
channels_min
!=
runtime
->
channels
||
cable
->
hw
.
channels_max
!=
runtime
->
channels
;
c
runtime
=
cable
->
streams
[
SNDRV_PCM_STREAM_CAPTURE
]
->
substream
->
runtime
;
check
=
runtime
->
format
!=
cruntime
->
format
||
runtime
->
rate
!=
cruntime
->
rate
||
runtime
->
channels
!=
c
runtime
->
channels
;
if
(
!
check
)
return
0
;
if
(
stream
==
SNDRV_PCM_STREAM_CAPTURE
)
{
...
...
@@ -274,12 +274,42 @@ static int loopback_trigger(struct snd_pcm_substream *substream, int cmd)
return
0
;
}
static
void
params_change_substream
(
struct
loopback_pcm
*
dpcm
,
struct
snd_pcm_runtime
*
runtime
)
{
struct
snd_pcm_runtime
*
dst_runtime
;
if
(
dpcm
==
NULL
||
dpcm
->
substream
==
NULL
)
return
;
dst_runtime
=
dpcm
->
substream
->
runtime
;
if
(
dst_runtime
==
NULL
)
return
;
dst_runtime
->
hw
=
dpcm
->
cable
->
hw
;
}
static
void
params_change
(
struct
snd_pcm_substream
*
substream
)
{
struct
snd_pcm_runtime
*
runtime
=
substream
->
runtime
;
struct
loopback_pcm
*
dpcm
=
runtime
->
private_data
;
struct
loopback_cable
*
cable
=
dpcm
->
cable
;
cable
->
hw
.
formats
=
(
1ULL
<<
runtime
->
format
);
cable
->
hw
.
rate_min
=
runtime
->
rate
;
cable
->
hw
.
rate_max
=
runtime
->
rate
;
cable
->
hw
.
channels_min
=
runtime
->
channels
;
cable
->
hw
.
channels_max
=
runtime
->
channels
;
params_change_substream
(
cable
->
streams
[
SNDRV_PCM_STREAM_PLAYBACK
],
runtime
);
params_change_substream
(
cable
->
streams
[
SNDRV_PCM_STREAM_CAPTURE
],
runtime
);
}
static
int
loopback_prepare
(
struct
snd_pcm_substream
*
substream
)
{
struct
snd_pcm_runtime
*
runtime
=
substream
->
runtime
;
struct
loopback_pcm
*
dpcm
=
runtime
->
private_data
;
struct
loopback_cable
*
cable
=
dpcm
->
cable
;
unsigned
int
bps
,
salign
;
int
bps
,
salign
;
salign
=
(
snd_pcm_format_width
(
runtime
->
format
)
*
runtime
->
channels
)
/
8
;
...
...
@@ -303,13 +333,10 @@ static int loopback_prepare(struct snd_pcm_substream *substream)
dpcm
->
pcm_period_size
=
frames_to_bytes
(
runtime
,
runtime
->
period_size
);
mutex_lock
(
&
dpcm
->
loopback
->
cable_lock
);
if
(
!
(
cable
->
valid
&
~
(
1
<<
substream
->
stream
)))
{
cable
->
hw
.
formats
=
(
1ULL
<<
runtime
->
format
);
cable
->
hw
.
rate_min
=
runtime
->
rate
;
cable
->
hw
.
rate_max
=
runtime
->
rate
;
cable
->
hw
.
channels_min
=
runtime
->
channels
;
cable
->
hw
.
channels_max
=
runtime
->
channels
;
}
if
(
!
(
cable
->
valid
&
~
(
1
<<
substream
->
stream
))
||
(
get_setup
(
dpcm
)
->
notify
&&
substream
->
stream
==
SNDRV_PCM_STREAM_PLAYBACK
))
params_change
(
substream
);
cable
->
valid
|=
1
<<
substream
->
stream
;
mutex_unlock
(
&
dpcm
->
loopback
->
cable_lock
);
...
...
@@ -542,6 +569,47 @@ static unsigned int get_cable_index(struct snd_pcm_substream *substream)
return
!
substream
->
stream
;
}
static
int
rule_format
(
struct
snd_pcm_hw_params
*
params
,
struct
snd_pcm_hw_rule
*
rule
)
{
struct
snd_pcm_hardware
*
hw
=
rule
->
private
;
struct
snd_mask
*
maskp
=
hw_param_mask
(
params
,
rule
->
var
);
maskp
->
bits
[
0
]
&=
(
u_int32_t
)
hw
->
formats
;
maskp
->
bits
[
1
]
&=
(
u_int32_t
)(
hw
->
formats
>>
32
);
memset
(
maskp
->
bits
+
2
,
0
,
(
SNDRV_MASK_MAX
-
64
)
/
8
);
/* clear rest */
if
(
!
maskp
->
bits
[
0
]
&&
!
maskp
->
bits
[
1
])
return
-
EINVAL
;
return
0
;
}
static
int
rule_rate
(
struct
snd_pcm_hw_params
*
params
,
struct
snd_pcm_hw_rule
*
rule
)
{
struct
snd_pcm_hardware
*
hw
=
rule
->
private
;
struct
snd_interval
t
;
t
.
min
=
hw
->
rate_min
;
t
.
max
=
hw
->
rate_max
;
t
.
openmin
=
t
.
openmax
=
0
;
t
.
integer
=
0
;
return
snd_interval_refine
(
hw_param_interval
(
params
,
rule
->
var
),
&
t
);
}
static
int
rule_channels
(
struct
snd_pcm_hw_params
*
params
,
struct
snd_pcm_hw_rule
*
rule
)
{
struct
snd_pcm_hardware
*
hw
=
rule
->
private
;
struct
snd_interval
t
;
t
.
min
=
hw
->
channels_min
;
t
.
max
=
hw
->
channels_max
;
t
.
openmin
=
t
.
openmax
=
0
;
t
.
integer
=
0
;
return
snd_interval_refine
(
hw_param_interval
(
params
,
rule
->
var
),
&
t
);
}
static
int
loopback_open
(
struct
snd_pcm_substream
*
substream
)
{
struct
snd_pcm_runtime
*
runtime
=
substream
->
runtime
;
...
...
@@ -579,14 +647,34 @@ static int loopback_open(struct snd_pcm_substream *substream)
snd_pcm_hw_constraint_integer
(
runtime
,
SNDRV_PCM_HW_PARAM_PERIODS
);
/* use dynamic rules based on actual runtime->hw values */
/* note that the default rules created in the PCM midlevel code */
/* are cached -> they do not reflect the actual state */
err
=
snd_pcm_hw_rule_add
(
runtime
,
0
,
SNDRV_PCM_HW_PARAM_FORMAT
,
rule_format
,
&
runtime
->
hw
,
SNDRV_PCM_HW_PARAM_FORMAT
,
-
1
);
if
(
err
<
0
)
goto
unlock
;
err
=
snd_pcm_hw_rule_add
(
runtime
,
0
,
SNDRV_PCM_HW_PARAM_RATE
,
rule_rate
,
&
runtime
->
hw
,
SNDRV_PCM_HW_PARAM_RATE
,
-
1
);
if
(
err
<
0
)
goto
unlock
;
err
=
snd_pcm_hw_rule_add
(
runtime
,
0
,
SNDRV_PCM_HW_PARAM_CHANNELS
,
rule_channels
,
&
runtime
->
hw
,
SNDRV_PCM_HW_PARAM_CHANNELS
,
-
1
);
if
(
err
<
0
)
goto
unlock
;
runtime
->
private_data
=
dpcm
;
runtime
->
private_free
=
loopback_runtime_free
;
if
(
get_notify
(
dpcm
)
&&
substream
->
stream
==
SNDRV_PCM_STREAM_PLAYBACK
)
{
if
(
get_notify
(
dpcm
))
runtime
->
hw
=
loopback_pcm_hardware
;
}
else
{
else
runtime
->
hw
=
cable
->
hw
;
}
unlock:
mutex_unlock
(
&
loopback
->
cable_lock
);
return
err
;
...
...
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