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
nexedi
linux
Commits
81af7261
Commit
81af7261
authored
Sep 29, 2016
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'asoc/topic/rcar' into asoc-next
parents
60955521
4b9c75ea
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
682 additions
and
161 deletions
+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
No files found.
Documentation/devicetree/bindings/sound/
renesas,rsrc
-card.txt
→
Documentation/devicetree/bindings/sound/
simple-scu
-card.txt
View file @
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:
- compatible : "renesas,rsrc-card{,<board>}"
Examples with boards are:
- "renesas,rsrc-card"
- "renesas,rsrc-card,lager"
- "renesas,rsrc-card,koelsch"
- compatible : "simple-scu-audio-card"
"renesas,rsrc-card"
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.
-
cpu
: CPU sub-node
-
codec
: CODEC sub-node
-
simple-audio-card,cpu
: CPU sub-node
-
simple-audio-card,codec
: CODEC sub-node
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"
"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.
-
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.
-
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.
-
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.
-
convert-rate
: platform specified sampling rate convert
-
convert-channels
: platform specified converted channel size (2 - 8 ch)
-
audio-prefix
: see audio-routing
-
audio-routing
: A list of the connections between audio components.
-
simple-audio-card,convert-rate
: platform specified sampling rate convert
-
simple-audio-card,convert-channels
: platform specified converted channel size (2 - 8 ch)
-
simple-audio-card,prefix
: see audio-routing
-
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,
the second being the connection's source. Valid names for sources.
use audio-prefix if some components is using same sink/sources naming.
...
...
@@ -54,22 +52,59 @@ Optional CPU/CODEC subnodes properties:
clk_disable_unprepare() in dai
shutdown().
Example
Example
1. Sampling Rate Covert
sound {
compatible = "
renesas,rsrc-card,lager
";
compatible = "
simple-scu-audio-card
";
card-name = "rsnd-ak4643";
format = "left_j";
bitclock-master = <&sndcodec>;
frame-master = <&sndcodec>;
simple-audio-card,name = "rsnd-ak4643";
simple-audio-card,format = "left_j";
simple-audio-card,format = "left_j";
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>;
};
sndcodec: codec {
sndcodec:
simple-audio-card,
codec {
sound-dai = <&ak4643>;
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
View file @
81af7261
...
...
@@ -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
,
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 */
sound/soc/generic/Kconfig
View file @
81af7261
...
...
@@ -6,3 +6,11 @@ config SND_SIMPLE_CARD
select SND_SIMPLE_CARD_UTILS
help
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
View file @
81af7261
snd-soc-simple-card-utils-objs
:=
simple-card-utils.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)
+=
snd-soc-simple-card.o
obj-$(CONFIG_SND_SIMPLE_SCU_CARD)
+=
snd-soc-simple-scu-card.o
sound/soc/generic/simple-card-utils.c
View file @
81af7261
...
...
@@ -7,6 +7,7 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/clk.h>
#include <linux/module.h>
#include <linux/of.h>
#include <sound/simple_card_utils.h>
...
...
@@ -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
);
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_AUTHOR
(
"Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"
);
MODULE_DESCRIPTION
(
"ALSA SoC Simple Card Utils"
);
...
...
sound/soc/generic/simple-card.c
View file @
81af7261
...
...
@@ -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_props(priv, i) ((priv)->dai_props + i)
#define DAI "sound-dai"
#define CELL "#sound-dai-cells"
#define PREFIX "simple-audio-card,"
#define asoc_simple_card_init_hp(card, sjack, prefix)\
...
...
@@ -177,51 +179,19 @@ static struct snd_soc_ops asoc_simple_card_ops = {
.
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
)
{
struct
simple_card_data
*
priv
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
struct
snd_soc_dai
*
codec
=
rtd
->
codec_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
;
dai_props
=
&
priv
->
dai_props
[
rtd
->
num
];
ret
=
__asoc_simple_card_dai_init
(
codec
,
&
dai_props
->
codec_dai
);
ret
=
asoc_simple_card_init_dai
(
codec
,
&
dai_props
->
codec_dai
);
if
(
ret
<
0
)
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
)
return
ret
;
...
...
@@ -236,78 +206,6 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
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
,
struct
simple_card_data
*
priv
,
int
idx
,
...
...
@@ -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
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
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
*
plat
=
NULL
;
struct
device_node
*
codec
=
NULL
;
char
prop
[
128
];
char
*
prefix
=
""
;
int
ret
,
cpu_args
;
int
ret
,
single_cpu
;
u32
val
;
/* 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,
if
(
!
of_property_read_u32
(
node
,
"mclk-fs"
,
&
val
))
dai_props
->
mclk_fs
=
val
;
ret
=
asoc_simple_card_sub_parse_of
(
cpu
,
&
dai_props
->
cpu_dai
,
&
dai_link
->
cpu_of_node
,
&
dai_link
->
cpu_dai_name
,
&
cpu_args
);
ret
=
asoc_simple_card_parse_cpu
(
cpu
,
dai_link
,
DAI
,
CELL
,
&
single_cpu
);
if
(
ret
<
0
)
goto
dai_link_of_err
;
ret
=
asoc_simple_card_sub_parse_of
(
codec
,
&
dai_props
->
codec_dai
,
&
dai_link
->
codec_of_node
,
&
dai_link
->
codec_dai_name
,
NULL
);
ret
=
asoc_simple_card_parse_codec
(
codec
,
dai_link
,
DAI
,
CELL
);
if
(
ret
<
0
)
goto
dai_link_of_err
;
ret
=
asoc_simple_card_sub_parse_of
(
plat
,
NULL
,
&
dai_link
->
platform_of_node
,
NULL
,
NULL
);
ret
=
asoc_simple_card_parse_platform
(
plat
,
dai_link
,
DAI
,
CELL
);
if
(
ret
<
0
)
goto
dai_link_of_err
;
if
(
!
dai_link
->
cpu_dai_name
||
!
dai_link
->
codec_dai_name
)
{
ret
=
-
EINVAL
;
ret
=
snd_soc_of_parse_tdm_slot
(
cpu
,
&
cpu_dai
->
tx_slot_mask
,
&
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
;
}
/* Assumes platform == cpu */
if
(
!
dai_link
->
platform_of_node
)
dai_link
->
platform_of_node
=
dai_link
->
cpu_of_node
;
ret
=
asoc_simple_card_parse_clk_codec
(
codec
,
dai_link
,
codec_dai
);
if
(
ret
<
0
)
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
,
"%s-%s"
,
...
...
@@ -398,17 +309,7 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
dai_link
->
codec_dai_name
,
dai_props
->
codec_dai
.
sysclk
);
/*
* 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
;
asoc_simple_card_canonicalize_cpu
(
dai_link
,
single_cpu
);
dai_link_of_err:
of_node_put
(
cpu
);
...
...
@@ -477,21 +378,6 @@ static int asoc_simple_card_parse_of(struct device_node *node,
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
)
{
struct
simple_card_data
*
priv
;
...
...
@@ -577,7 +463,7 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
return
ret
;
err:
asoc_simple_card_
unref
(
&
priv
->
snd_card
);
asoc_simple_card_
clean_reference
(
&
priv
->
snd_card
);
return
ret
;
}
...
...
@@ -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
->
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
[]
=
{
...
...
sound/soc/
sh/rcar/rsrc
-card.c
→
sound/soc/
generic/simple-scu
-card.c
View file @
81af7261
/*
*
Renesas Sampling Rate Convert Sound Card for DPCM
*
ASoC simple SCU sound card support
*
* Copyright (C) 2015 Renesas Solutions Corp.
* Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
...
...
@@ -22,34 +22,7 @@
#include <sound/soc-dai.h>
#include <sound/simple_card_utils.h>
struct
rsrc_card_of_data
{
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
asoc_simple_card_priv
{
struct
snd_soc_card
snd_card
;
struct
snd_soc_codec_conf
codec_conf
;
struct
asoc_simple_dai
*
dai_props
;
...
...
@@ -58,80 +31,60 @@ struct rsrc_card_priv {
u32
convert_channels
;
};
#define rsrc_priv_to_dev(priv) ((priv)->snd_card.dev)
#define rsrc_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_dev(priv) ((priv)->snd_card.dev)
#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 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
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
=
rsrc
_priv_to_props
(
priv
,
rtd
->
num
);
simple
_priv_to_props
(
priv
,
rtd
->
num
);
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
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
=
rsrc
_priv_to_props
(
priv
,
rtd
->
num
);
simple
_priv_to_props
(
priv
,
rtd
->
num
);
clk_disable_unprepare
(
dai_props
->
clk
);
}
static
struct
snd_soc_ops
rsrc
_card_ops
=
{
.
startup
=
rsrc
_card_startup
,
.
shutdown
=
rsrc
_card_shutdown
,
static
struct
snd_soc_ops
asoc_simple
_card_ops
=
{
.
startup
=
asoc_simple
_card_startup
,
.
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_link
*
dai_link
;
struct
asoc_simple_dai
*
dai_props
;
int
num
=
rtd
->
num
;
int
ret
;
dai_link
=
rsrc
_priv_to_link
(
priv
,
num
);
dai_props
=
rsrc
_priv_to_props
(
priv
,
num
);
dai_link
=
simple
_priv_to_link
(
priv
,
num
);
dai_props
=
simple
_priv_to_props
(
priv
,
num
);
dai
=
dai_link
->
dynamic
?
rtd
->
cpu_dai
:
rtd
->
codec_dai
;
if
(
dai_props
->
sysclk
)
{
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
;
return
asoc_simple_card_init_dai
(
dai
,
dai_props
);
}
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
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
,
SNDRV_PCM_HW_PARAM_RATE
);
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,
return
0
;
}
static
int
rsrc_card_parse_links
(
struct
device_node
*
np
,
struct
rsrc_card_priv
*
priv
,
int
idx
,
bool
is_fe
)
static
int
asoc_simple_card_parse_links
(
struct
device_node
*
np
,
struct
asoc_simple_card_priv
*
priv
,
unsigned
int
daifmt
,
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
);
struct
of_phandle_args
args
;
struct
device
*
dev
=
simple_priv_to_dev
(
priv
);
struct
snd_soc_dai_link
*
dai_link
=
simple_priv_to_link
(
priv
,
idx
);
struct
asoc_simple_dai
*
dai_props
=
simple_priv_to_props
(
priv
,
idx
);
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
)
{
int
is_single_links
=
0
;
/* BE is dummy */
dai_link
->
codec_of_node
=
NULL
;
dai_link
->
codec_dai_name
=
"snd-soc-dummy-dai"
;
...
...
@@ -185,8 +122,13 @@ static int rsrc_card_parse_links(struct device_node *np,
/* FE settings */
dai_link
->
dynamic
=
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
)
return
ret
;
...
...
@@ -196,22 +138,8 @@ static int rsrc_card_parse_links(struct device_node *np,
if
(
ret
<
0
)
return
ret
;
/*
* 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
;
asoc_simple_card_canonicalize_cpu
(
dai_link
,
is_single_links
);
}
else
{
const
struct
rsrc_card_of_data
*
of_data
;
of_data
=
of_device_get_match_data
(
dev
);
/* FE is dummy */
dai_link
->
cpu_of_node
=
NULL
;
dai_link
->
cpu_dai_name
=
"snd-soc-dummy-dai"
;
...
...
@@ -219,9 +147,13 @@ static int rsrc_card_parse_links(struct device_node *np,
/* BE settings */
dai_link
->
no_pcm
=
1
;
dai_link
->
be_hw_params_fixup
=
rsrc_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
);
dai_link
->
be_hw_params_fixup
=
asoc_simple_card_be_hw_params_fixup
;
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
)
return
ret
;
...
...
@@ -231,124 +163,64 @@ static int rsrc_card_parse_links(struct device_node *np,
if
(
ret
<
0
)
return
ret
;
/* additional name prefix */
if
(
of_data
)
{
priv
->
codec_conf
.
of_node
=
dai_link
->
codec_of_node
;
priv
->
codec_conf
.
name_prefix
=
of_data
->
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
);
snd_soc_of_parse_audio_prefix
(
&
priv
->
snd_card
,
&
priv
->
codec_conf
,
dai_link
->
codec_of_node
,
PREFIX
"prefix"
);
}
return
0
;
}
static
int
rsrc_card_dai_sub_link_of
(
struct
device_node
*
node
,
struct
device_node
*
np
,
struct
rsrc_card_priv
*
priv
,
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
)
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
;
ret
=
rsrc_card_parse_clk
(
np
,
priv
,
idx
,
is_fe
);
ret
=
asoc_simple_card_canonicalize_dailink
(
dai_link
);
if
(
ret
<
0
)
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
"
,
dai_link
->
name
,
dai_link
->
dai_fmt
,
dai_props
->
sysclk
);
return
ret
;
return
0
;
}
static
int
rsrc
_card_dai_link_of
(
struct
device_node
*
node
,
struct
rsrc
_card_priv
*
priv
)
static
int
asoc_simple
_card_dai_link_of
(
struct
device_node
*
node
,
struct
asoc_simple
_card_priv
*
priv
)
{
struct
device
*
dev
=
rsrc_priv_to_dev
(
priv
);
struct
snd_soc_dai_link
*
dai_link
;
struct
device
*
dev
=
simple_priv_to_dev
(
priv
);
struct
device_node
*
np
;
unsigned
int
daifmt
=
0
;
int
ret
,
i
;
bool
is_fe
;
/* find 1st codec */
i
=
0
;
for_each_child_of_node
(
node
,
np
)
{
dai_link
=
rsrc_priv_to_link
(
priv
,
i
);
if
(
strcmp
(
np
->
name
,
"codec"
)
==
0
)
{
ret
=
asoc_simple_card_parse_daifmt
(
dev
,
node
,
np
,
NULL
,
&
daifmt
);
if
(
ret
<
0
)
return
ret
;
break
;
}
i
++
;
}
np
=
of_get_child_by_name
(
node
,
PREFIX
"codec"
);
if
(
!
np
)
return
-
ENODEV
;
ret
=
asoc_simple_card_parse_daifmt
(
dev
,
node
,
np
,
PREFIX
,
&
daifmt
);
if
(
ret
<
0
)
return
ret
;
i
=
0
;
for_each_child_of_node
(
node
,
np
)
{
dai_link
=
rsrc_priv_to_link
(
priv
,
i
);
dai_link
->
dai_fmt
=
daifmt
;
is_fe
=
false
;
if
(
strcmp
(
np
->
name
,
"cpu"
)
==
0
)
if
(
strcmp
(
np
->
name
,
PREFIX
"cpu"
)
==
0
)
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
)
return
ret
;
i
++
;
...
...
@@ -357,11 +229,10 @@ static int rsrc_card_dai_link_of(struct device_node *node,
return
0
;
}
static
int
rsrc
_card_parse_of
(
struct
device_node
*
node
,
struct
rsrc
_card_priv
*
priv
,
static
int
asoc_simple
_card_parse_of
(
struct
device_node
*
node
,
struct
asoc_simple
_card_priv
*
priv
,
struct
device
*
dev
)
{
const
struct
rsrc_card_of_data
*
of_data
=
of_device_get_match_data
(
dev
);
struct
asoc_simple_dai
*
props
;
struct
snd_soc_dai_link
*
links
;
int
ret
;
...
...
@@ -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
.
num_configs
=
1
;
if
(
of_data
)
{
priv
->
snd_card
.
of_dapm_routes
=
of_data
->
routes
;
priv
->
snd_card
.
num_of_dapm_routes
=
of_data
->
num_routes
;
}
else
{
snd_soc_of_parse_audio_routing
(
&
priv
->
snd_card
,
"audio-routing"
);
}
ret
=
snd_soc_of_parse_audio_routing
(
&
priv
->
snd_card
,
PREFIX
"routing"
);
if
(
ret
<
0
)
return
ret
;
/* 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 */
of_property_read_u32
(
node
,
"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
);
of_property_read_u32
(
node
,
PREFIX
"convert-channels"
,
&
priv
->
convert_channels
);
ret
=
rsrc
_card_dai_link_of
(
node
,
priv
);
ret
=
asoc_simple
_card_dai_link_of
(
node
,
priv
);
if
(
ret
<
0
)
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
)
return
ret
;
return
0
;
}
/* Decrease the reference count of the device nodes */
static
int
rsrc_card_unref
(
struct
snd_soc_card
*
card
)
{
struct
snd_soc_dai_link
*
dai_link
;
int
num_links
;
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
);
dev_dbg
(
dev
,
"convert_channels %d
\n
"
,
priv
->
convert_channels
);
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
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
*
dev
=
&
pdev
->
dev
;
int
ret
;
...
...
@@ -444,7 +296,7 @@ static int rsrc_card_probe(struct platform_device *pdev)
if
(
!
priv
)
return
-
ENOMEM
;
ret
=
rsrc
_card_parse_of
(
np
,
priv
,
dev
);
ret
=
asoc_simple
_card_parse_of
(
np
,
priv
,
dev
);
if
(
ret
<
0
)
{
if
(
ret
!=
-
EPROBE_DEFER
)
dev_err
(
dev
,
"parse error %d
\n
"
,
ret
);
...
...
@@ -457,30 +309,37 @@ static int rsrc_card_probe(struct platform_device *pdev)
if
(
ret
>=
0
)
return
ret
;
err:
rsrc_card_unref
(
&
priv
->
snd_card
);
asoc_simple_card_clean_reference
(
&
priv
->
snd_card
);
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
);
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
=
{
.
name
=
"
renesas-src
-audio-card"
,
.
of_match_table
=
rsrc_card
_of_match
,
.
name
=
"
simple-scu
-audio-card"
,
.
of_match_table
=
asoc_simple
_of_match
,
},
.
probe
=
rsrc
_card_probe
,
.
remove
=
rsrc
_card_remove
,
.
probe
=
asoc_simple
_card_probe
,
.
remove
=
asoc_simple
_card_remove
,
};
module_platform_driver
(
rsrc
_card
);
module_platform_driver
(
asoc_simple
_card
);
MODULE_ALIAS
(
"platform:
renesas-src-audio
-card"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_DESCRIPTION
(
"
Renesas Sampling Rate Convert
Sound Card"
);
MODULE_ALIAS
(
"platform:
asoc-simple-scu
-card"
);
MODULE_LICENSE
(
"GPL
v2
"
);
MODULE_DESCRIPTION
(
"
ASoC Simple SCU
Sound Card"
);
MODULE_AUTHOR
(
"Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"
);
sound/soc/sh/Kconfig
View file @
81af7261
...
...
@@ -42,12 +42,6 @@ config SND_SOC_RCAR
help
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
##
...
...
sound/soc/sh/rcar/Makefile
View file @
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
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
View file @
81af7261
...
...
@@ -110,6 +110,7 @@ MODULE_DEVICE_TABLE(of, rsnd_of_match);
/*
* rsnd_mod functions
*/
#ifdef DEBUG
void
rsnd_mod_make_sure
(
struct
rsnd_mod
*
mod
,
enum
rsnd_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)
rsnd_mod_name
(
mod
),
rsnd_mod_id
(
mod
));
}
}
#endif
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,
switch
(
cmd
)
{
case
SNDRV_PCM_TRIGGER_START
:
case
SNDRV_PCM_TRIGGER_RESUME
:
rsnd_dai_stream_init
(
io
,
substream
);
ret
=
rsnd_dai_call
(
init
,
io
,
priv
);
...
...
@@ -590,6 +593,7 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
break
;
case
SNDRV_PCM_TRIGGER_STOP
:
case
SNDRV_PCM_TRIGGER_SUSPEND
:
ret
=
rsnd_dai_call
(
irq
,
io
,
priv
,
0
);
ret
|=
rsnd_dai_call
(
stop
,
io
,
priv
);
...
...
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