Commit 81af7261 authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branch 'asoc/topic/rcar' into asoc-next

parents 60955521 4b9c75ea
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>;
};
};
...@@ -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 */
...@@ -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.
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
...@@ -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");
......
...@@ -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; goto dai_link_of_err;
}
/* Assumes platform == cpu */ ret = snd_soc_of_parse_tdm_slot(codec, &codec_dai->tx_slot_mask,
if (!dai_link->platform_of_node) &codec_dai->rx_slot_mask,
dai_link->platform_of_node = dai_link->cpu_of_node; &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;
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, 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[] = {
......
/* /*
* 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,
unsigned int daifmt,
int idx, bool is_fe) 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 */
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, snd_soc_of_parse_audio_prefix(&priv->snd_card,
&priv->codec_conf, &priv->codec_conf,
dai_link->codec_of_node, dai_link->codec_of_node,
"audio-prefix"); PREFIX "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,
NULL, &daifmt); PREFIX, &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", ret = asoc_simple_card_dai_link_of(node, priv);
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);
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>");
...@@ -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
## ##
......
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
...@@ -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%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment