Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
81af7261
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看板
提交
81af7261
编写于
9月 29, 2016
作者:
M
Mark Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'asoc/topic/rcar' into asoc-next
上级
60955521
4b9c75ea
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
682 addition
and
161 deletion
+682
-161
Documentation/devicetree/bindings/sound/simple-scu-card.txt
Documentation/devicetree/bindings/sound/simple-scu-card.txt
+110
-0
include/sound/simple_card_utils.h
include/sound/simple_card_utils.h
+34
-0
sound/soc/generic/Kconfig
sound/soc/generic/Kconfig
+8
-0
sound/soc/generic/Makefile
sound/soc/generic/Makefile
+2
-0
sound/soc/generic/simple-card-utils.c
sound/soc/generic/simple-card-utils.c
+141
-0
sound/soc/generic/simple-card.c
sound/soc/generic/simple-card.c
+38
-152
sound/soc/generic/simple-scu-card.c
sound/soc/generic/simple-scu-card.c
+345
-0
sound/soc/sh/Kconfig
sound/soc/sh/Kconfig
+0
-6
sound/soc/sh/rcar/Makefile
sound/soc/sh/rcar/Makefile
+0
-3
sound/soc/sh/rcar/core.c
sound/soc/sh/rcar/core.c
+4
-0
未找到文件。
Documentation/devicetree/bindings/sound/
renesas,rsrc
-card.txt
→
Documentation/devicetree/bindings/sound/
simple-scu
-card.txt
浏览文件 @
81af7261
Renesas Sampling Rate Convert Sound Card:
ASoC simple SCU Sound Card
Renesas Sampling Rate Convert Sound
Card specifies audio DAI connections of SoC <-> codec.
Simple-
Card specifies audio DAI connections of SoC <-> codec.
Required properties:
Required properties:
- compatible : "renesas,rsrc-card{,<board>}"
- compatible : "simple-scu-audio-card"
Examples with boards are:
"renesas,rsrc-card"
- "renesas,rsrc-card"
- "renesas,rsrc-card,lager"
- "renesas,rsrc-card,koelsch"
Optional properties:
Optional properties:
-
card_name
: User specified audio sound card name, one string
-
simple-audio-card,name
: User specified audio sound card name, one string
property.
property.
-
cpu
: CPU sub-node
-
simple-audio-card,cpu
: CPU sub-node
-
codec
: CODEC sub-node
-
simple-audio-card,codec
: CODEC sub-node
Optional subnode properties:
Optional subnode properties:
-
format
: CPU/CODEC common audio format.
-
simple-audio-card,format
: CPU/CODEC common audio format.
"i2s", "right_j", "left_j" , "dsp_a"
"i2s", "right_j", "left_j" , "dsp_a"
"dsp_b", "ac97", "pdm", "msb", "lsb"
"dsp_b", "ac97", "pdm", "msb", "lsb"
-
frame-master
: Indicates dai-link frame master.
-
simple-audio-card,frame-master
: Indicates dai-link frame master.
phandle to a cpu or codec subnode.
phandle to a cpu or codec subnode.
-
bitclock-master
: Indicates dai-link bit clock master.
-
simple-audio-card,bitclock-master
: Indicates dai-link bit clock master.
phandle to a cpu or codec subnode.
phandle to a cpu or codec subnode.
-
bitclock-inversion
: bool property. Add this if the
-
simple-audio-card,bitclock-inversion
: bool property. Add this if the
dai-link uses bit clock inversion.
dai-link uses bit clock inversion.
-
frame-inversion
: bool property. Add this if the
-
simple-audio-card,frame-inversion
: bool property. Add this if the
dai-link uses frame clock inversion.
dai-link uses frame clock inversion.
-
convert-rate
: platform specified sampling rate convert
-
simple-audio-card,convert-rate
: platform specified sampling rate convert
-
convert-channels
: platform specified converted channel size (2 - 8 ch)
-
simple-audio-card,convert-channels
: platform specified converted channel size (2 - 8 ch)
-
audio-prefix
: see audio-routing
-
simple-audio-card,prefix
: see audio-routing
-
audio-routing
: A list of the connections between audio components.
-
simple-audio-card,routing
: A list of the connections between audio components.
Each entry is a pair of strings, the first being the connection's sink,
Each entry is a pair of strings, the first being the connection's sink,
the second being the connection's source. Valid names for sources.
the second being the connection's source. Valid names for sources.
use audio-prefix if some components is using same sink/sources naming.
use audio-prefix if some components is using same sink/sources naming.
...
@@ -54,22 +52,59 @@ Optional CPU/CODEC subnodes properties:
...
@@ -54,22 +52,59 @@ Optional CPU/CODEC subnodes properties:
clk_disable_unprepare() in dai
clk_disable_unprepare() in dai
shutdown().
shutdown().
Example
Example
1. Sampling Rate Covert
sound {
sound {
compatible = "
renesas,rsrc-card,lager
";
compatible = "
simple-scu-audio-card
";
card-name = "rsnd-ak4643";
simple-audio-card,name = "rsnd-ak4643";
format = "left_j";
simple-audio-card,format = "left_j";
bitclock-master = <&sndcodec>;
simple-audio-card,format = "left_j";
frame-master = <&sndcodec>;
simple-audio-card,bitclock-master = <&sndcodec>;
simple-audio-card,frame-master = <&sndcodec>;
sndcpu: cpu {
simple-audio-card,convert-rate = <48000>; /* see audio_clk_a */
simple-audio-card,prefix = "ak4642";
simple-audio-card,routing = "ak4642 Playback", "DAI0 Playback",
"DAI0 Capture", "ak4642 Capture";
sndcpu: simple-audio-card,cpu {
sound-dai = <&rcar_sound>;
sound-dai = <&rcar_sound>;
};
};
sndcodec: codec {
sndcodec:
simple-audio-card,
codec {
sound-dai = <&ak4643>;
sound-dai = <&ak4643>;
system-clock-frequency = <11289600>;
system-clock-frequency = <11289600>;
};
};
};
};
Example 2. 2 CPU 1 Codec
sound {
compatible = "renesas,rsrc-card";
card-name = "rsnd-ak4643";
format = "left_j";
bitclock-master = <&dpcmcpu>;
frame-master = <&dpcmcpu>;
convert-rate = <48000>; /* see audio_clk_a */
audio-prefix = "ak4642";
audio-routing = "ak4642 Playback", "DAI0 Playback",
"ak4642 Playback", "DAI1 Playback";
dpcmcpu: cpu@0 {
sound-dai = <&rcar_sound 0>;
};
cpu@1 {
sound-dai = <&rcar_sound 1>;
};
codec {
sound-dai = <&ak4643>;
clocks = <&audio_clock>;
};
};
include/sound/simple_card_utils.h
浏览文件 @
81af7261
...
@@ -33,4 +33,38 @@ int asoc_simple_card_set_dailink_name(struct device *dev,
...
@@ -33,4 +33,38 @@ int asoc_simple_card_set_dailink_name(struct device *dev,
int
asoc_simple_card_parse_card_name
(
struct
snd_soc_card
*
card
,
int
asoc_simple_card_parse_card_name
(
struct
snd_soc_card
*
card
,
char
*
prefix
);
char
*
prefix
);
#define asoc_simple_card_parse_clk_cpu(node, dai_link, simple_dai) \
asoc_simple_card_parse_clk(node, dai_link->cpu_of_node, simple_dai)
#define asoc_simple_card_parse_clk_codec(node, dai_link, simple_dai) \
asoc_simple_card_parse_clk(node, dai_link->codec_of_node, simple_dai)
int
asoc_simple_card_parse_clk
(
struct
device_node
*
node
,
struct
device_node
*
dai_of_node
,
struct
asoc_simple_dai
*
simple_dai
);
#define asoc_simple_card_parse_cpu(node, dai_link, \
list_name, cells_name, is_single_link) \
asoc_simple_card_parse_dai(node, &dai_link->cpu_of_node, \
&dai_link->cpu_dai_name, list_name, cells_name, is_single_link)
#define asoc_simple_card_parse_codec(node, dai_link, list_name, cells_name) \
asoc_simple_card_parse_dai(node, &dai_link->codec_of_node, \
&dai_link->codec_dai_name, list_name, cells_name, NULL)
#define asoc_simple_card_parse_platform(node, dai_link, list_name, cells_name) \
asoc_simple_card_parse_dai(node, &dai_link->platform_of_node, \
NULL, list_name, cells_name, NULL)
int
asoc_simple_card_parse_dai
(
struct
device_node
*
node
,
struct
device_node
**
endpoint_np
,
const
char
**
dai_name
,
const
char
*
list_name
,
const
char
*
cells_name
,
int
*
is_single_links
);
int
asoc_simple_card_init_dai
(
struct
snd_soc_dai
*
dai
,
struct
asoc_simple_dai
*
simple_dai
);
int
asoc_simple_card_canonicalize_dailink
(
struct
snd_soc_dai_link
*
dai_link
);
void
asoc_simple_card_canonicalize_cpu
(
struct
snd_soc_dai_link
*
dai_link
,
int
is_single_links
);
int
asoc_simple_card_clean_reference
(
struct
snd_soc_card
*
card
);
#endif
/* __SIMPLE_CARD_CORE_H */
#endif
/* __SIMPLE_CARD_CORE_H */
sound/soc/generic/Kconfig
浏览文件 @
81af7261
...
@@ -6,3 +6,11 @@ config SND_SIMPLE_CARD
...
@@ -6,3 +6,11 @@ config SND_SIMPLE_CARD
select SND_SIMPLE_CARD_UTILS
select SND_SIMPLE_CARD_UTILS
help
help
This option enables generic simple sound card support
This option enables generic simple sound card support
config SND_SIMPLE_SCU_CARD
tristate "ASoC Simple SCU sound card support"
depends on OF
select SND_SIMPLE_CARD_UTILS
help
This option enables generic simple SCU sound card support.
It supports DPCM of multi CPU single Codec system.
sound/soc/generic/Makefile
浏览文件 @
81af7261
snd-soc-simple-card-utils-objs
:=
simple-card-utils.o
snd-soc-simple-card-utils-objs
:=
simple-card-utils.o
snd-soc-simple-card-objs
:=
simple-card.o
snd-soc-simple-card-objs
:=
simple-card.o
snd-soc-simple-scu-card-objs
:=
simple-scu-card.o
obj-$(CONFIG_SND_SIMPLE_CARD_UTILS)
+=
snd-soc-simple-card-utils.o
obj-$(CONFIG_SND_SIMPLE_CARD_UTILS)
+=
snd-soc-simple-card-utils.o
obj-$(CONFIG_SND_SIMPLE_CARD)
+=
snd-soc-simple-card.o
obj-$(CONFIG_SND_SIMPLE_CARD)
+=
snd-soc-simple-card.o
obj-$(CONFIG_SND_SIMPLE_SCU_CARD)
+=
snd-soc-simple-scu-card.o
sound/soc/generic/simple-card-utils.c
浏览文件 @
81af7261
...
@@ -7,6 +7,7 @@
...
@@ -7,6 +7,7 @@
* it under the terms of the GNU General Public License version 2 as
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
* published by the Free Software Foundation.
*/
*/
#include <linux/clk.h>
#include <linux/module.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of.h>
#include <sound/simple_card_utils.h>
#include <sound/simple_card_utils.h>
...
@@ -97,6 +98,146 @@ int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
...
@@ -97,6 +98,146 @@ int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
}
}
EXPORT_SYMBOL_GPL
(
asoc_simple_card_parse_card_name
);
EXPORT_SYMBOL_GPL
(
asoc_simple_card_parse_card_name
);
int
asoc_simple_card_parse_clk
(
struct
device_node
*
node
,
struct
device_node
*
dai_of_node
,
struct
asoc_simple_dai
*
simple_dai
)
{
struct
clk
*
clk
;
u32
val
;
/*
* Parse dai->sysclk come from "clocks = <&xxx>"
* (if system has common clock)
* or "system-clock-frequency = <xxx>"
* or device's module clock.
*/
clk
=
of_clk_get
(
node
,
0
);
if
(
!
IS_ERR
(
clk
))
{
simple_dai
->
sysclk
=
clk_get_rate
(
clk
);
simple_dai
->
clk
=
clk
;
}
else
if
(
!
of_property_read_u32
(
node
,
"system-clock-frequency"
,
&
val
))
{
simple_dai
->
sysclk
=
val
;
}
else
{
clk
=
of_clk_get
(
dai_of_node
,
0
);
if
(
!
IS_ERR
(
clk
))
simple_dai
->
sysclk
=
clk_get_rate
(
clk
);
}
return
0
;
}
EXPORT_SYMBOL_GPL
(
asoc_simple_card_parse_clk
);
int
asoc_simple_card_parse_dai
(
struct
device_node
*
node
,
struct
device_node
**
dai_of_node
,
const
char
**
dai_name
,
const
char
*
list_name
,
const
char
*
cells_name
,
int
*
is_single_link
)
{
struct
of_phandle_args
args
;
int
ret
;
if
(
!
node
)
return
0
;
/*
* Get node via "sound-dai = <&phandle port>"
* it will be used as xxx_of_node on soc_bind_dai_link()
*/
ret
=
of_parse_phandle_with_args
(
node
,
list_name
,
cells_name
,
0
,
&
args
);
if
(
ret
)
return
ret
;
/* Get dai->name */
if
(
dai_name
)
{
ret
=
snd_soc_of_get_dai_name
(
node
,
dai_name
);
if
(
ret
<
0
)
return
ret
;
}
*
dai_of_node
=
args
.
np
;
if
(
is_single_link
)
*
is_single_link
=
!
args
.
args_count
;
return
0
;
}
EXPORT_SYMBOL_GPL
(
asoc_simple_card_parse_dai
);
int
asoc_simple_card_init_dai
(
struct
snd_soc_dai
*
dai
,
struct
asoc_simple_dai
*
simple_dai
)
{
int
ret
;
if
(
simple_dai
->
sysclk
)
{
ret
=
snd_soc_dai_set_sysclk
(
dai
,
0
,
simple_dai
->
sysclk
,
0
);
if
(
ret
&&
ret
!=
-
ENOTSUPP
)
{
dev_err
(
dai
->
dev
,
"simple-card: set_sysclk error
\n
"
);
return
ret
;
}
}
if
(
simple_dai
->
slots
)
{
ret
=
snd_soc_dai_set_tdm_slot
(
dai
,
simple_dai
->
tx_slot_mask
,
simple_dai
->
rx_slot_mask
,
simple_dai
->
slots
,
simple_dai
->
slot_width
);
if
(
ret
&&
ret
!=
-
ENOTSUPP
)
{
dev_err
(
dai
->
dev
,
"simple-card: set_tdm_slot error
\n
"
);
return
ret
;
}
}
return
0
;
}
EXPORT_SYMBOL_GPL
(
asoc_simple_card_init_dai
);
int
asoc_simple_card_canonicalize_dailink
(
struct
snd_soc_dai_link
*
dai_link
)
{
if
(
!
dai_link
->
cpu_dai_name
||
!
dai_link
->
codec_dai_name
)
return
-
EINVAL
;
/* Assumes platform == cpu */
if
(
!
dai_link
->
platform_of_node
)
dai_link
->
platform_of_node
=
dai_link
->
cpu_of_node
;
return
0
;
}
EXPORT_SYMBOL_GPL
(
asoc_simple_card_canonicalize_dailink
);
void
asoc_simple_card_canonicalize_cpu
(
struct
snd_soc_dai_link
*
dai_link
,
int
is_single_links
)
{
/*
* In soc_bind_dai_link() will check cpu name after
* of_node matching if dai_link has cpu_dai_name.
* but, it will never match if name was created by
* fmt_single_name() remove cpu_dai_name if cpu_args
* was 0. See:
* fmt_single_name()
* fmt_multiple_name()
*/
if
(
is_single_links
)
dai_link
->
cpu_dai_name
=
NULL
;
}
EXPORT_SYMBOL_GPL
(
asoc_simple_card_canonicalize_cpu
);
int
asoc_simple_card_clean_reference
(
struct
snd_soc_card
*
card
)
{
struct
snd_soc_dai_link
*
dai_link
;
int
num_links
;
for
(
num_links
=
0
,
dai_link
=
card
->
dai_link
;
num_links
<
card
->
num_links
;
num_links
++
,
dai_link
++
)
{
of_node_put
(
dai_link
->
cpu_of_node
);
of_node_put
(
dai_link
->
codec_of_node
);
}
return
0
;
}
EXPORT_SYMBOL_GPL
(
asoc_simple_card_clean_reference
);
/* Module information */
/* Module information */
MODULE_AUTHOR
(
"Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"
);
MODULE_AUTHOR
(
"Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"
);
MODULE_DESCRIPTION
(
"ALSA SoC Simple Card Utils"
);
MODULE_DESCRIPTION
(
"ALSA SoC Simple Card Utils"
);
...
...
sound/soc/generic/simple-card.c
浏览文件 @
81af7261
...
@@ -44,6 +44,8 @@ struct simple_card_data {
...
@@ -44,6 +44,8 @@ struct simple_card_data {
#define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + i)
#define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + i)
#define simple_priv_to_props(priv, i) ((priv)->dai_props + i)
#define simple_priv_to_props(priv, i) ((priv)->dai_props + i)
#define DAI "sound-dai"
#define CELL "#sound-dai-cells"
#define PREFIX "simple-audio-card,"
#define PREFIX "simple-audio-card,"
#define asoc_simple_card_init_hp(card, sjack, prefix)\
#define asoc_simple_card_init_hp(card, sjack, prefix)\
...
@@ -177,51 +179,19 @@ static struct snd_soc_ops asoc_simple_card_ops = {
...
@@ -177,51 +179,19 @@ static struct snd_soc_ops asoc_simple_card_ops = {
.
hw_params
=
asoc_simple_card_hw_params
,
.
hw_params
=
asoc_simple_card_hw_params
,
};
};
static
int
__asoc_simple_card_dai_init
(
struct
snd_soc_dai
*
dai
,
struct
asoc_simple_dai
*
set
)
{
int
ret
;
if
(
set
->
sysclk
)
{
ret
=
snd_soc_dai_set_sysclk
(
dai
,
0
,
set
->
sysclk
,
0
);
if
(
ret
&&
ret
!=
-
ENOTSUPP
)
{
dev_err
(
dai
->
dev
,
"simple-card: set_sysclk error
\n
"
);
goto
err
;
}
}
if
(
set
->
slots
)
{
ret
=
snd_soc_dai_set_tdm_slot
(
dai
,
set
->
tx_slot_mask
,
set
->
rx_slot_mask
,
set
->
slots
,
set
->
slot_width
);
if
(
ret
&&
ret
!=
-
ENOTSUPP
)
{
dev_err
(
dai
->
dev
,
"simple-card: set_tdm_slot error
\n
"
);
goto
err
;
}
}
ret
=
0
;
err:
return
ret
;
}
static
int
asoc_simple_card_dai_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
static
int
asoc_simple_card_dai_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
{
struct
simple_card_data
*
priv
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
struct
simple_card_data
*
priv
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
struct
snd_soc_dai
*
codec
=
rtd
->
codec_dai
;
struct
snd_soc_dai
*
codec
=
rtd
->
codec_dai
;
struct
snd_soc_dai
*
cpu
=
rtd
->
cpu_dai
;
struct
snd_soc_dai
*
cpu
=
rtd
->
cpu_dai
;
struct
simple_dai_props
*
dai_props
;
struct
simple_dai_props
*
dai_props
=
&
priv
->
dai_props
[
rtd
->
num
]
;
int
ret
;
int
ret
;
dai_props
=
&
priv
->
dai_props
[
rtd
->
num
];
ret
=
asoc_simple_card_init_dai
(
codec
,
&
dai_props
->
codec_dai
);
ret
=
__asoc_simple_card_dai_init
(
codec
,
&
dai_props
->
codec_dai
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
ret
=
__asoc_simple_card_dai_init
(
cpu
,
&
dai_props
->
cpu_dai
);
ret
=
asoc_simple_card_init_dai
(
cpu
,
&
dai_props
->
cpu_dai
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
...
@@ -236,78 +206,6 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
...
@@ -236,78 +206,6 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
return
0
;
return
0
;
}
}
static
int
asoc_simple_card_sub_parse_of
(
struct
device_node
*
np
,
struct
asoc_simple_dai
*
dai
,
struct
device_node
**
p_node
,
const
char
**
name
,
int
*
args_count
)
{
struct
of_phandle_args
args
;
struct
clk
*
clk
;
u32
val
;
int
ret
;
if
(
!
np
)
return
0
;
/*
* Get node via "sound-dai = <&phandle port>"
* it will be used as xxx_of_node on soc_bind_dai_link()
*/
ret
=
of_parse_phandle_with_args
(
np
,
"sound-dai"
,
"#sound-dai-cells"
,
0
,
&
args
);
if
(
ret
)
return
ret
;
*
p_node
=
args
.
np
;
if
(
args_count
)
*
args_count
=
args
.
args_count
;
/* Get dai->name */
if
(
name
)
{
ret
=
snd_soc_of_get_dai_name
(
np
,
name
);
if
(
ret
<
0
)
return
ret
;
}
if
(
!
dai
)
return
0
;
/* Parse TDM slot */
ret
=
snd_soc_of_parse_tdm_slot
(
np
,
&
dai
->
tx_slot_mask
,
&
dai
->
rx_slot_mask
,
&
dai
->
slots
,
&
dai
->
slot_width
);
if
(
ret
)
return
ret
;
/*
* Parse dai->sysclk come from "clocks = <&xxx>"
* (if system has common clock)
* or "system-clock-frequency = <xxx>"
* or device's module clock.
*/
if
(
of_property_read_bool
(
np
,
"clocks"
))
{
clk
=
of_clk_get
(
np
,
0
);
if
(
IS_ERR
(
clk
))
{
ret
=
PTR_ERR
(
clk
);
return
ret
;
}
dai
->
sysclk
=
clk_get_rate
(
clk
);
dai
->
clk
=
clk
;
}
else
if
(
!
of_property_read_u32
(
np
,
"system-clock-frequency"
,
&
val
))
{
dai
->
sysclk
=
val
;
}
else
{
clk
=
of_clk_get
(
args
.
np
,
0
);
if
(
!
IS_ERR
(
clk
))
dai
->
sysclk
=
clk_get_rate
(
clk
);
}
return
0
;
}
static
int
asoc_simple_card_dai_link_of
(
struct
device_node
*
node
,
static
int
asoc_simple_card_dai_link_of
(
struct
device_node
*
node
,
struct
simple_card_data
*
priv
,
struct
simple_card_data
*
priv
,
int
idx
,
int
idx
,
...
@@ -316,12 +214,14 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
...
@@ -316,12 +214,14 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
struct
device
*
dev
=
simple_priv_to_dev
(
priv
);
struct
device
*
dev
=
simple_priv_to_dev
(
priv
);
struct
snd_soc_dai_link
*
dai_link
=
simple_priv_to_link
(
priv
,
idx
);
struct
snd_soc_dai_link
*
dai_link
=
simple_priv_to_link
(
priv
,
idx
);
struct
simple_dai_props
*
dai_props
=
simple_priv_to_props
(
priv
,
idx
);
struct
simple_dai_props
*
dai_props
=
simple_priv_to_props
(
priv
,
idx
);
struct
asoc_simple_dai
*
cpu_dai
=
&
dai_props
->
cpu_dai
;
struct
asoc_simple_dai
*
codec_dai
=
&
dai_props
->
codec_dai
;
struct
device_node
*
cpu
=
NULL
;
struct
device_node
*
cpu
=
NULL
;
struct
device_node
*
plat
=
NULL
;
struct
device_node
*
plat
=
NULL
;
struct
device_node
*
codec
=
NULL
;
struct
device_node
*
codec
=
NULL
;
char
prop
[
128
];
char
prop
[
128
];
char
*
prefix
=
""
;
char
*
prefix
=
""
;
int
ret
,
cpu_args
;
int
ret
,
single_cpu
;
u32
val
;
u32
val
;
/* For single DAI link & old style of DT node */
/* For single DAI link & old style of DT node */
...
@@ -351,33 +251,44 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
...
@@ -351,33 +251,44 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
if
(
!
of_property_read_u32
(
node
,
"mclk-fs"
,
&
val
))
if
(
!
of_property_read_u32
(
node
,
"mclk-fs"
,
&
val
))
dai_props
->
mclk_fs
=
val
;
dai_props
->
mclk_fs
=
val
;
ret
=
asoc_simple_card_sub_parse_of
(
cpu
,
&
dai_props
->
cpu_dai
,
ret
=
asoc_simple_card_parse_cpu
(
cpu
,
dai_link
,
&
dai_link
->
cpu_of_node
,
DAI
,
CELL
,
&
single_cpu
);
&
dai_link
->
cpu_dai_name
,
&
cpu_args
);
if
(
ret
<
0
)
if
(
ret
<
0
)
goto
dai_link_of_err
;
goto
dai_link_of_err
;
ret
=
asoc_simple_card_sub_parse_of
(
codec
,
&
dai_props
->
codec_dai
,
ret
=
asoc_simple_card_parse_codec
(
codec
,
dai_link
,
DAI
,
CELL
);
&
dai_link
->
codec_of_node
,
&
dai_link
->
codec_dai_name
,
NULL
);
if
(
ret
<
0
)
if
(
ret
<
0
)
goto
dai_link_of_err
;
goto
dai_link_of_err
;
ret
=
asoc_simple_card_sub_parse_of
(
plat
,
NULL
,
ret
=
asoc_simple_card_parse_platform
(
plat
,
dai_link
,
DAI
,
CELL
);
&
dai_link
->
platform_of_node
,
NULL
,
NULL
);
if
(
ret
<
0
)
if
(
ret
<
0
)
goto
dai_link_of_err
;
goto
dai_link_of_err
;
if
(
!
dai_link
->
cpu_dai_name
||
!
dai_link
->
codec_dai_name
)
{
ret
=
snd_soc_of_parse_tdm_slot
(
cpu
,
&
cpu_dai
->
tx_slot_mask
,
ret
=
-
EINVAL
;
&
cpu_dai
->
rx_slot_mask
,
&
cpu_dai
->
slots
,
&
cpu_dai
->
slot_width
);
if
(
ret
<
0
)
goto
dai_link_of_err
;
ret
=
snd_soc_of_parse_tdm_slot
(
codec
,
&
codec_dai
->
tx_slot_mask
,
&
codec_dai
->
rx_slot_mask
,
&
codec_dai
->
slots
,
&
codec_dai
->
slot_width
);
if
(
ret
<
0
)
goto
dai_link_of_err
;
ret
=
asoc_simple_card_parse_clk_cpu
(
cpu
,
dai_link
,
cpu_dai
);
if
(
ret
<
0
)
goto
dai_link_of_err
;
goto
dai_link_of_err
;
}
/* Assumes platform == cpu */
ret
=
asoc_simple_card_parse_clk_codec
(
codec
,
dai_link
,
codec_dai
);
if
(
!
dai_link
->
platform_of_node
)
if
(
ret
<
0
)
dai_link
->
platform_of_node
=
dai_link
->
cpu_of_node
;
goto
dai_link_of_err
;
ret
=
asoc_simple_card_canonicalize_dailink
(
dai_link
);
if
(
ret
<
0
)
goto
dai_link_of_err
;
ret
=
asoc_simple_card_set_dailink_name
(
dev
,
dai_link
,
ret
=
asoc_simple_card_set_dailink_name
(
dev
,
dai_link
,
"%s-%s"
,
"%s-%s"
,
...
@@ -398,17 +309,7 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
...
@@ -398,17 +309,7 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
dai_link
->
codec_dai_name
,
dai_link
->
codec_dai_name
,
dai_props
->
codec_dai
.
sysclk
);
dai_props
->
codec_dai
.
sysclk
);
/*
asoc_simple_card_canonicalize_cpu
(
dai_link
,
single_cpu
);
* In soc_bind_dai_link() will check cpu name after
* of_node matching if dai_link has cpu_dai_name.
* but, it will never match if name was created by
* fmt_single_name() remove cpu_dai_name if cpu_args
* was 0. See:
* fmt_single_name()
* fmt_multiple_name()
*/
if
(
!
cpu_args
)
dai_link
->
cpu_dai_name
=
NULL
;
dai_link_of_err:
dai_link_of_err:
of_node_put
(
cpu
);
of_node_put
(
cpu
);
...
@@ -477,21 +378,6 @@ static int asoc_simple_card_parse_of(struct device_node *node,
...
@@ -477,21 +378,6 @@ static int asoc_simple_card_parse_of(struct device_node *node,
return
0
;
return
0
;
}
}
/* Decrease the reference count of the device nodes */
static
int
asoc_simple_card_unref
(
struct
snd_soc_card
*
card
)
{
struct
snd_soc_dai_link
*
dai_link
;
int
num_links
;
for
(
num_links
=
0
,
dai_link
=
card
->
dai_link
;
num_links
<
card
->
num_links
;
num_links
++
,
dai_link
++
)
{
of_node_put
(
dai_link
->
cpu_of_node
);
of_node_put
(
dai_link
->
codec_of_node
);
}
return
0
;
}
static
int
asoc_simple_card_probe
(
struct
platform_device
*
pdev
)
static
int
asoc_simple_card_probe
(
struct
platform_device
*
pdev
)
{
{
struct
simple_card_data
*
priv
;
struct
simple_card_data
*
priv
;
...
@@ -577,7 +463,7 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
...
@@ -577,7 +463,7 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
return
ret
;
return
ret
;
err:
err:
asoc_simple_card_
unref
(
&
priv
->
snd_card
);
asoc_simple_card_
clean_reference
(
&
priv
->
snd_card
);
return
ret
;
return
ret
;
}
}
...
@@ -589,7 +475,7 @@ static int asoc_simple_card_remove(struct platform_device *pdev)
...
@@ -589,7 +475,7 @@ static int asoc_simple_card_remove(struct platform_device *pdev)
asoc_simple_card_remove_jack
(
&
priv
->
hp_jack
);
asoc_simple_card_remove_jack
(
&
priv
->
hp_jack
);
asoc_simple_card_remove_jack
(
&
priv
->
mic_jack
);
asoc_simple_card_remove_jack
(
&
priv
->
mic_jack
);
return
asoc_simple_card_
unref
(
card
);
return
asoc_simple_card_
clean_reference
(
card
);
}
}
static
const
struct
of_device_id
asoc_simple_of_match
[]
=
{
static
const
struct
of_device_id
asoc_simple_of_match
[]
=
{
...
...
sound/soc/
sh/rcar/rsrc
-card.c
→
sound/soc/
generic/simple-scu
-card.c
浏览文件 @
81af7261
/*
/*
*
Renesas Sampling Rate Convert Sound Card for DPCM
*
ASoC simple SCU sound card support
*
*
* Copyright (C) 2015 Renesas Solutions Corp.
* Copyright (C) 2015 Renesas Solutions Corp.
* Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
* Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
...
@@ -22,34 +22,7 @@
...
@@ -22,34 +22,7 @@
#include <sound/soc-dai.h>
#include <sound/soc-dai.h>
#include <sound/simple_card_utils.h>
#include <sound/simple_card_utils.h>
struct
rsrc_card_of_data
{
struct
asoc_simple_card_priv
{
const
char
*
prefix
;
const
struct
snd_soc_dapm_route
*
routes
;
int
num_routes
;
};
static
const
struct
snd_soc_dapm_route
routes_ssi0_ak4642
[]
=
{
{
"ak4642 Playback"
,
NULL
,
"DAI0 Playback"
},
{
"DAI0 Capture"
,
NULL
,
"ak4642 Capture"
},
};
static
const
struct
rsrc_card_of_data
routes_of_ssi0_ak4642
=
{
.
prefix
=
"ak4642"
,
.
routes
=
routes_ssi0_ak4642
,
.
num_routes
=
ARRAY_SIZE
(
routes_ssi0_ak4642
),
};
static
const
struct
of_device_id
rsrc_card_of_match
[]
=
{
{
.
compatible
=
"renesas,rsrc-card,lager"
,
.
data
=
&
routes_of_ssi0_ak4642
},
{
.
compatible
=
"renesas,rsrc-card,koelsch"
,
.
data
=
&
routes_of_ssi0_ak4642
},
{
.
compatible
=
"renesas,rsrc-card"
,
},
{},
};
MODULE_DEVICE_TABLE
(
of
,
rsrc_card_of_match
);
#define IDX_CPU 0
#define IDX_CODEC 1
struct
rsrc_card_priv
{
struct
snd_soc_card
snd_card
;
struct
snd_soc_card
snd_card
;
struct
snd_soc_codec_conf
codec_conf
;
struct
snd_soc_codec_conf
codec_conf
;
struct
asoc_simple_dai
*
dai_props
;
struct
asoc_simple_dai
*
dai_props
;
...
@@ -58,80 +31,60 @@ struct rsrc_card_priv {
...
@@ -58,80 +31,60 @@ struct rsrc_card_priv {
u32
convert_channels
;
u32
convert_channels
;
};
};
#define rsrc_priv_to_dev(priv) ((priv)->snd_card.dev)
#define simple_priv_to_dev(priv) ((priv)->snd_card.dev)
#define rsrc_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i))
#define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i))
#define rsrc_priv_to_props(priv, i) ((priv)->dai_props + (i))
#define simple_priv_to_props(priv, i) ((priv)->dai_props + (i))
#define DAI "sound-dai"
#define CELL "#sound-dai-cells"
#define PREFIX "simple-audio-card,"
static
int
rsrc
_card_startup
(
struct
snd_pcm_substream
*
substream
)
static
int
asoc_simple
_card_startup
(
struct
snd_pcm_substream
*
substream
)
{
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
rsrc
_card_priv
*
priv
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
struct
asoc_simple
_card_priv
*
priv
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
struct
asoc_simple_dai
*
dai_props
=
struct
asoc_simple_dai
*
dai_props
=
rsrc
_priv_to_props
(
priv
,
rtd
->
num
);
simple
_priv_to_props
(
priv
,
rtd
->
num
);
return
clk_prepare_enable
(
dai_props
->
clk
);
return
clk_prepare_enable
(
dai_props
->
clk
);
}
}
static
void
rsrc
_card_shutdown
(
struct
snd_pcm_substream
*
substream
)
static
void
asoc_simple
_card_shutdown
(
struct
snd_pcm_substream
*
substream
)
{
{
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
snd_soc_pcm_runtime
*
rtd
=
substream
->
private_data
;
struct
rsrc
_card_priv
*
priv
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
struct
asoc_simple
_card_priv
*
priv
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
struct
asoc_simple_dai
*
dai_props
=
struct
asoc_simple_dai
*
dai_props
=
rsrc
_priv_to_props
(
priv
,
rtd
->
num
);
simple
_priv_to_props
(
priv
,
rtd
->
num
);
clk_disable_unprepare
(
dai_props
->
clk
);
clk_disable_unprepare
(
dai_props
->
clk
);
}
}
static
struct
snd_soc_ops
rsrc
_card_ops
=
{
static
struct
snd_soc_ops
asoc_simple
_card_ops
=
{
.
startup
=
rsrc
_card_startup
,
.
startup
=
asoc_simple
_card_startup
,
.
shutdown
=
rsrc
_card_shutdown
,
.
shutdown
=
asoc_simple
_card_shutdown
,
};
};
static
int
rsrc
_card_dai_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
static
int
asoc_simple
_card_dai_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
{
struct
rsrc
_card_priv
*
priv
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
struct
asoc_simple
_card_priv
*
priv
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
struct
snd_soc_dai
*
dai
;
struct
snd_soc_dai
*
dai
;
struct
snd_soc_dai_link
*
dai_link
;
struct
snd_soc_dai_link
*
dai_link
;
struct
asoc_simple_dai
*
dai_props
;
struct
asoc_simple_dai
*
dai_props
;
int
num
=
rtd
->
num
;
int
num
=
rtd
->
num
;
int
ret
;
dai_link
=
rsrc
_priv_to_link
(
priv
,
num
);
dai_link
=
simple
_priv_to_link
(
priv
,
num
);
dai_props
=
rsrc
_priv_to_props
(
priv
,
num
);
dai_props
=
simple
_priv_to_props
(
priv
,
num
);
dai
=
dai_link
->
dynamic
?
dai
=
dai_link
->
dynamic
?
rtd
->
cpu_dai
:
rtd
->
cpu_dai
:
rtd
->
codec_dai
;
rtd
->
codec_dai
;
if
(
dai_props
->
sysclk
)
{
return
asoc_simple_card_init_dai
(
dai
,
dai_props
);
ret
=
snd_soc_dai_set_sysclk
(
dai
,
0
,
dai_props
->
sysclk
,
0
);
if
(
ret
&&
ret
!=
-
ENOTSUPP
)
{
dev_err
(
dai
->
dev
,
"set_sysclk error
\n
"
);
goto
err
;
}
}
if
(
dai_props
->
slots
)
{
ret
=
snd_soc_dai_set_tdm_slot
(
dai
,
dai_props
->
tx_slot_mask
,
dai_props
->
rx_slot_mask
,
dai_props
->
slots
,
dai_props
->
slot_width
);
if
(
ret
&&
ret
!=
-
ENOTSUPP
)
{
dev_err
(
dai
->
dev
,
"set_tdm_slot error
\n
"
);
goto
err
;
}
}
ret
=
0
;
err:
return
ret
;
}
}
static
int
rsrc
_card_be_hw_params_fixup
(
struct
snd_soc_pcm_runtime
*
rtd
,
static
int
asoc_simple
_card_be_hw_params_fixup
(
struct
snd_soc_pcm_runtime
*
rtd
,
struct
snd_pcm_hw_params
*
params
)
struct
snd_pcm_hw_params
*
params
)
{
{
struct
rsrc
_card_priv
*
priv
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
struct
asoc_simple
_card_priv
*
priv
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
struct
snd_interval
*
rate
=
hw_param_interval
(
params
,
struct
snd_interval
*
rate
=
hw_param_interval
(
params
,
SNDRV_PCM_HW_PARAM_RATE
);
SNDRV_PCM_HW_PARAM_RATE
);
struct
snd_interval
*
channels
=
hw_param_interval
(
params
,
struct
snd_interval
*
channels
=
hw_param_interval
(
params
,
...
@@ -148,35 +101,19 @@ static int rsrc_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
...
@@ -148,35 +101,19 @@ static int rsrc_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
return
0
;
return
0
;
}
}
static
int
rsrc_card_parse_links
(
struct
device_node
*
np
,
static
int
asoc_simple_card_parse_links
(
struct
device_node
*
np
,
struct
rsrc_card_priv
*
priv
,
struct
asoc_simple_card_priv
*
priv
,
int
idx
,
bool
is_fe
)
unsigned
int
daifmt
,
int
idx
,
bool
is_fe
)
{
{
struct
device
*
dev
=
rsrc_priv_to_dev
(
priv
);
struct
device
*
dev
=
simple_priv_to_dev
(
priv
);
struct
snd_soc_dai_link
*
dai_link
=
rsrc_priv_to_link
(
priv
,
idx
);
struct
snd_soc_dai_link
*
dai_link
=
simple_priv_to_link
(
priv
,
idx
);
struct
asoc_simple_dai
*
dai_props
=
rsrc_priv_to_props
(
priv
,
idx
);
struct
asoc_simple_dai
*
dai_props
=
simple_priv_to_props
(
priv
,
idx
);
struct
of_phandle_args
args
;
int
ret
;
int
ret
;
/*
* Get node via "sound-dai = <&phandle port>"
* it will be used as xxx_of_node on soc_bind_dai_link()
*/
ret
=
of_parse_phandle_with_args
(
np
,
"sound-dai"
,
"#sound-dai-cells"
,
0
,
&
args
);
if
(
ret
)
return
ret
;
/* Parse TDM slot */
ret
=
snd_soc_of_parse_tdm_slot
(
np
,
&
dai_props
->
tx_slot_mask
,
&
dai_props
->
rx_slot_mask
,
&
dai_props
->
slots
,
&
dai_props
->
slot_width
);
if
(
ret
)
return
ret
;
if
(
is_fe
)
{
if
(
is_fe
)
{
int
is_single_links
=
0
;
/* BE is dummy */
/* BE is dummy */
dai_link
->
codec_of_node
=
NULL
;
dai_link
->
codec_of_node
=
NULL
;
dai_link
->
codec_dai_name
=
"snd-soc-dummy-dai"
;
dai_link
->
codec_dai_name
=
"snd-soc-dummy-dai"
;
...
@@ -185,8 +122,13 @@ static int rsrc_card_parse_links(struct device_node *np,
...
@@ -185,8 +122,13 @@ static int rsrc_card_parse_links(struct device_node *np,
/* FE settings */
/* FE settings */
dai_link
->
dynamic
=
1
;
dai_link
->
dynamic
=
1
;
dai_link
->
dpcm_merged_format
=
1
;
dai_link
->
dpcm_merged_format
=
1
;
dai_link
->
cpu_of_node
=
args
.
np
;
ret
=
snd_soc_of_get_dai_name
(
np
,
&
dai_link
->
cpu_dai_name
);
ret
=
asoc_simple_card_parse_cpu
(
np
,
dai_link
,
DAI
,
CELL
,
&
is_single_links
);
if
(
ret
)
return
ret
;
ret
=
asoc_simple_card_parse_clk_cpu
(
np
,
dai_link
,
dai_props
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
...
@@ -196,22 +138,8 @@ static int rsrc_card_parse_links(struct device_node *np,
...
@@ -196,22 +138,8 @@ static int rsrc_card_parse_links(struct device_node *np,
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
/*
asoc_simple_card_canonicalize_cpu
(
dai_link
,
is_single_links
);
* In soc_bind_dai_link() will check cpu name after
* of_node matching if dai_link has cpu_dai_name.
* but, it will never match if name was created by
* fmt_single_name() remove cpu_dai_name if cpu_args
* was 0. See:
* fmt_single_name()
* fmt_multiple_name()
*/
if
(
!
args
.
args_count
)
dai_link
->
cpu_dai_name
=
NULL
;
}
else
{
}
else
{
const
struct
rsrc_card_of_data
*
of_data
;
of_data
=
of_device_get_match_data
(
dev
);
/* FE is dummy */
/* FE is dummy */
dai_link
->
cpu_of_node
=
NULL
;
dai_link
->
cpu_of_node
=
NULL
;
dai_link
->
cpu_dai_name
=
"snd-soc-dummy-dai"
;
dai_link
->
cpu_dai_name
=
"snd-soc-dummy-dai"
;
...
@@ -219,9 +147,13 @@ static int rsrc_card_parse_links(struct device_node *np,
...
@@ -219,9 +147,13 @@ static int rsrc_card_parse_links(struct device_node *np,
/* BE settings */
/* BE settings */
dai_link
->
no_pcm
=
1
;
dai_link
->
no_pcm
=
1
;
dai_link
->
be_hw_params_fixup
=
rsrc_card_be_hw_params_fixup
;
dai_link
->
be_hw_params_fixup
=
asoc_simple_card_be_hw_params_fixup
;
dai_link
->
codec_of_node
=
args
.
np
;
ret
=
snd_soc_of_get_dai_name
(
np
,
&
dai_link
->
codec_dai_name
);
ret
=
asoc_simple_card_parse_codec
(
np
,
dai_link
,
DAI
,
CELL
);
if
(
ret
<
0
)
return
ret
;
ret
=
asoc_simple_card_parse_clk_codec
(
np
,
dai_link
,
dai_props
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
...
@@ -231,124 +163,64 @@ static int rsrc_card_parse_links(struct device_node *np,
...
@@ -231,124 +163,64 @@ static int rsrc_card_parse_links(struct device_node *np,
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
/* additional name prefix */
snd_soc_of_parse_audio_prefix
(
&
priv
->
snd_card
,
if
(
of_data
)
{
&
priv
->
codec_conf
,
priv
->
codec_conf
.
of_node
=
dai_link
->
codec_of_node
;
dai_link
->
codec_of_node
,
priv
->
codec_conf
.
name_prefix
=
of_data
->
prefix
;
PREFIX
"prefix"
);
}
else
{
snd_soc_of_parse_audio_prefix
(
&
priv
->
snd_card
,
&
priv
->
codec_conf
,
dai_link
->
codec_of_node
,
"audio-prefix"
);
}
}
/* Simple Card assumes platform == cpu */
dai_link
->
platform_of_node
=
dai_link
->
cpu_of_node
;
dai_link
->
dpcm_playback
=
1
;
dai_link
->
dpcm_capture
=
1
;
dai_link
->
ops
=
&
rsrc_card_ops
;
dai_link
->
init
=
rsrc_card_dai_init
;
return
0
;
}
static
int
rsrc_card_parse_clk
(
struct
device_node
*
np
,
struct
rsrc_card_priv
*
priv
,
int
idx
,
bool
is_fe
)
{
struct
snd_soc_dai_link
*
dai_link
=
rsrc_priv_to_link
(
priv
,
idx
);
struct
asoc_simple_dai
*
dai_props
=
rsrc_priv_to_props
(
priv
,
idx
);
struct
clk
*
clk
;
struct
device_node
*
of_np
=
is_fe
?
dai_link
->
cpu_of_node
:
dai_link
->
codec_of_node
;
u32
val
;
/*
* Parse dai->sysclk come from "clocks = <&xxx>"
* (if system has common clock)
* or "system-clock-frequency = <xxx>"
* or device's module clock.
*/
if
(
of_property_read_bool
(
np
,
"clocks"
))
{
clk
=
of_clk_get
(
np
,
0
);
if
(
IS_ERR
(
clk
))
return
PTR_ERR
(
clk
);
dai_props
->
sysclk
=
clk_get_rate
(
clk
);
dai_props
->
clk
=
clk
;
}
else
if
(
!
of_property_read_u32
(
np
,
"system-clock-frequency"
,
&
val
))
{
dai_props
->
sysclk
=
val
;
}
else
{
clk
=
of_clk_get
(
of_np
,
0
);
if
(
!
IS_ERR
(
clk
))
dai_props
->
sysclk
=
clk_get_rate
(
clk
);
}
}
return
0
;
ret
=
snd_soc_of_parse_tdm_slot
(
np
,
}
&
dai_props
->
tx_slot_mask
,
&
dai_props
->
rx_slot_mask
,
static
int
rsrc_card_dai_sub_link_of
(
struct
device_node
*
node
,
&
dai_props
->
slots
,
struct
device_node
*
np
,
&
dai_props
->
slot_width
);
struct
rsrc_card_priv
*
priv
,
if
(
ret
)
int
idx
,
bool
is_fe
)
{
struct
device
*
dev
=
rsrc_priv_to_dev
(
priv
);
struct
snd_soc_dai_link
*
dai_link
=
rsrc_priv_to_link
(
priv
,
idx
);
struct
asoc_simple_dai
*
dai_props
=
rsrc_priv_to_props
(
priv
,
idx
);
int
ret
;
ret
=
rsrc_card_parse_links
(
np
,
priv
,
idx
,
is_fe
);
if
(
ret
<
0
)
return
ret
;
return
ret
;
ret
=
rsrc_card_parse_clk
(
np
,
priv
,
idx
,
is_fe
);
ret
=
asoc_simple_card_canonicalize_dailink
(
dai_link
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
dai_link
->
dai_fmt
=
daifmt
;
dai_link
->
dpcm_playback
=
1
;
dai_link
->
dpcm_capture
=
1
;
dai_link
->
ops
=
&
asoc_simple_card_ops
;
dai_link
->
init
=
asoc_simple_card_dai_init
;
dev_dbg
(
dev
,
"
\t
%s / %04x / %d
\n
"
,
dev_dbg
(
dev
,
"
\t
%s / %04x / %d
\n
"
,
dai_link
->
name
,
dai_link
->
name
,
dai_link
->
dai_fmt
,
dai_link
->
dai_fmt
,
dai_props
->
sysclk
);
dai_props
->
sysclk
);
return
ret
;
return
0
;
}
}
static
int
rsrc
_card_dai_link_of
(
struct
device_node
*
node
,
static
int
asoc_simple
_card_dai_link_of
(
struct
device_node
*
node
,
struct
rsrc
_card_priv
*
priv
)
struct
asoc_simple
_card_priv
*
priv
)
{
{
struct
device
*
dev
=
rsrc_priv_to_dev
(
priv
);
struct
device
*
dev
=
simple_priv_to_dev
(
priv
);
struct
snd_soc_dai_link
*
dai_link
;
struct
device_node
*
np
;
struct
device_node
*
np
;
unsigned
int
daifmt
=
0
;
unsigned
int
daifmt
=
0
;
int
ret
,
i
;
int
ret
,
i
;
bool
is_fe
;
bool
is_fe
;
/* find 1st codec */
/* find 1st codec */
i
=
0
;
np
=
of_get_child_by_name
(
node
,
PREFIX
"codec"
);
for_each_child_of_node
(
node
,
np
)
{
if
(
!
np
)
dai_link
=
rsrc_priv_to_link
(
priv
,
i
);
return
-
ENODEV
;
if
(
strcmp
(
np
->
name
,
"codec"
)
==
0
)
{
ret
=
asoc_simple_card_parse_daifmt
(
dev
,
node
,
np
,
ret
=
asoc_simple_card_parse_daifmt
(
dev
,
node
,
np
,
PREFIX
,
&
daifmt
);
NULL
,
&
daifmt
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
break
;
}
i
++
;
}
i
=
0
;
i
=
0
;
for_each_child_of_node
(
node
,
np
)
{
for_each_child_of_node
(
node
,
np
)
{
dai_link
=
rsrc_priv_to_link
(
priv
,
i
);
dai_link
->
dai_fmt
=
daifmt
;
is_fe
=
false
;
is_fe
=
false
;
if
(
strcmp
(
np
->
name
,
"cpu"
)
==
0
)
if
(
strcmp
(
np
->
name
,
PREFIX
"cpu"
)
==
0
)
is_fe
=
true
;
is_fe
=
true
;
ret
=
rsrc_card_dai_sub_link_of
(
node
,
np
,
priv
,
i
,
is_fe
);
ret
=
asoc_simple_card_parse_links
(
np
,
priv
,
daifmt
,
i
,
is_fe
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
i
++
;
i
++
;
...
@@ -357,11 +229,10 @@ static int rsrc_card_dai_link_of(struct device_node *node,
...
@@ -357,11 +229,10 @@ static int rsrc_card_dai_link_of(struct device_node *node,
return
0
;
return
0
;
}
}
static
int
rsrc
_card_parse_of
(
struct
device_node
*
node
,
static
int
asoc_simple
_card_parse_of
(
struct
device_node
*
node
,
struct
rsrc
_card_priv
*
priv
,
struct
asoc_simple
_card_priv
*
priv
,
struct
device
*
dev
)
struct
device
*
dev
)
{
{
const
struct
rsrc_card_of_data
*
of_data
=
of_device_get_match_data
(
dev
);
struct
asoc_simple_dai
*
props
;
struct
asoc_simple_dai
*
props
;
struct
snd_soc_dai_link
*
links
;
struct
snd_soc_dai_link
*
links
;
int
ret
;
int
ret
;
...
@@ -387,54 +258,35 @@ static int rsrc_card_parse_of(struct device_node *node,
...
@@ -387,54 +258,35 @@ static int rsrc_card_parse_of(struct device_node *node,
priv
->
snd_card
.
codec_conf
=
&
priv
->
codec_conf
;
priv
->
snd_card
.
codec_conf
=
&
priv
->
codec_conf
;
priv
->
snd_card
.
num_configs
=
1
;
priv
->
snd_card
.
num_configs
=
1
;
if
(
of_data
)
{
ret
=
snd_soc_of_parse_audio_routing
(
&
priv
->
snd_card
,
PREFIX
"routing"
);
priv
->
snd_card
.
of_dapm_routes
=
of_data
->
routes
;
if
(
ret
<
0
)
priv
->
snd_card
.
num_of_dapm_routes
=
of_data
->
num_routes
;
return
ret
;
}
else
{
snd_soc_of_parse_audio_routing
(
&
priv
->
snd_card
,
"audio-routing"
);
}
/* sampling rate convert */
/* sampling rate convert */
of_property_read_u32
(
node
,
"convert-rate"
,
&
priv
->
convert_rate
);
of_property_read_u32
(
node
,
PREFIX
"convert-rate"
,
&
priv
->
convert_rate
);
/* channels transfer */
/* channels transfer */
of_property_read_u32
(
node
,
"convert-channels"
,
&
priv
->
convert_channels
);
of_property_read_u32
(
node
,
PREFIX
"convert-channels"
,
&
priv
->
convert_channels
);
dev_dbg
(
dev
,
"New rsrc-audio-card: %s
\n
"
,
priv
->
snd_card
.
name
?
priv
->
snd_card
.
name
:
""
);
dev_dbg
(
dev
,
"SRC : convert_rate %d
\n
"
,
priv
->
convert_rate
);
dev_dbg
(
dev
,
"CTU : convert_channels %d
\n
"
,
priv
->
convert_channels
);
ret
=
rsrc
_card_dai_link_of
(
node
,
priv
);
ret
=
asoc_simple
_card_dai_link_of
(
node
,
priv
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
ret
=
asoc_simple_card_parse_card_name
(
&
priv
->
snd_card
,
"card-"
);
ret
=
asoc_simple_card_parse_card_name
(
&
priv
->
snd_card
,
PREFIX
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
return
0
;
dev_dbg
(
dev
,
"New card: %s
\n
"
,
}
priv
->
snd_card
.
name
?
priv
->
snd_card
.
name
:
""
);
dev_dbg
(
dev
,
"convert_rate %d
\n
"
,
priv
->
convert_rate
);
/* Decrease the reference count of the device nodes */
dev_dbg
(
dev
,
"convert_channels %d
\n
"
,
priv
->
convert_channels
);
static
int
rsrc_card_unref
(
struct
snd_soc_card
*
card
)
{
struct
snd_soc_dai_link
*
dai_link
;
int
num_links
;
for
(
num_links
=
0
,
dai_link
=
card
->
dai_link
;
num_links
<
card
->
num_links
;
num_links
++
,
dai_link
++
)
{
of_node_put
(
dai_link
->
cpu_of_node
);
of_node_put
(
dai_link
->
codec_of_node
);
}
return
0
;
return
0
;
}
}
static
int
rsrc
_card_probe
(
struct
platform_device
*
pdev
)
static
int
asoc_simple
_card_probe
(
struct
platform_device
*
pdev
)
{
{
struct
rsrc
_card_priv
*
priv
;
struct
asoc_simple
_card_priv
*
priv
;
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
struct
device_node
*
np
=
pdev
->
dev
.
of_node
;
struct
device
*
dev
=
&
pdev
->
dev
;
struct
device
*
dev
=
&
pdev
->
dev
;
int
ret
;
int
ret
;
...
@@ -444,7 +296,7 @@ static int rsrc_card_probe(struct platform_device *pdev)
...
@@ -444,7 +296,7 @@ static int rsrc_card_probe(struct platform_device *pdev)
if
(
!
priv
)
if
(
!
priv
)
return
-
ENOMEM
;
return
-
ENOMEM
;
ret
=
rsrc
_card_parse_of
(
np
,
priv
,
dev
);
ret
=
asoc_simple
_card_parse_of
(
np
,
priv
,
dev
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
if
(
ret
!=
-
EPROBE_DEFER
)
if
(
ret
!=
-
EPROBE_DEFER
)
dev_err
(
dev
,
"parse error %d
\n
"
,
ret
);
dev_err
(
dev
,
"parse error %d
\n
"
,
ret
);
...
@@ -457,30 +309,37 @@ static int rsrc_card_probe(struct platform_device *pdev)
...
@@ -457,30 +309,37 @@ static int rsrc_card_probe(struct platform_device *pdev)
if
(
ret
>=
0
)
if
(
ret
>=
0
)
return
ret
;
return
ret
;
err:
err:
rsrc_card_unref
(
&
priv
->
snd_card
);
asoc_simple_card_clean_reference
(
&
priv
->
snd_card
);
return
ret
;
return
ret
;
}
}
static
int
rsrc
_card_remove
(
struct
platform_device
*
pdev
)
static
int
asoc_simple
_card_remove
(
struct
platform_device
*
pdev
)
{
{
struct
snd_soc_card
*
card
=
platform_get_drvdata
(
pdev
);
struct
snd_soc_card
*
card
=
platform_get_drvdata
(
pdev
);
return
rsrc_card_unref
(
card
);
return
asoc_simple_card_clean_reference
(
card
);
}
}
static
struct
platform_driver
rsrc_card
=
{
static
const
struct
of_device_id
asoc_simple_of_match
[]
=
{
{
.
compatible
=
"renesas,rsrc-card"
,
},
{
.
compatible
=
"simple-scu-audio-card"
,
},
{},
};
MODULE_DEVICE_TABLE
(
of
,
asoc_simple_of_match
);
static
struct
platform_driver
asoc_simple_card
=
{
.
driver
=
{
.
driver
=
{
.
name
=
"
renesas-src
-audio-card"
,
.
name
=
"
simple-scu
-audio-card"
,
.
of_match_table
=
rsrc_card
_of_match
,
.
of_match_table
=
asoc_simple
_of_match
,
},
},
.
probe
=
rsrc
_card_probe
,
.
probe
=
asoc_simple
_card_probe
,
.
remove
=
rsrc
_card_remove
,
.
remove
=
asoc_simple
_card_remove
,
};
};
module_platform_driver
(
rsrc
_card
);
module_platform_driver
(
asoc_simple
_card
);
MODULE_ALIAS
(
"platform:
renesas-src-audio
-card"
);
MODULE_ALIAS
(
"platform:
asoc-simple-scu
-card"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_LICENSE
(
"GPL
v2
"
);
MODULE_DESCRIPTION
(
"
Renesas Sampling Rate Convert
Sound Card"
);
MODULE_DESCRIPTION
(
"
ASoC Simple SCU
Sound Card"
);
MODULE_AUTHOR
(
"Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"
);
MODULE_AUTHOR
(
"Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"
);
sound/soc/sh/Kconfig
浏览文件 @
81af7261
...
@@ -42,12 +42,6 @@ config SND_SOC_RCAR
...
@@ -42,12 +42,6 @@ config SND_SOC_RCAR
help
help
This option enables R-Car SRU/SCU/SSIU/SSI sound support
This option enables R-Car SRU/SCU/SSIU/SSI sound support
config SND_SOC_RSRC_CARD
tristate "Renesas Sampling Rate Convert Sound Card"
select SND_SIMPLE_CARD_UTILS
help
This option enables simple sound if you need sampling rate convert
##
##
## Boards
## Boards
##
##
...
...
sound/soc/sh/rcar/Makefile
浏览文件 @
81af7261
snd-soc-rcar-objs
:=
core.o gen.o dma.o adg.o ssi.o ssiu.o src.o ctu.o mix.o dvc.o cmd.o
snd-soc-rcar-objs
:=
core.o gen.o dma.o adg.o ssi.o ssiu.o src.o ctu.o mix.o dvc.o cmd.o
obj-$(CONFIG_SND_SOC_RCAR)
+=
snd-soc-rcar.o
obj-$(CONFIG_SND_SOC_RCAR)
+=
snd-soc-rcar.o
snd-soc-rsrc-card-objs
:=
rsrc-card.o
obj-$(CONFIG_SND_SOC_RSRC_CARD)
+=
snd-soc-rsrc-card.o
sound/soc/sh/rcar/core.c
浏览文件 @
81af7261
...
@@ -110,6 +110,7 @@ MODULE_DEVICE_TABLE(of, rsnd_of_match);
...
@@ -110,6 +110,7 @@ MODULE_DEVICE_TABLE(of, rsnd_of_match);
/*
/*
* rsnd_mod functions
* rsnd_mod functions
*/
*/
#ifdef DEBUG
void
rsnd_mod_make_sure
(
struct
rsnd_mod
*
mod
,
enum
rsnd_mod_type
type
)
void
rsnd_mod_make_sure
(
struct
rsnd_mod
*
mod
,
enum
rsnd_mod_type
type
)
{
{
if
(
mod
->
type
!=
type
)
{
if
(
mod
->
type
!=
type
)
{
...
@@ -120,6 +121,7 @@ void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type)
...
@@ -120,6 +121,7 @@ void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type)
rsnd_mod_name
(
mod
),
rsnd_mod_id
(
mod
));
rsnd_mod_name
(
mod
),
rsnd_mod_id
(
mod
));
}
}
}
}
#endif
char
*
rsnd_mod_name
(
struct
rsnd_mod
*
mod
)
char
*
rsnd_mod_name
(
struct
rsnd_mod
*
mod
)
{
{
...
@@ -574,6 +576,7 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
...
@@ -574,6 +576,7 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
switch
(
cmd
)
{
switch
(
cmd
)
{
case
SNDRV_PCM_TRIGGER_START
:
case
SNDRV_PCM_TRIGGER_START
:
case
SNDRV_PCM_TRIGGER_RESUME
:
rsnd_dai_stream_init
(
io
,
substream
);
rsnd_dai_stream_init
(
io
,
substream
);
ret
=
rsnd_dai_call
(
init
,
io
,
priv
);
ret
=
rsnd_dai_call
(
init
,
io
,
priv
);
...
@@ -590,6 +593,7 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
...
@@ -590,6 +593,7 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
break
;
break
;
case
SNDRV_PCM_TRIGGER_STOP
:
case
SNDRV_PCM_TRIGGER_STOP
:
case
SNDRV_PCM_TRIGGER_SUSPEND
:
ret
=
rsnd_dai_call
(
irq
,
io
,
priv
,
0
);
ret
=
rsnd_dai_call
(
irq
,
io
,
priv
,
0
);
ret
|=
rsnd_dai_call
(
stop
,
io
,
priv
);
ret
|=
rsnd_dai_call
(
stop
,
io
,
priv
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录