Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
a1916ff3
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
a1916ff3
编写于
1月 11, 2016
作者:
M
Mark Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'asoc/topic/pcm-list' into asoc-next
上级
2dd49f8e
f2ed6b07
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
180 addition
and
106 deletion
+180
-106
include/sound/soc-dai.h
include/sound/soc-dai.h
+1
-0
include/sound/soc.h
include/sound/soc.h
+9
-2
sound/soc/soc-core.c
sound/soc/soc-core.c
+170
-104
未找到文件。
include/sound/soc-dai.h
浏览文件 @
a1916ff3
...
...
@@ -222,6 +222,7 @@ struct snd_soc_dai_driver {
const
char
*
name
;
unsigned
int
id
;
unsigned
int
base
;
struct
snd_soc_dobj
dobj
;
/* DAI driver callbacks */
int
(
*
probe
)(
struct
snd_soc_dai
*
dai
);
...
...
include/sound/soc.h
浏览文件 @
a1916ff3
...
...
@@ -798,6 +798,7 @@ struct snd_soc_component {
unsigned
int
registered_as_component
:
1
;
struct
list_head
list
;
struct
list_head
list_aux
;
/* for auxiliary component of the card */
struct
snd_soc_dai_driver
*
dai_drv
;
int
num_dai
;
...
...
@@ -841,6 +842,9 @@ struct snd_soc_component {
int
(
*
probe
)(
struct
snd_soc_component
*
);
void
(
*
remove
)(
struct
snd_soc_component
*
);
/* machine specific init */
int
(
*
init
)(
struct
snd_soc_component
*
component
);
#ifdef CONFIG_DEBUG_FS
void
(
*
init_debugfs
)(
struct
snd_soc_component
*
component
);
const
char
*
debugfs_prefix
;
...
...
@@ -1141,8 +1145,7 @@ struct snd_soc_card {
*/
struct
snd_soc_aux_dev
*
aux_dev
;
int
num_aux_devs
;
struct
snd_soc_pcm_runtime
*
rtd_aux
;
int
num_aux_rtd
;
struct
list_head
aux_comp_list
;
const
struct
snd_kcontrol_new
*
controls
;
int
num_controls
;
...
...
@@ -1550,6 +1553,7 @@ static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card)
INIT_LIST_HEAD
(
&
card
->
widgets
);
INIT_LIST_HEAD
(
&
card
->
paths
);
INIT_LIST_HEAD
(
&
card
->
dapm_list
);
INIT_LIST_HEAD
(
&
card
->
aux_comp_list
);
}
static
inline
bool
snd_soc_volsw_is_stereo
(
struct
soc_mixer_control
*
mc
)
...
...
@@ -1676,6 +1680,9 @@ int snd_soc_add_dai_link(struct snd_soc_card *card,
void
snd_soc_remove_dai_link
(
struct
snd_soc_card
*
card
,
struct
snd_soc_dai_link
*
dai_link
);
int
snd_soc_register_dai
(
struct
snd_soc_component
*
component
,
struct
snd_soc_dai_driver
*
dai_drv
);
#include <sound/soc-dai.h>
#ifdef CONFIG_DEBUG_FS
...
...
sound/soc/soc-core.c
浏览文件 @
a1916ff3
...
...
@@ -1413,6 +1413,16 @@ static int soc_probe_component(struct snd_soc_card *card,
component
->
name
);
}
/* machine specific init */
if
(
component
->
init
)
{
ret
=
component
->
init
(
component
);
if
(
ret
<
0
)
{
dev_err
(
component
->
dev
,
"Failed to do machine specific init %d
\n
"
,
ret
);
goto
err_probe
;
}
}
if
(
component
->
controls
)
snd_soc_add_component_controls
(
component
,
component
->
controls
,
component
->
num_controls
);
...
...
@@ -1657,65 +1667,81 @@ static int soc_probe_link_dais(struct snd_soc_card *card,
static
int
soc_bind_aux_dev
(
struct
snd_soc_card
*
card
,
int
num
)
{
struct
snd_soc_pcm_runtime
*
rtd
=
&
card
->
rtd_aux
[
num
];
struct
snd_soc_aux_dev
*
aux_dev
=
&
card
->
aux_dev
[
num
];
const
char
*
name
=
aux_dev
->
codec_name
;
rtd
->
component
=
soc_find_component
(
aux_dev
->
codec_of_node
,
name
);
if
(
!
rtd
->
component
)
{
if
(
aux_dev
->
codec_of_node
)
name
=
of_node_full_name
(
aux_dev
->
codec_of_node
);
dev_err
(
card
->
dev
,
"ASoC: %s not registered
\n
"
,
name
);
return
-
EPROBE_DEFER
;
struct
snd_soc_component
*
component
;
const
char
*
name
;
struct
device_node
*
codec_of_node
;
if
(
aux_dev
->
codec_of_node
||
aux_dev
->
codec_name
)
{
/* codecs, usually analog devices */
name
=
aux_dev
->
codec_name
;
codec_of_node
=
aux_dev
->
codec_of_node
;
component
=
soc_find_component
(
codec_of_node
,
name
);
if
(
!
component
)
{
if
(
codec_of_node
)
name
=
of_node_full_name
(
codec_of_node
);
goto
err_defer
;
}
}
else
if
(
aux_dev
->
name
)
{
/* generic components */
name
=
aux_dev
->
name
;
component
=
soc_find_component
(
NULL
,
name
);
if
(
!
component
)
goto
err_defer
;
}
else
{
dev_err
(
card
->
dev
,
"ASoC: Invalid auxiliary device
\n
"
);
return
-
EINVAL
;
}
/*
* Some places still reference rtd->codec, so we have to keep that
* initialized if the component is a CODEC. Once all those references
* have been removed, this code can be removed as well.
*/
rtd
->
codec
=
rtd
->
component
->
codec
;
component
->
init
=
aux_dev
->
init
;
list_add
(
&
component
->
list_aux
,
&
card
->
aux_comp_list
);
return
0
;
err_defer:
dev_err
(
card
->
dev
,
"ASoC: %s not registered
\n
"
,
name
);
return
-
EPROBE_DEFER
;
}
static
int
soc_probe_aux_dev
(
struct
snd_soc_card
*
card
,
int
num
)
static
int
soc_probe_aux_dev
ices
(
struct
snd_soc_card
*
card
)
{
struct
snd_soc_
pcm_runtime
*
rtd
=
&
card
->
rtd_aux
[
num
]
;
struct
snd_soc_aux_dev
*
aux_dev
=
&
card
->
aux_dev
[
num
]
;
struct
snd_soc_
component
*
comp
;
int
order
;
int
ret
;
ret
=
soc_probe_component
(
card
,
rtd
->
component
);
if
(
ret
<
0
)
return
ret
;
/* do machine specific initialization */
if
(
aux_dev
->
init
)
{
ret
=
aux_dev
->
init
(
rtd
->
component
);
if
(
ret
<
0
)
{
dev_err
(
card
->
dev
,
"ASoC: failed to init %s: %d
\n
"
,
aux_dev
->
name
,
ret
);
return
ret
;
for
(
order
=
SND_SOC_COMP_ORDER_FIRST
;
order
<=
SND_SOC_COMP_ORDER_LAST
;
order
++
)
{
list_for_each_entry
(
comp
,
&
card
->
aux_comp_list
,
list_aux
)
{
if
(
comp
->
driver
->
probe_order
==
order
)
{
ret
=
soc_probe_component
(
card
,
comp
);
if
(
ret
<
0
)
{
dev_err
(
card
->
dev
,
"ASoC: failed to probe aux component %s %d
\n
"
,
comp
->
name
,
ret
);
return
ret
;
}
}
}
}
return
soc_post_component_init
(
rtd
,
aux_dev
->
name
)
;
return
0
;
}
static
void
soc_remove_aux_dev
(
struct
snd_soc_card
*
card
,
int
num
)
static
void
soc_remove_aux_dev
ices
(
struct
snd_soc_card
*
card
)
{
struct
snd_soc_
pcm_runtime
*
rtd
=
&
card
->
rtd_aux
[
num
]
;
struct
snd_soc_component
*
component
=
rtd
->
component
;
struct
snd_soc_
component
*
comp
,
*
_comp
;
int
order
;
/* unregister the rtd device */
if
(
rtd
->
dev_registered
)
{
device_unregister
(
rtd
->
dev
);
rtd
->
dev_registered
=
0
;
for
(
order
=
SND_SOC_COMP_ORDER_FIRST
;
order
<=
SND_SOC_COMP_ORDER_LAST
;
order
++
)
{
list_for_each_entry_safe
(
comp
,
_comp
,
&
card
->
aux_comp_list
,
list_aux
)
{
if
(
comp
->
driver
->
remove_order
==
order
)
{
soc_remove_component
(
comp
);
/* remove it from the card's aux_comp_list */
list_del
(
&
comp
->
list_aux
);
}
}
}
if
(
component
)
soc_remove_component
(
component
);
}
static
int
snd_soc_init_codec_cache
(
struct
snd_soc_codec
*
codec
)
...
...
@@ -1894,6 +1920,11 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
}
}
/* probe auxiliary components */
ret
=
soc_probe_aux_devices
(
card
);
if
(
ret
<
0
)
goto
probe_dai_err
;
/* Find new DAI links added during probing components and bind them.
* Components with topology may bring new DAIs and DAI links.
*/
...
...
@@ -1923,16 +1954,6 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
}
}
for
(
i
=
0
;
i
<
card
->
num_aux_devs
;
i
++
)
{
ret
=
soc_probe_aux_dev
(
card
,
i
);
if
(
ret
<
0
)
{
dev_err
(
card
->
dev
,
"ASoC: failed to add auxiliary devices %d
\n
"
,
ret
);
goto
probe_aux_dev_err
;
}
}
snd_soc_dapm_link_dai_widgets
(
card
);
snd_soc_dapm_connect_dai_link_widgets
(
card
);
...
...
@@ -1992,8 +2013,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
return
0
;
probe_aux_dev_err:
for
(
i
=
0
;
i
<
card
->
num_aux_devs
;
i
++
)
soc_remove_aux_dev
(
card
,
i
);
soc_remove_aux_devices
(
card
);
probe_dai_err:
soc_remove_dai_links
(
card
);
...
...
@@ -2039,20 +2059,18 @@ static int soc_probe(struct platform_device *pdev)
static
int
soc_cleanup_card_resources
(
struct
snd_soc_card
*
card
)
{
struct
snd_soc_pcm_runtime
*
rtd
;
int
i
;
/* make sure any delayed work runs */
list_for_each_entry
(
rtd
,
&
card
->
rtd_list
,
list
)
flush_delayed_work
(
&
rtd
->
delayed_work
);
/* remove auxiliary devices */
for
(
i
=
0
;
i
<
card
->
num_aux_devs
;
i
++
)
soc_remove_aux_dev
(
card
,
i
);
/* remove and free each DAI */
soc_remove_dai_links
(
card
);
soc_remove_pcm_runtimes
(
card
);
/* remove auxiliary devices */
soc_remove_aux_devices
(
card
);
soc_cleanup_card_debugfs
(
card
);
/* remove the card */
...
...
@@ -2608,16 +2626,6 @@ int snd_soc_register_card(struct snd_soc_card *card)
INIT_LIST_HEAD
(
&
card
->
rtd_list
);
card
->
num_rtd
=
0
;
card
->
rtd_aux
=
devm_kzalloc
(
card
->
dev
,
sizeof
(
struct
snd_soc_pcm_runtime
)
*
card
->
num_aux_devs
,
GFP_KERNEL
);
if
(
card
->
rtd_aux
==
NULL
)
return
-
ENOMEM
;
for
(
i
=
0
;
i
<
card
->
num_aux_devs
;
i
++
)
card
->
rtd_aux
[
i
].
card
=
card
;
INIT_LIST_HEAD
(
&
card
->
dapm_dirty
);
INIT_LIST_HEAD
(
&
card
->
dobj_list
);
card
->
instantiated
=
0
;
...
...
@@ -2744,6 +2752,56 @@ static void snd_soc_unregister_dais(struct snd_soc_component *component)
}
}
/* Create a DAI and add it to the component's DAI list */
static
struct
snd_soc_dai
*
soc_add_dai
(
struct
snd_soc_component
*
component
,
struct
snd_soc_dai_driver
*
dai_drv
,
bool
legacy_dai_naming
)
{
struct
device
*
dev
=
component
->
dev
;
struct
snd_soc_dai
*
dai
;
dev_dbg
(
dev
,
"ASoC: dynamically register DAI %s
\n
"
,
dev_name
(
dev
));
dai
=
kzalloc
(
sizeof
(
struct
snd_soc_dai
),
GFP_KERNEL
);
if
(
dai
==
NULL
)
return
NULL
;
/*
* Back in the old days when we still had component-less DAIs,
* instead of having a static name, component-less DAIs would
* inherit the name of the parent device so it is possible to
* register multiple instances of the DAI. We still need to keep
* the same naming style even though those DAIs are not
* component-less anymore.
*/
if
(
legacy_dai_naming
&&
(
dai_drv
->
id
==
0
||
dai_drv
->
name
==
NULL
))
{
dai
->
name
=
fmt_single_name
(
dev
,
&
dai
->
id
);
}
else
{
dai
->
name
=
fmt_multiple_name
(
dev
,
dai_drv
);
if
(
dai_drv
->
id
)
dai
->
id
=
dai_drv
->
id
;
else
dai
->
id
=
component
->
num_dai
;
}
if
(
dai
->
name
==
NULL
)
{
kfree
(
dai
);
return
NULL
;
}
dai
->
component
=
component
;
dai
->
dev
=
dev
;
dai
->
driver
=
dai_drv
;
if
(
!
dai
->
driver
->
ops
)
dai
->
driver
->
ops
=
&
null_dai_ops
;
list_add
(
&
dai
->
list
,
&
component
->
dai_list
);
component
->
num_dai
++
;
dev_dbg
(
dev
,
"ASoC: Registered DAI '%s'
\n
"
,
dai
->
name
);
return
dai
;
}
/**
* snd_soc_register_dais - Register a DAI with the ASoC core
*
...
...
@@ -2765,58 +2823,66 @@ static int snd_soc_register_dais(struct snd_soc_component *component,
dev_dbg
(
dev
,
"ASoC: dai register %s #%Zu
\n
"
,
dev_name
(
dev
),
count
);
component
->
dai_drv
=
dai_drv
;
component
->
num_dai
=
count
;
for
(
i
=
0
;
i
<
count
;
i
++
)
{
dai
=
kzalloc
(
sizeof
(
struct
snd_soc_dai
),
GFP_KERNEL
);
dai
=
soc_add_dai
(
component
,
dai_drv
+
i
,
count
==
1
&&
legacy_dai_naming
);
if
(
dai
==
NULL
)
{
ret
=
-
ENOMEM
;
goto
err
;
}
}
/*
* Back in the old days when we still had component-less DAIs,
* instead of having a static name, component-less DAIs would
* inherit the name of the parent device so it is possible to
* register multiple instances of the DAI. We still need to keep
* the same naming style even though those DAIs are not
* component-less anymore.
*/
if
(
count
==
1
&&
legacy_dai_naming
&&
(
dai_drv
[
i
].
id
==
0
||
dai_drv
[
i
].
name
==
NULL
))
{
dai
->
name
=
fmt_single_name
(
dev
,
&
dai
->
id
);
}
else
{
dai
->
name
=
fmt_multiple_name
(
dev
,
&
dai_drv
[
i
]);
if
(
dai_drv
[
i
].
id
)
dai
->
id
=
dai_drv
[
i
].
id
;
else
dai
->
id
=
i
;
}
if
(
dai
->
name
==
NULL
)
{
kfree
(
dai
);
ret
=
-
ENOMEM
;
goto
err
;
}
return
0
;
dai
->
component
=
component
;
dai
->
dev
=
dev
;
dai
->
driver
=
&
dai_drv
[
i
];
if
(
!
dai
->
driver
->
ops
)
dai
->
driver
->
ops
=
&
null_dai_ops
;
err:
snd_soc_unregister_dais
(
component
);
list_add
(
&
dai
->
list
,
&
component
->
dai_list
);
return
ret
;
}
dev_dbg
(
dev
,
"ASoC: Registered DAI '%s'
\n
"
,
dai
->
name
);
/**
* snd_soc_register_dai - Register a DAI dynamically & create its widgets
*
* @component: The component the DAIs are registered for
* @dai_drv: DAI driver to use for the DAI
*
* Topology can use this API to register DAIs when probing a component.
* These DAIs's widgets will be freed in the card cleanup and the DAIs
* will be freed in the component cleanup.
*/
int
snd_soc_register_dai
(
struct
snd_soc_component
*
component
,
struct
snd_soc_dai_driver
*
dai_drv
)
{
struct
snd_soc_dapm_context
*
dapm
=
snd_soc_component_get_dapm
(
component
);
struct
snd_soc_dai
*
dai
;
int
ret
;
if
(
dai_drv
->
dobj
.
type
!=
SND_SOC_DOBJ_PCM
)
{
dev_err
(
component
->
dev
,
"Invalid dai type %d
\n
"
,
dai_drv
->
dobj
.
type
);
return
-
EINVAL
;
}
return
0
;
lockdep_assert_held
(
&
client_mutex
);
dai
=
soc_add_dai
(
component
,
dai_drv
,
false
);
if
(
!
dai
)
return
-
ENOMEM
;
err:
snd_soc_unregister_dais
(
component
);
/* Create the DAI widgets here. After adding DAIs, topology may
* also add routes that need these widgets as source or sink.
*/
ret
=
snd_soc_dapm_new_dai_widgets
(
dapm
,
dai
);
if
(
ret
!=
0
)
{
dev_err
(
component
->
dev
,
"Failed to create DAI widgets %d
\n
"
,
ret
);
}
return
ret
;
}
EXPORT_SYMBOL_GPL
(
snd_soc_register_dai
);
static
void
snd_soc_component_seq_notifier
(
struct
snd_soc_dapm_context
*
dapm
,
enum
snd_soc_dapm_type
type
,
int
subseq
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录