All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ASoC: sun4i-i2s: Add quirks for newer SoCs
@ 2016-12-20 14:55 ` codekipper-Re5JQEeQqe8AvxtiuMwx3w
  0 siblings, 0 replies; 9+ messages in thread
From: codekipper @ 2016-12-20 14:55 UTC (permalink / raw)
  To: maxime.ripard
  Cc: linux-arm-kernel, linux-sunxi, lgirdwood, broonie, linux-kernel,
	alsa-devel, be17068, Marcus Cooper

From: Marcus Cooper <codekipper@gmail.com>

Newer SoCs have additional functionality so a quirks structure
has been added to handle them. So far we've seen the use of a
reset controller, a different address for the TXFIFO and varying
register changes.

This patch prepares the driver for these changes and adds the
reset specifier.

Signed-off-by: Marcus Cooper <codekipper@gmail.com>
---
 .../devicetree/bindings/sound/sun4i-i2s.txt        |  2 +
 sound/soc/sunxi/sun4i-i2s.c                        | 47 ++++++++++++++++++++--
 2 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
index 7a2c0945fd22..494a881ccd21 100644
--- a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
+++ b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
@@ -18,6 +18,8 @@ Required properties:
    - "apb" : clock for the I2S bus interface
    - "mod" : module clock for the I2S controller
 - #sound-dai-cells : Must be equal to 0
+- resets: reset specifier for the ahb reset (A31 and newer only)
+
 
 Example:
 
diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index f24d19526603..80fe4f1d6e3b 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -14,9 +14,11 @@
 #include <linux/clk.h>
 #include <linux/dmaengine.h>
 #include <linux/module.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
+#include <linux/reset.h>
 
 #include <sound/dmaengine_pcm.h>
 #include <sound/pcm_params.h>
@@ -92,6 +94,7 @@ struct sun4i_i2s {
 	struct clk	*bus_clk;
 	struct clk	*mod_clk;
 	struct regmap	*regmap;
+	struct reset_control *rst;
 
 	unsigned int	mclk_freq;
 
@@ -104,6 +107,13 @@ struct sun4i_i2s_clk_div {
 	u8	val;
 };
 
+struct sun4i_i2s_quirks {
+	unsigned int	reg_dac_txdata;	/* TX FIFO offset for DMA config */
+	bool 		has_reset;
+	const struct regmap_config	*sun4i_i2s_regmap;
+	const struct snd_soc_dai_ops	*ops;
+};
+
 static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = {
 	{ .div = 2, .val = 0 },
 	{ .div = 4, .val = 1 },
@@ -541,7 +551,6 @@ static struct snd_soc_dai_driver sun4i_i2s_dai = {
 		.rates = SNDRV_PCM_RATE_8000_192000,
 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
 	},
-	.ops = &sun4i_i2s_dai_ops,
 	.symmetric_rates = 1,
 };
 
@@ -655,6 +664,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
 {
 	struct sun4i_i2s *i2s;
 	struct resource *res;
+	const struct sun4i_i2s_quirks *quirks;
 	void __iomem *regs;
 	int irq, ret;
 
@@ -680,8 +690,14 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
 		return PTR_ERR(i2s->bus_clk);
 	}
 
+	quirks = of_device_get_match_data(&pdev->dev);
+	if (quirks == NULL) {
+		dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
+		return -ENODEV;
+	}
+
 	i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
-					    &sun4i_i2s_regmap_config);
+					    quirks->sun4i_i2s_regmap);
 	if (IS_ERR(i2s->regmap)) {
 		dev_err(&pdev->dev, "Regmap initialisation failed\n");
 		return PTR_ERR(i2s->regmap);
@@ -692,13 +708,25 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "Can't get our mod clock\n");
 		return PTR_ERR(i2s->mod_clk);
 	}
+
 	
-	i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG;
+	i2s->playback_dma_data.addr = res->start + quirks->reg_dac_txdata;
 	i2s->playback_dma_data.maxburst = 4;
 
 	i2s->capture_dma_data.addr = res->start + SUN4I_I2S_FIFO_RX_REG;
 	i2s->capture_dma_data.maxburst = 4;
 
+	if (quirks->has_reset) {
+		i2s->rst = devm_reset_control_get_optional(&pdev->dev, NULL);
+		if (IS_ERR(i2s->rst) && PTR_ERR(i2s->rst) == -EPROBE_DEFER) {
+			ret = -EPROBE_DEFER;
+			dev_err(&pdev->dev, "Failed to get reset: %d\n", ret);
+			goto err_pm_disable;
+		}
+		if (!IS_ERR(i2s->rst))
+			reset_control_deassert(i2s->rst);
+	}
+
 	pm_runtime_enable(&pdev->dev);
 	if (!pm_runtime_enabled(&pdev->dev)) {
 		ret = sun4i_i2s_runtime_resume(&pdev->dev);
@@ -706,6 +734,8 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
 			goto err_pm_disable;
 	}
 
+	/* Register ops with dai */
+	sun4i_i2s_dai.ops = quirks->ops;
 	ret = devm_snd_soc_register_component(&pdev->dev,
 					      &sun4i_i2s_component,
 					      &sun4i_i2s_dai, 1);
@@ -742,8 +772,17 @@ static int sun4i_i2s_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
+	.reg_dac_txdata		= SUN4I_I2S_FIFO_TX_REG,
+	.sun4i_i2s_regmap	= &sun4i_i2s_regmap_config,
+	.ops			= &sun4i_i2s_dai_ops,
+};
+
 static const struct of_device_id sun4i_i2s_match[] = {
-	{ .compatible = "allwinner,sun4i-a10-i2s", },
+	{
+		.compatible = "allwinner,sun4i-a10-i2s",
+		.data = &sun4i_a10_i2s_quirks,
+	},
 	{}
 };
 MODULE_DEVICE_TABLE(of, sun4i_i2s_match);
-- 
2.11.0

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

* [PATCH] ASoC: sun4i-i2s: Add quirks for newer SoCs
@ 2016-12-20 14:55 ` codekipper-Re5JQEeQqe8AvxtiuMwx3w
  0 siblings, 0 replies; 9+ messages in thread
From: codekipper-Re5JQEeQqe8AvxtiuMwx3w @ 2016-12-20 14:55 UTC (permalink / raw)
  To: maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	be17068-p0aYb1w59bq9tCD/VL7h6Q, Marcus Cooper

From: Marcus Cooper <codekipper-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Newer SoCs have additional functionality so a quirks structure
has been added to handle them. So far we've seen the use of a
reset controller, a different address for the TXFIFO and varying
register changes.

This patch prepares the driver for these changes and adds the
reset specifier.

Signed-off-by: Marcus Cooper <codekipper-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 .../devicetree/bindings/sound/sun4i-i2s.txt        |  2 +
 sound/soc/sunxi/sun4i-i2s.c                        | 47 ++++++++++++++++++++--
 2 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
index 7a2c0945fd22..494a881ccd21 100644
--- a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
+++ b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
@@ -18,6 +18,8 @@ Required properties:
    - "apb" : clock for the I2S bus interface
    - "mod" : module clock for the I2S controller
 - #sound-dai-cells : Must be equal to 0
+- resets: reset specifier for the ahb reset (A31 and newer only)
+
 
 Example:
 
diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index f24d19526603..80fe4f1d6e3b 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -14,9 +14,11 @@
 #include <linux/clk.h>
 #include <linux/dmaengine.h>
 #include <linux/module.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
+#include <linux/reset.h>
 
 #include <sound/dmaengine_pcm.h>
 #include <sound/pcm_params.h>
@@ -92,6 +94,7 @@ struct sun4i_i2s {
 	struct clk	*bus_clk;
 	struct clk	*mod_clk;
 	struct regmap	*regmap;
+	struct reset_control *rst;
 
 	unsigned int	mclk_freq;
 
@@ -104,6 +107,13 @@ struct sun4i_i2s_clk_div {
 	u8	val;
 };
 
+struct sun4i_i2s_quirks {
+	unsigned int	reg_dac_txdata;	/* TX FIFO offset for DMA config */
+	bool 		has_reset;
+	const struct regmap_config	*sun4i_i2s_regmap;
+	const struct snd_soc_dai_ops	*ops;
+};
+
 static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = {
 	{ .div = 2, .val = 0 },
 	{ .div = 4, .val = 1 },
@@ -541,7 +551,6 @@ static struct snd_soc_dai_driver sun4i_i2s_dai = {
 		.rates = SNDRV_PCM_RATE_8000_192000,
 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
 	},
-	.ops = &sun4i_i2s_dai_ops,
 	.symmetric_rates = 1,
 };
 
@@ -655,6 +664,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
 {
 	struct sun4i_i2s *i2s;
 	struct resource *res;
+	const struct sun4i_i2s_quirks *quirks;
 	void __iomem *regs;
 	int irq, ret;
 
@@ -680,8 +690,14 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
 		return PTR_ERR(i2s->bus_clk);
 	}
 
+	quirks = of_device_get_match_data(&pdev->dev);
+	if (quirks == NULL) {
+		dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
+		return -ENODEV;
+	}
+
 	i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
-					    &sun4i_i2s_regmap_config);
+					    quirks->sun4i_i2s_regmap);
 	if (IS_ERR(i2s->regmap)) {
 		dev_err(&pdev->dev, "Regmap initialisation failed\n");
 		return PTR_ERR(i2s->regmap);
@@ -692,13 +708,25 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "Can't get our mod clock\n");
 		return PTR_ERR(i2s->mod_clk);
 	}
+
 	
-	i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG;
+	i2s->playback_dma_data.addr = res->start + quirks->reg_dac_txdata;
 	i2s->playback_dma_data.maxburst = 4;
 
 	i2s->capture_dma_data.addr = res->start + SUN4I_I2S_FIFO_RX_REG;
 	i2s->capture_dma_data.maxburst = 4;
 
+	if (quirks->has_reset) {
+		i2s->rst = devm_reset_control_get_optional(&pdev->dev, NULL);
+		if (IS_ERR(i2s->rst) && PTR_ERR(i2s->rst) == -EPROBE_DEFER) {
+			ret = -EPROBE_DEFER;
+			dev_err(&pdev->dev, "Failed to get reset: %d\n", ret);
+			goto err_pm_disable;
+		}
+		if (!IS_ERR(i2s->rst))
+			reset_control_deassert(i2s->rst);
+	}
+
 	pm_runtime_enable(&pdev->dev);
 	if (!pm_runtime_enabled(&pdev->dev)) {
 		ret = sun4i_i2s_runtime_resume(&pdev->dev);
@@ -706,6 +734,8 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
 			goto err_pm_disable;
 	}
 
+	/* Register ops with dai */
+	sun4i_i2s_dai.ops = quirks->ops;
 	ret = devm_snd_soc_register_component(&pdev->dev,
 					      &sun4i_i2s_component,
 					      &sun4i_i2s_dai, 1);
@@ -742,8 +772,17 @@ static int sun4i_i2s_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
+	.reg_dac_txdata		= SUN4I_I2S_FIFO_TX_REG,
+	.sun4i_i2s_regmap	= &sun4i_i2s_regmap_config,
+	.ops			= &sun4i_i2s_dai_ops,
+};
+
 static const struct of_device_id sun4i_i2s_match[] = {
-	{ .compatible = "allwinner,sun4i-a10-i2s", },
+	{
+		.compatible = "allwinner,sun4i-a10-i2s",
+		.data = &sun4i_a10_i2s_quirks,
+	},
 	{}
 };
 MODULE_DEVICE_TABLE(of, sun4i_i2s_match);
-- 
2.11.0

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

* [PATCH] ASoC: sun4i-i2s: Add quirks for newer SoCs
@ 2016-12-20 14:55 ` codekipper-Re5JQEeQqe8AvxtiuMwx3w
  0 siblings, 0 replies; 9+ messages in thread
From: codekipper at gmail.com @ 2016-12-20 14:55 UTC (permalink / raw)
  To: linux-arm-kernel

From: Marcus Cooper <codekipper@gmail.com>

Newer SoCs have additional functionality so a quirks structure
has been added to handle them. So far we've seen the use of a
reset controller, a different address for the TXFIFO and varying
register changes.

This patch prepares the driver for these changes and adds the
reset specifier.

Signed-off-by: Marcus Cooper <codekipper@gmail.com>
---
 .../devicetree/bindings/sound/sun4i-i2s.txt        |  2 +
 sound/soc/sunxi/sun4i-i2s.c                        | 47 ++++++++++++++++++++--
 2 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
index 7a2c0945fd22..494a881ccd21 100644
--- a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
+++ b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
@@ -18,6 +18,8 @@ Required properties:
    - "apb" : clock for the I2S bus interface
    - "mod" : module clock for the I2S controller
 - #sound-dai-cells : Must be equal to 0
+- resets: reset specifier for the ahb reset (A31 and newer only)
+
 
 Example:
 
diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index f24d19526603..80fe4f1d6e3b 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -14,9 +14,11 @@
 #include <linux/clk.h>
 #include <linux/dmaengine.h>
 #include <linux/module.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
+#include <linux/reset.h>
 
 #include <sound/dmaengine_pcm.h>
 #include <sound/pcm_params.h>
@@ -92,6 +94,7 @@ struct sun4i_i2s {
 	struct clk	*bus_clk;
 	struct clk	*mod_clk;
 	struct regmap	*regmap;
+	struct reset_control *rst;
 
 	unsigned int	mclk_freq;
 
@@ -104,6 +107,13 @@ struct sun4i_i2s_clk_div {
 	u8	val;
 };
 
+struct sun4i_i2s_quirks {
+	unsigned int	reg_dac_txdata;	/* TX FIFO offset for DMA config */
+	bool 		has_reset;
+	const struct regmap_config	*sun4i_i2s_regmap;
+	const struct snd_soc_dai_ops	*ops;
+};
+
 static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = {
 	{ .div = 2, .val = 0 },
 	{ .div = 4, .val = 1 },
@@ -541,7 +551,6 @@ static struct snd_soc_dai_driver sun4i_i2s_dai = {
 		.rates = SNDRV_PCM_RATE_8000_192000,
 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
 	},
-	.ops = &sun4i_i2s_dai_ops,
 	.symmetric_rates = 1,
 };
 
@@ -655,6 +664,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
 {
 	struct sun4i_i2s *i2s;
 	struct resource *res;
+	const struct sun4i_i2s_quirks *quirks;
 	void __iomem *regs;
 	int irq, ret;
 
@@ -680,8 +690,14 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
 		return PTR_ERR(i2s->bus_clk);
 	}
 
+	quirks = of_device_get_match_data(&pdev->dev);
+	if (quirks == NULL) {
+		dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
+		return -ENODEV;
+	}
+
 	i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
-					    &sun4i_i2s_regmap_config);
+					    quirks->sun4i_i2s_regmap);
 	if (IS_ERR(i2s->regmap)) {
 		dev_err(&pdev->dev, "Regmap initialisation failed\n");
 		return PTR_ERR(i2s->regmap);
@@ -692,13 +708,25 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "Can't get our mod clock\n");
 		return PTR_ERR(i2s->mod_clk);
 	}
+
 	
-	i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG;
+	i2s->playback_dma_data.addr = res->start + quirks->reg_dac_txdata;
 	i2s->playback_dma_data.maxburst = 4;
 
 	i2s->capture_dma_data.addr = res->start + SUN4I_I2S_FIFO_RX_REG;
 	i2s->capture_dma_data.maxburst = 4;
 
+	if (quirks->has_reset) {
+		i2s->rst = devm_reset_control_get_optional(&pdev->dev, NULL);
+		if (IS_ERR(i2s->rst) && PTR_ERR(i2s->rst) == -EPROBE_DEFER) {
+			ret = -EPROBE_DEFER;
+			dev_err(&pdev->dev, "Failed to get reset: %d\n", ret);
+			goto err_pm_disable;
+		}
+		if (!IS_ERR(i2s->rst))
+			reset_control_deassert(i2s->rst);
+	}
+
 	pm_runtime_enable(&pdev->dev);
 	if (!pm_runtime_enabled(&pdev->dev)) {
 		ret = sun4i_i2s_runtime_resume(&pdev->dev);
@@ -706,6 +734,8 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
 			goto err_pm_disable;
 	}
 
+	/* Register ops with dai */
+	sun4i_i2s_dai.ops = quirks->ops;
 	ret = devm_snd_soc_register_component(&pdev->dev,
 					      &sun4i_i2s_component,
 					      &sun4i_i2s_dai, 1);
@@ -742,8 +772,17 @@ static int sun4i_i2s_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
+	.reg_dac_txdata		= SUN4I_I2S_FIFO_TX_REG,
+	.sun4i_i2s_regmap	= &sun4i_i2s_regmap_config,
+	.ops			= &sun4i_i2s_dai_ops,
+};
+
 static const struct of_device_id sun4i_i2s_match[] = {
-	{ .compatible = "allwinner,sun4i-a10-i2s", },
+	{
+		.compatible = "allwinner,sun4i-a10-i2s",
+		.data = &sun4i_a10_i2s_quirks,
+	},
 	{}
 };
 MODULE_DEVICE_TABLE(of, sun4i_i2s_match);
-- 
2.11.0

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

* Re: [PATCH] ASoC: sun4i-i2s: Add quirks for newer SoCs
@ 2016-12-20 19:16   ` Maxime Ripard
  0 siblings, 0 replies; 9+ messages in thread
From: Maxime Ripard @ 2016-12-20 19:16 UTC (permalink / raw)
  To: codekipper
  Cc: linux-arm-kernel, linux-sunxi, lgirdwood, broonie, linux-kernel,
	alsa-devel, be17068

[-- Attachment #1: Type: text/plain, Size: 4746 bytes --]

Hi,

On Tue, Dec 20, 2016 at 03:55:24PM +0100, codekipper@gmail.com wrote:
> From: Marcus Cooper <codekipper@gmail.com>
> 
> Newer SoCs have additional functionality so a quirks structure
> has been added to handle them. So far we've seen the use of a
> reset controller, a different address for the TXFIFO and varying
> register changes.
> 
> This patch prepares the driver for these changes and adds the
> reset specifier.
> 
> Signed-off-by: Marcus Cooper <codekipper@gmail.com>
> ---
>  .../devicetree/bindings/sound/sun4i-i2s.txt        |  2 +
>  sound/soc/sunxi/sun4i-i2s.c                        | 47 ++++++++++++++++++++--
>  2 files changed, 45 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
> index 7a2c0945fd22..494a881ccd21 100644
> --- a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
> +++ b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
> @@ -18,6 +18,8 @@ Required properties:
>     - "apb" : clock for the I2S bus interface
>     - "mod" : module clock for the I2S controller
>  - #sound-dai-cells : Must be equal to 0
> +- resets: reset specifier for the ahb reset (A31 and newer only)
> +
>  
>  Example:
>  
> diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
> index f24d19526603..80fe4f1d6e3b 100644
> --- a/sound/soc/sunxi/sun4i-i2s.c
> +++ b/sound/soc/sunxi/sun4i-i2s.c
> @@ -14,9 +14,11 @@
>  #include <linux/clk.h>
>  #include <linux/dmaengine.h>
>  #include <linux/module.h>
> +#include <linux/of_device.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/regmap.h>
> +#include <linux/reset.h>
>  
>  #include <sound/dmaengine_pcm.h>
>  #include <sound/pcm_params.h>
> @@ -92,6 +94,7 @@ struct sun4i_i2s {
>  	struct clk	*bus_clk;
>  	struct clk	*mod_clk;
>  	struct regmap	*regmap;
> +	struct reset_control *rst;
>  
>  	unsigned int	mclk_freq;
>  
> @@ -104,6 +107,13 @@ struct sun4i_i2s_clk_div {
>  	u8	val;
>  };
>  
> +struct sun4i_i2s_quirks {
> +	unsigned int	reg_dac_txdata;	/* TX FIFO offset for DMA config */
> +	bool 		has_reset;
> +	const struct regmap_config	*sun4i_i2s_regmap;
> +	const struct snd_soc_dai_ops	*ops;
> +};
> +

This is quite hard to review without actual example of what you'll put
in there.

>  static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = {
>  	{ .div = 2, .val = 0 },
>  	{ .div = 4, .val = 1 },
> @@ -541,7 +551,6 @@ static struct snd_soc_dai_driver sun4i_i2s_dai = {
>  		.rates = SNDRV_PCM_RATE_8000_192000,
>  		.formats = SNDRV_PCM_FMTBIT_S16_LE,
>  	},
> -	.ops = &sun4i_i2s_dai_ops,
>  	.symmetric_rates = 1,
>  };
>  
> @@ -655,6 +664,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>  {
>  	struct sun4i_i2s *i2s;
>  	struct resource *res;
> +	const struct sun4i_i2s_quirks *quirks;
>  	void __iomem *regs;
>  	int irq, ret;
>  
> @@ -680,8 +690,14 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>  		return PTR_ERR(i2s->bus_clk);
>  	}
>  
> +	quirks = of_device_get_match_data(&pdev->dev);
> +	if (quirks == NULL) {
> +		dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
> +		return -ENODEV;
> +	}
> +
>  	i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
> -					    &sun4i_i2s_regmap_config);
> +					    quirks->sun4i_i2s_regmap);
>  	if (IS_ERR(i2s->regmap)) {
>  		dev_err(&pdev->dev, "Regmap initialisation failed\n");
>  		return PTR_ERR(i2s->regmap);
> @@ -692,13 +708,25 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>  		dev_err(&pdev->dev, "Can't get our mod clock\n");
>  		return PTR_ERR(i2s->mod_clk);
>  	}
> +

Spurious change?

>  	
> -	i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG;
> +	i2s->playback_dma_data.addr = res->start + quirks->reg_dac_txdata;
>  	i2s->playback_dma_data.maxburst = 4;
>  
>  	i2s->capture_dma_data.addr = res->start + SUN4I_I2S_FIFO_RX_REG;
>  	i2s->capture_dma_data.maxburst = 4;
>  
> +	if (quirks->has_reset) {
> +		i2s->rst = devm_reset_control_get_optional(&pdev->dev, NULL);
> +		if (IS_ERR(i2s->rst) && PTR_ERR(i2s->rst) == -EPROBE_DEFER) {
> +			ret = -EPROBE_DEFER;
> +			dev_err(&pdev->dev, "Failed to get reset: %d\n", ret);
> +			goto err_pm_disable;
> +		}
> +		if (!IS_ERR(i2s->rst))
> +			reset_control_deassert(i2s->rst);
> +	}
> +

That reset line is not optional. The <A31 SoCs don't need it, and you
cover that case already, but it is definitely mandatory for the A31.

Thanks,
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

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

* Re: [PATCH] ASoC: sun4i-i2s: Add quirks for newer SoCs
@ 2016-12-20 19:16   ` Maxime Ripard
  0 siblings, 0 replies; 9+ messages in thread
From: Maxime Ripard @ 2016-12-20 19:16 UTC (permalink / raw)
  To: codekipper-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	be17068-p0aYb1w59bq9tCD/VL7h6Q

[-- Attachment #1: Type: text/plain, Size: 4691 bytes --]

Hi,

On Tue, Dec 20, 2016 at 03:55:24PM +0100, codekipper-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org wrote:
> From: Marcus Cooper <codekipper-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> 
> Newer SoCs have additional functionality so a quirks structure
> has been added to handle them. So far we've seen the use of a
> reset controller, a different address for the TXFIFO and varying
> register changes.
> 
> This patch prepares the driver for these changes and adds the
> reset specifier.
> 
> Signed-off-by: Marcus Cooper <codekipper-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
>  .../devicetree/bindings/sound/sun4i-i2s.txt        |  2 +
>  sound/soc/sunxi/sun4i-i2s.c                        | 47 ++++++++++++++++++++--
>  2 files changed, 45 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
> index 7a2c0945fd22..494a881ccd21 100644
> --- a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
> +++ b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
> @@ -18,6 +18,8 @@ Required properties:
>     - "apb" : clock for the I2S bus interface
>     - "mod" : module clock for the I2S controller
>  - #sound-dai-cells : Must be equal to 0
> +- resets: reset specifier for the ahb reset (A31 and newer only)
> +
>  
>  Example:
>  
> diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
> index f24d19526603..80fe4f1d6e3b 100644
> --- a/sound/soc/sunxi/sun4i-i2s.c
> +++ b/sound/soc/sunxi/sun4i-i2s.c
> @@ -14,9 +14,11 @@
>  #include <linux/clk.h>
>  #include <linux/dmaengine.h>
>  #include <linux/module.h>
> +#include <linux/of_device.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/regmap.h>
> +#include <linux/reset.h>
>  
>  #include <sound/dmaengine_pcm.h>
>  #include <sound/pcm_params.h>
> @@ -92,6 +94,7 @@ struct sun4i_i2s {
>  	struct clk	*bus_clk;
>  	struct clk	*mod_clk;
>  	struct regmap	*regmap;
> +	struct reset_control *rst;
>  
>  	unsigned int	mclk_freq;
>  
> @@ -104,6 +107,13 @@ struct sun4i_i2s_clk_div {
>  	u8	val;
>  };
>  
> +struct sun4i_i2s_quirks {
> +	unsigned int	reg_dac_txdata;	/* TX FIFO offset for DMA config */
> +	bool 		has_reset;
> +	const struct regmap_config	*sun4i_i2s_regmap;
> +	const struct snd_soc_dai_ops	*ops;
> +};
> +

This is quite hard to review without actual example of what you'll put
in there.

>  static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = {
>  	{ .div = 2, .val = 0 },
>  	{ .div = 4, .val = 1 },
> @@ -541,7 +551,6 @@ static struct snd_soc_dai_driver sun4i_i2s_dai = {
>  		.rates = SNDRV_PCM_RATE_8000_192000,
>  		.formats = SNDRV_PCM_FMTBIT_S16_LE,
>  	},
> -	.ops = &sun4i_i2s_dai_ops,
>  	.symmetric_rates = 1,
>  };
>  
> @@ -655,6 +664,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>  {
>  	struct sun4i_i2s *i2s;
>  	struct resource *res;
> +	const struct sun4i_i2s_quirks *quirks;
>  	void __iomem *regs;
>  	int irq, ret;
>  
> @@ -680,8 +690,14 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>  		return PTR_ERR(i2s->bus_clk);
>  	}
>  
> +	quirks = of_device_get_match_data(&pdev->dev);
> +	if (quirks == NULL) {
> +		dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
> +		return -ENODEV;
> +	}
> +
>  	i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
> -					    &sun4i_i2s_regmap_config);
> +					    quirks->sun4i_i2s_regmap);
>  	if (IS_ERR(i2s->regmap)) {
>  		dev_err(&pdev->dev, "Regmap initialisation failed\n");
>  		return PTR_ERR(i2s->regmap);
> @@ -692,13 +708,25 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>  		dev_err(&pdev->dev, "Can't get our mod clock\n");
>  		return PTR_ERR(i2s->mod_clk);
>  	}
> +

Spurious change?

>  	
> -	i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG;
> +	i2s->playback_dma_data.addr = res->start + quirks->reg_dac_txdata;
>  	i2s->playback_dma_data.maxburst = 4;
>  
>  	i2s->capture_dma_data.addr = res->start + SUN4I_I2S_FIFO_RX_REG;
>  	i2s->capture_dma_data.maxburst = 4;
>  
> +	if (quirks->has_reset) {
> +		i2s->rst = devm_reset_control_get_optional(&pdev->dev, NULL);
> +		if (IS_ERR(i2s->rst) && PTR_ERR(i2s->rst) == -EPROBE_DEFER) {
> +			ret = -EPROBE_DEFER;
> +			dev_err(&pdev->dev, "Failed to get reset: %d\n", ret);
> +			goto err_pm_disable;
> +		}
> +		if (!IS_ERR(i2s->rst))
> +			reset_control_deassert(i2s->rst);
> +	}
> +

That reset line is not optional. The <A31 SoCs don't need it, and you
cover that case already, but it is definitely mandatory for the A31.

Thanks,
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* [PATCH] ASoC: sun4i-i2s: Add quirks for newer SoCs
@ 2016-12-20 19:16   ` Maxime Ripard
  0 siblings, 0 replies; 9+ messages in thread
From: Maxime Ripard @ 2016-12-20 19:16 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Tue, Dec 20, 2016 at 03:55:24PM +0100, codekipper at gmail.com wrote:
> From: Marcus Cooper <codekipper@gmail.com>
> 
> Newer SoCs have additional functionality so a quirks structure
> has been added to handle them. So far we've seen the use of a
> reset controller, a different address for the TXFIFO and varying
> register changes.
> 
> This patch prepares the driver for these changes and adds the
> reset specifier.
> 
> Signed-off-by: Marcus Cooper <codekipper@gmail.com>
> ---
>  .../devicetree/bindings/sound/sun4i-i2s.txt        |  2 +
>  sound/soc/sunxi/sun4i-i2s.c                        | 47 ++++++++++++++++++++--
>  2 files changed, 45 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
> index 7a2c0945fd22..494a881ccd21 100644
> --- a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
> +++ b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
> @@ -18,6 +18,8 @@ Required properties:
>     - "apb" : clock for the I2S bus interface
>     - "mod" : module clock for the I2S controller
>  - #sound-dai-cells : Must be equal to 0
> +- resets: reset specifier for the ahb reset (A31 and newer only)
> +
>  
>  Example:
>  
> diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
> index f24d19526603..80fe4f1d6e3b 100644
> --- a/sound/soc/sunxi/sun4i-i2s.c
> +++ b/sound/soc/sunxi/sun4i-i2s.c
> @@ -14,9 +14,11 @@
>  #include <linux/clk.h>
>  #include <linux/dmaengine.h>
>  #include <linux/module.h>
> +#include <linux/of_device.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/regmap.h>
> +#include <linux/reset.h>
>  
>  #include <sound/dmaengine_pcm.h>
>  #include <sound/pcm_params.h>
> @@ -92,6 +94,7 @@ struct sun4i_i2s {
>  	struct clk	*bus_clk;
>  	struct clk	*mod_clk;
>  	struct regmap	*regmap;
> +	struct reset_control *rst;
>  
>  	unsigned int	mclk_freq;
>  
> @@ -104,6 +107,13 @@ struct sun4i_i2s_clk_div {
>  	u8	val;
>  };
>  
> +struct sun4i_i2s_quirks {
> +	unsigned int	reg_dac_txdata;	/* TX FIFO offset for DMA config */
> +	bool 		has_reset;
> +	const struct regmap_config	*sun4i_i2s_regmap;
> +	const struct snd_soc_dai_ops	*ops;
> +};
> +

This is quite hard to review without actual example of what you'll put
in there.

>  static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = {
>  	{ .div = 2, .val = 0 },
>  	{ .div = 4, .val = 1 },
> @@ -541,7 +551,6 @@ static struct snd_soc_dai_driver sun4i_i2s_dai = {
>  		.rates = SNDRV_PCM_RATE_8000_192000,
>  		.formats = SNDRV_PCM_FMTBIT_S16_LE,
>  	},
> -	.ops = &sun4i_i2s_dai_ops,
>  	.symmetric_rates = 1,
>  };
>  
> @@ -655,6 +664,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>  {
>  	struct sun4i_i2s *i2s;
>  	struct resource *res;
> +	const struct sun4i_i2s_quirks *quirks;
>  	void __iomem *regs;
>  	int irq, ret;
>  
> @@ -680,8 +690,14 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>  		return PTR_ERR(i2s->bus_clk);
>  	}
>  
> +	quirks = of_device_get_match_data(&pdev->dev);
> +	if (quirks == NULL) {
> +		dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
> +		return -ENODEV;
> +	}
> +
>  	i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
> -					    &sun4i_i2s_regmap_config);
> +					    quirks->sun4i_i2s_regmap);
>  	if (IS_ERR(i2s->regmap)) {
>  		dev_err(&pdev->dev, "Regmap initialisation failed\n");
>  		return PTR_ERR(i2s->regmap);
> @@ -692,13 +708,25 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>  		dev_err(&pdev->dev, "Can't get our mod clock\n");
>  		return PTR_ERR(i2s->mod_clk);
>  	}
> +

Spurious change?

>  	
> -	i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG;
> +	i2s->playback_dma_data.addr = res->start + quirks->reg_dac_txdata;
>  	i2s->playback_dma_data.maxburst = 4;
>  
>  	i2s->capture_dma_data.addr = res->start + SUN4I_I2S_FIFO_RX_REG;
>  	i2s->capture_dma_data.maxburst = 4;
>  
> +	if (quirks->has_reset) {
> +		i2s->rst = devm_reset_control_get_optional(&pdev->dev, NULL);
> +		if (IS_ERR(i2s->rst) && PTR_ERR(i2s->rst) == -EPROBE_DEFER) {
> +			ret = -EPROBE_DEFER;
> +			dev_err(&pdev->dev, "Failed to get reset: %d\n", ret);
> +			goto err_pm_disable;
> +		}
> +		if (!IS_ERR(i2s->rst))
> +			reset_control_deassert(i2s->rst);
> +	}
> +

That reset line is not optional. The <A31 SoCs don't need it, and you
cover that case already, but it is definitely mandatory for the A31.

Thanks,
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161220/368fceb7/attachment-0001.sig>

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

* Re: [PATCH] ASoC: sun4i-i2s: Add quirks for newer SoCs
  2016-12-20 19:16   ` Maxime Ripard
  (?)
@ 2016-12-20 19:40     ` Code Kipper
  -1 siblings, 0 replies; 9+ messages in thread
From: Code Kipper @ 2016-12-20 19:40 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: linux-arm-kernel, linux-sunxi, Liam Girdwood, Mark Brown,
	linux-kernel, alsa-devel, Andrea Venturi (pers)

On 20 December 2016 at 20:16, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Hi,
>
> On Tue, Dec 20, 2016 at 03:55:24PM +0100, codekipper@gmail.com wrote:
>> From: Marcus Cooper <codekipper@gmail.com>
>>
>> Newer SoCs have additional functionality so a quirks structure
>> has been added to handle them. So far we've seen the use of a
>> reset controller, a different address for the TXFIFO and varying
>> register changes.
>>
>> This patch prepares the driver for these changes and adds the
>> reset specifier.
>>
>> Signed-off-by: Marcus Cooper <codekipper@gmail.com>
>> ---
>>  .../devicetree/bindings/sound/sun4i-i2s.txt        |  2 +
>>  sound/soc/sunxi/sun4i-i2s.c                        | 47 ++++++++++++++++++++--
>>  2 files changed, 45 insertions(+), 4 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
>> index 7a2c0945fd22..494a881ccd21 100644
>> --- a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
>> +++ b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
>> @@ -18,6 +18,8 @@ Required properties:
>>     - "apb" : clock for the I2S bus interface
>>     - "mod" : module clock for the I2S controller
>>  - #sound-dai-cells : Must be equal to 0
>> +- resets: reset specifier for the ahb reset (A31 and newer only)
>> +
>>
>>  Example:
>>
>> diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
>> index f24d19526603..80fe4f1d6e3b 100644
>> --- a/sound/soc/sunxi/sun4i-i2s.c
>> +++ b/sound/soc/sunxi/sun4i-i2s.c
>> @@ -14,9 +14,11 @@
>>  #include <linux/clk.h>
>>  #include <linux/dmaengine.h>
>>  #include <linux/module.h>
>> +#include <linux/of_device.h>
>>  #include <linux/platform_device.h>
>>  #include <linux/pm_runtime.h>
>>  #include <linux/regmap.h>
>> +#include <linux/reset.h>
>>
>>  #include <sound/dmaengine_pcm.h>
>>  #include <sound/pcm_params.h>
>> @@ -92,6 +94,7 @@ struct sun4i_i2s {
>>       struct clk      *bus_clk;
>>       struct clk      *mod_clk;
>>       struct regmap   *regmap;
>> +     struct reset_control *rst;
>>
>>       unsigned int    mclk_freq;
>>
>> @@ -104,6 +107,13 @@ struct sun4i_i2s_clk_div {
>>       u8      val;
>>  };
>>
>> +struct sun4i_i2s_quirks {
>> +     unsigned int    reg_dac_txdata; /* TX FIFO offset for DMA config */
>> +     bool            has_reset;
>> +     const struct regmap_config      *sun4i_i2s_regmap;
>> +     const struct snd_soc_dai_ops    *ops;
>> +};
>> +
>
> This is quite hard to review without actual example of what you'll put
> in there.
Fair enough...I have a patch for the A31 but haven't got any hardware
that I can verify it on. I've confirmed on the H3 but I feel like that
patch needs some tidying up. That being said...I'll push it as a patch
set and we can talk about the setup.

>
>>  static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = {
>>       { .div = 2, .val = 0 },
>>       { .div = 4, .val = 1 },
>> @@ -541,7 +551,6 @@ static struct snd_soc_dai_driver sun4i_i2s_dai = {
>>               .rates = SNDRV_PCM_RATE_8000_192000,
>>               .formats = SNDRV_PCM_FMTBIT_S16_LE,
>>       },
>> -     .ops = &sun4i_i2s_dai_ops,
>>       .symmetric_rates = 1,
>>  };
>>
>> @@ -655,6 +664,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>>  {
>>       struct sun4i_i2s *i2s;
>>       struct resource *res;
>> +     const struct sun4i_i2s_quirks *quirks;
>>       void __iomem *regs;
>>       int irq, ret;
>>
>> @@ -680,8 +690,14 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>>               return PTR_ERR(i2s->bus_clk);
>>       }
>>
>> +     quirks = of_device_get_match_data(&pdev->dev);
>> +     if (quirks == NULL) {
>> +             dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
>> +             return -ENODEV;
>> +     }
>> +
>>       i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
>> -                                         &sun4i_i2s_regmap_config);
>> +                                         quirks->sun4i_i2s_regmap);
>>       if (IS_ERR(i2s->regmap)) {
>>               dev_err(&pdev->dev, "Regmap initialisation failed\n");
>>               return PTR_ERR(i2s->regmap);
>> @@ -692,13 +708,25 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>>               dev_err(&pdev->dev, "Can't get our mod clock\n");
>>               return PTR_ERR(i2s->mod_clk);
>>       }
>> +
>
> Spurious change?
ACK
>
>>
>> -     i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG;
>> +     i2s->playback_dma_data.addr = res->start + quirks->reg_dac_txdata;
>>       i2s->playback_dma_data.maxburst = 4;
>>
>>       i2s->capture_dma_data.addr = res->start + SUN4I_I2S_FIFO_RX_REG;
>>       i2s->capture_dma_data.maxburst = 4;
>>
>> +     if (quirks->has_reset) {
>> +             i2s->rst = devm_reset_control_get_optional(&pdev->dev, NULL);
>> +             if (IS_ERR(i2s->rst) && PTR_ERR(i2s->rst) == -EPROBE_DEFER) {
>> +                     ret = -EPROBE_DEFER;
>> +                     dev_err(&pdev->dev, "Failed to get reset: %d\n", ret);
>> +                     goto err_pm_disable;
>> +             }
>> +             if (!IS_ERR(i2s->rst))
>> +                     reset_control_deassert(i2s->rst);
>> +     }
>> +
>
> That reset line is not optional. The <A31 SoCs don't need it, and you
> cover that case already, but it is definitely mandatory for the A31.
OK..I'll search for a better function call. Thanks for this and the
other reviews.
CK
>
> Thanks,
> Maxime
>
> --
> Maxime Ripard, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com

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

* Re: [PATCH] ASoC: sun4i-i2s: Add quirks for newer SoCs
@ 2016-12-20 19:40     ` Code Kipper
  0 siblings, 0 replies; 9+ messages in thread
From: Code Kipper @ 2016-12-20 19:40 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: linux-arm-kernel, linux-sunxi, Liam Girdwood, Mark Brown,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw, Andrea Venturi (pers)

On 20 December 2016 at 20:16, Maxime Ripard
<maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> Hi,
>
> On Tue, Dec 20, 2016 at 03:55:24PM +0100, codekipper-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org wrote:
>> From: Marcus Cooper <codekipper-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>>
>> Newer SoCs have additional functionality so a quirks structure
>> has been added to handle them. So far we've seen the use of a
>> reset controller, a different address for the TXFIFO and varying
>> register changes.
>>
>> This patch prepares the driver for these changes and adds the
>> reset specifier.
>>
>> Signed-off-by: Marcus Cooper <codekipper-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> ---
>>  .../devicetree/bindings/sound/sun4i-i2s.txt        |  2 +
>>  sound/soc/sunxi/sun4i-i2s.c                        | 47 ++++++++++++++++++++--
>>  2 files changed, 45 insertions(+), 4 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
>> index 7a2c0945fd22..494a881ccd21 100644
>> --- a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
>> +++ b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
>> @@ -18,6 +18,8 @@ Required properties:
>>     - "apb" : clock for the I2S bus interface
>>     - "mod" : module clock for the I2S controller
>>  - #sound-dai-cells : Must be equal to 0
>> +- resets: reset specifier for the ahb reset (A31 and newer only)
>> +
>>
>>  Example:
>>
>> diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
>> index f24d19526603..80fe4f1d6e3b 100644
>> --- a/sound/soc/sunxi/sun4i-i2s.c
>> +++ b/sound/soc/sunxi/sun4i-i2s.c
>> @@ -14,9 +14,11 @@
>>  #include <linux/clk.h>
>>  #include <linux/dmaengine.h>
>>  #include <linux/module.h>
>> +#include <linux/of_device.h>
>>  #include <linux/platform_device.h>
>>  #include <linux/pm_runtime.h>
>>  #include <linux/regmap.h>
>> +#include <linux/reset.h>
>>
>>  #include <sound/dmaengine_pcm.h>
>>  #include <sound/pcm_params.h>
>> @@ -92,6 +94,7 @@ struct sun4i_i2s {
>>       struct clk      *bus_clk;
>>       struct clk      *mod_clk;
>>       struct regmap   *regmap;
>> +     struct reset_control *rst;
>>
>>       unsigned int    mclk_freq;
>>
>> @@ -104,6 +107,13 @@ struct sun4i_i2s_clk_div {
>>       u8      val;
>>  };
>>
>> +struct sun4i_i2s_quirks {
>> +     unsigned int    reg_dac_txdata; /* TX FIFO offset for DMA config */
>> +     bool            has_reset;
>> +     const struct regmap_config      *sun4i_i2s_regmap;
>> +     const struct snd_soc_dai_ops    *ops;
>> +};
>> +
>
> This is quite hard to review without actual example of what you'll put
> in there.
Fair enough...I have a patch for the A31 but haven't got any hardware
that I can verify it on. I've confirmed on the H3 but I feel like that
patch needs some tidying up. That being said...I'll push it as a patch
set and we can talk about the setup.

>
>>  static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = {
>>       { .div = 2, .val = 0 },
>>       { .div = 4, .val = 1 },
>> @@ -541,7 +551,6 @@ static struct snd_soc_dai_driver sun4i_i2s_dai = {
>>               .rates = SNDRV_PCM_RATE_8000_192000,
>>               .formats = SNDRV_PCM_FMTBIT_S16_LE,
>>       },
>> -     .ops = &sun4i_i2s_dai_ops,
>>       .symmetric_rates = 1,
>>  };
>>
>> @@ -655,6 +664,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>>  {
>>       struct sun4i_i2s *i2s;
>>       struct resource *res;
>> +     const struct sun4i_i2s_quirks *quirks;
>>       void __iomem *regs;
>>       int irq, ret;
>>
>> @@ -680,8 +690,14 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>>               return PTR_ERR(i2s->bus_clk);
>>       }
>>
>> +     quirks = of_device_get_match_data(&pdev->dev);
>> +     if (quirks == NULL) {
>> +             dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
>> +             return -ENODEV;
>> +     }
>> +
>>       i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
>> -                                         &sun4i_i2s_regmap_config);
>> +                                         quirks->sun4i_i2s_regmap);
>>       if (IS_ERR(i2s->regmap)) {
>>               dev_err(&pdev->dev, "Regmap initialisation failed\n");
>>               return PTR_ERR(i2s->regmap);
>> @@ -692,13 +708,25 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>>               dev_err(&pdev->dev, "Can't get our mod clock\n");
>>               return PTR_ERR(i2s->mod_clk);
>>       }
>> +
>
> Spurious change?
ACK
>
>>
>> -     i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG;
>> +     i2s->playback_dma_data.addr = res->start + quirks->reg_dac_txdata;
>>       i2s->playback_dma_data.maxburst = 4;
>>
>>       i2s->capture_dma_data.addr = res->start + SUN4I_I2S_FIFO_RX_REG;
>>       i2s->capture_dma_data.maxburst = 4;
>>
>> +     if (quirks->has_reset) {
>> +             i2s->rst = devm_reset_control_get_optional(&pdev->dev, NULL);
>> +             if (IS_ERR(i2s->rst) && PTR_ERR(i2s->rst) == -EPROBE_DEFER) {
>> +                     ret = -EPROBE_DEFER;
>> +                     dev_err(&pdev->dev, "Failed to get reset: %d\n", ret);
>> +                     goto err_pm_disable;
>> +             }
>> +             if (!IS_ERR(i2s->rst))
>> +                     reset_control_deassert(i2s->rst);
>> +     }
>> +
>
> That reset line is not optional. The <A31 SoCs don't need it, and you
> cover that case already, but it is definitely mandatory for the A31.
OK..I'll search for a better function call. Thanks for this and the
other reviews.
CK
>
> Thanks,
> Maxime
>
> --
> Maxime Ripard, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com

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

* [PATCH] ASoC: sun4i-i2s: Add quirks for newer SoCs
@ 2016-12-20 19:40     ` Code Kipper
  0 siblings, 0 replies; 9+ messages in thread
From: Code Kipper @ 2016-12-20 19:40 UTC (permalink / raw)
  To: linux-arm-kernel

On 20 December 2016 at 20:16, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Hi,
>
> On Tue, Dec 20, 2016 at 03:55:24PM +0100, codekipper at gmail.com wrote:
>> From: Marcus Cooper <codekipper@gmail.com>
>>
>> Newer SoCs have additional functionality so a quirks structure
>> has been added to handle them. So far we've seen the use of a
>> reset controller, a different address for the TXFIFO and varying
>> register changes.
>>
>> This patch prepares the driver for these changes and adds the
>> reset specifier.
>>
>> Signed-off-by: Marcus Cooper <codekipper@gmail.com>
>> ---
>>  .../devicetree/bindings/sound/sun4i-i2s.txt        |  2 +
>>  sound/soc/sunxi/sun4i-i2s.c                        | 47 ++++++++++++++++++++--
>>  2 files changed, 45 insertions(+), 4 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
>> index 7a2c0945fd22..494a881ccd21 100644
>> --- a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
>> +++ b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt
>> @@ -18,6 +18,8 @@ Required properties:
>>     - "apb" : clock for the I2S bus interface
>>     - "mod" : module clock for the I2S controller
>>  - #sound-dai-cells : Must be equal to 0
>> +- resets: reset specifier for the ahb reset (A31 and newer only)
>> +
>>
>>  Example:
>>
>> diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
>> index f24d19526603..80fe4f1d6e3b 100644
>> --- a/sound/soc/sunxi/sun4i-i2s.c
>> +++ b/sound/soc/sunxi/sun4i-i2s.c
>> @@ -14,9 +14,11 @@
>>  #include <linux/clk.h>
>>  #include <linux/dmaengine.h>
>>  #include <linux/module.h>
>> +#include <linux/of_device.h>
>>  #include <linux/platform_device.h>
>>  #include <linux/pm_runtime.h>
>>  #include <linux/regmap.h>
>> +#include <linux/reset.h>
>>
>>  #include <sound/dmaengine_pcm.h>
>>  #include <sound/pcm_params.h>
>> @@ -92,6 +94,7 @@ struct sun4i_i2s {
>>       struct clk      *bus_clk;
>>       struct clk      *mod_clk;
>>       struct regmap   *regmap;
>> +     struct reset_control *rst;
>>
>>       unsigned int    mclk_freq;
>>
>> @@ -104,6 +107,13 @@ struct sun4i_i2s_clk_div {
>>       u8      val;
>>  };
>>
>> +struct sun4i_i2s_quirks {
>> +     unsigned int    reg_dac_txdata; /* TX FIFO offset for DMA config */
>> +     bool            has_reset;
>> +     const struct regmap_config      *sun4i_i2s_regmap;
>> +     const struct snd_soc_dai_ops    *ops;
>> +};
>> +
>
> This is quite hard to review without actual example of what you'll put
> in there.
Fair enough...I have a patch for the A31 but haven't got any hardware
that I can verify it on. I've confirmed on the H3 but I feel like that
patch needs some tidying up. That being said...I'll push it as a patch
set and we can talk about the setup.

>
>>  static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = {
>>       { .div = 2, .val = 0 },
>>       { .div = 4, .val = 1 },
>> @@ -541,7 +551,6 @@ static struct snd_soc_dai_driver sun4i_i2s_dai = {
>>               .rates = SNDRV_PCM_RATE_8000_192000,
>>               .formats = SNDRV_PCM_FMTBIT_S16_LE,
>>       },
>> -     .ops = &sun4i_i2s_dai_ops,
>>       .symmetric_rates = 1,
>>  };
>>
>> @@ -655,6 +664,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>>  {
>>       struct sun4i_i2s *i2s;
>>       struct resource *res;
>> +     const struct sun4i_i2s_quirks *quirks;
>>       void __iomem *regs;
>>       int irq, ret;
>>
>> @@ -680,8 +690,14 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>>               return PTR_ERR(i2s->bus_clk);
>>       }
>>
>> +     quirks = of_device_get_match_data(&pdev->dev);
>> +     if (quirks == NULL) {
>> +             dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
>> +             return -ENODEV;
>> +     }
>> +
>>       i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
>> -                                         &sun4i_i2s_regmap_config);
>> +                                         quirks->sun4i_i2s_regmap);
>>       if (IS_ERR(i2s->regmap)) {
>>               dev_err(&pdev->dev, "Regmap initialisation failed\n");
>>               return PTR_ERR(i2s->regmap);
>> @@ -692,13 +708,25 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>>               dev_err(&pdev->dev, "Can't get our mod clock\n");
>>               return PTR_ERR(i2s->mod_clk);
>>       }
>> +
>
> Spurious change?
ACK
>
>>
>> -     i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG;
>> +     i2s->playback_dma_data.addr = res->start + quirks->reg_dac_txdata;
>>       i2s->playback_dma_data.maxburst = 4;
>>
>>       i2s->capture_dma_data.addr = res->start + SUN4I_I2S_FIFO_RX_REG;
>>       i2s->capture_dma_data.maxburst = 4;
>>
>> +     if (quirks->has_reset) {
>> +             i2s->rst = devm_reset_control_get_optional(&pdev->dev, NULL);
>> +             if (IS_ERR(i2s->rst) && PTR_ERR(i2s->rst) == -EPROBE_DEFER) {
>> +                     ret = -EPROBE_DEFER;
>> +                     dev_err(&pdev->dev, "Failed to get reset: %d\n", ret);
>> +                     goto err_pm_disable;
>> +             }
>> +             if (!IS_ERR(i2s->rst))
>> +                     reset_control_deassert(i2s->rst);
>> +     }
>> +
>
> That reset line is not optional. The <A31 SoCs don't need it, and you
> cover that case already, but it is definitely mandatory for the A31.
OK..I'll search for a better function call. Thanks for this and the
other reviews.
CK
>
> Thanks,
> Maxime
>
> --
> Maxime Ripard, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com

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

end of thread, other threads:[~2016-12-20 19:40 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-20 14:55 [PATCH] ASoC: sun4i-i2s: Add quirks for newer SoCs codekipper
2016-12-20 14:55 ` codekipper at gmail.com
2016-12-20 14:55 ` codekipper-Re5JQEeQqe8AvxtiuMwx3w
2016-12-20 19:16 ` Maxime Ripard
2016-12-20 19:16   ` Maxime Ripard
2016-12-20 19:16   ` Maxime Ripard
2016-12-20 19:40   ` Code Kipper
2016-12-20 19:40     ` Code Kipper
2016-12-20 19:40     ` Code Kipper

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.