From a3235938308150fbd0f8b478e73d1e66e945937a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 23 Aug 2016 01:33:57 +0000 Subject: ASoC: rsrc-card: remove board specific compatible rsrc-card has board specific compatible (= lager/koelsh), but these were created as 1st prototype, and it is used in my test environment only. Now normal user can use generic compatible (= renesas,rsrc-card). Removing these board specific compatible doesn't breake compatibility. This patch remove these. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt b/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt index 255ece3043ad..f148bf27723b 100644 --- a/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt +++ b/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt @@ -4,11 +4,8 @@ Renesas Sampling Rate Convert Sound Card specifies audio DAI connections of SoC Required properties: -- compatible : "renesas,rsrc-card{,}" - Examples with boards are: - - "renesas,rsrc-card" - - "renesas,rsrc-card,lager" - - "renesas,rsrc-card,koelsch" +- compatible : "renesas,rsrc-card" + Optional properties: - card_name : User specified audio sound card name, one string -- cgit v1.3-14-g43fede From 64df0e6842925311d74f6944710495981d5a0ace Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 23 Aug 2016 01:34:43 +0000 Subject: ASoC: rsrc-card: rename rsrc-card to simple-scu-card phase2 rsrc-card which is using DPCM feature was created for Renesas sound. But not only Renesas, but many SoC can use this driver, because it is based on simple-card driver. To use it as more open driver, rsrc-card will be renamed to simple-scu-card. In order to easy patch review, as 2nd step, this patch adds new compatible "simple-scu-audio-card"; rcar-card used specific property, not "simple-audio-card", but it should be now. Actually, rsrc-card is upstreamed driver, but noone is using it on upstream. The user is only local, and it is only me. Thus, there is no compatible break by this patch. This patch uses "simple-audio-card" prefix. And it removes rcar-card specifix compatible too. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- .../bindings/sound/renesas,rsrc-card.txt | 52 +++++++++++--------- sound/soc/sh/rcar/rsrc-card.c | 55 +++++++++------------- 2 files changed, 51 insertions(+), 56 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt b/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt index f148bf27723b..ecb4a249fe6e 100644 --- a/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt +++ b/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt @@ -1,35 +1,36 @@ -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" +- 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,18 +55,25 @@ Optional CPU/CODEC subnodes properties: Example 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>; }; diff --git a/sound/soc/sh/rcar/rsrc-card.c b/sound/soc/sh/rcar/rsrc-card.c index a0d0f3679eeb..3fa19084e326 100644 --- a/sound/soc/sh/rcar/rsrc-card.c +++ b/sound/soc/sh/rcar/rsrc-card.c @@ -30,6 +30,7 @@ struct asoc_simple_card_of_data { static const struct of_device_id asoc_simple_card_of_match[] = { { .compatible = "renesas,rsrc-card", }, + { .compatible = "simple-scu-audio-card", }, {}, }; MODULE_DEVICE_TABLE(of, asoc_simple_card_of_match); @@ -51,6 +52,7 @@ struct asoc_simple_card_priv { #define DAI "sound-dai" #define CELL "#sound-dai-cells" +#define PREFIX "simple-audio-card," static int asoc_simple_card_startup(struct snd_pcm_substream *substream) { @@ -161,10 +163,6 @@ static int asoc_simple_card_parse_links(struct device_node *np, asoc_simple_card_canonicalize_cpu(dai_link, is_single_links); } else { - const struct asoc_simple_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"; @@ -188,16 +186,10 @@ static int asoc_simple_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"); - } + snd_soc_of_parse_audio_prefix(&priv->snd_card, + &priv->codec_conf, + dai_link->codec_of_node, + PREFIX "prefix"); } ret = asoc_simple_card_canonicalize_dailink(dai_link); @@ -232,9 +224,9 @@ static int asoc_simple_card_dai_link_of(struct device_node *node, for_each_child_of_node(node, np) { dai_link = simple_priv_to_link(priv, i); - if (strcmp(np->name, "codec") == 0) { + if (strcmp(np->name, PREFIX "codec") == 0) { ret = asoc_simple_card_parse_daifmt(dev, node, np, - NULL, &daifmt); + PREFIX, &daifmt); if (ret < 0) return ret; break; @@ -248,7 +240,7 @@ static int asoc_simple_card_dai_link_of(struct device_node *node, 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 = asoc_simple_card_parse_links(np, priv, i, is_fe); @@ -264,7 +256,6 @@ static int asoc_simple_card_parse_of(struct device_node *node, struct asoc_simple_card_priv *priv, struct device *dev) { - const struct asoc_simple_card_of_data *of_data = of_device_get_match_data(dev); struct asoc_simple_dai *props; struct snd_soc_dai_link *links; int ret; @@ -290,33 +281,29 @@ static int asoc_simple_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 = 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; + 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); + return 0; } @@ -359,7 +346,7 @@ static int asoc_simple_card_remove(struct platform_device *pdev) static struct platform_driver asoc_simple_card = { .driver = { - .name = "renesas-src-audio-card", + .name = "simple-scu-audio-card", .of_match_table = asoc_simple_card_of_match, }, .probe = asoc_simple_card_probe, -- cgit v1.3-14-g43fede From d12c6216c4a58f9fd2a58bc489783a095d84b2fc Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 23 Aug 2016 01:35:02 +0000 Subject: ASoC: rsrc-card: rename rsrc-card to simple-scu-card phase3 rsrc-card which is using DPCM feature was created for Renesas sound. But not only Renesas, but many SoC can use this driver, because it is based on simple-card driver. To use it as more open driver, rsrc-card will be renamed to simple-scu-card. In order to easy patch review, as 3rd step, this patch moves rsrc-card driver to generic folder. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- .../bindings/sound/renesas,rsrc-card.txt | 80 ----- .../devicetree/bindings/sound/simple-scu-card.txt | 80 +++++ sound/soc/generic/Kconfig | 7 + sound/soc/generic/Makefile | 2 + sound/soc/generic/simple-scu-card.c | 361 +++++++++++++++++++++ sound/soc/sh/Kconfig | 6 - sound/soc/sh/rcar/Makefile | 3 - sound/soc/sh/rcar/rsrc-card.c | 361 --------------------- 8 files changed, 450 insertions(+), 450 deletions(-) delete mode 100644 Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt create mode 100644 Documentation/devicetree/bindings/sound/simple-scu-card.txt create mode 100644 sound/soc/generic/simple-scu-card.c delete mode 100644 sound/soc/sh/rcar/rsrc-card.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt b/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt deleted file mode 100644 index ecb4a249fe6e..000000000000 --- a/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt +++ /dev/null @@ -1,80 +0,0 @@ -ASoC simple SCU Sound Card - -Simple-Card specifies audio DAI connections of SoC <-> codec. - -Required properties: - -- compatible : "simple-scu-audio-card" - "renesas,rsrc-card" - -Optional properties: - -- simple-audio-card,name : User specified audio sound card name, one string - property. -- simple-audio-card,cpu : CPU sub-node -- simple-audio-card,codec : CODEC sub-node - -Optional subnode properties: - -- simple-audio-card,format : CPU/CODEC common audio format. - "i2s", "right_j", "left_j" , "dsp_a" - "dsp_b", "ac97", "pdm", "msb", "lsb" -- simple-audio-card,frame-master : Indicates dai-link frame master. - phandle to a cpu or codec subnode. -- simple-audio-card,bitclock-master : Indicates dai-link bit clock master. - phandle to a cpu or codec subnode. -- simple-audio-card,bitclock-inversion : bool property. Add this if the - dai-link uses bit clock inversion. -- simple-audio-card,frame-inversion : bool property. Add this if the - dai-link uses frame clock inversion. -- 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. - it can be used if compatible was "renesas,rsrc-card"; - -Required CPU/CODEC subnodes properties: - -- sound-dai : phandle and port of CPU/CODEC - -Optional CPU/CODEC subnodes properties: - -- clocks / system-clock-frequency : specify subnode's clock if needed. - it can be specified via "clocks" if system has - clock node (= common clock), or "system-clock-frequency" - (if system doens't support common clock) - If a clock is specified, it is - enabled with clk_prepare_enable() - in dai startup() and disabled with - clk_disable_unprepare() in dai - shutdown(). - -Example - -sound { - compatible = "simple-scu-audio-card"; - - 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>; - - 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: simple-audio-card,codec { - sound-dai = <&ak4643>; - system-clock-frequency = <11289600>; - }; -}; diff --git a/Documentation/devicetree/bindings/sound/simple-scu-card.txt b/Documentation/devicetree/bindings/sound/simple-scu-card.txt new file mode 100644 index 000000000000..ecb4a249fe6e --- /dev/null +++ b/Documentation/devicetree/bindings/sound/simple-scu-card.txt @@ -0,0 +1,80 @@ +ASoC simple SCU Sound Card + +Simple-Card specifies audio DAI connections of SoC <-> codec. + +Required properties: + +- compatible : "simple-scu-audio-card" + "renesas,rsrc-card" + +Optional properties: + +- simple-audio-card,name : User specified audio sound card name, one string + property. +- simple-audio-card,cpu : CPU sub-node +- simple-audio-card,codec : CODEC sub-node + +Optional subnode properties: + +- simple-audio-card,format : CPU/CODEC common audio format. + "i2s", "right_j", "left_j" , "dsp_a" + "dsp_b", "ac97", "pdm", "msb", "lsb" +- simple-audio-card,frame-master : Indicates dai-link frame master. + phandle to a cpu or codec subnode. +- simple-audio-card,bitclock-master : Indicates dai-link bit clock master. + phandle to a cpu or codec subnode. +- simple-audio-card,bitclock-inversion : bool property. Add this if the + dai-link uses bit clock inversion. +- simple-audio-card,frame-inversion : bool property. Add this if the + dai-link uses frame clock inversion. +- 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. + it can be used if compatible was "renesas,rsrc-card"; + +Required CPU/CODEC subnodes properties: + +- sound-dai : phandle and port of CPU/CODEC + +Optional CPU/CODEC subnodes properties: + +- clocks / system-clock-frequency : specify subnode's clock if needed. + it can be specified via "clocks" if system has + clock node (= common clock), or "system-clock-frequency" + (if system doens't support common clock) + If a clock is specified, it is + enabled with clk_prepare_enable() + in dai startup() and disabled with + clk_disable_unprepare() in dai + shutdown(). + +Example + +sound { + compatible = "simple-scu-audio-card"; + + 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>; + + 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: simple-audio-card,codec { + sound-dai = <&ak4643>; + system-clock-frequency = <11289600>; + }; +}; diff --git a/sound/soc/generic/Kconfig b/sound/soc/generic/Kconfig index c01c5dd68601..2d0ff037c5a1 100644 --- a/sound/soc/generic/Kconfig +++ b/sound/soc/generic/Kconfig @@ -6,3 +6,10 @@ 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" + select SND_SIMPLE_CARD_UTILS + help + This option enables generic simple SCU sound card support. + It supports DPCM of multi CPU single Codec ststem. diff --git a/sound/soc/generic/Makefile b/sound/soc/generic/Makefile index 2d53c8d70705..ee750f3023ba 100644 --- a/sound/soc/generic/Makefile +++ b/sound/soc/generic/Makefile @@ -1,5 +1,7 @@ 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 diff --git a/sound/soc/generic/simple-scu-card.c b/sound/soc/generic/simple-scu-card.c new file mode 100644 index 000000000000..3fa19084e326 --- /dev/null +++ b/sound/soc/generic/simple-scu-card.c @@ -0,0 +1,361 @@ +/* + * ASoC simple SCU sound card support + * + * Copyright (C) 2015 Renesas Solutions Corp. + * Kuninori Morimoto + * + * based on ${LINUX}/sound/soc/generic/simple-card.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct asoc_simple_card_of_data { + const char *prefix; + const struct snd_soc_dapm_route *routes; + int num_routes; +}; + +static const struct of_device_id asoc_simple_card_of_match[] = { + { .compatible = "renesas,rsrc-card", }, + { .compatible = "simple-scu-audio-card", }, + {}, +}; +MODULE_DEVICE_TABLE(of, asoc_simple_card_of_match); + +#define IDX_CPU 0 +#define IDX_CODEC 1 +struct asoc_simple_card_priv { + struct snd_soc_card snd_card; + struct snd_soc_codec_conf codec_conf; + struct asoc_simple_dai *dai_props; + struct snd_soc_dai_link *dai_link; + u32 convert_rate; + u32 convert_channels; +}; + +#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 asoc_simple_card_startup(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct asoc_simple_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); + struct asoc_simple_dai *dai_props = + simple_priv_to_props(priv, rtd->num); + + return clk_prepare_enable(dai_props->clk); +} + +static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct asoc_simple_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); + struct asoc_simple_dai *dai_props = + simple_priv_to_props(priv, rtd->num); + + clk_disable_unprepare(dai_props->clk); +} + +static struct snd_soc_ops asoc_simple_card_ops = { + .startup = asoc_simple_card_startup, + .shutdown = asoc_simple_card_shutdown, +}; + +static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) +{ + 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; + + 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; + + return asoc_simple_card_init_dai(dai, dai_props); +} + +static int asoc_simple_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + 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, + SNDRV_PCM_HW_PARAM_CHANNELS); + + if (priv->convert_rate) + rate->min = + rate->max = priv->convert_rate; + + if (priv->convert_channels) + channels->min = + channels->max = priv->convert_channels; + + return 0; +} + +static int asoc_simple_card_parse_links(struct device_node *np, + struct asoc_simple_card_priv *priv, + int idx, bool is_fe) +{ + 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; + + /* 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"; + dai_link->codec_name = "snd-soc-dummy"; + + /* FE settings */ + dai_link->dynamic = 1; + dai_link->dpcm_merged_format = 1; + + 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; + + ret = asoc_simple_card_set_dailink_name(dev, dai_link, + "fe.%s", + dai_link->cpu_dai_name); + if (ret < 0) + return ret; + + asoc_simple_card_canonicalize_cpu(dai_link, is_single_links); + } else { + /* FE is dummy */ + dai_link->cpu_of_node = NULL; + dai_link->cpu_dai_name = "snd-soc-dummy-dai"; + dai_link->cpu_name = "snd-soc-dummy"; + + /* BE settings */ + dai_link->no_pcm = 1; + 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; + + ret = asoc_simple_card_set_dailink_name(dev, dai_link, + "be.%s", + dai_link->codec_dai_name); + if (ret < 0) + return ret; + + snd_soc_of_parse_audio_prefix(&priv->snd_card, + &priv->codec_conf, + dai_link->codec_of_node, + PREFIX "prefix"); + } + + ret = asoc_simple_card_canonicalize_dailink(dai_link); + if (ret < 0) + return ret; + + 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 0; +} + +static int asoc_simple_card_dai_link_of(struct device_node *node, + struct asoc_simple_card_priv *priv) +{ + struct device *dev = simple_priv_to_dev(priv); + struct snd_soc_dai_link *dai_link; + 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 = simple_priv_to_link(priv, i); + + if (strcmp(np->name, PREFIX "codec") == 0) { + ret = asoc_simple_card_parse_daifmt(dev, node, np, + PREFIX, &daifmt); + if (ret < 0) + return ret; + break; + } + i++; + } + + i = 0; + for_each_child_of_node(node, np) { + dai_link = simple_priv_to_link(priv, i); + dai_link->dai_fmt = daifmt; + + is_fe = false; + if (strcmp(np->name, PREFIX "cpu") == 0) + is_fe = true; + + ret = asoc_simple_card_parse_links(np, priv, i, is_fe); + if (ret < 0) + return ret; + i++; + } + + return 0; +} + +static int asoc_simple_card_parse_of(struct device_node *node, + struct asoc_simple_card_priv *priv, + struct device *dev) +{ + struct asoc_simple_dai *props; + struct snd_soc_dai_link *links; + int ret; + int num; + + if (!node) + return -EINVAL; + + num = of_get_child_count(node); + props = devm_kzalloc(dev, sizeof(*props) * num, GFP_KERNEL); + links = devm_kzalloc(dev, sizeof(*links) * num, GFP_KERNEL); + if (!props || !links) + return -ENOMEM; + + priv->dai_props = props; + priv->dai_link = links; + + /* Init snd_soc_card */ + priv->snd_card.owner = THIS_MODULE; + priv->snd_card.dev = dev; + priv->snd_card.dai_link = priv->dai_link; + priv->snd_card.num_links = num; + priv->snd_card.codec_conf = &priv->codec_conf; + priv->snd_card.num_configs = 1; + + 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, PREFIX "convert-rate", &priv->convert_rate); + + /* channels transfer */ + of_property_read_u32(node, PREFIX "convert-channels", &priv->convert_channels); + + ret = asoc_simple_card_dai_link_of(node, priv); + if (ret < 0) + return ret; + + ret = asoc_simple_card_parse_card_name(&priv->snd_card, PREFIX); + if (ret < 0) + return ret; + + 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); + + return 0; +} + +static int asoc_simple_card_probe(struct platform_device *pdev) +{ + struct asoc_simple_card_priv *priv; + struct device_node *np = pdev->dev.of_node; + struct device *dev = &pdev->dev; + int ret; + + /* Allocate the private data */ + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + ret = asoc_simple_card_parse_of(np, priv, dev); + if (ret < 0) { + if (ret != -EPROBE_DEFER) + dev_err(dev, "parse error %d\n", ret); + goto err; + } + + snd_soc_card_set_drvdata(&priv->snd_card, priv); + + ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card); + if (ret >= 0) + return ret; +err: + asoc_simple_card_clean_reference(&priv->snd_card); + + return ret; +} + +static int asoc_simple_card_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + + return asoc_simple_card_clean_reference(card); +} + +static struct platform_driver asoc_simple_card = { + .driver = { + .name = "simple-scu-audio-card", + .of_match_table = asoc_simple_card_of_match, + }, + .probe = asoc_simple_card_probe, + .remove = asoc_simple_card_remove, +}; + +module_platform_driver(asoc_simple_card); + +MODULE_ALIAS("platform:asoc-simple-scu-card"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("ASoC Simple SCU Sound Card"); +MODULE_AUTHOR("Kuninori Morimoto "); diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig index 9311f119feb5..6db6405d952f 100644 --- a/sound/soc/sh/Kconfig +++ b/sound/soc/sh/Kconfig @@ -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 ## diff --git a/sound/soc/sh/rcar/Makefile b/sound/soc/sh/rcar/Makefile index a89ddf758695..9c3d5aed99d1 100644 --- a/sound/soc/sh/rcar/Makefile +++ b/sound/soc/sh/rcar/Makefile @@ -1,5 +1,2 @@ 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 diff --git a/sound/soc/sh/rcar/rsrc-card.c b/sound/soc/sh/rcar/rsrc-card.c deleted file mode 100644 index 3fa19084e326..000000000000 --- a/sound/soc/sh/rcar/rsrc-card.c +++ /dev/null @@ -1,361 +0,0 @@ -/* - * ASoC simple SCU sound card support - * - * Copyright (C) 2015 Renesas Solutions Corp. - * Kuninori Morimoto - * - * based on ${LINUX}/sound/soc/generic/simple-card.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct asoc_simple_card_of_data { - const char *prefix; - const struct snd_soc_dapm_route *routes; - int num_routes; -}; - -static const struct of_device_id asoc_simple_card_of_match[] = { - { .compatible = "renesas,rsrc-card", }, - { .compatible = "simple-scu-audio-card", }, - {}, -}; -MODULE_DEVICE_TABLE(of, asoc_simple_card_of_match); - -#define IDX_CPU 0 -#define IDX_CODEC 1 -struct asoc_simple_card_priv { - struct snd_soc_card snd_card; - struct snd_soc_codec_conf codec_conf; - struct asoc_simple_dai *dai_props; - struct snd_soc_dai_link *dai_link; - u32 convert_rate; - u32 convert_channels; -}; - -#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 asoc_simple_card_startup(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct asoc_simple_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); - struct asoc_simple_dai *dai_props = - simple_priv_to_props(priv, rtd->num); - - return clk_prepare_enable(dai_props->clk); -} - -static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct asoc_simple_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); - struct asoc_simple_dai *dai_props = - simple_priv_to_props(priv, rtd->num); - - clk_disable_unprepare(dai_props->clk); -} - -static struct snd_soc_ops asoc_simple_card_ops = { - .startup = asoc_simple_card_startup, - .shutdown = asoc_simple_card_shutdown, -}; - -static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) -{ - 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; - - 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; - - return asoc_simple_card_init_dai(dai, dai_props); -} - -static int asoc_simple_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) -{ - 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, - SNDRV_PCM_HW_PARAM_CHANNELS); - - if (priv->convert_rate) - rate->min = - rate->max = priv->convert_rate; - - if (priv->convert_channels) - channels->min = - channels->max = priv->convert_channels; - - return 0; -} - -static int asoc_simple_card_parse_links(struct device_node *np, - struct asoc_simple_card_priv *priv, - int idx, bool is_fe) -{ - 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; - - /* 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"; - dai_link->codec_name = "snd-soc-dummy"; - - /* FE settings */ - dai_link->dynamic = 1; - dai_link->dpcm_merged_format = 1; - - 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; - - ret = asoc_simple_card_set_dailink_name(dev, dai_link, - "fe.%s", - dai_link->cpu_dai_name); - if (ret < 0) - return ret; - - asoc_simple_card_canonicalize_cpu(dai_link, is_single_links); - } else { - /* FE is dummy */ - dai_link->cpu_of_node = NULL; - dai_link->cpu_dai_name = "snd-soc-dummy-dai"; - dai_link->cpu_name = "snd-soc-dummy"; - - /* BE settings */ - dai_link->no_pcm = 1; - 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; - - ret = asoc_simple_card_set_dailink_name(dev, dai_link, - "be.%s", - dai_link->codec_dai_name); - if (ret < 0) - return ret; - - snd_soc_of_parse_audio_prefix(&priv->snd_card, - &priv->codec_conf, - dai_link->codec_of_node, - PREFIX "prefix"); - } - - ret = asoc_simple_card_canonicalize_dailink(dai_link); - if (ret < 0) - return ret; - - 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 0; -} - -static int asoc_simple_card_dai_link_of(struct device_node *node, - struct asoc_simple_card_priv *priv) -{ - struct device *dev = simple_priv_to_dev(priv); - struct snd_soc_dai_link *dai_link; - 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 = simple_priv_to_link(priv, i); - - if (strcmp(np->name, PREFIX "codec") == 0) { - ret = asoc_simple_card_parse_daifmt(dev, node, np, - PREFIX, &daifmt); - if (ret < 0) - return ret; - break; - } - i++; - } - - i = 0; - for_each_child_of_node(node, np) { - dai_link = simple_priv_to_link(priv, i); - dai_link->dai_fmt = daifmt; - - is_fe = false; - if (strcmp(np->name, PREFIX "cpu") == 0) - is_fe = true; - - ret = asoc_simple_card_parse_links(np, priv, i, is_fe); - if (ret < 0) - return ret; - i++; - } - - return 0; -} - -static int asoc_simple_card_parse_of(struct device_node *node, - struct asoc_simple_card_priv *priv, - struct device *dev) -{ - struct asoc_simple_dai *props; - struct snd_soc_dai_link *links; - int ret; - int num; - - if (!node) - return -EINVAL; - - num = of_get_child_count(node); - props = devm_kzalloc(dev, sizeof(*props) * num, GFP_KERNEL); - links = devm_kzalloc(dev, sizeof(*links) * num, GFP_KERNEL); - if (!props || !links) - return -ENOMEM; - - priv->dai_props = props; - priv->dai_link = links; - - /* Init snd_soc_card */ - priv->snd_card.owner = THIS_MODULE; - priv->snd_card.dev = dev; - priv->snd_card.dai_link = priv->dai_link; - priv->snd_card.num_links = num; - priv->snd_card.codec_conf = &priv->codec_conf; - priv->snd_card.num_configs = 1; - - 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, PREFIX "convert-rate", &priv->convert_rate); - - /* channels transfer */ - of_property_read_u32(node, PREFIX "convert-channels", &priv->convert_channels); - - ret = asoc_simple_card_dai_link_of(node, priv); - if (ret < 0) - return ret; - - ret = asoc_simple_card_parse_card_name(&priv->snd_card, PREFIX); - if (ret < 0) - return ret; - - 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); - - return 0; -} - -static int asoc_simple_card_probe(struct platform_device *pdev) -{ - struct asoc_simple_card_priv *priv; - struct device_node *np = pdev->dev.of_node; - struct device *dev = &pdev->dev; - int ret; - - /* Allocate the private data */ - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - ret = asoc_simple_card_parse_of(np, priv, dev); - if (ret < 0) { - if (ret != -EPROBE_DEFER) - dev_err(dev, "parse error %d\n", ret); - goto err; - } - - snd_soc_card_set_drvdata(&priv->snd_card, priv); - - ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card); - if (ret >= 0) - return ret; -err: - asoc_simple_card_clean_reference(&priv->snd_card); - - return ret; -} - -static int asoc_simple_card_remove(struct platform_device *pdev) -{ - struct snd_soc_card *card = platform_get_drvdata(pdev); - - return asoc_simple_card_clean_reference(card); -} - -static struct platform_driver asoc_simple_card = { - .driver = { - .name = "simple-scu-audio-card", - .of_match_table = asoc_simple_card_of_match, - }, - .probe = asoc_simple_card_probe, - .remove = asoc_simple_card_remove, -}; - -module_platform_driver(asoc_simple_card); - -MODULE_ALIAS("platform:asoc-simple-scu-card"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("ASoC Simple SCU Sound Card"); -MODULE_AUTHOR("Kuninori Morimoto "); -- cgit v1.3-14-g43fede From e5a01eb5fc6f0e77033f005e6b5f7fb8b4ea837f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 25 Aug 2016 01:58:10 +0000 Subject: ASoC: simple-scu-card: add 2 CPU 1 Codec example Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/simple-scu-card.txt | 32 +++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/sound/simple-scu-card.txt b/Documentation/devicetree/bindings/sound/simple-scu-card.txt index ecb4a249fe6e..d6fe47ed09af 100644 --- a/Documentation/devicetree/bindings/sound/simple-scu-card.txt +++ b/Documentation/devicetree/bindings/sound/simple-scu-card.txt @@ -52,7 +52,7 @@ Optional CPU/CODEC subnodes properties: clk_disable_unprepare() in dai shutdown(). -Example +Example 1. Sampling Rate Covert sound { compatible = "simple-scu-audio-card"; @@ -78,3 +78,33 @@ sound { 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>; + }; +}; -- cgit v1.3-14-g43fede