All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] ASoC: rsnd: DPCM base sampling rate convert support
@ 2015-03-24  5:02 Kuninori Morimoto
       [not found] ` <878uen3s5m.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
  0 siblings, 1 reply; 7+ messages in thread
From: Kuninori Morimoto @ 2015-03-24  5:02 UTC (permalink / raw)
  To: Mark Brown, Linux-DT; +Cc: Simon, Linux-ALSA, Liam Girdwood, Das Biju


Hi Mark

These are remains of my previous patch set.
Basically, these doesn't need soc-core's new feature, but it is assuming
DPCM base sampling rate convert has both playback/capture in same time.

1 - 2: new Renesas sound card for DPCM
3    : bug fix patch. it can be applied in linus/master branch
4 - 5: new feature, but based on 3) patch

Kuninori Morimoto (5):
      1) ASoC: rsrc-card: add Renesas sampling rate convert sound card support
      2) ASoC: rsrc-card: add .be_hw_params_fixup support for convert rate
      3) ASoC: rsnd: call clk_prepare_enable/unprepare() in probe/remove
      4) ASoC: rsnd: remove useless debug message
      5) ASoC: rsnd: add DPCM based sampling rate convert

 Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt |  67 +++++++++++++
 sound/soc/sh/Kconfig                                          |   5 +
 sound/soc/sh/rcar/Makefile                                    |   5 +-
 sound/soc/sh/rcar/adg.c                                       |   2 -
 sound/soc/sh/rcar/core.c                                      |  25 ++++-
 sound/soc/sh/rcar/dma.c                                       |   4 -
 sound/soc/sh/rcar/dvc.c                                       |  28 +-----
 sound/soc/sh/rcar/gen.c                                       |   4 -
 sound/soc/sh/rcar/rsnd.h                                      |  12 ++-
 sound/soc/sh/rcar/rsrc-card.c                                 | 512 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sound/soc/sh/rcar/src.c                                       |  84 +++++++++-------
 sound/soc/sh/rcar/ssi.c                                       |  31 ++----
 12 files changed, 683 insertions(+), 96 deletions(-)
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/5] ASoC: rsrc-card: add Renesas sampling rate convert sound card support
       [not found] ` <878uen3s5m.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
@ 2015-03-24  5:03   ` Kuninori Morimoto
  2015-03-24  5:04   ` [PATCH 2/5] ASoC: rsrc-card: add .be_hw_params_fixup support for convert rate Kuninori Morimoto
                     ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Kuninori Morimoto @ 2015-03-24  5:03 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux-DT, Simon, Linux-ALSA, Liam Girdwood, Das Biju

From: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>

Renesas sound card has "sampling rate convert" feature which
should be implemented via DPCM.
But, sound card driver point of view, it is difficult to add
this DPCM feature on simple-card driver. Especially, DT binding
support is very difficult.

This patch implements DPCM feature on DT as Renesas specific sound card.
This new driver is copied from current simple-card driver.
Main difference between simple-card and this driver are...
 1. removed unused feature from simple-card
 2. removed driver named prefix from DT property
 3. CPU will be FE, CODEC will be BE with snd-soc-dummy
 4. it supports sampling rate convert via .be_hw_params_fixup
 5. board specific routing is implemented in driver
 6. it support DT boot only

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
---
 - it doesn't need soc-core feature

 .../bindings/sound/renesas,rsrc-card.txt           |  66 +++
 sound/soc/sh/Kconfig                               |   5 +
 sound/soc/sh/rcar/Makefile                         |   5 +-
 sound/soc/sh/rcar/rsrc-card.c                      | 489 +++++++++++++++++++++
 4 files changed, 564 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt
 create mode 100644 sound/soc/sh/rcar/rsrc-card.c

diff --git a/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt b/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt
new file mode 100644
index 0000000..12e287e
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt
@@ -0,0 +1,66 @@
+Renesas Sampling Rate Convert Sound Card:
+
+Renesas Sampling Rate Convert Sound Card specifies audio DAI connections of SoC <-> codec.
+
+Required properties:
+
+- compatible				: "renesas,rsrc-card,<board>"
+					  Examples with soctypes are:
+					    - "renesas,rsrc-card,lager"
+					    - "renesas,rsrc-card,koelsch"
+Optional properties:
+
+- card_name				: User specified audio sound card name, one string
+					  property.
+- cpu					: CPU   sub-node
+- codec					: CODEC sub-node
+
+Optional subnode properties:
+
+- 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.
+					  phandle to a cpu or codec subnode.
+- bitclock-master			: Indicates dai-link bit clock master.
+					  phandle to a cpu or codec subnode.
+- bitclock-inversion			: bool property. Add this if the
+					  dai-link uses bit clock inversion.
+- frame-inversion			: bool property. Add this if the
+					  dai-link uses frame clock inversion.
+
+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 = "renesas,rsrc-card,lager";
+
+	card-name = "rsnd-ak4643";
+	format = "left_j";
+	bitclock-master = <&sndcodec>;
+	frame-master = <&sndcodec>;
+
+	sndcpu: cpu {
+		sound-dai = <&rcar_sound>;
+	};
+
+	sndcodec: codec {
+		sound-dai = <&ak4643>;
+		system-clock-frequency = <11289600>;
+	};
+};
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index 80245b6..2b30304 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -41,6 +41,11 @@ config SND_SOC_RCAR
 	help
 	  This option enables R-Car SUR/SCU/SSIU/SSI sound support
 
+config SND_SOC_RSRC_CARD
+	tristate "Renesas Sampling Rate Convert Sound Card"
+	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 7b20492..f1b4451 100644
--- a/sound/soc/sh/rcar/Makefile
+++ b/sound/soc/sh/rcar/Makefile
@@ -1,2 +1,5 @@
 snd-soc-rcar-objs	:= core.o gen.o dma.o src.o adg.o ssi.o dvc.o
-obj-$(CONFIG_SND_SOC_RCAR)	+= snd-soc-rcar.o
\ No newline at end of file
+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
new file mode 100644
index 0000000..3baeab7
--- /dev/null
+++ b/sound/soc/sh/rcar/rsrc-card.c
@@ -0,0 +1,489 @@
+/*
+ * Renesas Sampling Rate Convert Sound Card for DPCM
+ *
+ * Copyright (C) 2015 Renesas Solutions Corp.
+ * Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
+ *
+ * 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 <linux/clk.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/string.h>
+#include <sound/jack.h>
+#include <sound/soc.h>
+#include <sound/soc-dai.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 },
+	{},
+};
+MODULE_DEVICE_TABLE(of, rsrc_card_of_match);
+
+struct rsrc_card_dai {
+	const char *name;
+	unsigned int fmt;
+	unsigned int sysclk;
+	struct clk *clk;
+};
+
+#define RSRC_FB_NUM	2 /* FE/BE */
+#define IDX_CPU		0
+#define IDX_CODEC	1
+struct rsrc_card_priv {
+	struct snd_soc_card snd_card;
+	struct rsrc_card_dai_props {
+		struct rsrc_card_dai cpu_dai;
+		struct rsrc_card_dai codec_dai;
+	} dai_props[RSRC_FB_NUM];
+	struct snd_soc_codec_conf codec_conf;
+	struct snd_soc_dai_link dai_link[RSRC_FB_NUM];
+};
+
+#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 rsrc_dev_to_of_data(dev) (of_match_device(rsrc_card_of_match, (dev))->data)
+
+static int rsrc_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 rsrc_card_dai_props *dai_props =
+		&priv->dai_props[rtd - rtd->card->rtd];
+	int ret;
+
+	ret = clk_prepare_enable(dai_props->cpu_dai.clk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(dai_props->codec_dai.clk);
+	if (ret)
+		clk_disable_unprepare(dai_props->cpu_dai.clk);
+
+	return ret;
+}
+
+static void rsrc_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 rsrc_card_dai_props *dai_props =
+		&priv->dai_props[rtd - rtd->card->rtd];
+
+	clk_disable_unprepare(dai_props->cpu_dai.clk);
+
+	clk_disable_unprepare(dai_props->codec_dai.clk);
+}
+
+static struct snd_soc_ops rsrc_card_ops = {
+	.startup = rsrc_card_startup,
+	.shutdown = rsrc_card_shutdown,
+};
+
+static int __rsrc_card_dai_init(struct snd_soc_dai *dai,
+				struct rsrc_card_dai *set)
+{
+	int ret;
+
+	if (set->fmt) {
+		ret = snd_soc_dai_set_fmt(dai, set->fmt);
+		if (ret && ret != -ENOTSUPP) {
+			dev_err(dai->dev, "set_fmt error\n");
+			goto err;
+		}
+	}
+
+	if (set->sysclk) {
+		ret = snd_soc_dai_set_sysclk(dai, 0, set->sysclk, 0);
+		if (ret && ret != -ENOTSUPP) {
+			dev_err(dai->dev, "set_sysclk error\n");
+			goto err;
+		}
+	}
+
+	ret = 0;
+
+err:
+	return ret;
+}
+
+static int rsrc_card_dai_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct rsrc_card_priv *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 rsrc_card_dai_props *dai_props;
+	int num, ret;
+
+	num = rtd - rtd->card->rtd;
+	dai_props = &priv->dai_props[num];
+	ret = __rsrc_card_dai_init(codec, &dai_props->codec_dai);
+	if (ret < 0)
+		return ret;
+
+	ret = __rsrc_card_dai_init(cpu, &dai_props->cpu_dai);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int
+rsrc_card_sub_parse_of(struct rsrc_card_priv *priv,
+		       struct device_node *np,
+		       struct rsrc_card_dai *dai,
+		       struct snd_soc_dai_link *dai_link,
+		       int *args_count)
+{
+	struct device *dev = rsrc_priv_to_dev(priv);
+	const struct rsrc_card_of_data *of_data = rsrc_dev_to_of_data(dev);
+	struct of_phandle_args args;
+	struct device_node **p_node;
+	struct clk *clk;
+	const char **dai_name;
+	const char **name;
+	u32 val;
+	int ret;
+
+	if (args_count) {
+		p_node		= &dai_link->cpu_of_node;
+		dai_name	= &dai_link->cpu_dai_name;
+		name		= &dai_link->cpu_name;
+	} else {
+		p_node		= &dai_link->codec_of_node;
+		dai_name	= &dai_link->codec_dai_name;
+		name		= &dai_link->codec_name;
+	}
+
+	if (!np) {
+		/* use snd-soc-dummy */
+		*p_node		= NULL;
+		*dai_name	= "snd-soc-dummy-dai";
+		*name		= "snd-soc-dummy";
+		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;
+
+	/* Get dai->name */
+	ret = snd_soc_of_get_dai_name(np, dai_name);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * FIXME
+	 *
+	 * rsrc assumes DPCM playback/capture
+	 */
+	dai_link->dpcm_playback = 1;
+	dai_link->dpcm_capture = 1;
+
+	if (args_count) {
+		*args_count = args.args_count;
+		dai_link->dynamic = 1;
+	} else {
+		dai_link->no_pcm = 1;
+		priv->codec_conf.of_node = (*p_node);
+		priv->codec_conf.name_prefix = of_data->prefix;
+	}
+
+	/*
+	 * 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 rsrc_card_parse_daifmt(struct device_node *node,
+				  struct rsrc_card_priv *priv,
+				  struct device_node *codec,
+				  int idx)
+{
+	struct device_node *bitclkmaster = NULL;
+	struct device_node *framemaster = NULL;
+	struct rsrc_card_dai_props *dai_props = rsrc_priv_to_props(priv, idx);
+	struct rsrc_card_dai *cpu_dai = &dai_props->cpu_dai;
+	struct rsrc_card_dai *codec_dai = &dai_props->codec_dai;
+	unsigned int daifmt;
+
+	daifmt = snd_soc_of_parse_daifmt(node, NULL,
+					 &bitclkmaster, &framemaster);
+	daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
+
+	if (!bitclkmaster && !framemaster)
+		return -EINVAL;
+
+	if (codec == bitclkmaster)
+		daifmt |= (codec == framemaster) ?
+			SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS;
+	else
+		daifmt |= (codec == framemaster) ?
+			SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS;
+
+	cpu_dai->fmt	= daifmt;
+	codec_dai->fmt	= daifmt;
+
+	of_node_put(bitclkmaster);
+	of_node_put(framemaster);
+
+	return 0;
+}
+
+static int rsrc_card_dai_link_of(struct device_node *node,
+				 struct rsrc_card_priv *priv,
+				 int idx)
+{
+	struct device *dev = rsrc_priv_to_dev(priv);
+	struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx);
+	struct rsrc_card_dai_props *dai_props = rsrc_priv_to_props(priv, idx);
+	struct device_node *cpu = NULL;
+	struct device_node *codec = NULL;
+	char *name;
+	char prop[128];
+	int ret, cpu_args;
+
+	cpu = of_get_child_by_name(node, "cpu");
+	codec = of_get_child_by_name(node, "codec");
+
+	if (!cpu || !codec) {
+		ret = -EINVAL;
+		dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop);
+		goto dai_link_of_err;
+	}
+
+	ret = rsrc_card_parse_daifmt(node, priv, codec, idx);
+	if (ret < 0)
+		goto dai_link_of_err;
+
+	ret = rsrc_card_sub_parse_of(priv, (idx == IDX_CPU) ? cpu : NULL,
+				     &dai_props->cpu_dai,
+				     dai_link,
+				     &cpu_args);
+	if (ret < 0)
+		goto dai_link_of_err;
+
+	ret = rsrc_card_sub_parse_of(priv, (idx == IDX_CODEC) ? codec : NULL,
+				     &dai_props->codec_dai,
+				     dai_link,
+				     NULL);
+	if (ret < 0)
+		goto dai_link_of_err;
+
+	if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) {
+		ret = -EINVAL;
+		goto dai_link_of_err;
+	}
+
+	/* Simple Card assumes platform == cpu */
+	dai_link->platform_of_node = dai_link->cpu_of_node;
+
+	/* DAI link name is created from CPU/CODEC dai name */
+	name = devm_kzalloc(dev,
+			    strlen(dai_link->cpu_dai_name)   +
+			    strlen(dai_link->codec_dai_name) + 2,
+			    GFP_KERNEL);
+	if (!name) {
+		ret = -ENOMEM;
+		goto dai_link_of_err;
+	}
+
+	sprintf(name, "%s-%s", dai_link->cpu_dai_name,
+		dai_link->codec_dai_name);
+	dai_link->name = dai_link->stream_name = name;
+	dai_link->ops = &rsrc_card_ops;
+	dai_link->init = rsrc_card_dai_init;
+
+	dev_dbg(dev, "\tname : %s\n", dai_link->stream_name);
+	dev_dbg(dev, "\tcpu : %s / %04x / %d\n",
+		dai_link->cpu_dai_name,
+		dai_props->cpu_dai.fmt,
+		dai_props->cpu_dai.sysclk);
+	dev_dbg(dev, "\tcodec : %s / %04x / %d\n",
+		dai_link->codec_dai_name,
+		dai_props->codec_dai.fmt,
+		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;
+
+dai_link_of_err:
+	of_node_put(cpu);
+	of_node_put(codec);
+
+	return ret;
+}
+
+static int rsrc_card_parse_of(struct device_node *node,
+			      struct rsrc_card_priv *priv)
+{
+	struct device *dev = rsrc_priv_to_dev(priv);
+	const struct rsrc_card_of_data *of_data = rsrc_dev_to_of_data(dev);
+	int ret;
+	int i;
+
+	if (!node)
+		return -EINVAL;
+
+	/* Parse the card name from DT */
+	snd_soc_of_parse_card_name(&priv->snd_card, "card-name");
+
+	/* DAPM routes */
+	priv->snd_card.of_dapm_routes		= of_data->routes;
+	priv->snd_card.num_of_dapm_routes	= of_data->num_routes;
+
+	dev_dbg(dev, "New rsrc-audio-card: %s\n", priv->snd_card.name ?
+		priv->snd_card.name : "");
+
+	/* FE/BE */
+	for (i = 0; i < RSRC_FB_NUM; i++) {
+		ret = rsrc_card_dai_link_of(node, priv, i);
+		if (ret < 0)
+			return ret;
+	}
+
+	if (!priv->snd_card.name)
+		priv->snd_card.name = priv->snd_card.dai_link->name;
+
+	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;
+
+	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)
+{
+	struct rsrc_card_priv *priv;
+	struct snd_soc_dai_link *dai_link;
+	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;
+
+	/* Init snd_soc_card */
+	priv->snd_card.owner = THIS_MODULE;
+	priv->snd_card.dev = dev;
+	dai_link = priv->dai_link;
+	priv->snd_card.dai_link = dai_link;
+	priv->snd_card.num_links = RSRC_FB_NUM;
+	priv->snd_card.codec_conf = &priv->codec_conf;
+	priv->snd_card.num_configs = 1;
+
+	ret = rsrc_card_parse_of(np, priv);
+	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:
+	rsrc_card_unref(&priv->snd_card);
+
+	return ret;
+}
+
+static int rsrc_card_remove(struct platform_device *pdev)
+{
+	struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+	return rsrc_card_unref(card);
+}
+
+static struct platform_driver rsrc_card = {
+	.driver = {
+		.name = "renesas-src-audio-card",
+		.of_match_table = rsrc_card_of_match,
+	},
+	.probe = rsrc_card_probe,
+	.remove = rsrc_card_remove,
+};
+
+module_platform_driver(rsrc_card);
+
+MODULE_ALIAS("platform:renesas-src-audio-card");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Renesas Sampling Rate Convert Sound Card");
+MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>");
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/5] ASoC: rsrc-card: add .be_hw_params_fixup support for convert rate
       [not found] ` <878uen3s5m.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
  2015-03-24  5:03   ` [PATCH 1/5] ASoC: rsrc-card: add Renesas sampling rate convert sound card support Kuninori Morimoto
@ 2015-03-24  5:04   ` Kuninori Morimoto
  2015-03-24  5:04   ` [PATCH 3/5] ASoC: rsnd: call clk_prepare_enable/unprepare() from probe/remove Kuninori Morimoto
                     ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Kuninori Morimoto @ 2015-03-24  5:04 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux-DT, Simon, Linux-ALSA, Liam Girdwood, Das Biju

From: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>

Current rsnd-dpcm-card is supporting DPCM FE/BE sound card.
This patch adds .be_hw_params_fixup and enabled sampling convert rate.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
---
- no change

 .../bindings/sound/renesas,rsrc-card.txt           |  1 +
 sound/soc/sh/rcar/rsrc-card.c                      | 27 ++++++++++++++++++++--
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt b/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt
index 12e287e..c641550 100644
--- a/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt
+++ b/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt
@@ -28,6 +28,7 @@ Optional subnode properties:
 					  dai-link uses bit clock inversion.
 - frame-inversion			: bool property. Add this if the
 					  dai-link uses frame clock inversion.
+- convert-rate				: platform specified sampling rate convert
 
 Required CPU/CODEC subnodes properties:
 
diff --git a/sound/soc/sh/rcar/rsrc-card.c b/sound/soc/sh/rcar/rsrc-card.c
index 3baeab7..a68517a 100644
--- a/sound/soc/sh/rcar/rsrc-card.c
+++ b/sound/soc/sh/rcar/rsrc-card.c
@@ -63,6 +63,7 @@ struct rsrc_card_priv {
 	} dai_props[RSRC_FB_NUM];
 	struct snd_soc_codec_conf codec_conf;
 	struct snd_soc_dai_link dai_link[RSRC_FB_NUM];
+	u32 convert_rate;
 };
 
 #define rsrc_priv_to_dev(priv) ((priv)->snd_card.dev)
@@ -154,6 +155,21 @@ static int rsrc_card_dai_init(struct snd_soc_pcm_runtime *rtd)
 	return 0;
 }
 
+static int rsrc_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 snd_interval *rate = hw_param_interval(params,
+						      SNDRV_PCM_HW_PARAM_RATE);
+
+	if (!priv->convert_rate)
+		return 0;
+
+	rate->min = rate->max = priv->convert_rate;
+
+	return 0;
+}
+
 static int
 rsrc_card_sub_parse_of(struct rsrc_card_priv *priv,
 		       struct device_node *np,
@@ -347,6 +363,9 @@ static int rsrc_card_dai_link_of(struct device_node *node,
 	dai_link->ops = &rsrc_card_ops;
 	dai_link->init = rsrc_card_dai_init;
 
+	if (idx == IDX_CODEC)
+		dai_link->be_hw_params_fixup = rsrc_card_be_hw_params_fixup;
+
 	dev_dbg(dev, "\tname : %s\n", dai_link->stream_name);
 	dev_dbg(dev, "\tcpu : %s / %04x / %d\n",
 		dai_link->cpu_dai_name,
@@ -394,8 +413,12 @@ static int rsrc_card_parse_of(struct device_node *node,
 	priv->snd_card.of_dapm_routes		= of_data->routes;
 	priv->snd_card.num_of_dapm_routes	= of_data->num_routes;
 
-	dev_dbg(dev, "New rsrc-audio-card: %s\n", priv->snd_card.name ?
-		priv->snd_card.name : "");
+	/* sampling rate convert */
+	of_property_read_u32(node, "convert-rate", &priv->convert_rate);
+
+	dev_dbg(dev, "New rsrc-audio-card: %s (%d)\n",
+		priv->snd_card.name ? priv->snd_card.name : "",
+		priv->convert_rate);
 
 	/* FE/BE */
 	for (i = 0; i < RSRC_FB_NUM; i++) {
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/5] ASoC: rsnd: call clk_prepare_enable/unprepare() from probe/remove
       [not found] ` <878uen3s5m.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
  2015-03-24  5:03   ` [PATCH 1/5] ASoC: rsrc-card: add Renesas sampling rate convert sound card support Kuninori Morimoto
  2015-03-24  5:04   ` [PATCH 2/5] ASoC: rsrc-card: add .be_hw_params_fixup support for convert rate Kuninori Morimoto
@ 2015-03-24  5:04   ` Kuninori Morimoto
  2015-03-24  5:05   ` [PATCH 4/5] ASoC: rsnd: remove useless debug message Kuninori Morimoto
                     ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Kuninori Morimoto @ 2015-03-24  5:04 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux-DT, Simon, Linux-ALSA, Liam Girdwood, Das Biju

From: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>

clk_prepare_enable/unprepare() uses mutex inside, and it uses __schedule().
Then, raw_spin_lock/unlock_irq() is called, and it breaks Renesas
sound driver's spin lock irq.
This patch moves clk_prepare_enable/unprepare to probe/remove function.
Special thanks to Das Biju.

Reported-by: Das Biju <biju.das-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org>
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
---
 - it should goes to linus/master too

 sound/soc/sh/rcar/core.c | 14 ++++++++++++++
 sound/soc/sh/rcar/dvc.c  | 20 +++++++-------------
 sound/soc/sh/rcar/rsnd.h |  4 ++--
 sound/soc/sh/rcar/src.c  | 18 ++++++++++++------
 sound/soc/sh/rcar/ssi.c  | 25 ++++++++++++++++---------
 5 files changed, 51 insertions(+), 30 deletions(-)

diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 8d67042..398eb8f 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -157,6 +157,20 @@ void rsnd_mod_init(struct rsnd_mod *mod,
 	mod->clk	= clk;
 }
 
+int rsnd_mod_probe(struct rsnd_mod *mod,
+		   struct rsnd_priv *priv)
+{
+	return clk_prepare_enable(mod->clk);
+}
+
+int rsnd_mod_remove(struct rsnd_mod *mod,
+		    struct rsnd_priv *priv)
+{
+	clk_disable_unprepare(mod->clk);
+
+	return 0;
+}
+
 /*
  *	settting function
  */
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c
index aeeef13..8f7558c 100644
--- a/sound/soc/sh/rcar/dvc.c
+++ b/sound/soc/sh/rcar/dvc.c
@@ -123,11 +123,16 @@ static int rsnd_dvc_probe_gen2(struct rsnd_mod *mod,
 			       struct rsnd_priv *priv)
 {
 	struct device *dev = rsnd_priv_to_dev(priv);
+	int ret;
+
+	ret = rsnd_mod_probe(mod, priv);
+	if (ret)
+		return ret;
 
 	dev_dbg(dev, "%s[%d] (Gen2) is probed\n",
 		rsnd_mod_name(mod), rsnd_mod_id(mod));
 
-	return 0;
+	return ret;
 }
 
 static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod,
@@ -141,7 +146,7 @@ static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod,
 	rsnd_kctrl_remove(dvc->rup);
 	rsnd_kctrl_remove(dvc->rdown);
 
-	return 0;
+	return rsnd_mod_remove(mod, priv);
 }
 
 static int rsnd_dvc_init(struct rsnd_mod *dvc_mod,
@@ -166,8 +171,6 @@ static int rsnd_dvc_init(struct rsnd_mod *dvc_mod,
 		return -EINVAL;
 	}
 
-	rsnd_mod_hw_start(dvc_mod);
-
 	/*
 	 * fixme
 	 * it doesn't support CTU/MIX
@@ -191,14 +194,6 @@ static int rsnd_dvc_init(struct rsnd_mod *dvc_mod,
 	return 0;
 }
 
-static int rsnd_dvc_quit(struct rsnd_mod *mod,
-			 struct rsnd_priv *priv)
-{
-	rsnd_mod_hw_stop(mod);
-
-	return 0;
-}
-
 static int rsnd_dvc_start(struct rsnd_mod *mod,
 			  struct rsnd_priv *priv)
 {
@@ -286,7 +281,6 @@ static struct rsnd_mod_ops rsnd_dvc_ops = {
 	.probe		= rsnd_dvc_probe_gen2,
 	.remove		= rsnd_dvc_remove_gen2,
 	.init		= rsnd_dvc_init,
-	.quit		= rsnd_dvc_quit,
 	.start		= rsnd_dvc_start,
 	.stop		= rsnd_dvc_stop,
 	.pcm_new	= rsnd_dvc_pcm_new,
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 5f35af7..49ea11b 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -285,9 +285,9 @@ struct rsnd_mod {
 #define rsnd_mod_to_dma(mod) (&(mod)->dma)
 #define rsnd_mod_to_io(mod) ((mod)->io)
 #define rsnd_mod_id(mod) ((mod)->id)
-#define rsnd_mod_hw_start(mod)	clk_prepare_enable((mod)->clk)
-#define rsnd_mod_hw_stop(mod)	clk_disable_unprepare((mod)->clk)
 
+int rsnd_mod_probe(struct rsnd_mod *mod, struct rsnd_priv *priv);
+int rsnd_mod_remove(struct rsnd_mod *mod, struct rsnd_priv *priv);
 void rsnd_mod_init(struct rsnd_mod *mod,
 		   struct rsnd_mod_ops *ops,
 		   struct clk *clk,
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
index cc93f32..327771a 100644
--- a/sound/soc/sh/rcar/src.c
+++ b/sound/soc/sh/rcar/src.c
@@ -292,8 +292,6 @@ static int rsnd_src_init(struct rsnd_mod *mod)
 {
 	struct rsnd_src *src = rsnd_mod_to_src(mod);
 
-	rsnd_mod_hw_start(mod);
-
 	src->err = 0;
 
 	/*
@@ -311,8 +309,6 @@ static int rsnd_src_quit(struct rsnd_mod *mod,
 	struct rsnd_src *src = rsnd_mod_to_src(mod);
 	struct device *dev = rsnd_priv_to_dev(priv);
 
-	rsnd_mod_hw_stop(mod);
-
 	if (src->err)
 		dev_warn(dev, "%s[%d] under/over flow err = %d\n",
 			 rsnd_mod_name(mod), rsnd_mod_id(mod), src->err);
@@ -464,11 +460,16 @@ static int rsnd_src_probe_gen1(struct rsnd_mod *mod,
 			       struct rsnd_priv *priv)
 {
 	struct device *dev = rsnd_priv_to_dev(priv);
+	int ret;
+
+	ret = rsnd_mod_probe(mod, priv);
+	if (ret)
+		return ret;
 
 	dev_dbg(dev, "%s[%d] (Gen1) is probed\n",
 		rsnd_mod_name(mod), rsnd_mod_id(mod));
 
-	return 0;
+	return ret;
 }
 
 static int rsnd_src_init_gen1(struct rsnd_mod *mod,
@@ -519,6 +520,7 @@ static struct rsnd_mod_ops rsnd_src_gen1_ops = {
 	.name	= SRC_NAME,
 	.dma_req = rsnd_src_dma_req,
 	.probe	= rsnd_src_probe_gen1,
+	.remove	= rsnd_mod_remove,
 	.init	= rsnd_src_init_gen1,
 	.quit	= rsnd_src_quit,
 	.start	= rsnd_src_start_gen1,
@@ -734,6 +736,10 @@ static int rsnd_src_probe_gen2(struct rsnd_mod *mod,
 	if (ret)
 		goto rsnd_src_probe_gen2_fail;
 
+	ret = rsnd_mod_probe(mod, priv);
+	if (ret)
+		goto rsnd_src_probe_gen2_fail;
+
 	dev_dbg(dev, "%s[%d] (Gen2) is probed\n",
 		rsnd_mod_name(mod), rsnd_mod_id(mod));
 
@@ -751,7 +757,7 @@ static int rsnd_src_remove_gen2(struct rsnd_mod *mod,
 {
 	rsnd_dma_quit(rsnd_mod_to_dma(mod));
 
-	return 0;
+	return rsnd_mod_remove(mod, priv);
 }
 
 static int rsnd_src_init_gen2(struct rsnd_mod *mod,
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 060d3d2..dd49559 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -186,8 +186,6 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi,
 	u32 cr;
 
 	if (0 == ssi->usrcnt) {
-		rsnd_mod_hw_start(&ssi->mod);
-
 		if (rsnd_rdai_is_clk_master(rdai)) {
 			if (rsnd_ssi_clk_from_parent(ssi))
 				rsnd_ssi_hw_start(ssi->parent, io);
@@ -258,8 +256,6 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi)
 			else
 				rsnd_ssi_master_clk_stop(ssi);
 		}
-
-		rsnd_mod_hw_stop(&ssi->mod);
 	}
 
 	dev_dbg(dev, "%s[%d] hw stopped\n",
@@ -445,12 +441,18 @@ static int rsnd_ssi_pio_probe(struct rsnd_mod *mod,
 			       rsnd_ssi_interrupt,
 			       IRQF_SHARED,
 			       dev_name(dev), ssi);
-	if (ret)
+	if (ret) {
 		dev_err(dev, "%s[%d] (PIO) request interrupt failed\n",
 			rsnd_mod_name(mod), rsnd_mod_id(mod));
-	else
-		dev_dbg(dev, "%s[%d] (PIO) is probed\n",
-			rsnd_mod_name(mod), rsnd_mod_id(mod));
+		return ret;
+	}
+
+	ret = rsnd_mod_probe(mod, priv);
+	if (ret)
+		return ret;
+
+	dev_dbg(dev, "%s[%d] (PIO) is probed\n",
+		rsnd_mod_name(mod), rsnd_mod_id(mod));
 
 	return ret;
 }
@@ -458,6 +460,7 @@ static int rsnd_ssi_pio_probe(struct rsnd_mod *mod,
 static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
 	.name	= SSI_NAME,
 	.probe	= rsnd_ssi_pio_probe,
+	.remove	= rsnd_mod_remove,
 	.init	= rsnd_ssi_init,
 	.quit	= rsnd_ssi_quit,
 	.start	= rsnd_ssi_start,
@@ -485,6 +488,10 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod,
 	if (ret)
 		goto rsnd_ssi_dma_probe_fail;
 
+	ret = rsnd_mod_probe(mod, priv);
+	if (ret)
+		goto rsnd_ssi_dma_probe_fail;
+
 	dev_dbg(dev, "%s[%d] (DMA) is probed\n",
 		rsnd_mod_name(mod), rsnd_mod_id(mod));
 
@@ -509,7 +516,7 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod,
 	/* PIO will request IRQ again */
 	devm_free_irq(dev, irq, ssi);
 
-	return 0;
+	return rsnd_mod_remove(mod, priv);
 }
 
 static int rsnd_ssi_fallback(struct rsnd_mod *mod,
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 4/5] ASoC: rsnd: remove useless debug message
       [not found] ` <878uen3s5m.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
                     ` (2 preceding siblings ...)
  2015-03-24  5:04   ` [PATCH 3/5] ASoC: rsnd: call clk_prepare_enable/unprepare() from probe/remove Kuninori Morimoto
@ 2015-03-24  5:05   ` Kuninori Morimoto
  2015-03-24  5:05   ` [PATCH 5/5] ASoC: rsnd: add DPCM based sampling rate convert Kuninori Morimoto
  2015-03-26  0:36   ` [alsa-devel] [PATCH 0/5] ASoC: rsnd: DPCM base sampling rate convert support Kuninori Morimoto
  5 siblings, 0 replies; 7+ messages in thread
From: Kuninori Morimoto @ 2015-03-24  5:05 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux-DT, Simon, Linux-ALSA, Liam Girdwood, Das Biju

From: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>

This patch removes useless debug message. especially some kind of
"probed" message will be printed from core.c if it has #define DEBUG

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
---
 - cleanup patch

 sound/soc/sh/rcar/adg.c |  2 --
 sound/soc/sh/rcar/dma.c |  4 ----
 sound/soc/sh/rcar/dvc.c | 20 +-------------------
 sound/soc/sh/rcar/gen.c |  4 ----
 sound/soc/sh/rcar/src.c | 39 ++++-----------------------------------
 sound/soc/sh/rcar/ssi.c | 28 ++++------------------------
 6 files changed, 9 insertions(+), 88 deletions(-)

diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index 7af374b..fefc881 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -434,7 +434,5 @@ int rsnd_adg_probe(struct platform_device *pdev,
 
 	priv->adg = adg;
 
-	dev_dbg(dev, "adg probed\n");
-
 	return 0;
 }
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c
index cd7b79a..ac3756f 100644
--- a/sound/soc/sh/rcar/dma.c
+++ b/sound/soc/sh/rcar/dma.c
@@ -144,8 +144,6 @@ static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id,
 		return -EIO;
 	}
 
-	dev_dbg(dev, "Audio DMAC init\n");
-
 	if (dev->of_node) {
 		dmaen->chan = rsnd_dmaen_request_channel(mod_from, mod_to);
 	} else {
@@ -329,8 +327,6 @@ static int rsnd_dmapp_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id,
 	struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
 	struct device *dev = rsnd_priv_to_dev(priv);
 
-	dev_dbg(dev, "Audio DMAC peri peri init\n");
-
 	dmapp->dmapp_id = dmac->dmapp_num;
 	dmapp->chcr = rsnd_dmapp_get_chcr(mod_from, mod_to) | PDMACHCR_DE;
 
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c
index 8f7558c..8351a617 100644
--- a/sound/soc/sh/rcar/dvc.c
+++ b/sound/soc/sh/rcar/dvc.c
@@ -119,22 +119,6 @@ static void rsnd_dvc_volume_update(struct rsnd_mod *mod)
 	rsnd_mod_write(mod, DVC_DVUER, 1);
 }
 
-static int rsnd_dvc_probe_gen2(struct rsnd_mod *mod,
-			       struct rsnd_priv *priv)
-{
-	struct device *dev = rsnd_priv_to_dev(priv);
-	int ret;
-
-	ret = rsnd_mod_probe(mod, priv);
-	if (ret)
-		return ret;
-
-	dev_dbg(dev, "%s[%d] (Gen2) is probed\n",
-		rsnd_mod_name(mod), rsnd_mod_id(mod));
-
-	return ret;
-}
-
 static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod,
 				struct rsnd_priv *priv)
 {
@@ -278,7 +262,7 @@ static struct dma_chan *rsnd_dvc_dma_req(struct rsnd_mod *mod)
 static struct rsnd_mod_ops rsnd_dvc_ops = {
 	.name		= DVC_NAME,
 	.dma_req	= rsnd_dvc_dma_req,
-	.probe		= rsnd_dvc_probe_gen2,
+	.probe		= rsnd_mod_probe,
 	.remove		= rsnd_dvc_remove_gen2,
 	.init		= rsnd_dvc_init,
 	.start		= rsnd_dvc_start,
@@ -374,8 +358,6 @@ int rsnd_dvc_probe(struct platform_device *pdev,
 
 		rsnd_mod_init(&dvc->mod, &rsnd_dvc_ops,
 			      clk, RSND_MOD_DVC, i);
-
-		dev_dbg(dev, "CMD%d probed\n", i);
 	}
 
 	return 0;
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c
index a17a504..20b0ccd 100644
--- a/sound/soc/sh/rcar/gen.c
+++ b/sound/soc/sh/rcar/gen.c
@@ -278,8 +278,6 @@ static int rsnd_gen2_probe(struct platform_device *pdev,
 	    ret_ssi  < 0)
 		return ret_ssiu | ret_scu | ret_adg | ret_ssi;
 
-	dev_dbg(dev, "Gen2 is probed\n");
-
 	return 0;
 }
 
@@ -348,8 +346,6 @@ static int rsnd_gen1_probe(struct platform_device *pdev,
 	    ret_ssi  < 0)
 		return ret_sru | ret_adg | ret_ssi;
 
-	dev_dbg(dev, "Gen1 is probed\n");
-
 	return 0;
 }
 
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
index 327771a..8d752b5 100644
--- a/sound/soc/sh/rcar/src.c
+++ b/sound/soc/sh/rcar/src.c
@@ -456,22 +456,6 @@ static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod)
 	return 0;
 }
 
-static int rsnd_src_probe_gen1(struct rsnd_mod *mod,
-			       struct rsnd_priv *priv)
-{
-	struct device *dev = rsnd_priv_to_dev(priv);
-	int ret;
-
-	ret = rsnd_mod_probe(mod, priv);
-	if (ret)
-		return ret;
-
-	dev_dbg(dev, "%s[%d] (Gen1) is probed\n",
-		rsnd_mod_name(mod), rsnd_mod_id(mod));
-
-	return ret;
-}
-
 static int rsnd_src_init_gen1(struct rsnd_mod *mod,
 			      struct rsnd_priv *priv)
 {
@@ -519,7 +503,7 @@ static int rsnd_src_stop_gen1(struct rsnd_mod *mod,
 static struct rsnd_mod_ops rsnd_src_gen1_ops = {
 	.name	= SRC_NAME,
 	.dma_req = rsnd_src_dma_req,
-	.probe	= rsnd_src_probe_gen1,
+	.probe	= rsnd_mod_probe,
 	.remove	= rsnd_mod_remove,
 	.init	= rsnd_src_init_gen1,
 	.quit	= rsnd_src_quit,
@@ -727,29 +711,16 @@ static int rsnd_src_probe_gen2(struct rsnd_mod *mod,
 				       IRQF_SHARED,
 				       dev_name(dev), mod);
 		if (ret)
-			goto rsnd_src_probe_gen2_fail;
+			return ret;
 	}
 
 	ret = rsnd_dma_init(priv,
 			    rsnd_mod_to_dma(mod),
 			    src->info->dma_id);
 	if (ret)
-		goto rsnd_src_probe_gen2_fail;
-
-	ret = rsnd_mod_probe(mod, priv);
-	if (ret)
-		goto rsnd_src_probe_gen2_fail;
-
-	dev_dbg(dev, "%s[%d] (Gen2) is probed\n",
-		rsnd_mod_name(mod), rsnd_mod_id(mod));
-
-	return ret;
-
-rsnd_src_probe_gen2_fail:
-	dev_err(dev, "%s[%d] (Gen2) failed\n",
-		rsnd_mod_name(mod), rsnd_mod_id(mod));
+		return ret;
 
-	return ret;
+	return rsnd_mod_probe(mod, priv);
 }
 
 static int rsnd_src_remove_gen2(struct rsnd_mod *mod,
@@ -914,8 +885,6 @@ int rsnd_src_probe(struct platform_device *pdev,
 		src->info = &info->src_info[i];
 
 		rsnd_mod_init(&src->mod, ops, clk, RSND_MOD_SRC, i);
-
-		dev_dbg(dev, "SRC%d probed\n", i);
 	}
 
 	return 0;
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index dd49559..c9b60a8 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -447,14 +447,7 @@ static int rsnd_ssi_pio_probe(struct rsnd_mod *mod,
 		return ret;
 	}
 
-	ret = rsnd_mod_probe(mod, priv);
-	if (ret)
-		return ret;
-
-	dev_dbg(dev, "%s[%d] (PIO) is probed\n",
-		rsnd_mod_name(mod), rsnd_mod_id(mod));
-
-	return ret;
+	return rsnd_mod_probe(mod, priv);
 }
 
 static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
@@ -480,28 +473,15 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod,
 			       IRQF_SHARED,
 			       dev_name(dev), ssi);
 	if (ret)
-		goto rsnd_ssi_dma_probe_fail;
+		return ret;
 
 	ret = rsnd_dma_init(
 		priv, rsnd_mod_to_dma(mod),
 		dma_id);
 	if (ret)
-		goto rsnd_ssi_dma_probe_fail;
-
-	ret = rsnd_mod_probe(mod, priv);
-	if (ret)
-		goto rsnd_ssi_dma_probe_fail;
-
-	dev_dbg(dev, "%s[%d] (DMA) is probed\n",
-		rsnd_mod_name(mod), rsnd_mod_id(mod));
-
-	return ret;
-
-rsnd_ssi_dma_probe_fail:
-	dev_err(dev, "%s[%d] (DMA) is failed\n",
-		rsnd_mod_name(mod), rsnd_mod_id(mod));
+		return ret;
 
-	return ret;
+	return rsnd_mod_probe(mod, priv);
 }
 
 static int rsnd_ssi_dma_remove(struct rsnd_mod *mod,
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 5/5] ASoC: rsnd: add DPCM based sampling rate convert
       [not found] ` <878uen3s5m.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
                     ` (3 preceding siblings ...)
  2015-03-24  5:05   ` [PATCH 4/5] ASoC: rsnd: remove useless debug message Kuninori Morimoto
@ 2015-03-24  5:05   ` Kuninori Morimoto
  2015-03-26  0:36   ` [alsa-devel] [PATCH 0/5] ASoC: rsnd: DPCM base sampling rate convert support Kuninori Morimoto
  5 siblings, 0 replies; 7+ messages in thread
From: Kuninori Morimoto @ 2015-03-24  5:05 UTC (permalink / raw)
  To: Mark Brown; +Cc: Linux-DT, Simon, Linux-ALSA, Liam Girdwood, Das Biju

From: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>

This patch supports DPCM based sampling rate convert on Renesas sound
driver. It assumes...
 1. SRC is implemented as FE
 2. BE dai_link supports .be_hw_params_fixup

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
---
 - no change

 sound/soc/sh/rcar/core.c | 11 ++++++++++-
 sound/soc/sh/rcar/rsnd.h |  8 ++++++++
 sound/soc/sh/rcar/src.c  | 49 ++++++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 63 insertions(+), 5 deletions(-)

diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 398eb8f..68ff763 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -204,7 +204,7 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod)
 ({								\
 	struct rsnd_priv *priv = rsnd_mod_to_priv(mod);		\
 	struct device *dev = rsnd_priv_to_dev(priv);		\
-	u32 mask = 1 << __rsnd_mod_shift_##func;			\
+	u32 mask = (1 << __rsnd_mod_shift_##func) & ~(1 << 31);	\
 	u32 call = __rsnd_mod_call_##func << __rsnd_mod_shift_##func;	\
 	int ret = 0;							\
 	if ((mod->status & mask) == call) {				\
@@ -729,6 +729,15 @@ static int rsnd_pcm_open(struct snd_pcm_substream *substream)
 static int rsnd_hw_params(struct snd_pcm_substream *substream,
 			 struct snd_pcm_hw_params *hw_params)
 {
+	struct snd_soc_dai *dai = rsnd_substream_to_dai(substream);
+	struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
+	struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream);
+	int ret;
+
+	ret = rsnd_dai_call(hw_params, io, substream, hw_params);
+	if (ret)
+		return ret;
+
 	return snd_pcm_lib_malloc_pages(substream,
 					params_buffer_bytes(hw_params));
 }
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 49ea11b..449ede3 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -239,6 +239,9 @@ struct rsnd_mod_ops {
 		    struct rsnd_priv *priv);
 	int (*pcm_new)(struct rsnd_mod *mod,
 		       struct snd_soc_pcm_runtime *rtd);
+	int (*hw_params)(struct rsnd_mod *mod,
+			 struct snd_pcm_substream *substream,
+			 struct snd_pcm_hw_params *hw_params);
 	int (*fallback)(struct rsnd_mod *mod,
 			struct rsnd_priv *priv);
 };
@@ -262,6 +265,9 @@ struct rsnd_mod {
  * 2	0: start	1: stop
  * 3	0: pcm_new
  * 4	0: fallback
+ *
+ * 31 bit is always called (see __rsnd_mod_call)
+ * 31	0: hw_params
  */
 #define __rsnd_mod_shift_probe		0
 #define __rsnd_mod_shift_remove		0
@@ -271,6 +277,7 @@ struct rsnd_mod {
 #define __rsnd_mod_shift_stop		2
 #define __rsnd_mod_shift_pcm_new	3
 #define __rsnd_mod_shift_fallback	4
+#define __rsnd_mod_shift_hw_params	31 /* always called */
 
 #define __rsnd_mod_call_probe		0
 #define __rsnd_mod_call_remove		1
@@ -280,6 +287,7 @@ struct rsnd_mod {
 #define __rsnd_mod_call_stop		1
 #define __rsnd_mod_call_pcm_new		0
 #define __rsnd_mod_call_fallback	0
+#define __rsnd_mod_call_hw_params	0
 
 #define rsnd_mod_to_priv(mod) (rsnd_io_to_priv(rsnd_mod_to_io(mod)))
 #define rsnd_mod_to_dma(mod) (&(mod)->dma)
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
index 8d752b5..67e1ccf 100644
--- a/sound/soc/sh/rcar/src.c
+++ b/sound/soc/sh/rcar/src.c
@@ -22,12 +22,13 @@
 struct rsnd_src {
 	struct rsnd_src_platform_info *info; /* rcar_snd.h */
 	struct rsnd_mod mod;
+	u32 convert_rate; /* sampling rate convert */
 	int err;
 };
 
 #define RSND_SRC_NAME_SIZE 16
 
-#define rsnd_src_convert_rate(p) ((p)->info->convert_rate)
+#define rsnd_src_convert_rate(s) ((s)->convert_rate)
 #define rsnd_src_of_node(priv) \
 	of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,src")
 
@@ -288,7 +289,43 @@ static int rsnd_src_set_convert_rate(struct rsnd_mod *mod)
 	return 0;
 }
 
-static int rsnd_src_init(struct rsnd_mod *mod)
+static int rsnd_src_hw_params(struct rsnd_mod *mod,
+			      struct snd_pcm_substream *substream,
+			      struct snd_pcm_hw_params *fe_params)
+{
+	struct rsnd_src *src = rsnd_mod_to_src(mod);
+	struct snd_soc_pcm_runtime *fe = substream->private_data;
+
+	/* default value (mainly for non-DT) */
+	src->convert_rate = src->info->convert_rate;
+
+	/*
+	 * SRC assumes that it is used under DPCM if user want to use
+	 * sampling rate convert. Then, SRC should be FE.
+	 * And then, this function will be called *after* BE settings.
+	 * this means, each BE already has fixuped hw_params.
+	 * see
+	 *	dpcm_fe_dai_hw_params()
+	 *	dpcm_be_dai_hw_params()
+	 */
+	if (fe->dai_link->dynamic) {
+		int stream = substream->stream;
+		struct snd_soc_dpcm *dpcm;
+		struct snd_pcm_hw_params *be_params;
+
+		list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
+			be_params = &dpcm->hw_params;
+
+			if (params_rate(fe_params) != params_rate(be_params))
+				src->convert_rate = params_rate(be_params);
+		}
+	}
+
+	return 0;
+}
+
+static int rsnd_src_init(struct rsnd_mod *mod,
+			 struct rsnd_priv *priv)
 {
 	struct rsnd_src *src = rsnd_mod_to_src(mod);
 
@@ -313,6 +350,8 @@ static int rsnd_src_quit(struct rsnd_mod *mod,
 		dev_warn(dev, "%s[%d] under/over flow err = %d\n",
 			 rsnd_mod_name(mod), rsnd_mod_id(mod), src->err);
 
+	src->convert_rate = 0;
+
 	return 0;
 }
 
@@ -461,7 +500,7 @@ static int rsnd_src_init_gen1(struct rsnd_mod *mod,
 {
 	int ret;
 
-	ret = rsnd_src_init(mod);
+	ret = rsnd_src_init(mod, priv);
 	if (ret < 0)
 		return ret;
 
@@ -509,6 +548,7 @@ static struct rsnd_mod_ops rsnd_src_gen1_ops = {
 	.quit	= rsnd_src_quit,
 	.start	= rsnd_src_start_gen1,
 	.stop	= rsnd_src_stop_gen1,
+	.hw_params = rsnd_src_hw_params,
 };
 
 /*
@@ -736,7 +776,7 @@ static int rsnd_src_init_gen2(struct rsnd_mod *mod,
 {
 	int ret;
 
-	ret = rsnd_src_init(mod);
+	ret = rsnd_src_init(mod, priv);
 	if (ret < 0)
 		return ret;
 
@@ -780,6 +820,7 @@ static struct rsnd_mod_ops rsnd_src_gen2_ops = {
 	.quit	= rsnd_src_quit,
 	.start	= rsnd_src_start_gen2,
 	.stop	= rsnd_src_stop_gen2,
+	.hw_params = rsnd_src_hw_params,
 };
 
 struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id)
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [alsa-devel] [PATCH 0/5] ASoC: rsnd: DPCM base sampling rate convert support
       [not found] ` <878uen3s5m.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
                     ` (4 preceding siblings ...)
  2015-03-24  5:05   ` [PATCH 5/5] ASoC: rsnd: add DPCM based sampling rate convert Kuninori Morimoto
@ 2015-03-26  0:36   ` Kuninori Morimoto
  5 siblings, 0 replies; 7+ messages in thread
From: Kuninori Morimoto @ 2015-03-26  0:36 UTC (permalink / raw)
  To: Kuninori Morimoto
  Cc: Mark Brown, Linux-DT, Linux-ALSA, Simon, Liam Girdwood, Das Biju


Hi Mark

> These are remains of my previous patch set.
> Basically, these doesn't need soc-core's new feature, but it is assuming
> DPCM base sampling rate convert has both playback/capture in same time.
> 
> 1 - 2: new Renesas sound card for DPCM
> 3    : bug fix patch. it can be applied in linus/master branch
> 4 - 5: new feature, but based on 3) patch
> 
> Kuninori Morimoto (5):
>       1) ASoC: rsrc-card: add Renesas sampling rate convert sound card support
>       2) ASoC: rsrc-card: add .be_hw_params_fixup support for convert rate
>       3) ASoC: rsnd: call clk_prepare_enable/unprepare() in probe/remove
>       4) ASoC: rsnd: remove useless debug message
>       5) ASoC: rsnd: add DPCM based sampling rate convert

I got nice feedback about this patch-set (in off-list).
I would like to create v2 patch.
So, please drop these.

Thank you for your help

Best regards
---
Kuninori Morimoto
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2015-03-26  0:36 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-24  5:02 [PATCH 0/5] ASoC: rsnd: DPCM base sampling rate convert support Kuninori Morimoto
     [not found] ` <878uen3s5m.wl%kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
2015-03-24  5:03   ` [PATCH 1/5] ASoC: rsrc-card: add Renesas sampling rate convert sound card support Kuninori Morimoto
2015-03-24  5:04   ` [PATCH 2/5] ASoC: rsrc-card: add .be_hw_params_fixup support for convert rate Kuninori Morimoto
2015-03-24  5:04   ` [PATCH 3/5] ASoC: rsnd: call clk_prepare_enable/unprepare() from probe/remove Kuninori Morimoto
2015-03-24  5:05   ` [PATCH 4/5] ASoC: rsnd: remove useless debug message Kuninori Morimoto
2015-03-24  5:05   ` [PATCH 5/5] ASoC: rsnd: add DPCM based sampling rate convert Kuninori Morimoto
2015-03-26  0:36   ` [alsa-devel] [PATCH 0/5] ASoC: rsnd: DPCM base sampling rate convert support Kuninori Morimoto

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.