Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
7b451962
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
161
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
7b451962
编写于
4月 12, 2013
作者:
M
Mark Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'asoc/topic/dapm' into asoc-next
上级
69976189
1059ecfa
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
171 addition
and
148 deletion
+171
-148
sound/soc/soc-dapm.c
sound/soc/soc-dapm.c
+171
-148
未找到文件。
sound/soc/soc-dapm.c
浏览文件 @
7b451962
...
...
@@ -504,17 +504,27 @@ static int dapm_is_shared_kcontrol(struct snd_soc_dapm_context *dapm,
return
0
;
}
/* create new dapm mixer control */
static
int
dapm_new_mixer
(
struct
snd_soc_dapm_widget
*
w
)
/*
* Determine if a kcontrol is shared. If it is, look it up. If it isn't,
* create it. Either way, add the widget into the control's widget list
*/
static
int
dapm_create_or_share_mixmux_kcontrol
(
struct
snd_soc_dapm_widget
*
w
,
int
kci
,
struct
snd_soc_dapm_path
*
path
)
{
struct
snd_soc_dapm_context
*
dapm
=
w
->
dapm
;
int
i
,
ret
=
0
;
size_t
name_len
,
prefix_len
;
struct
snd_soc_dapm_path
*
path
;
struct
snd_card
*
card
=
dapm
->
card
->
snd_card
;
const
char
*
prefix
;
size_t
prefix_len
;
int
shared
;
struct
snd_kcontrol
*
kcontrol
;
struct
snd_soc_dapm_widget_list
*
wlist
;
int
wlistentries
;
size_t
wlistsize
;
bool
wname_in_long_name
,
kcname_in_long_name
;
size_t
name_len
;
char
*
long_name
;
const
char
*
name
;
int
ret
;
if
(
dapm
->
codec
)
prefix
=
dapm
->
codec
->
name_prefix
;
...
...
@@ -526,103 +536,141 @@ static int dapm_new_mixer(struct snd_soc_dapm_widget *w)
else
prefix_len
=
0
;
/* add kcontrol */
for
(
i
=
0
;
i
<
w
->
num_kcontrols
;
i
++
)
{
shared
=
dapm_is_shared_kcontrol
(
dapm
,
w
,
&
w
->
kcontrol_news
[
kci
],
&
kcontrol
);
/* match name */
list_for_each_entry
(
path
,
&
w
->
sources
,
list_sink
)
{
if
(
kcontrol
)
{
wlist
=
kcontrol
->
private_data
;
wlistentries
=
wlist
->
num_widgets
+
1
;
}
else
{
wlist
=
NULL
;
wlistentries
=
1
;
}
/* mixer/mux paths name must match control name */
if
(
path
->
name
!=
(
char
*
)
w
->
kcontrol_news
[
i
].
name
)
continue
;
wlistsize
=
sizeof
(
struct
snd_soc_dapm_widget_list
)
+
wlistentries
*
sizeof
(
struct
snd_soc_dapm_widget
*
);
wlist
=
krealloc
(
wlist
,
wlistsize
,
GFP_KERNEL
);
if
(
wlist
==
NULL
)
{
dev_err
(
dapm
->
dev
,
"ASoC: can't allocate widget list for %s
\n
"
,
w
->
name
);
return
-
ENOMEM
;
}
wlist
->
num_widgets
=
wlistentries
;
wlist
->
widgets
[
wlistentries
-
1
]
=
w
;
if
(
w
->
kcontrols
[
i
])
{
path
->
kcontrol
=
w
->
kcontrols
[
i
];
continue
;
if
(
!
kcontrol
)
{
if
(
shared
)
{
wname_in_long_name
=
false
;
kcname_in_long_name
=
true
;
}
else
{
switch
(
w
->
id
)
{
case
snd_soc_dapm_switch
:
case
snd_soc_dapm_mixer
:
wname_in_long_name
=
true
;
kcname_in_long_name
=
true
;
break
;
case
snd_soc_dapm_mixer_named_ctl
:
wname_in_long_name
=
false
;
kcname_in_long_name
=
true
;
break
;
case
snd_soc_dapm_mux
:
case
snd_soc_dapm_virt_mux
:
case
snd_soc_dapm_value_mux
:
wname_in_long_name
=
true
;
kcname_in_long_name
=
false
;
break
;
default:
kfree
(
wlist
);
return
-
EINVAL
;
}
}
if
(
wname_in_long_name
&&
kcname_in_long_name
)
{
name_len
=
strlen
(
w
->
name
)
-
prefix_len
+
1
+
strlen
(
w
->
kcontrol_news
[
kci
].
name
)
+
1
;
wlistsize
=
sizeof
(
struct
snd_soc_dapm_widget_list
)
+
sizeof
(
struct
snd_soc_dapm_widget
*
),
wlist
=
kzalloc
(
wlistsize
,
GFP_KERNEL
);
if
(
wlist
==
NULL
)
{
dev_err
(
dapm
->
dev
,
"ASoC: can't allocate widget list for %s
\n
"
,
w
->
name
);
long_name
=
kmalloc
(
name_len
,
GFP_KERNEL
);
if
(
long_name
==
NULL
)
{
kfree
(
wlist
);
return
-
ENOMEM
;
}
wlist
->
num_widgets
=
1
;
wlist
->
widgets
[
0
]
=
w
;
/* add dapm control with long name.
* for dapm_mixer this is the concatenation of the
* mixer and kcontrol name.
* for dapm_mixer_named_ctl this is simply the
* kcontrol name.
/*
* The control will get a prefix from the control
* creation process but we're also using the same
* prefix for widgets so cut the prefix off the
* front of the widget name.
*/
name_len
=
strlen
(
w
->
kcontrol_news
[
i
].
name
)
+
1
;
if
(
w
->
id
!=
snd_soc_dapm_mixer_named_ctl
)
name_len
+=
1
+
strlen
(
w
->
name
);
snprintf
(
long_name
,
name_len
,
"%s %s"
,
w
->
name
+
prefix_len
,
w
->
kcontrol_news
[
kci
].
name
);
long_name
[
name_len
-
1
]
=
'\0'
;
name
=
long_name
;
}
else
if
(
wname_in_long_name
)
{
long_name
=
NULL
;
name
=
w
->
name
+
prefix_len
;
}
else
{
long_name
=
NULL
;
name
=
w
->
kcontrol_news
[
kci
].
name
;
}
path
->
long_name
=
kmalloc
(
name_len
,
GFP_KERNEL
);
kcontrol
=
snd_soc_cnew
(
&
w
->
kcontrol_news
[
kci
],
wlist
,
name
,
prefix
);
ret
=
snd_ctl_add
(
card
,
kcontrol
);
if
(
ret
<
0
)
{
dev_err
(
dapm
->
dev
,
"ASoC: failed to add widget %s dapm kcontrol %s: %d
\n
"
,
w
->
name
,
name
,
ret
);
kfree
(
wlist
);
kfree
(
long_name
);
return
ret
;
}
if
(
path
->
long_name
==
NULL
)
{
kfree
(
wlist
);
return
-
ENOMEM
;
}
path
->
long_name
=
long_name
;
}
switch
(
w
->
id
)
{
default:
/* The control will get a prefix from
* the control creation process but
* we're also using the same prefix
* for widgets so cut the prefix off
* the front of the widget name.
*/
snprintf
((
char
*
)
path
->
long_name
,
name_len
,
"%s %s"
,
w
->
name
+
prefix_len
,
w
->
kcontrol_news
[
i
].
name
);
break
;
case
snd_soc_dapm_mixer_named_ctl
:
snprintf
((
char
*
)
path
->
long_name
,
name_len
,
"%s"
,
w
->
kcontrol_news
[
i
].
name
);
break
;
}
kcontrol
->
private_data
=
wlist
;
w
->
kcontrols
[
kci
]
=
kcontrol
;
path
->
kcontrol
=
kcontrol
;
((
char
*
)
path
->
long_name
)[
name_len
-
1
]
=
'\0'
;
return
0
;
}
path
->
kcontrol
=
snd_soc_cnew
(
&
w
->
kcontrol_news
[
i
],
wlist
,
path
->
long_name
,
prefix
);
ret
=
snd_ctl_add
(
card
,
path
->
kcontrol
);
if
(
ret
<
0
)
{
dev_err
(
dapm
->
dev
,
"ASoC: failed to add widget"
" %s dapm kcontrol %s: %d
\n
"
,
w
->
name
,
path
->
long_name
,
ret
);
kfree
(
wlist
);
kfree
(
path
->
long_name
);
path
->
long_name
=
NULL
;
return
ret
;
/* create new dapm mixer control */
static
int
dapm_new_mixer
(
struct
snd_soc_dapm_widget
*
w
)
{
int
i
,
ret
;
struct
snd_soc_dapm_path
*
path
;
/* add kcontrol */
for
(
i
=
0
;
i
<
w
->
num_kcontrols
;
i
++
)
{
/* match name */
list_for_each_entry
(
path
,
&
w
->
sources
,
list_sink
)
{
/* mixer/mux paths name must match control name */
if
(
path
->
name
!=
(
char
*
)
w
->
kcontrol_news
[
i
].
name
)
continue
;
if
(
w
->
kcontrols
[
i
])
{
path
->
kcontrol
=
w
->
kcontrols
[
i
];
continue
;
}
w
->
kcontrols
[
i
]
=
path
->
kcontrol
;
ret
=
dapm_create_or_share_mixmux_kcontrol
(
w
,
i
,
path
);
if
(
ret
<
0
)
return
ret
;
}
}
return
ret
;
return
0
;
}
/* create new dapm mux control */
static
int
dapm_new_mux
(
struct
snd_soc_dapm_widget
*
w
)
{
struct
snd_soc_dapm_context
*
dapm
=
w
->
dapm
;
struct
snd_soc_dapm_path
*
path
=
NULL
;
struct
snd_kcontrol
*
kcontrol
;
struct
snd_card
*
card
=
dapm
->
card
->
snd_card
;
const
char
*
prefix
;
size_t
prefix_len
;
struct
snd_soc_dapm_path
*
path
;
int
ret
;
struct
snd_soc_dapm_widget_list
*
wlist
;
int
shared
,
wlistentries
;
size_t
wlistsize
;
const
char
*
name
;
if
(
w
->
num_kcontrols
!=
1
)
{
dev_err
(
dapm
->
dev
,
...
...
@@ -631,65 +679,19 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w)
return
-
EINVAL
;
}
shared
=
dapm_is_shared_kcontrol
(
dapm
,
w
,
&
w
->
kcontrol_news
[
0
],
&
kcontrol
);
if
(
kcontrol
)
{
wlist
=
kcontrol
->
private_data
;
wlistentries
=
wlist
->
num_widgets
+
1
;
}
else
{
wlist
=
NULL
;
wlistentries
=
1
;
}
wlistsize
=
sizeof
(
struct
snd_soc_dapm_widget_list
)
+
wlistentries
*
sizeof
(
struct
snd_soc_dapm_widget
*
),
wlist
=
krealloc
(
wlist
,
wlistsize
,
GFP_KERNEL
);
if
(
wlist
==
NULL
)
{
dev_err
(
dapm
->
dev
,
"ASoC: can't allocate widget list for %s
\n
"
,
w
->
name
);
return
-
ENOMEM
;
}
wlist
->
num_widgets
=
wlistentries
;
wlist
->
widgets
[
wlistentries
-
1
]
=
w
;
if
(
!
kcontrol
)
{
if
(
dapm
->
codec
)
prefix
=
dapm
->
codec
->
name_prefix
;
else
prefix
=
NULL
;
if
(
shared
)
{
name
=
w
->
kcontrol_news
[
0
].
name
;
prefix_len
=
0
;
}
else
{
name
=
w
->
name
;
if
(
prefix
)
prefix_len
=
strlen
(
prefix
)
+
1
;
else
prefix_len
=
0
;
}
/*
* The control will get a prefix from the control creation
* process but we're also using the same prefix for widgets so
* cut the prefix off the front of the widget name.
*/
kcontrol
=
snd_soc_cnew
(
&
w
->
kcontrol_news
[
0
],
wlist
,
name
+
prefix_len
,
prefix
);
ret
=
snd_ctl_add
(
card
,
kcontrol
);
if
(
ret
<
0
)
{
dev_err
(
dapm
->
dev
,
"ASoC: failed to add kcontrol %s: %d
\n
"
,
w
->
name
,
ret
);
kfree
(
wlist
);
return
ret
;
}
path
=
list_first_entry
(
&
w
->
sources
,
struct
snd_soc_dapm_path
,
list_sink
);
if
(
!
path
)
{
dev_err
(
dapm
->
dev
,
"ASoC: mux %s has no paths
\n
"
,
w
->
name
);
return
-
EINVAL
;
}
kcontrol
->
private_data
=
wlist
;
w
->
kcontrols
[
0
]
=
kcontrol
;
ret
=
dapm_create_or_share_mixmux_kcontrol
(
w
,
0
,
path
)
;
if
(
ret
<
0
)
return
ret
;
list_for_each_entry
(
path
,
&
w
->
sources
,
list_sink
)
path
->
kcontrol
=
kcontrol
;
path
->
kcontrol
=
w
->
kcontrols
[
0
]
;
return
0
;
}
...
...
@@ -705,14 +707,33 @@ static int dapm_new_pga(struct snd_soc_dapm_widget *w)
}
/* reset 'walked' bit for each dapm path */
static
inline
void
dapm_clear_walk
(
struct
snd_soc_dapm_context
*
dapm
)
static
void
dapm_clear_walk_output
(
struct
snd_soc_dapm_context
*
dapm
,
struct
list_head
*
sink
)
{
struct
snd_soc_dapm_path
*
p
;
list_for_each_entry
(
p
,
&
dapm
->
card
->
paths
,
list
)
p
->
walked
=
0
;
list_for_each_entry
(
p
,
sink
,
list_source
)
{
if
(
p
->
walked
)
{
p
->
walked
=
0
;
dapm_clear_walk_output
(
dapm
,
&
p
->
sink
->
sinks
);
}
}
}
static
void
dapm_clear_walk_input
(
struct
snd_soc_dapm_context
*
dapm
,
struct
list_head
*
source
)
{
struct
snd_soc_dapm_path
*
p
;
list_for_each_entry
(
p
,
source
,
list_sink
)
{
if
(
p
->
walked
)
{
p
->
walked
=
0
;
dapm_clear_walk_input
(
dapm
,
&
p
->
source
->
sources
);
}
}
}
/* We implement power down on suspend by checking the power state of
* the ALSA card - when we are suspending the ALSA state for the card
* is set to D3.
...
...
@@ -995,13 +1016,17 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
mutex_lock_nested
(
&
card
->
dapm_mutex
,
SND_SOC_DAPM_CLASS_RUNTIME
);
dapm_reset
(
card
);
if
(
stream
==
SNDRV_PCM_STREAM_PLAYBACK
)
if
(
stream
==
SNDRV_PCM_STREAM_PLAYBACK
)
{
paths
=
is_connected_output_ep
(
dai
->
playback_widget
,
list
);
else
dapm_clear_walk_output
(
&
card
->
dapm
,
&
dai
->
playback_widget
->
sinks
);
}
else
{
paths
=
is_connected_input_ep
(
dai
->
capture_widget
,
list
);
dapm_clear_walk_input
(
&
card
->
dapm
,
&
dai
->
capture_widget
->
sources
);
}
trace_snd_soc_dapm_connected
(
paths
,
stream
);
dapm_clear_walk
(
&
card
->
dapm
);
mutex_unlock
(
&
card
->
dapm_mutex
);
return
paths
;
...
...
@@ -1104,9 +1129,9 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
DAPM_UPDATE_STAT
(
w
,
power_checks
);
in
=
is_connected_input_ep
(
w
,
NULL
);
dapm_clear_walk
(
w
->
dapm
);
dapm_clear_walk
_input
(
w
->
dapm
,
&
w
->
sources
);
out
=
is_connected_output_ep
(
w
,
NULL
);
dapm_clear_walk
(
w
->
dapm
);
dapm_clear_walk
_output
(
w
->
dapm
,
&
w
->
sinks
);
return
out
!=
0
&&
in
!=
0
;
}
...
...
@@ -1129,7 +1154,7 @@ static int dapm_adc_check_power(struct snd_soc_dapm_widget *w)
if
(
w
->
active
)
{
in
=
is_connected_input_ep
(
w
,
NULL
);
dapm_clear_walk
(
w
->
dapm
);
dapm_clear_walk
_input
(
w
->
dapm
,
&
w
->
sources
);
return
in
!=
0
;
}
else
{
return
dapm_generic_check_power
(
w
);
...
...
@@ -1145,7 +1170,7 @@ static int dapm_dac_check_power(struct snd_soc_dapm_widget *w)
if
(
w
->
active
)
{
out
=
is_connected_output_ep
(
w
,
NULL
);
dapm_clear_walk
(
w
->
dapm
);
dapm_clear_walk
_output
(
w
->
dapm
,
&
w
->
sinks
);
return
out
!=
0
;
}
else
{
return
dapm_generic_check_power
(
w
);
...
...
@@ -1177,8 +1202,6 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
return
1
;
}
dapm_clear_walk
(
w
->
dapm
);
return
0
;
}
...
...
@@ -1759,9 +1782,9 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
return
-
ENOMEM
;
in
=
is_connected_input_ep
(
w
,
NULL
);
dapm_clear_walk
(
w
->
dapm
);
dapm_clear_walk
_input
(
w
->
dapm
,
&
w
->
sources
);
out
=
is_connected_output_ep
(
w
,
NULL
);
dapm_clear_walk
(
w
->
dapm
);
dapm_clear_walk
_output
(
w
->
dapm
,
&
w
->
sinks
);
ret
=
snprintf
(
buf
,
PAGE_SIZE
,
"%s: %s%s in %d out %d"
,
w
->
name
,
w
->
power
?
"On"
:
"Off"
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录