All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/14] ASoc: sunxi: Add Allwinner A33 codec driver
@ 2016-10-04  9:46 ` Mylène Josserand
  0 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt
  Cc: linux-kernel, dmaengine, linux-arm-kernel, linux-clk, alsa-devel,
	devicetree, linux-sunxi, thomas.petazzoni, mylene.josserand,
	alexandre.belloni

Hi everyone,


This patchset add the audio codec for Allwinner A33 (sun8i) SoC.

It adds different drivers:
   - sun8i-codec-analog (patch 4): This driver implements the analog part
   of the audio codec. The analog part is handled in PRCM registers so this
   driver must be added as prcm's subnode (patch 5).
   - sun8i-codec (patch 6): This driver implements the digital part of the
   A33 codec.
   - sun8i (patch 7): This driver implements a sound card for A33.
   It links the DAI and the audio codec. The analog codec driver is handled
   as an "aux_device".

The DAI for this codec is the same than for A20: "sun4i-i2s".
The digital codec code is coming from Allwinner's BSP (after some
cleanup and DAPM conversion) [1]
The analog codec driver is coming from Chen-Yu Tsai's driver [2]
with some modifications (such as read/write regmap functions).

Currently, all the drivers handle only the playback feature.
The other ones (such as capture) and all other interfaces except
headphone are not supported.

These drivers are functional except for one issue. When playing a sound
for the first time, a short delay can be noticed. On a second play
(right after), the sound is played correctly. If we wait a short time
(~5 sec), the delay is back.
There is the same behavior for left/right channel. On the first
time, a left sound is played on the left channel but in the second
time, the sound will be played on wrong channel.

These issues will be fixed in a second time. Is someone have suggestions
about it?

Examples of amixer commands:
	amixer set 'Headphone' 75%
	amixer set 'Headphone' on
	amixer set 'DAC' on
	amixer set 'Right DAC Mixer RSlot 0' on
	amixer set 'Left DAC Mixer LSlot 0' on
	amixer set 'DAC Reversed Right' on
	amixer set 'DAC Reversed Left' on

It was tested on Parrot and Sinlinx board where device tree's modifications
are added (patch 11 to 14).

Thank you in advance,
Best regards,

[1]: https://github.com/allwinner-zh/linux-3.4-sunxi/blob/master/sound/soc/sunxi/audiocodec/sun8iw5_sndcodec.c
[2]: https://github.com/wens/linux/tree/a31-audio

Mylène Josserand (14):
  dma: sun6i-dma: Add burst case of 4
  clk: ccu-sun8i-a33: Add CLK_SET_RATE_PARENT to ac-dig
  ASoC: sun4i-i2s: Add apb reset
  ASoC: Add sun8i analog codec driver
  mfd: sun6i-prcm: Add sun8i analog codec as subnode
  ASoC: Add sun8i digital audio codec
  ASoC: Add sun8i audio card
  dt-bindings: sound: Add sun8i analog codec documentation
  dt-bindings: sound: Add sun8i codec documentation
  dt-bindings: sound: Add sun8i audio card documentation
  ARM: dts: sun8i: Add analog codec on prcm node
  ARM: dts: sun8i: Add audio codec, dai and card for A33
  ARM: dts: sun8i: parrot: Enable audio nodes
  ARM: dts: sun8i: sinlinx: Enable audio nodes

 .../devicetree/bindings/sound/sun8i-audio.txt      |  17 +
 .../bindings/sound/sun8i-codec-analog.txt          |  20 +
 .../devicetree/bindings/sound/sun8i-codec.txt      |  24 +
 arch/arm/boot/dts/sun8i-a23-a33.dtsi               |   7 +
 arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts     |   8 +
 arch/arm/boot/dts/sun8i-a33.dtsi                   |  33 ++
 arch/arm/boot/dts/sun8i-r16-parrot.dts             |   8 +
 drivers/clk/sunxi-ng/ccu-sun8i-a33.c               |   2 +-
 drivers/dma/sun6i-dma.c                            |   2 +
 drivers/mfd/sun6i-prcm.c                           |  16 +
 sound/soc/sunxi/Kconfig                            |  30 ++
 sound/soc/sunxi/Makefile                           |   3 +
 sound/soc/sunxi/sun4i-i2s.c                        |  16 +-
 sound/soc/sunxi/sun8i-codec-analog.c               | 305 +++++++++++++
 sound/soc/sunxi/sun8i-codec.c                      | 492 +++++++++++++++++++++
 sound/soc/sunxi/sun8i.c                            | 101 +++++
 16 files changed, 1082 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/sound/sun8i-audio.txt
 create mode 100644 Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
 create mode 100644 Documentation/devicetree/bindings/sound/sun8i-codec.txt
 create mode 100644 sound/soc/sunxi/sun8i-codec-analog.c
 create mode 100644 sound/soc/sunxi/sun8i-codec.c
 create mode 100644 sound/soc/sunxi/sun8i.c

-- 
2.9.3

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

* [PATCH 00/14] ASoc: sunxi: Add Allwinner A33 codec driver
@ 2016-10-04  9:46 ` Mylène Josserand
  0 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel

Hi everyone,


This patchset add the audio codec for Allwinner A33 (sun8i) SoC.

It adds different drivers:
   - sun8i-codec-analog (patch 4): This driver implements the analog part
   of the audio codec. The analog part is handled in PRCM registers so this
   driver must be added as prcm's subnode (patch 5).
   - sun8i-codec (patch 6): This driver implements the digital part of the
   A33 codec.
   - sun8i (patch 7): This driver implements a sound card for A33.
   It links the DAI and the audio codec. The analog codec driver is handled
   as an "aux_device".

The DAI for this codec is the same than for A20: "sun4i-i2s".
The digital codec code is coming from Allwinner's BSP (after some
cleanup and DAPM conversion) [1]
The analog codec driver is coming from Chen-Yu Tsai's driver [2]
with some modifications (such as read/write regmap functions).

Currently, all the drivers handle only the playback feature.
The other ones (such as capture) and all other interfaces except
headphone are not supported.

These drivers are functional except for one issue. When playing a sound
for the first time, a short delay can be noticed. On a second play
(right after), the sound is played correctly. If we wait a short time
(~5 sec), the delay is back.
There is the same behavior for left/right channel. On the first
time, a left sound is played on the left channel but in the second
time, the sound will be played on wrong channel.

These issues will be fixed in a second time. Is someone have suggestions
about it?

Examples of amixer commands:
	amixer set 'Headphone' 75%
	amixer set 'Headphone' on
	amixer set 'DAC' on
	amixer set 'Right DAC Mixer RSlot 0' on
	amixer set 'Left DAC Mixer LSlot 0' on
	amixer set 'DAC Reversed Right' on
	amixer set 'DAC Reversed Left' on

It was tested on Parrot and Sinlinx board where device tree's modifications
are added (patch 11 to 14).

Thank you in advance,
Best regards,

[1]: https://github.com/allwinner-zh/linux-3.4-sunxi/blob/master/sound/soc/sunxi/audiocodec/sun8iw5_sndcodec.c
[2]: https://github.com/wens/linux/tree/a31-audio

Myl?ne Josserand (14):
  dma: sun6i-dma: Add burst case of 4
  clk: ccu-sun8i-a33: Add CLK_SET_RATE_PARENT to ac-dig
  ASoC: sun4i-i2s: Add apb reset
  ASoC: Add sun8i analog codec driver
  mfd: sun6i-prcm: Add sun8i analog codec as subnode
  ASoC: Add sun8i digital audio codec
  ASoC: Add sun8i audio card
  dt-bindings: sound: Add sun8i analog codec documentation
  dt-bindings: sound: Add sun8i codec documentation
  dt-bindings: sound: Add sun8i audio card documentation
  ARM: dts: sun8i: Add analog codec on prcm node
  ARM: dts: sun8i: Add audio codec, dai and card for A33
  ARM: dts: sun8i: parrot: Enable audio nodes
  ARM: dts: sun8i: sinlinx: Enable audio nodes

 .../devicetree/bindings/sound/sun8i-audio.txt      |  17 +
 .../bindings/sound/sun8i-codec-analog.txt          |  20 +
 .../devicetree/bindings/sound/sun8i-codec.txt      |  24 +
 arch/arm/boot/dts/sun8i-a23-a33.dtsi               |   7 +
 arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts     |   8 +
 arch/arm/boot/dts/sun8i-a33.dtsi                   |  33 ++
 arch/arm/boot/dts/sun8i-r16-parrot.dts             |   8 +
 drivers/clk/sunxi-ng/ccu-sun8i-a33.c               |   2 +-
 drivers/dma/sun6i-dma.c                            |   2 +
 drivers/mfd/sun6i-prcm.c                           |  16 +
 sound/soc/sunxi/Kconfig                            |  30 ++
 sound/soc/sunxi/Makefile                           |   3 +
 sound/soc/sunxi/sun4i-i2s.c                        |  16 +-
 sound/soc/sunxi/sun8i-codec-analog.c               | 305 +++++++++++++
 sound/soc/sunxi/sun8i-codec.c                      | 492 +++++++++++++++++++++
 sound/soc/sunxi/sun8i.c                            | 101 +++++
 16 files changed, 1082 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/sound/sun8i-audio.txt
 create mode 100644 Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
 create mode 100644 Documentation/devicetree/bindings/sound/sun8i-codec.txt
 create mode 100644 sound/soc/sunxi/sun8i-codec-analog.c
 create mode 100644 sound/soc/sunxi/sun8i-codec.c
 create mode 100644 sound/soc/sunxi/sun8i.c

-- 
2.9.3

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

* [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
  2016-10-04  9:46 ` Mylène Josserand
@ 2016-10-04  9:46     ` Mylène Josserand
  -1 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt
  Cc: linux-kernel, dmaengine, linux-arm-kernel, linux-clk, alsa-devel,
	devicetree, linux-sunxi, thomas.petazzoni, mylene.josserand,
	alexandre.belloni

Add the case of a burst of 4 which is handled by the SoC.

Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
---
 drivers/dma/sun6i-dma.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
index 8346199..0485204 100644
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
 	switch (maxburst) {
 	case 1:
 		return 0;
+	case 4:
+		return 1;
 	case 8:
 		return 2;
 	default:
-- 
2.9.3

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

* [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-10-04  9:46     ` Mylène Josserand
  0 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel

Add the case of a burst of 4 which is handled by the SoC.

Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
---
 drivers/dma/sun6i-dma.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
index 8346199..0485204 100644
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
 	switch (maxburst) {
 	case 1:
 		return 0;
+	case 4:
+		return 1;
 	case 8:
 		return 2;
 	default:
-- 
2.9.3

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

* [PATCH 02/14] clk: ccu-sun8i-a33: Add CLK_SET_RATE_PARENT to ac-dig
  2016-10-04  9:46 ` Mylène Josserand
@ 2016-10-04  9:46     ` Mylène Josserand
  -1 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt
  Cc: linux-kernel, dmaengine, linux-arm-kernel, linux-clk, alsa-devel,
	devicetree, linux-sunxi, thomas.petazzoni, mylene.josserand,
	alexandre.belloni

Add the flag CLK_SET_RATE_PARENT to 'ac-dig' clock.

Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
---
 drivers/clk/sunxi-ng/ccu-sun8i-a33.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
index 96b40ca..37c4d8d 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
@@ -440,7 +440,7 @@ static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve",
 			     0x13c, 16, 3, BIT(31), CLK_SET_RATE_PARENT);
 
 static SUNXI_CCU_GATE(ac_dig_clk,	"ac-dig",	"pll-audio",
-		      0x140, BIT(31), 0);
+		      0x140, BIT(31), CLK_SET_RATE_PARENT);
 static SUNXI_CCU_GATE(ac_dig_4x_clk,	"ac-dig-4x",	"pll-audio-4x",
 		      0x140, BIT(30), 0);
 static SUNXI_CCU_GATE(avs_clk,		"avs",		"osc24M",
-- 
2.9.3

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

* [PATCH 02/14] clk: ccu-sun8i-a33: Add CLK_SET_RATE_PARENT to ac-dig
@ 2016-10-04  9:46     ` Mylène Josserand
  0 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel

Add the flag CLK_SET_RATE_PARENT to 'ac-dig' clock.

Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
---
 drivers/clk/sunxi-ng/ccu-sun8i-a33.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
index 96b40ca..37c4d8d 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
@@ -440,7 +440,7 @@ static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve",
 			     0x13c, 16, 3, BIT(31), CLK_SET_RATE_PARENT);
 
 static SUNXI_CCU_GATE(ac_dig_clk,	"ac-dig",	"pll-audio",
-		      0x140, BIT(31), 0);
+		      0x140, BIT(31), CLK_SET_RATE_PARENT);
 static SUNXI_CCU_GATE(ac_dig_4x_clk,	"ac-dig-4x",	"pll-audio-4x",
 		      0x140, BIT(30), 0);
 static SUNXI_CCU_GATE(avs_clk,		"avs",		"osc24M",
-- 
2.9.3

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

* [PATCH 03/14] ASoC: sun4i-i2s: Add apb reset
  2016-10-04  9:46 ` Mylène Josserand
@ 2016-10-04  9:46     ` Mylène Josserand
  -1 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt
  Cc: linux-kernel, dmaengine, linux-arm-kernel, linux-clk, alsa-devel,
	devicetree, linux-sunxi, thomas.petazzoni, mylene.josserand,
	alexandre.belloni

Add APB deassert function for sun4i-i2s driver.

Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
---
 sound/soc/sunxi/sun4i-i2s.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 687a8f8..f3f7026 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -17,6 +17,7 @@
 #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>
@@ -589,6 +590,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
 {
 	struct sun4i_i2s *i2s;
 	struct resource *res;
+	struct reset_control *reset_apb;
 	void __iomem *regs;
 	int irq, ret;
 
@@ -626,7 +628,19 @@ 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);
 	}
-	
+
+	reset_apb = devm_reset_control_get(&pdev->dev, "apb_reset");
+	if (IS_ERR(reset_apb)) {
+		dev_err(&pdev->dev, "Can't get apb reset\n");
+		return PTR_ERR(i2s->mod_clk);
+	}
+
+	ret = reset_control_deassert(reset_apb);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Can't deassert apb reset (%d)\n", ret);
+		return ret;
+	}
+
 	i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG;
 	i2s->playback_dma_data.maxburst = 4;
 
-- 
2.9.3

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

* [PATCH 03/14] ASoC: sun4i-i2s: Add apb reset
@ 2016-10-04  9:46     ` Mylène Josserand
  0 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel

Add APB deassert function for sun4i-i2s driver.

Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
---
 sound/soc/sunxi/sun4i-i2s.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 687a8f8..f3f7026 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -17,6 +17,7 @@
 #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>
@@ -589,6 +590,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
 {
 	struct sun4i_i2s *i2s;
 	struct resource *res;
+	struct reset_control *reset_apb;
 	void __iomem *regs;
 	int irq, ret;
 
@@ -626,7 +628,19 @@ 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);
 	}
-	
+
+	reset_apb = devm_reset_control_get(&pdev->dev, "apb_reset");
+	if (IS_ERR(reset_apb)) {
+		dev_err(&pdev->dev, "Can't get apb reset\n");
+		return PTR_ERR(i2s->mod_clk);
+	}
+
+	ret = reset_control_deassert(reset_apb);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Can't deassert apb reset (%d)\n", ret);
+		return ret;
+	}
+
 	i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG;
 	i2s->playback_dma_data.maxburst = 4;
 
-- 
2.9.3

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

* [PATCH 04/14] ASoC: Add sun8i analog codec driver
       [not found] ` <cover.1475571575.git.mylene.josserand@free-electrons.com>
  2016-10-04  9:46     ` Mylène Josserand
@ 2016-10-04  9:46     ` Mylène Josserand
  2016-10-04  9:46     ` Mylène Josserand
                       ` (11 subsequent siblings)
  13 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt
  Cc: linux-kernel, dmaengine, linux-arm-kernel, linux-clk, alsa-devel,
	devicetree, linux-sunxi, thomas.petazzoni, mylene.josserand,
	alexandre.belloni

Add the analog part of the sun8i (A33) codec driver. This driver
implements all the analog part of the codec using PRCM registers.

The read/write regmap functions must be handled in a custom way as
the PRCM register behaves as "mailbox" register.

Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
---
 sound/soc/sunxi/Kconfig              |   7 +
 sound/soc/sunxi/Makefile             |   1 +
 sound/soc/sunxi/sun8i-codec-analog.c | 304 +++++++++++++++++++++++++++++++++++
 3 files changed, 312 insertions(+)
 create mode 100644 sound/soc/sunxi/sun8i-codec-analog.c

diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
index dd23682..7aee95a 100644
--- a/sound/soc/sunxi/Kconfig
+++ b/sound/soc/sunxi/Kconfig
@@ -26,4 +26,11 @@ config SND_SUN4I_SPDIF
 	help
 	  Say Y or M to add support for the S/PDIF audio block in the Allwinner
 	  A10 and affiliated SoCs.
+
+config SND_SUN8I_CODEC_ANALOG
+	tristate "Allwinner SUN8I analog codec"
+	select REGMAP_MMIO
+        help
+	  Say Y or M if you want to add sun8i analog audiocodec support
+
 endmenu
diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
index 604c7b84..241c0df 100644
--- a/sound/soc/sunxi/Makefile
+++ b/sound/soc/sunxi/Makefile
@@ -1,3 +1,4 @@
 obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
 obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
 obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
+obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
diff --git a/sound/soc/sunxi/sun8i-codec-analog.c b/sound/soc/sunxi/sun8i-codec-analog.c
new file mode 100644
index 0000000..be3d540
--- /dev/null
+++ b/sound/soc/sunxi/sun8i-codec-analog.c
@@ -0,0 +1,304 @@
+/*
+ * This driver supports the analog controls for the internal codec
+ * found in Allwinner's A31s, A33 and A23 SoCs.
+ *
+ * Copyright 2016 Chen-Yu Tsai <wens@csie.org>
+ * Copyright 2016 Mylène Josserand <mylene.josserand@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/tlv.h>
+
+/* Codec analog control register offsets and bit fields */
+#define SUN8I_ADDA_HP_VOLC				0x00
+#define SUN8I_ADDA_HP_VOLC_PA_CLK_GATE			7
+#define SUN8I_ADDA_HP_VOLC_HP_VOL			0
+#define SUN8I_ADDA_LOMIXSC				0x01
+#define SUN8I_ADDA_LOMIXSC_MIC1			6
+#define SUN8I_ADDA_LOMIXSC_MIC2			5
+#define SUN8I_ADDA_LOMIXSC_PHONE			4
+#define SUN8I_ADDA_LOMIXSC_PHONEN			3
+#define SUN8I_ADDA_LOMIXSC_LINEINL			2
+#define SUN8I_ADDA_LOMIXSC_DACL			1
+#define SUN8I_ADDA_LOMIXSC_DACR			0
+#define SUN8I_ADDA_ROMIXSC				0x02
+#define SUN8I_ADDA_ROMIXSC_MIC1			6
+#define SUN8I_ADDA_ROMIXSC_MIC2			5
+#define SUN8I_ADDA_ROMIXSC_PHONE			4
+#define SUN8I_ADDA_ROMIXSC_PHONEP			3
+#define SUN8I_ADDA_ROMIXSC_LINEINR			2
+#define SUN8I_ADDA_ROMIXSC_DACR			1
+#define SUN8I_ADDA_ROMIXSC_DACL			0
+#define SUN8I_ADDA_DAC_PA_SRC				0x03
+#define SUN8I_ADDA_DAC_PA_SRC_DACAREN			7
+#define SUN8I_ADDA_DAC_PA_SRC_DACALEN			6
+#define SUN8I_ADDA_DAC_PA_SRC_RMIXEN			5
+#define SUN8I_ADDA_DAC_PA_SRC_LMIXEN			4
+#define SUN8I_ADDA_DAC_PA_SRC_RHPPAMUTE		3
+#define SUN8I_ADDA_DAC_PA_SRC_LHPPAMUTE		2
+#define SUN8I_ADDA_DAC_PA_SRC_RHPIS			1
+#define SUN8I_ADDA_DAC_PA_SRC_LHPIS			0
+#define SUN8I_ADDA_PHONEIN_GCTRL			0x04
+#define SUN8I_ADDA_PHONEIN_GCTRL_PHONEPG		4
+#define SUN8I_ADDA_PHONEIN_GCTRL_PHONENG		0
+#define SUN8I_ADDA_LINEIN_GCTRL			0x05
+#define SUN8I_ADDA_LINEIN_GCTRL_LINEING		4
+#define SUN8I_ADDA_LINEIN_GCTRL_PHONEG			0
+#define SUN8I_ADDA_MICIN_GCTRL				0x06
+#define SUN8I_ADDA_MICIN_GCTRL_MIC1G			4
+#define SUN8I_ADDA_MICIN_GCTRL_MIC2G			0
+#define SUN8I_ADDA_PAEN_HP_CTRL			0x07
+#define SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN			7
+#define SUN8I_ADDA_PAEN_HP_CTRL_HPCOM_FC		5
+#define SUN8I_ADDA_PAEN_HP_CTRL_COMPTEN		4
+#define SUN8I_ADDA_PAEN_HP_CTRL_PA_ANTI_POP_CTRL	2
+#define SUN8I_ADDA_PAEN_HP_CTRL_LTRNMUTE		1
+#define SUN8I_ADDA_PAEN_HP_CTRL_RTLNMUTE		0
+#define SUN8I_ADDA_PHONEOUT_CTRL			0x08
+#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTG		5
+#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTEN		4
+#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS3		3
+#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS2		2
+#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS1		1
+#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS0		0
+#define SUN8I_ADDA_PHONE_GAIN_CTRL			0x09
+#define SUN8I_ADDA_PHONE_GAIN_CTRL_PHONEPREG		0
+#define SUN8I_ADDA_MIC2G_CTRL				0x0a
+#define SUN8I_ADDA_MIC2G_CTRL_MIC2AMPEN		7
+#define SUN8I_ADDA_MIC2G_CTRL_MIC2BOOST		4
+#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL			0x0b
+#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIASEN	7
+#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MMICBIASEN	6
+#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIAS_MODE	5
+#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1AMPEN	3
+#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1BOOST	0
+#define SUN8I_ADDA_PA_ANTI_POP_CTRL			0x0e
+#define SUN8I_ADDA_ADC_AP_EN				0x0f
+
+/* Analog control register access bits */
+#define ADDA_PR				0x0 /* PRCM base + 0x1c0 */
+#define ADDA_PR_RESET				BIT(28)
+#define ADDA_PR_WRITE				BIT(24)
+#define ADDA_PR_ADDR_SHIFT			16
+#define ADDA_PR_ADDR_MASK			GENMASK(4, 0)
+#define ADDA_PR_DATA_IN_SHIFT			8
+#define ADDA_PR_DATA_IN_MASK			GENMASK(7, 0)
+#define ADDA_PR_DATA_OUT_SHIFT			0
+#define ADDA_PR_DATA_OUT_MASK			GENMASK(7, 0)
+
+/* regmap access bits */
+static int adda_reg_read(void *context, unsigned int reg, unsigned int *val)
+{
+	void __iomem *base = context;
+	u32 tmp;
+
+	tmp = readl(base);
+
+	/* De-assert reset */
+	writel(tmp | ADDA_PR_RESET, base);
+
+	tmp &= ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT);
+	tmp |= reg << ADDA_PR_ADDR_SHIFT;
+	writel(tmp, base);
+
+	*val = readl(base) & ADDA_PR_DATA_OUT_MASK;
+
+	return 0;
+}
+
+static int adda_reg_write(void *context, unsigned int reg, unsigned int val)
+{
+	void __iomem *base = context;
+	u32 tmp;
+
+	tmp = readl(base);
+	/* De-assert reset */
+	writel(tmp | ADDA_PR_RESET, base);
+
+	/* Write the address */
+	tmp &= ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT);
+	tmp |= reg << ADDA_PR_ADDR_SHIFT;
+	writel(tmp, base);
+
+	/* Write the value */
+	tmp &= ~(ADDA_PR_DATA_IN_MASK << ADDA_PR_DATA_IN_SHIFT);
+	tmp |= val << ADDA_PR_DATA_IN_SHIFT;
+	writel(tmp, base);
+
+	/* Indicate that the previous value must be written */
+	writel(readl(base) | ADDA_PR_WRITE, base);
+
+	/* Reset the write bit */
+	writel(readl(base) & ~(ADDA_PR_WRITE), base);
+
+	return 0;
+}
+
+struct regmap_config adda_pr_regmap_cfg = {
+	.name		= "adda-pr",
+	.reg_bits	= 5,
+	.reg_stride	= 1,
+	.val_bits	= 8,
+	.reg_read	= adda_reg_read,
+	.reg_write	= adda_reg_write,
+	.fast_io	= true,
+	.max_register	= 24,
+};
+
+static DECLARE_TLV_DB_SCALE(sun8i_codec_headphone_volume_scale, -6300, 100, 1);
+
+static const struct snd_kcontrol_new sun8i_analog_widgets[] = {
+	SOC_SINGLE_TLV("Headphone Volume", SUN8I_ADDA_HP_VOLC,
+		       SUN8I_ADDA_HP_VOLC_HP_VOL, 0x3F, 0,
+		       sun8i_codec_headphone_volume_scale),
+
+	/* Playback Switch */
+	SOC_DOUBLE("DAC Playback Switch", SUN8I_ADDA_DAC_PA_SRC,
+		   SUN8I_ADDA_DAC_PA_SRC_DACALEN, SUN8I_ADDA_DAC_PA_SRC_DACAREN,
+		   1, 0),
+
+	SOC_DOUBLE("Headphone Playback Switch", SUN8I_ADDA_DAC_PA_SRC,
+		   SUN8I_ADDA_DAC_PA_SRC_LHPPAMUTE,
+		   SUN8I_ADDA_DAC_PA_SRC_RHPPAMUTE, 1, 0),
+};
+
+/* headphone controls */
+static const char * const sun8i_codec_hp_src_enum_text[] = {
+	"DAC", "Mixer",
+};
+
+static SOC_ENUM_DOUBLE_DECL(sun8i_codec_hp_src_enum,
+			    SUN8I_ADDA_DAC_PA_SRC,
+			    SUN8I_ADDA_DAC_PA_SRC_LHPIS,
+			    SUN8I_ADDA_DAC_PA_SRC_RHPIS,
+			    sun8i_codec_hp_src_enum_text);
+
+static const struct snd_kcontrol_new sun8i_codec_hp_src[] = {
+	SOC_DAPM_ENUM("Headphone Source Playback Route",
+		      sun8i_codec_hp_src_enum),
+};
+
+static const struct snd_kcontrol_new sun8i_codec_mixer_controls[] = {
+	SOC_DAPM_SINGLE("DAC Left Playback Switch",
+			SUN8I_ADDA_LOMIXSC,
+			SUN8I_ADDA_LOMIXSC_DACL, 1, 0),
+	SOC_DAPM_SINGLE("DAC Right Playback Switch",
+			SUN8I_ADDA_ROMIXSC,
+			SUN8I_ADDA_ROMIXSC_DACR, 1, 0),
+	SOC_DAPM_SINGLE("DAC Reversed Left Playback Switch",
+			SUN8I_ADDA_LOMIXSC,
+			SUN8I_ADDA_LOMIXSC_DACR, 1, 0),
+	SOC_DAPM_SINGLE("DAC Reversed Right Playback Switch",
+			SUN8I_ADDA_ROMIXSC,
+			SUN8I_ADDA_ROMIXSC_DACL, 1, 0),
+};
+
+static const struct snd_soc_dapm_widget sun8i_codec_analog_dapm_widgets[] = {
+	/* Mixers */
+	SOC_MIXER_ARRAY("Left Mixer", SUN8I_ADDA_DAC_PA_SRC,
+			SUN8I_ADDA_DAC_PA_SRC_LMIXEN, 0,
+			sun8i_codec_mixer_controls),
+	SOC_MIXER_ARRAY("Right Mixer", SUN8I_ADDA_DAC_PA_SRC,
+			SUN8I_ADDA_DAC_PA_SRC_RMIXEN, 0,
+			sun8i_codec_mixer_controls),
+
+	/* Headphone output path */
+	SND_SOC_DAPM_MUX("Headphone Source Playback Route",
+			 SND_SOC_NOPM, 0, 0, sun8i_codec_hp_src),
+	SND_SOC_DAPM_OUT_DRV("Headphone Amp", SUN8I_ADDA_PAEN_HP_CTRL,
+			     SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN, 0, NULL, 0),
+
+	/* Headphone outputs */
+	SND_SOC_DAPM_OUTPUT("HP"),
+
+};
+
+static const struct snd_soc_dapm_route sun8i_codec_analog_dapm_routes[] = {
+	/* Left Mixer Routes */
+	{ "Left Mixer", "DAC Playback Switch", "Left DAC" },
+	{ "Left Mixer", "DAC Reversed Left Playback Switch", "Right DAC" },
+
+	/* Right Mixer Routes */
+	{ "Right Mixer", "DAC Playback Switch", "Right DAC" },
+	{ "Right Mixer", "DAC Reversed Right Playback Switch", "Left DAC" },
+
+	/* Headphone Routes */
+	{ "Headphone Source Playback Route", "DAC", "Left DAC" },
+	{ "Headphone Source Playback Route", "DAC", "Right DAC" },
+	{ "Headphone Source Playback Route", "Mixer", "Left Mixer" },
+	{ "Headphone Source Playback Route", "Mixer", "Right Mixer" },
+	{ "Headphone Amp", NULL, "Headphone Source Playback Route" },
+	{ "HP", NULL, "Headphone Amp" },
+};
+
+static const struct snd_soc_component_driver sun8i_codec_analog_cmpnt_drv = {
+	.name			= "sun8i-codec-analog",
+	.controls		= sun8i_analog_widgets,
+	.num_controls		= ARRAY_SIZE(sun8i_analog_widgets),
+	.dapm_widgets		= sun8i_codec_analog_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(sun8i_codec_analog_dapm_widgets),
+	.dapm_routes		= sun8i_codec_analog_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(sun8i_codec_analog_dapm_routes),
+};
+
+static const struct of_device_id sun8i_codec_analog_of_match[] = {
+	{ .compatible = "allwinner,sun8i-codec-analog", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, sun8i_codec_analog_of_match);
+
+static int sun8i_codec_analog_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	struct regmap *regmap;
+	void __iomem *base;
+
+	/* Get PRCM resources and registers */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base)) {
+		dev_err(&pdev->dev, "Failed to map PRCM registers\n");
+		return PTR_ERR(base);
+	}
+
+	regmap = devm_regmap_init(&pdev->dev, NULL, base, &adda_pr_regmap_cfg);
+	if (IS_ERR(regmap)) {
+		dev_err(&pdev->dev, "Regmap initialisation failed\n");
+		return PTR_ERR(regmap);
+	}
+
+	return devm_snd_soc_register_component(&pdev->dev,
+					       &sun8i_codec_analog_cmpnt_drv,
+					       NULL, 0);
+}
+
+static struct platform_driver sun8i_codec_analog_driver = {
+	.driver = {
+		.name = "sun8i-codec-analog",
+		.of_match_table = sun8i_codec_analog_of_match,
+	},
+	.probe = sun8i_codec_analog_probe,
+};
+module_platform_driver(sun8i_codec_analog_driver);
+
+MODULE_DESCRIPTION("Allwinner A31s/A33/A23 codec analog controls driver");
+MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
+MODULE_AUTHOR("Mylène Josserand <mylene.josserand@free-electrons.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:sun8i-codec-analog");
-- 
2.9.3

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

* [PATCH 04/14] ASoC: Add sun8i analog codec driver
@ 2016-10-04  9:46     ` Mylène Josserand
  0 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt
  Cc: thomas.petazzoni, devicetree, alsa-devel, linux-kernel,
	linux-sunxi, alexandre.belloni, dmaengine, mylene.josserand,
	linux-clk, linux-arm-kernel

Add the analog part of the sun8i (A33) codec driver. This driver
implements all the analog part of the codec using PRCM registers.

The read/write regmap functions must be handled in a custom way as
the PRCM register behaves as "mailbox" register.

Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
---
 sound/soc/sunxi/Kconfig              |   7 +
 sound/soc/sunxi/Makefile             |   1 +
 sound/soc/sunxi/sun8i-codec-analog.c | 304 +++++++++++++++++++++++++++++++++++
 3 files changed, 312 insertions(+)
 create mode 100644 sound/soc/sunxi/sun8i-codec-analog.c

diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
index dd23682..7aee95a 100644
--- a/sound/soc/sunxi/Kconfig
+++ b/sound/soc/sunxi/Kconfig
@@ -26,4 +26,11 @@ config SND_SUN4I_SPDIF
 	help
 	  Say Y or M to add support for the S/PDIF audio block in the Allwinner
 	  A10 and affiliated SoCs.
+
+config SND_SUN8I_CODEC_ANALOG
+	tristate "Allwinner SUN8I analog codec"
+	select REGMAP_MMIO
+        help
+	  Say Y or M if you want to add sun8i analog audiocodec support
+
 endmenu
diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
index 604c7b84..241c0df 100644
--- a/sound/soc/sunxi/Makefile
+++ b/sound/soc/sunxi/Makefile
@@ -1,3 +1,4 @@
 obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
 obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
 obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
+obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
diff --git a/sound/soc/sunxi/sun8i-codec-analog.c b/sound/soc/sunxi/sun8i-codec-analog.c
new file mode 100644
index 0000000..be3d540
--- /dev/null
+++ b/sound/soc/sunxi/sun8i-codec-analog.c
@@ -0,0 +1,304 @@
+/*
+ * This driver supports the analog controls for the internal codec
+ * found in Allwinner's A31s, A33 and A23 SoCs.
+ *
+ * Copyright 2016 Chen-Yu Tsai <wens@csie.org>
+ * Copyright 2016 Mylène Josserand <mylene.josserand@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/tlv.h>
+
+/* Codec analog control register offsets and bit fields */
+#define SUN8I_ADDA_HP_VOLC				0x00
+#define SUN8I_ADDA_HP_VOLC_PA_CLK_GATE			7
+#define SUN8I_ADDA_HP_VOLC_HP_VOL			0
+#define SUN8I_ADDA_LOMIXSC				0x01
+#define SUN8I_ADDA_LOMIXSC_MIC1			6
+#define SUN8I_ADDA_LOMIXSC_MIC2			5
+#define SUN8I_ADDA_LOMIXSC_PHONE			4
+#define SUN8I_ADDA_LOMIXSC_PHONEN			3
+#define SUN8I_ADDA_LOMIXSC_LINEINL			2
+#define SUN8I_ADDA_LOMIXSC_DACL			1
+#define SUN8I_ADDA_LOMIXSC_DACR			0
+#define SUN8I_ADDA_ROMIXSC				0x02
+#define SUN8I_ADDA_ROMIXSC_MIC1			6
+#define SUN8I_ADDA_ROMIXSC_MIC2			5
+#define SUN8I_ADDA_ROMIXSC_PHONE			4
+#define SUN8I_ADDA_ROMIXSC_PHONEP			3
+#define SUN8I_ADDA_ROMIXSC_LINEINR			2
+#define SUN8I_ADDA_ROMIXSC_DACR			1
+#define SUN8I_ADDA_ROMIXSC_DACL			0
+#define SUN8I_ADDA_DAC_PA_SRC				0x03
+#define SUN8I_ADDA_DAC_PA_SRC_DACAREN			7
+#define SUN8I_ADDA_DAC_PA_SRC_DACALEN			6
+#define SUN8I_ADDA_DAC_PA_SRC_RMIXEN			5
+#define SUN8I_ADDA_DAC_PA_SRC_LMIXEN			4
+#define SUN8I_ADDA_DAC_PA_SRC_RHPPAMUTE		3
+#define SUN8I_ADDA_DAC_PA_SRC_LHPPAMUTE		2
+#define SUN8I_ADDA_DAC_PA_SRC_RHPIS			1
+#define SUN8I_ADDA_DAC_PA_SRC_LHPIS			0
+#define SUN8I_ADDA_PHONEIN_GCTRL			0x04
+#define SUN8I_ADDA_PHONEIN_GCTRL_PHONEPG		4
+#define SUN8I_ADDA_PHONEIN_GCTRL_PHONENG		0
+#define SUN8I_ADDA_LINEIN_GCTRL			0x05
+#define SUN8I_ADDA_LINEIN_GCTRL_LINEING		4
+#define SUN8I_ADDA_LINEIN_GCTRL_PHONEG			0
+#define SUN8I_ADDA_MICIN_GCTRL				0x06
+#define SUN8I_ADDA_MICIN_GCTRL_MIC1G			4
+#define SUN8I_ADDA_MICIN_GCTRL_MIC2G			0
+#define SUN8I_ADDA_PAEN_HP_CTRL			0x07
+#define SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN			7
+#define SUN8I_ADDA_PAEN_HP_CTRL_HPCOM_FC		5
+#define SUN8I_ADDA_PAEN_HP_CTRL_COMPTEN		4
+#define SUN8I_ADDA_PAEN_HP_CTRL_PA_ANTI_POP_CTRL	2
+#define SUN8I_ADDA_PAEN_HP_CTRL_LTRNMUTE		1
+#define SUN8I_ADDA_PAEN_HP_CTRL_RTLNMUTE		0
+#define SUN8I_ADDA_PHONEOUT_CTRL			0x08
+#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTG		5
+#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTEN		4
+#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS3		3
+#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS2		2
+#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS1		1
+#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS0		0
+#define SUN8I_ADDA_PHONE_GAIN_CTRL			0x09
+#define SUN8I_ADDA_PHONE_GAIN_CTRL_PHONEPREG		0
+#define SUN8I_ADDA_MIC2G_CTRL				0x0a
+#define SUN8I_ADDA_MIC2G_CTRL_MIC2AMPEN		7
+#define SUN8I_ADDA_MIC2G_CTRL_MIC2BOOST		4
+#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL			0x0b
+#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIASEN	7
+#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MMICBIASEN	6
+#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIAS_MODE	5
+#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1AMPEN	3
+#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1BOOST	0
+#define SUN8I_ADDA_PA_ANTI_POP_CTRL			0x0e
+#define SUN8I_ADDA_ADC_AP_EN				0x0f
+
+/* Analog control register access bits */
+#define ADDA_PR				0x0 /* PRCM base + 0x1c0 */
+#define ADDA_PR_RESET				BIT(28)
+#define ADDA_PR_WRITE				BIT(24)
+#define ADDA_PR_ADDR_SHIFT			16
+#define ADDA_PR_ADDR_MASK			GENMASK(4, 0)
+#define ADDA_PR_DATA_IN_SHIFT			8
+#define ADDA_PR_DATA_IN_MASK			GENMASK(7, 0)
+#define ADDA_PR_DATA_OUT_SHIFT			0
+#define ADDA_PR_DATA_OUT_MASK			GENMASK(7, 0)
+
+/* regmap access bits */
+static int adda_reg_read(void *context, unsigned int reg, unsigned int *val)
+{
+	void __iomem *base = context;
+	u32 tmp;
+
+	tmp = readl(base);
+
+	/* De-assert reset */
+	writel(tmp | ADDA_PR_RESET, base);
+
+	tmp &= ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT);
+	tmp |= reg << ADDA_PR_ADDR_SHIFT;
+	writel(tmp, base);
+
+	*val = readl(base) & ADDA_PR_DATA_OUT_MASK;
+
+	return 0;
+}
+
+static int adda_reg_write(void *context, unsigned int reg, unsigned int val)
+{
+	void __iomem *base = context;
+	u32 tmp;
+
+	tmp = readl(base);
+	/* De-assert reset */
+	writel(tmp | ADDA_PR_RESET, base);
+
+	/* Write the address */
+	tmp &= ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT);
+	tmp |= reg << ADDA_PR_ADDR_SHIFT;
+	writel(tmp, base);
+
+	/* Write the value */
+	tmp &= ~(ADDA_PR_DATA_IN_MASK << ADDA_PR_DATA_IN_SHIFT);
+	tmp |= val << ADDA_PR_DATA_IN_SHIFT;
+	writel(tmp, base);
+
+	/* Indicate that the previous value must be written */
+	writel(readl(base) | ADDA_PR_WRITE, base);
+
+	/* Reset the write bit */
+	writel(readl(base) & ~(ADDA_PR_WRITE), base);
+
+	return 0;
+}
+
+struct regmap_config adda_pr_regmap_cfg = {
+	.name		= "adda-pr",
+	.reg_bits	= 5,
+	.reg_stride	= 1,
+	.val_bits	= 8,
+	.reg_read	= adda_reg_read,
+	.reg_write	= adda_reg_write,
+	.fast_io	= true,
+	.max_register	= 24,
+};
+
+static DECLARE_TLV_DB_SCALE(sun8i_codec_headphone_volume_scale, -6300, 100, 1);
+
+static const struct snd_kcontrol_new sun8i_analog_widgets[] = {
+	SOC_SINGLE_TLV("Headphone Volume", SUN8I_ADDA_HP_VOLC,
+		       SUN8I_ADDA_HP_VOLC_HP_VOL, 0x3F, 0,
+		       sun8i_codec_headphone_volume_scale),
+
+	/* Playback Switch */
+	SOC_DOUBLE("DAC Playback Switch", SUN8I_ADDA_DAC_PA_SRC,
+		   SUN8I_ADDA_DAC_PA_SRC_DACALEN, SUN8I_ADDA_DAC_PA_SRC_DACAREN,
+		   1, 0),
+
+	SOC_DOUBLE("Headphone Playback Switch", SUN8I_ADDA_DAC_PA_SRC,
+		   SUN8I_ADDA_DAC_PA_SRC_LHPPAMUTE,
+		   SUN8I_ADDA_DAC_PA_SRC_RHPPAMUTE, 1, 0),
+};
+
+/* headphone controls */
+static const char * const sun8i_codec_hp_src_enum_text[] = {
+	"DAC", "Mixer",
+};
+
+static SOC_ENUM_DOUBLE_DECL(sun8i_codec_hp_src_enum,
+			    SUN8I_ADDA_DAC_PA_SRC,
+			    SUN8I_ADDA_DAC_PA_SRC_LHPIS,
+			    SUN8I_ADDA_DAC_PA_SRC_RHPIS,
+			    sun8i_codec_hp_src_enum_text);
+
+static const struct snd_kcontrol_new sun8i_codec_hp_src[] = {
+	SOC_DAPM_ENUM("Headphone Source Playback Route",
+		      sun8i_codec_hp_src_enum),
+};
+
+static const struct snd_kcontrol_new sun8i_codec_mixer_controls[] = {
+	SOC_DAPM_SINGLE("DAC Left Playback Switch",
+			SUN8I_ADDA_LOMIXSC,
+			SUN8I_ADDA_LOMIXSC_DACL, 1, 0),
+	SOC_DAPM_SINGLE("DAC Right Playback Switch",
+			SUN8I_ADDA_ROMIXSC,
+			SUN8I_ADDA_ROMIXSC_DACR, 1, 0),
+	SOC_DAPM_SINGLE("DAC Reversed Left Playback Switch",
+			SUN8I_ADDA_LOMIXSC,
+			SUN8I_ADDA_LOMIXSC_DACR, 1, 0),
+	SOC_DAPM_SINGLE("DAC Reversed Right Playback Switch",
+			SUN8I_ADDA_ROMIXSC,
+			SUN8I_ADDA_ROMIXSC_DACL, 1, 0),
+};
+
+static const struct snd_soc_dapm_widget sun8i_codec_analog_dapm_widgets[] = {
+	/* Mixers */
+	SOC_MIXER_ARRAY("Left Mixer", SUN8I_ADDA_DAC_PA_SRC,
+			SUN8I_ADDA_DAC_PA_SRC_LMIXEN, 0,
+			sun8i_codec_mixer_controls),
+	SOC_MIXER_ARRAY("Right Mixer", SUN8I_ADDA_DAC_PA_SRC,
+			SUN8I_ADDA_DAC_PA_SRC_RMIXEN, 0,
+			sun8i_codec_mixer_controls),
+
+	/* Headphone output path */
+	SND_SOC_DAPM_MUX("Headphone Source Playback Route",
+			 SND_SOC_NOPM, 0, 0, sun8i_codec_hp_src),
+	SND_SOC_DAPM_OUT_DRV("Headphone Amp", SUN8I_ADDA_PAEN_HP_CTRL,
+			     SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN, 0, NULL, 0),
+
+	/* Headphone outputs */
+	SND_SOC_DAPM_OUTPUT("HP"),
+
+};
+
+static const struct snd_soc_dapm_route sun8i_codec_analog_dapm_routes[] = {
+	/* Left Mixer Routes */
+	{ "Left Mixer", "DAC Playback Switch", "Left DAC" },
+	{ "Left Mixer", "DAC Reversed Left Playback Switch", "Right DAC" },
+
+	/* Right Mixer Routes */
+	{ "Right Mixer", "DAC Playback Switch", "Right DAC" },
+	{ "Right Mixer", "DAC Reversed Right Playback Switch", "Left DAC" },
+
+	/* Headphone Routes */
+	{ "Headphone Source Playback Route", "DAC", "Left DAC" },
+	{ "Headphone Source Playback Route", "DAC", "Right DAC" },
+	{ "Headphone Source Playback Route", "Mixer", "Left Mixer" },
+	{ "Headphone Source Playback Route", "Mixer", "Right Mixer" },
+	{ "Headphone Amp", NULL, "Headphone Source Playback Route" },
+	{ "HP", NULL, "Headphone Amp" },
+};
+
+static const struct snd_soc_component_driver sun8i_codec_analog_cmpnt_drv = {
+	.name			= "sun8i-codec-analog",
+	.controls		= sun8i_analog_widgets,
+	.num_controls		= ARRAY_SIZE(sun8i_analog_widgets),
+	.dapm_widgets		= sun8i_codec_analog_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(sun8i_codec_analog_dapm_widgets),
+	.dapm_routes		= sun8i_codec_analog_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(sun8i_codec_analog_dapm_routes),
+};
+
+static const struct of_device_id sun8i_codec_analog_of_match[] = {
+	{ .compatible = "allwinner,sun8i-codec-analog", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, sun8i_codec_analog_of_match);
+
+static int sun8i_codec_analog_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	struct regmap *regmap;
+	void __iomem *base;
+
+	/* Get PRCM resources and registers */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base)) {
+		dev_err(&pdev->dev, "Failed to map PRCM registers\n");
+		return PTR_ERR(base);
+	}
+
+	regmap = devm_regmap_init(&pdev->dev, NULL, base, &adda_pr_regmap_cfg);
+	if (IS_ERR(regmap)) {
+		dev_err(&pdev->dev, "Regmap initialisation failed\n");
+		return PTR_ERR(regmap);
+	}
+
+	return devm_snd_soc_register_component(&pdev->dev,
+					       &sun8i_codec_analog_cmpnt_drv,
+					       NULL, 0);
+}
+
+static struct platform_driver sun8i_codec_analog_driver = {
+	.driver = {
+		.name = "sun8i-codec-analog",
+		.of_match_table = sun8i_codec_analog_of_match,
+	},
+	.probe = sun8i_codec_analog_probe,
+};
+module_platform_driver(sun8i_codec_analog_driver);
+
+MODULE_DESCRIPTION("Allwinner A31s/A33/A23 codec analog controls driver");
+MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
+MODULE_AUTHOR("Mylène Josserand <mylene.josserand@free-electrons.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:sun8i-codec-analog");
-- 
2.9.3


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 04/14] ASoC: Add sun8i analog codec driver
@ 2016-10-04  9:46     ` Mylène Josserand
  0 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel

Add the analog part of the sun8i (A33) codec driver. This driver
implements all the analog part of the codec using PRCM registers.

The read/write regmap functions must be handled in a custom way as
the PRCM register behaves as "mailbox" register.

Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
---
 sound/soc/sunxi/Kconfig              |   7 +
 sound/soc/sunxi/Makefile             |   1 +
 sound/soc/sunxi/sun8i-codec-analog.c | 304 +++++++++++++++++++++++++++++++++++
 3 files changed, 312 insertions(+)
 create mode 100644 sound/soc/sunxi/sun8i-codec-analog.c

diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
index dd23682..7aee95a 100644
--- a/sound/soc/sunxi/Kconfig
+++ b/sound/soc/sunxi/Kconfig
@@ -26,4 +26,11 @@ config SND_SUN4I_SPDIF
 	help
 	  Say Y or M to add support for the S/PDIF audio block in the Allwinner
 	  A10 and affiliated SoCs.
+
+config SND_SUN8I_CODEC_ANALOG
+	tristate "Allwinner SUN8I analog codec"
+	select REGMAP_MMIO
+        help
+	  Say Y or M if you want to add sun8i analog audiocodec support
+
 endmenu
diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
index 604c7b84..241c0df 100644
--- a/sound/soc/sunxi/Makefile
+++ b/sound/soc/sunxi/Makefile
@@ -1,3 +1,4 @@
 obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
 obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
 obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
+obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
diff --git a/sound/soc/sunxi/sun8i-codec-analog.c b/sound/soc/sunxi/sun8i-codec-analog.c
new file mode 100644
index 0000000..be3d540
--- /dev/null
+++ b/sound/soc/sunxi/sun8i-codec-analog.c
@@ -0,0 +1,304 @@
+/*
+ * This driver supports the analog controls for the internal codec
+ * found in Allwinner's A31s, A33 and A23 SoCs.
+ *
+ * Copyright 2016 Chen-Yu Tsai <wens@csie.org>
+ * Copyright 2016 Myl?ne Josserand <mylene.josserand@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/tlv.h>
+
+/* Codec analog control register offsets and bit fields */
+#define SUN8I_ADDA_HP_VOLC				0x00
+#define SUN8I_ADDA_HP_VOLC_PA_CLK_GATE			7
+#define SUN8I_ADDA_HP_VOLC_HP_VOL			0
+#define SUN8I_ADDA_LOMIXSC				0x01
+#define SUN8I_ADDA_LOMIXSC_MIC1			6
+#define SUN8I_ADDA_LOMIXSC_MIC2			5
+#define SUN8I_ADDA_LOMIXSC_PHONE			4
+#define SUN8I_ADDA_LOMIXSC_PHONEN			3
+#define SUN8I_ADDA_LOMIXSC_LINEINL			2
+#define SUN8I_ADDA_LOMIXSC_DACL			1
+#define SUN8I_ADDA_LOMIXSC_DACR			0
+#define SUN8I_ADDA_ROMIXSC				0x02
+#define SUN8I_ADDA_ROMIXSC_MIC1			6
+#define SUN8I_ADDA_ROMIXSC_MIC2			5
+#define SUN8I_ADDA_ROMIXSC_PHONE			4
+#define SUN8I_ADDA_ROMIXSC_PHONEP			3
+#define SUN8I_ADDA_ROMIXSC_LINEINR			2
+#define SUN8I_ADDA_ROMIXSC_DACR			1
+#define SUN8I_ADDA_ROMIXSC_DACL			0
+#define SUN8I_ADDA_DAC_PA_SRC				0x03
+#define SUN8I_ADDA_DAC_PA_SRC_DACAREN			7
+#define SUN8I_ADDA_DAC_PA_SRC_DACALEN			6
+#define SUN8I_ADDA_DAC_PA_SRC_RMIXEN			5
+#define SUN8I_ADDA_DAC_PA_SRC_LMIXEN			4
+#define SUN8I_ADDA_DAC_PA_SRC_RHPPAMUTE		3
+#define SUN8I_ADDA_DAC_PA_SRC_LHPPAMUTE		2
+#define SUN8I_ADDA_DAC_PA_SRC_RHPIS			1
+#define SUN8I_ADDA_DAC_PA_SRC_LHPIS			0
+#define SUN8I_ADDA_PHONEIN_GCTRL			0x04
+#define SUN8I_ADDA_PHONEIN_GCTRL_PHONEPG		4
+#define SUN8I_ADDA_PHONEIN_GCTRL_PHONENG		0
+#define SUN8I_ADDA_LINEIN_GCTRL			0x05
+#define SUN8I_ADDA_LINEIN_GCTRL_LINEING		4
+#define SUN8I_ADDA_LINEIN_GCTRL_PHONEG			0
+#define SUN8I_ADDA_MICIN_GCTRL				0x06
+#define SUN8I_ADDA_MICIN_GCTRL_MIC1G			4
+#define SUN8I_ADDA_MICIN_GCTRL_MIC2G			0
+#define SUN8I_ADDA_PAEN_HP_CTRL			0x07
+#define SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN			7
+#define SUN8I_ADDA_PAEN_HP_CTRL_HPCOM_FC		5
+#define SUN8I_ADDA_PAEN_HP_CTRL_COMPTEN		4
+#define SUN8I_ADDA_PAEN_HP_CTRL_PA_ANTI_POP_CTRL	2
+#define SUN8I_ADDA_PAEN_HP_CTRL_LTRNMUTE		1
+#define SUN8I_ADDA_PAEN_HP_CTRL_RTLNMUTE		0
+#define SUN8I_ADDA_PHONEOUT_CTRL			0x08
+#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTG		5
+#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTEN		4
+#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS3		3
+#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS2		2
+#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS1		1
+#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS0		0
+#define SUN8I_ADDA_PHONE_GAIN_CTRL			0x09
+#define SUN8I_ADDA_PHONE_GAIN_CTRL_PHONEPREG		0
+#define SUN8I_ADDA_MIC2G_CTRL				0x0a
+#define SUN8I_ADDA_MIC2G_CTRL_MIC2AMPEN		7
+#define SUN8I_ADDA_MIC2G_CTRL_MIC2BOOST		4
+#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL			0x0b
+#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIASEN	7
+#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MMICBIASEN	6
+#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIAS_MODE	5
+#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1AMPEN	3
+#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1BOOST	0
+#define SUN8I_ADDA_PA_ANTI_POP_CTRL			0x0e
+#define SUN8I_ADDA_ADC_AP_EN				0x0f
+
+/* Analog control register access bits */
+#define ADDA_PR				0x0 /* PRCM base + 0x1c0 */
+#define ADDA_PR_RESET				BIT(28)
+#define ADDA_PR_WRITE				BIT(24)
+#define ADDA_PR_ADDR_SHIFT			16
+#define ADDA_PR_ADDR_MASK			GENMASK(4, 0)
+#define ADDA_PR_DATA_IN_SHIFT			8
+#define ADDA_PR_DATA_IN_MASK			GENMASK(7, 0)
+#define ADDA_PR_DATA_OUT_SHIFT			0
+#define ADDA_PR_DATA_OUT_MASK			GENMASK(7, 0)
+
+/* regmap access bits */
+static int adda_reg_read(void *context, unsigned int reg, unsigned int *val)
+{
+	void __iomem *base = context;
+	u32 tmp;
+
+	tmp = readl(base);
+
+	/* De-assert reset */
+	writel(tmp | ADDA_PR_RESET, base);
+
+	tmp &= ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT);
+	tmp |= reg << ADDA_PR_ADDR_SHIFT;
+	writel(tmp, base);
+
+	*val = readl(base) & ADDA_PR_DATA_OUT_MASK;
+
+	return 0;
+}
+
+static int adda_reg_write(void *context, unsigned int reg, unsigned int val)
+{
+	void __iomem *base = context;
+	u32 tmp;
+
+	tmp = readl(base);
+	/* De-assert reset */
+	writel(tmp | ADDA_PR_RESET, base);
+
+	/* Write the address */
+	tmp &= ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT);
+	tmp |= reg << ADDA_PR_ADDR_SHIFT;
+	writel(tmp, base);
+
+	/* Write the value */
+	tmp &= ~(ADDA_PR_DATA_IN_MASK << ADDA_PR_DATA_IN_SHIFT);
+	tmp |= val << ADDA_PR_DATA_IN_SHIFT;
+	writel(tmp, base);
+
+	/* Indicate that the previous value must be written */
+	writel(readl(base) | ADDA_PR_WRITE, base);
+
+	/* Reset the write bit */
+	writel(readl(base) & ~(ADDA_PR_WRITE), base);
+
+	return 0;
+}
+
+struct regmap_config adda_pr_regmap_cfg = {
+	.name		= "adda-pr",
+	.reg_bits	= 5,
+	.reg_stride	= 1,
+	.val_bits	= 8,
+	.reg_read	= adda_reg_read,
+	.reg_write	= adda_reg_write,
+	.fast_io	= true,
+	.max_register	= 24,
+};
+
+static DECLARE_TLV_DB_SCALE(sun8i_codec_headphone_volume_scale, -6300, 100, 1);
+
+static const struct snd_kcontrol_new sun8i_analog_widgets[] = {
+	SOC_SINGLE_TLV("Headphone Volume", SUN8I_ADDA_HP_VOLC,
+		       SUN8I_ADDA_HP_VOLC_HP_VOL, 0x3F, 0,
+		       sun8i_codec_headphone_volume_scale),
+
+	/* Playback Switch */
+	SOC_DOUBLE("DAC Playback Switch", SUN8I_ADDA_DAC_PA_SRC,
+		   SUN8I_ADDA_DAC_PA_SRC_DACALEN, SUN8I_ADDA_DAC_PA_SRC_DACAREN,
+		   1, 0),
+
+	SOC_DOUBLE("Headphone Playback Switch", SUN8I_ADDA_DAC_PA_SRC,
+		   SUN8I_ADDA_DAC_PA_SRC_LHPPAMUTE,
+		   SUN8I_ADDA_DAC_PA_SRC_RHPPAMUTE, 1, 0),
+};
+
+/* headphone controls */
+static const char * const sun8i_codec_hp_src_enum_text[] = {
+	"DAC", "Mixer",
+};
+
+static SOC_ENUM_DOUBLE_DECL(sun8i_codec_hp_src_enum,
+			    SUN8I_ADDA_DAC_PA_SRC,
+			    SUN8I_ADDA_DAC_PA_SRC_LHPIS,
+			    SUN8I_ADDA_DAC_PA_SRC_RHPIS,
+			    sun8i_codec_hp_src_enum_text);
+
+static const struct snd_kcontrol_new sun8i_codec_hp_src[] = {
+	SOC_DAPM_ENUM("Headphone Source Playback Route",
+		      sun8i_codec_hp_src_enum),
+};
+
+static const struct snd_kcontrol_new sun8i_codec_mixer_controls[] = {
+	SOC_DAPM_SINGLE("DAC Left Playback Switch",
+			SUN8I_ADDA_LOMIXSC,
+			SUN8I_ADDA_LOMIXSC_DACL, 1, 0),
+	SOC_DAPM_SINGLE("DAC Right Playback Switch",
+			SUN8I_ADDA_ROMIXSC,
+			SUN8I_ADDA_ROMIXSC_DACR, 1, 0),
+	SOC_DAPM_SINGLE("DAC Reversed Left Playback Switch",
+			SUN8I_ADDA_LOMIXSC,
+			SUN8I_ADDA_LOMIXSC_DACR, 1, 0),
+	SOC_DAPM_SINGLE("DAC Reversed Right Playback Switch",
+			SUN8I_ADDA_ROMIXSC,
+			SUN8I_ADDA_ROMIXSC_DACL, 1, 0),
+};
+
+static const struct snd_soc_dapm_widget sun8i_codec_analog_dapm_widgets[] = {
+	/* Mixers */
+	SOC_MIXER_ARRAY("Left Mixer", SUN8I_ADDA_DAC_PA_SRC,
+			SUN8I_ADDA_DAC_PA_SRC_LMIXEN, 0,
+			sun8i_codec_mixer_controls),
+	SOC_MIXER_ARRAY("Right Mixer", SUN8I_ADDA_DAC_PA_SRC,
+			SUN8I_ADDA_DAC_PA_SRC_RMIXEN, 0,
+			sun8i_codec_mixer_controls),
+
+	/* Headphone output path */
+	SND_SOC_DAPM_MUX("Headphone Source Playback Route",
+			 SND_SOC_NOPM, 0, 0, sun8i_codec_hp_src),
+	SND_SOC_DAPM_OUT_DRV("Headphone Amp", SUN8I_ADDA_PAEN_HP_CTRL,
+			     SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN, 0, NULL, 0),
+
+	/* Headphone outputs */
+	SND_SOC_DAPM_OUTPUT("HP"),
+
+};
+
+static const struct snd_soc_dapm_route sun8i_codec_analog_dapm_routes[] = {
+	/* Left Mixer Routes */
+	{ "Left Mixer", "DAC Playback Switch", "Left DAC" },
+	{ "Left Mixer", "DAC Reversed Left Playback Switch", "Right DAC" },
+
+	/* Right Mixer Routes */
+	{ "Right Mixer", "DAC Playback Switch", "Right DAC" },
+	{ "Right Mixer", "DAC Reversed Right Playback Switch", "Left DAC" },
+
+	/* Headphone Routes */
+	{ "Headphone Source Playback Route", "DAC", "Left DAC" },
+	{ "Headphone Source Playback Route", "DAC", "Right DAC" },
+	{ "Headphone Source Playback Route", "Mixer", "Left Mixer" },
+	{ "Headphone Source Playback Route", "Mixer", "Right Mixer" },
+	{ "Headphone Amp", NULL, "Headphone Source Playback Route" },
+	{ "HP", NULL, "Headphone Amp" },
+};
+
+static const struct snd_soc_component_driver sun8i_codec_analog_cmpnt_drv = {
+	.name			= "sun8i-codec-analog",
+	.controls		= sun8i_analog_widgets,
+	.num_controls		= ARRAY_SIZE(sun8i_analog_widgets),
+	.dapm_widgets		= sun8i_codec_analog_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(sun8i_codec_analog_dapm_widgets),
+	.dapm_routes		= sun8i_codec_analog_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(sun8i_codec_analog_dapm_routes),
+};
+
+static const struct of_device_id sun8i_codec_analog_of_match[] = {
+	{ .compatible = "allwinner,sun8i-codec-analog", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, sun8i_codec_analog_of_match);
+
+static int sun8i_codec_analog_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	struct regmap *regmap;
+	void __iomem *base;
+
+	/* Get PRCM resources and registers */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base)) {
+		dev_err(&pdev->dev, "Failed to map PRCM registers\n");
+		return PTR_ERR(base);
+	}
+
+	regmap = devm_regmap_init(&pdev->dev, NULL, base, &adda_pr_regmap_cfg);
+	if (IS_ERR(regmap)) {
+		dev_err(&pdev->dev, "Regmap initialisation failed\n");
+		return PTR_ERR(regmap);
+	}
+
+	return devm_snd_soc_register_component(&pdev->dev,
+					       &sun8i_codec_analog_cmpnt_drv,
+					       NULL, 0);
+}
+
+static struct platform_driver sun8i_codec_analog_driver = {
+	.driver = {
+		.name = "sun8i-codec-analog",
+		.of_match_table = sun8i_codec_analog_of_match,
+	},
+	.probe = sun8i_codec_analog_probe,
+};
+module_platform_driver(sun8i_codec_analog_driver);
+
+MODULE_DESCRIPTION("Allwinner A31s/A33/A23 codec analog controls driver");
+MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
+MODULE_AUTHOR("Myl?ne Josserand <mylene.josserand@free-electrons.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:sun8i-codec-analog");
-- 
2.9.3

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

* [PATCH 05/14] mfd: sun6i-prcm: Add sun8i analog codec as subnode
  2016-10-04  9:46 ` Mylène Josserand
@ 2016-10-04  9:46     ` Mylène Josserand
  -1 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt
  Cc: linux-kernel, dmaengine, linux-arm-kernel, linux-clk, alsa-devel,
	devicetree, linux-sunxi, thomas.petazzoni, mylene.josserand,
	alexandre.belloni

The sun8i audio codec is using PRCM registers to configure all the
analog part of the audio codec. It is added as a subnode of the PRCM
with his resource (offset of 0x1c0).

Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
---
 drivers/mfd/sun6i-prcm.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/mfd/sun6i-prcm.c b/drivers/mfd/sun6i-prcm.c
index 011fcc5..e0c6bf5 100644
--- a/drivers/mfd/sun6i-prcm.c
+++ b/drivers/mfd/sun6i-prcm.c
@@ -12,6 +12,8 @@
 #include <linux/init.h>
 #include <linux/of.h>
 
+#define SUN6I_AUDIO_CODEC_ANALOG	0x1c0
+
 struct prcm_data {
 	int nsubdevs;
 	const struct mfd_cell *subdevs;
@@ -57,6 +59,14 @@ static const struct resource sun6i_a31_apb0_rstc_res[] = {
 	},
 };
 
+static const struct resource sun8i_adda_res[] = {
+	{
+		.start = SUN6I_AUDIO_CODEC_ANALOG,
+		.end = 0x1c3,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
 static const struct mfd_cell sun6i_a31_prcm_subdevs[] = {
 	{
 		.name = "sun6i-a31-ar100-clk",
@@ -109,6 +119,12 @@ static const struct mfd_cell sun8i_a23_prcm_subdevs[] = {
 		.num_resources = ARRAY_SIZE(sun6i_a31_apb0_rstc_res),
 		.resources = sun6i_a31_apb0_rstc_res,
 	},
+	{
+		.name = "sun8i-codec-analog",
+		.of_compatible = "allwinner,sun8i-codec-analog",
+		.num_resources = ARRAY_SIZE(sun8i_adda_res),
+		.resources = sun8i_adda_res,
+	},
 };
 
 static const struct prcm_data sun6i_a31_prcm_data = {
-- 
2.9.3

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

* [PATCH 05/14] mfd: sun6i-prcm: Add sun8i analog codec as subnode
@ 2016-10-04  9:46     ` Mylène Josserand
  0 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel

The sun8i audio codec is using PRCM registers to configure all the
analog part of the audio codec. It is added as a subnode of the PRCM
with his resource (offset of 0x1c0).

Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
---
 drivers/mfd/sun6i-prcm.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/mfd/sun6i-prcm.c b/drivers/mfd/sun6i-prcm.c
index 011fcc5..e0c6bf5 100644
--- a/drivers/mfd/sun6i-prcm.c
+++ b/drivers/mfd/sun6i-prcm.c
@@ -12,6 +12,8 @@
 #include <linux/init.h>
 #include <linux/of.h>
 
+#define SUN6I_AUDIO_CODEC_ANALOG	0x1c0
+
 struct prcm_data {
 	int nsubdevs;
 	const struct mfd_cell *subdevs;
@@ -57,6 +59,14 @@ static const struct resource sun6i_a31_apb0_rstc_res[] = {
 	},
 };
 
+static const struct resource sun8i_adda_res[] = {
+	{
+		.start = SUN6I_AUDIO_CODEC_ANALOG,
+		.end = 0x1c3,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
 static const struct mfd_cell sun6i_a31_prcm_subdevs[] = {
 	{
 		.name = "sun6i-a31-ar100-clk",
@@ -109,6 +119,12 @@ static const struct mfd_cell sun8i_a23_prcm_subdevs[] = {
 		.num_resources = ARRAY_SIZE(sun6i_a31_apb0_rstc_res),
 		.resources = sun6i_a31_apb0_rstc_res,
 	},
+	{
+		.name = "sun8i-codec-analog",
+		.of_compatible = "allwinner,sun8i-codec-analog",
+		.num_resources = ARRAY_SIZE(sun8i_adda_res),
+		.resources = sun8i_adda_res,
+	},
 };
 
 static const struct prcm_data sun6i_a31_prcm_data = {
-- 
2.9.3

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

* [PATCH 06/14] ASoC: Add sun8i digital audio codec
  2016-10-04  9:46 ` Mylène Josserand
@ 2016-10-04  9:46     ` Mylène Josserand
  -1 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt
  Cc: linux-kernel, dmaengine, linux-arm-kernel, linux-clk, alsa-devel,
	devicetree, linux-sunxi, thomas.petazzoni, mylene.josserand,
	alexandre.belloni

Add the digital sun8i audio codec which handles the base register
(without DAI).
The driver handles only the basic playback of the A33 codec, from
the DAC to the headphones. All other features (microphone, capture,
etc) will be added later.

Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
---
 sound/soc/sunxi/Kconfig       |   9 +
 sound/soc/sunxi/Makefile      |   1 +
 sound/soc/sunxi/sun8i-codec.c | 492 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 502 insertions(+)
 create mode 100644 sound/soc/sunxi/sun8i-codec.c

diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
index 7aee95a..9e287b0 100644
--- a/sound/soc/sunxi/Kconfig
+++ b/sound/soc/sunxi/Kconfig
@@ -27,6 +27,15 @@ config SND_SUN4I_SPDIF
 	  Say Y or M to add support for the S/PDIF audio block in the Allwinner
 	  A10 and affiliated SoCs.
 
+config SND_SUN8I_CODEC
+	tristate "Allwinner SUN8I audio codec"
+	select REGMAP_MMIO
+        help
+	  This option enables the digital part of the internal audio codec for
+	  Allwinner sun8i SoC.
+
+	  Say Y or M if you want to add sun8i digital audio codec support.
+
 config SND_SUN8I_CODEC_ANALOG
 	tristate "Allwinner SUN8I analog codec"
 	select REGMAP_MMIO
diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
index 241c0df..1da63d3 100644
--- a/sound/soc/sunxi/Makefile
+++ b/sound/soc/sunxi/Makefile
@@ -1,4 +1,5 @@
 obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
 obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
 obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
+obj-$(CONFIG_SND_SUN8I_CODEC) += sun8i-codec.o
 obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c
new file mode 100644
index 0000000..e157f89
--- /dev/null
+++ b/sound/soc/sunxi/sun8i-codec.c
@@ -0,0 +1,492 @@
+/*
+ * This driver supports the digital controls for the internal codec
+ * found in Allwinner's A33 and A23 SoCs.
+ *
+ * (C) Copyright 2010-2016
+ * Reuuimlla Technology Co., Ltd. <www.reuuimllatech.com>
+ * huangxin <huangxin@Reuuimllatech.com>
+ * Mylène Josserand <mylene.josserand@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/regmap.h>
+
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+
+/* CODEC_OFFSET represents the offset of the codec registers
+ * and not all the DAI registers
+ */
+#define CODEC_OFFSET				0x200
+#define CODEC_BASSADDRESS			0x01c22c00
+#define SUN8I_SYSCLK_CTL			(0x20c - CODEC_OFFSET)
+#define SUN8I_SYSCLK_CTL_AIF1CLK_ENA		(11)
+#define SUN8I_SYSCLK_CTL_SYSCLK_ENA		(3)
+#define SUN8I_SYSCLK_CTL_SYSCLK_SRC		(0)
+#define SUN8I_MOD_CLK_ENA			(0x210 - CODEC_OFFSET)
+#define SUN8I_MOD_CLK_ENA_AIF1			(15)
+#define SUN8I_MOD_CLK_ENA_DAC			(2)
+#define SUN8I_MOD_RST_CTL			(0x214 - CODEC_OFFSET)
+#define SUN8I_MOD_RST_CTL_AIF1			(15)
+#define SUN8I_MOD_RST_CTL_DAC			(2)
+#define SUN8I_SYS_SR_CTRL			(0x218 - CODEC_OFFSET)
+#define SUN8I_SYS_SR_CTRL_AIF1_FS		(12)
+#define SUN8I_SYS_SR_CTRL_AIF2_FS		(8)
+#define SUN8I_AIF1CLK_CTRL			(0x240 - CODEC_OFFSET)
+#define SUN8I_AIF1CLK_CTRL_AIF1_MSTR_MOD	(15)
+#define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_INV	(14)
+#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV	(13)
+#define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV	(9)
+#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV	(6)
+#define SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ	(4)
+#define SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT	(2)
+#define SUN8I_AIF1_DACDAT_CTRL			(0x248 - CODEC_OFFSET)
+#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA	(15)
+#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA	(14)
+#define SUN8I_DAC_DIG_CTRL			(0x320 - CODEC_OFFSET)
+#define SUN8I_DAC_DIG_CTRL_ENDA		(15)
+#define SUN8I_DAC_MXR_SRC			(0x330 - CODEC_OFFSET)
+#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA0L (15)
+#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA1L (14)
+#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF2DACL (13)
+#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_ADCL	(12)
+#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA0R (11)
+#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA1R (10)
+#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF2DACR (9)
+#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR	(8)
+
+struct sun8i_codec {
+	struct device	*dev;
+	struct regmap	*regmap;
+	struct clk	*clk_module;
+	struct clk	*clk_apb;
+};
+
+static int sun8i_codec_get_hw_rate(struct snd_pcm_hw_params *params)
+{
+	unsigned int rate = params_rate(params);
+
+	switch (rate) {
+	case 8000:
+	case 7350:
+		return 0x0;
+	case 11025:
+		return 0x1;
+	case 12000:
+		return 0x2;
+	case 16000:
+		return 0x3;
+	case 22050:
+		return 0x4;
+	case 24000:
+		return 0x5;
+	case 32000:
+		return 0x6;
+	case 44100:
+		return 0x7;
+	case 48000:
+		return 0x8;
+	case 96000:
+		return 0x9;
+	case 192000:
+		return 0xa;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int sun8i_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+	struct sun8i_codec *scodec = snd_soc_codec_get_drvdata(dai->codec);
+	unsigned long value;
+
+	/* clock masters */
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBS_CFS: /* DAI Slave */
+		value = 0x0; /* Codec Master */
+		break;
+	case SND_SOC_DAIFMT_CBM_CFM: /* DAI Master */
+		value = 0x1; /* Codec Slave */
+		break;
+	default:
+		return -EINVAL;
+	}
+	regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
+			   BIT(SUN8I_AIF1CLK_CTRL_AIF1_MSTR_MOD),
+			   value << SUN8I_AIF1CLK_CTRL_AIF1_MSTR_MOD);
+
+	/* clock inversion */
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_NF: /* Normal */
+		value = 0x0;
+		break;
+	case SND_SOC_DAIFMT_IB_IF: /* Inversion */
+		value = 0x1;
+		break;
+	default:
+		return -EINVAL;
+	}
+	regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
+			   BIT(SUN8I_AIF1CLK_CTRL_AIF1_BCLK_INV),
+			   value << SUN8I_AIF1CLK_CTRL_AIF1_BCLK_INV);
+	regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
+			   BIT(SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV),
+			   value << SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV);
+
+	/* DAI format */
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		value = 0x0;
+		break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		value = 0x1;
+		break;
+	case SND_SOC_DAIFMT_RIGHT_J:
+		value = 0x2;
+		break;
+	case SND_SOC_DAIFMT_DSP_A:
+	case SND_SOC_DAIFMT_DSP_B:
+		value = 0x3;
+		break;
+	default:
+		return -EINVAL;
+	}
+	regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
+			   BIT(SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT),
+			   value << SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT);
+
+	return 0;
+}
+
+static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *params,
+				 struct snd_soc_dai *dai)
+{
+	int rs_value  = 0;
+	u32 bclk_lrck_div = 0, sample_resolution;
+	int sample_rate = 0;
+	struct sun8i_codec *scodec = snd_soc_codec_get_drvdata(dai->codec);
+
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S16_LE:
+		sample_resolution = 16;
+		break;
+	case SNDRV_PCM_FORMAT_S20_3LE:
+	case SNDRV_PCM_FORMAT_S24_LE:
+	case SNDRV_PCM_FORMAT_S32_LE:
+		sample_resolution = 24;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/*calculate word select bit*/
+	switch (sample_resolution) {
+	case 8:
+		rs_value = 0x0;
+		break;
+	case 16:
+		rs_value = 0x1;
+		break;
+	case 20:
+		rs_value = 0x2;
+		break;
+	case 24:
+		rs_value = 0x3;
+		break;
+	default:
+		break;
+	}
+	regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
+			   0x3 << SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ,
+			   rs_value << SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ);
+
+	/* calculate bclk_lrck_div Ratio */
+	bclk_lrck_div = sample_resolution * 2;
+	switch (bclk_lrck_div) {
+	case 16:
+		bclk_lrck_div = 0;
+		break;
+	case 32:
+		bclk_lrck_div = 1;
+		break;
+	case 64:
+		bclk_lrck_div = 2;
+		break;
+	case 128:
+		bclk_lrck_div = 3;
+		break;
+	case 256:
+		bclk_lrck_div = 4;
+		break;
+	default:
+		break;
+	}
+	regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
+			   0x7 << SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV,
+			   bclk_lrck_div << SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV);
+
+	sample_rate = sun8i_codec_get_hw_rate(params);
+	if (sample_rate < 0)
+		return sample_rate;
+
+	regmap_update_bits(scodec->regmap, SUN8I_SYS_SR_CTRL,
+			   0xf << SUN8I_SYS_SR_CTRL_AIF1_FS,
+			   sample_rate << SUN8I_SYS_SR_CTRL_AIF1_FS);
+	regmap_update_bits(scodec->regmap, SUN8I_SYS_SR_CTRL,
+			   0xf << SUN8I_SYS_SR_CTRL_AIF2_FS,
+			   sample_rate << SUN8I_SYS_SR_CTRL_AIF2_FS);
+
+	return 0;
+}
+
+static const struct snd_kcontrol_new sun8i_output_left_mixer_controls[] = {
+	SOC_DAPM_SINGLE("LSlot 0", SUN8I_DAC_MXR_SRC,
+			SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA0L, 1, 0),
+	SOC_DAPM_SINGLE("LSlot 1", SUN8I_DAC_MXR_SRC,
+			SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA1L, 1, 0),
+	SOC_DAPM_SINGLE("DACL", SUN8I_DAC_MXR_SRC,
+			SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF2DACL, 1, 0),
+	SOC_DAPM_SINGLE("ADCL", SUN8I_DAC_MXR_SRC,
+			SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_ADCL, 1, 0),
+};
+
+static const struct snd_kcontrol_new sun8i_output_right_mixer_controls[] = {
+	SOC_DAPM_SINGLE("RSlot 0", SUN8I_DAC_MXR_SRC,
+			SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA0R, 1, 0),
+	SOC_DAPM_SINGLE("RSlot 1", SUN8I_DAC_MXR_SRC,
+			SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA1R, 1, 0),
+	SOC_DAPM_SINGLE("DACR", SUN8I_DAC_MXR_SRC,
+			SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF2DACR, 1, 0),
+	SOC_DAPM_SINGLE("ADCR", SUN8I_DAC_MXR_SRC,
+			SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR, 1, 0),
+};
+
+static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = {
+	/* Digital parts of the DACs */
+	SND_SOC_DAPM_SUPPLY("DAC", SUN8I_DAC_DIG_CTRL, SUN8I_DAC_DIG_CTRL_ENDA,
+			    0, NULL, 0),
+
+	/* Analog DAC */
+	SND_SOC_DAPM_DAC("Left DAC", "Playback", SUN8I_AIF1_DACDAT_CTRL,
+			 SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA, 0),
+	SND_SOC_DAPM_DAC("Right DAC", "Playback", SUN8I_AIF1_DACDAT_CTRL,
+			 SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA, 0),
+
+	/* DAC Mixers */
+	SND_SOC_DAPM_MIXER("Left DAC Mixer", SND_SOC_NOPM, 0, 0,
+			   sun8i_output_left_mixer_controls,
+			   ARRAY_SIZE(sun8i_output_left_mixer_controls)),
+	SND_SOC_DAPM_MIXER("Right DAC Mixer", SND_SOC_NOPM, 0, 0,
+			   sun8i_output_right_mixer_controls,
+			   ARRAY_SIZE(sun8i_output_right_mixer_controls)),
+
+	/* Clocks */
+	SND_SOC_DAPM_SUPPLY("MODCLK AFI1", SUN8I_MOD_CLK_ENA,
+			    SUN8I_MOD_CLK_ENA_AIF1, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("MODCLK DAC", SUN8I_MOD_CLK_ENA,
+			    SUN8I_MOD_CLK_ENA_DAC, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("AIF1", SUN8I_SYSCLK_CTL,
+			    SUN8I_SYSCLK_CTL_AIF1CLK_ENA, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("SYSCLK", SUN8I_SYSCLK_CTL,
+			    SUN8I_SYSCLK_CTL_SYSCLK_ENA, 0, NULL, 0),
+
+	SND_SOC_DAPM_SUPPLY("AIF1 PLL", SUN8I_SYSCLK_CTL, 0x9, 0, NULL, 0),
+	/* Inversion as 0=AIF1, 1=AIF2 */
+	SND_SOC_DAPM_SUPPLY("SYSCLK AIF1", SUN8I_SYSCLK_CTL,
+			    SUN8I_SYSCLK_CTL_SYSCLK_SRC, 1, NULL, 0),
+
+	/* Module reset */
+	SND_SOC_DAPM_SUPPLY("RST AIF1", SUN8I_MOD_RST_CTL,
+			    SUN8I_MOD_RST_CTL_AIF1, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("RST DAC", SUN8I_MOD_RST_CTL,
+			    SUN8I_MOD_RST_CTL_DAC, 0, NULL, 0),
+
+	/* Headphone outputs */
+	SND_SOC_DAPM_OUTPUT("HPOUTL"),
+	SND_SOC_DAPM_OUTPUT("HPOUTR"),
+
+};
+
+static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = {
+	/* Clock Routes */
+	{ "AIF1", NULL, "SYSCLK AIF1" },
+	{ "AIF1 PLL", NULL, "AIF1" },
+	{ "RST AIF1", NULL, "AIF1 PLL" },
+	{ "MODCLK AFI1", NULL, "RST AIF1" },
+	{ "DAC", NULL, "MODCLK AFI1" },
+
+	{ "RST DAC", NULL, "SYSCLK" },
+	{ "MODCLK DAC", NULL, "RST DAC" },
+	{ "DAC", NULL, "MODCLK DAC" },
+
+	/* DAC Routes */
+	{ "Left DAC", NULL, "DAC" },
+	{ "Right DAC", NULL, "DAC" },
+
+	/* DAC Mixer Routes */
+	{ "Left DAC Mixer", "LSlot 0", "Left DAC"},
+	{ "Right DAC Mixer", "RSlot 0", "Right DAC"},
+
+	/* End of route : HP out */
+	{ "HPOUTL", NULL, "Left DAC Mixer" },
+	{ "HPOUTR", NULL, "Right DAC Mixer" },
+};
+
+static struct snd_soc_dai_ops sun8i_codec_dai_ops = {
+	.hw_params = sun8i_codec_hw_params,
+	.set_fmt = sun8i_set_fmt,
+};
+
+static struct snd_soc_dai_driver sun8i_codec_dai = {
+	.name = "sun8i",
+	/* playback capabilities */
+	.playback = {
+		.stream_name = "Playback",
+		.channels_min = 1,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_8000_192000 |
+			SNDRV_PCM_RATE_KNOT,
+		.formats = SNDRV_PCM_FMTBIT_S8 |
+			SNDRV_PCM_FMTBIT_S16_LE |
+			SNDRV_PCM_FMTBIT_S18_3LE |
+			SNDRV_PCM_FMTBIT_S20_3LE |
+			SNDRV_PCM_FMTBIT_S24_LE |
+			SNDRV_PCM_FMTBIT_S32_LE,
+	},
+	/* pcm operations */
+	.ops = &sun8i_codec_dai_ops,
+};
+EXPORT_SYMBOL(sun8i_codec_dai);
+
+static int sun8i_soc_probe(struct snd_soc_codec *codec)
+{
+	return 0;
+}
+
+/* power down chip */
+static int sun8i_soc_remove(struct snd_soc_codec *codec)
+{
+	return 0;
+}
+
+static struct snd_soc_codec_driver sun8i_soc_codec = {
+	.probe			= sun8i_soc_probe,
+	.remove		= sun8i_soc_remove,
+	.component_driver = {
+		.dapm_widgets		= sun8i_codec_dapm_widgets,
+		.num_dapm_widgets	= ARRAY_SIZE(sun8i_codec_dapm_widgets),
+		.dapm_routes		= sun8i_codec_dapm_routes,
+		.num_dapm_routes	= ARRAY_SIZE(sun8i_codec_dapm_routes),
+	},
+};
+
+static const struct regmap_config sun8i_codec_regmap_config = {
+	.reg_bits	= 32,
+	.reg_stride	= 4,
+	.val_bits	= 32,
+	.max_register	= SUN8I_DAC_MXR_SRC,
+};
+
+static int sun8i_codec_probe(struct platform_device *pdev)
+{
+	struct resource *res_base;
+	struct sun8i_codec *scodec;
+	void __iomem *base;
+
+	scodec = devm_kzalloc(&pdev->dev, sizeof(*scodec), GFP_KERNEL);
+	if (!scodec)
+		return -ENOMEM;
+
+	scodec->dev = &pdev->dev;
+
+	/* Get the clocks from the DT */
+	scodec->clk_module = devm_clk_get(&pdev->dev, "codec");
+	if (IS_ERR(scodec->clk_module)) {
+		dev_err(&pdev->dev, "Failed to get the module clock\n");
+		return PTR_ERR(scodec->clk_module);
+	}
+	if (clk_prepare_enable(scodec->clk_module))
+		pr_err("err:open failed;\n");
+
+	scodec->clk_apb = devm_clk_get(&pdev->dev, "apb");
+	if (IS_ERR(scodec->clk_apb)) {
+		dev_err(&pdev->dev, "Failed to get the apb clock\n");
+		return PTR_ERR(scodec->clk_apb);
+	}
+	if (clk_prepare_enable(scodec->clk_apb))
+		pr_err("err:open failed;\n");
+
+	/* Get base resources, registers and regmap */
+	res_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audio");
+	base = devm_ioremap_resource(&pdev->dev, res_base);
+	if (IS_ERR(base)) {
+		dev_err(&pdev->dev, "Failed to map the registers\n");
+		return PTR_ERR(base);
+	}
+
+	scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
+					       &sun8i_codec_regmap_config);
+	if (IS_ERR(scodec->regmap)) {
+		dev_err(&pdev->dev, "Failed to create our regmap\n");
+		return PTR_ERR(scodec->regmap);
+	}
+
+	/* Set the codec data as driver data */
+	dev_set_drvdata(&pdev->dev, scodec);
+
+	snd_soc_register_codec(&pdev->dev, &sun8i_soc_codec, &sun8i_codec_dai,
+			       1);
+
+	return 0;
+}
+
+static int sun8i_codec_remove(struct platform_device *pdev)
+{
+	struct snd_soc_card *card = platform_get_drvdata(pdev);
+	struct sun8i_codec *scodec = snd_soc_card_get_drvdata(card);
+
+	snd_soc_unregister_codec(&pdev->dev);
+	clk_disable_unprepare(scodec->clk_module);
+	clk_disable_unprepare(scodec->clk_apb);
+
+	return 0;
+}
+
+static const struct of_device_id sun8i_codec_of_match[] = {
+	{ .compatible = "allwinner,sun8i-a33-codec" },
+	{ .compatible = "allwinner,sun8i-a23-codec" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, sun8i_codec_of_match);
+
+static struct platform_driver sun8i_codec_driver = {
+	.driver = {
+		.name = "sun8i-codec",
+		.owner = THIS_MODULE,
+		.of_match_table = sun8i_codec_of_match,
+	},
+	.probe = sun8i_codec_probe,
+	.remove = sun8i_codec_remove,
+};
+module_platform_driver(sun8i_codec_driver);
+
+MODULE_DESCRIPTION("Allwinner A33 (sun8i) codec driver");
+MODULE_AUTHOR("huanxin<huanxin@reuuimllatech.com>");
+MODULE_AUTHOR("Mylène Josserand <mylene.josserand@free-electrons.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:sun8i-codec");
-- 
2.9.3

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

* [PATCH 06/14] ASoC: Add sun8i digital audio codec
@ 2016-10-04  9:46     ` Mylène Josserand
  0 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel

Add the digital sun8i audio codec which handles the base register
(without DAI).
The driver handles only the basic playback of the A33 codec, from
the DAC to the headphones. All other features (microphone, capture,
etc) will be added later.

Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
---
 sound/soc/sunxi/Kconfig       |   9 +
 sound/soc/sunxi/Makefile      |   1 +
 sound/soc/sunxi/sun8i-codec.c | 492 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 502 insertions(+)
 create mode 100644 sound/soc/sunxi/sun8i-codec.c

diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
index 7aee95a..9e287b0 100644
--- a/sound/soc/sunxi/Kconfig
+++ b/sound/soc/sunxi/Kconfig
@@ -27,6 +27,15 @@ config SND_SUN4I_SPDIF
 	  Say Y or M to add support for the S/PDIF audio block in the Allwinner
 	  A10 and affiliated SoCs.
 
+config SND_SUN8I_CODEC
+	tristate "Allwinner SUN8I audio codec"
+	select REGMAP_MMIO
+        help
+	  This option enables the digital part of the internal audio codec for
+	  Allwinner sun8i SoC.
+
+	  Say Y or M if you want to add sun8i digital audio codec support.
+
 config SND_SUN8I_CODEC_ANALOG
 	tristate "Allwinner SUN8I analog codec"
 	select REGMAP_MMIO
diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
index 241c0df..1da63d3 100644
--- a/sound/soc/sunxi/Makefile
+++ b/sound/soc/sunxi/Makefile
@@ -1,4 +1,5 @@
 obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
 obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
 obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
+obj-$(CONFIG_SND_SUN8I_CODEC) += sun8i-codec.o
 obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c
new file mode 100644
index 0000000..e157f89
--- /dev/null
+++ b/sound/soc/sunxi/sun8i-codec.c
@@ -0,0 +1,492 @@
+/*
+ * This driver supports the digital controls for the internal codec
+ * found in Allwinner's A33 and A23 SoCs.
+ *
+ * (C) Copyright 2010-2016
+ * Reuuimlla Technology Co., Ltd. <www.reuuimllatech.com>
+ * huangxin <huangxin@Reuuimllatech.com>
+ * Myl?ne Josserand <mylene.josserand@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/regmap.h>
+
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+
+/* CODEC_OFFSET represents the offset of the codec registers
+ * and not all the DAI registers
+ */
+#define CODEC_OFFSET				0x200
+#define CODEC_BASSADDRESS			0x01c22c00
+#define SUN8I_SYSCLK_CTL			(0x20c - CODEC_OFFSET)
+#define SUN8I_SYSCLK_CTL_AIF1CLK_ENA		(11)
+#define SUN8I_SYSCLK_CTL_SYSCLK_ENA		(3)
+#define SUN8I_SYSCLK_CTL_SYSCLK_SRC		(0)
+#define SUN8I_MOD_CLK_ENA			(0x210 - CODEC_OFFSET)
+#define SUN8I_MOD_CLK_ENA_AIF1			(15)
+#define SUN8I_MOD_CLK_ENA_DAC			(2)
+#define SUN8I_MOD_RST_CTL			(0x214 - CODEC_OFFSET)
+#define SUN8I_MOD_RST_CTL_AIF1			(15)
+#define SUN8I_MOD_RST_CTL_DAC			(2)
+#define SUN8I_SYS_SR_CTRL			(0x218 - CODEC_OFFSET)
+#define SUN8I_SYS_SR_CTRL_AIF1_FS		(12)
+#define SUN8I_SYS_SR_CTRL_AIF2_FS		(8)
+#define SUN8I_AIF1CLK_CTRL			(0x240 - CODEC_OFFSET)
+#define SUN8I_AIF1CLK_CTRL_AIF1_MSTR_MOD	(15)
+#define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_INV	(14)
+#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV	(13)
+#define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV	(9)
+#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV	(6)
+#define SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ	(4)
+#define SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT	(2)
+#define SUN8I_AIF1_DACDAT_CTRL			(0x248 - CODEC_OFFSET)
+#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA	(15)
+#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA	(14)
+#define SUN8I_DAC_DIG_CTRL			(0x320 - CODEC_OFFSET)
+#define SUN8I_DAC_DIG_CTRL_ENDA		(15)
+#define SUN8I_DAC_MXR_SRC			(0x330 - CODEC_OFFSET)
+#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA0L (15)
+#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA1L (14)
+#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF2DACL (13)
+#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_ADCL	(12)
+#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA0R (11)
+#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA1R (10)
+#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF2DACR (9)
+#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR	(8)
+
+struct sun8i_codec {
+	struct device	*dev;
+	struct regmap	*regmap;
+	struct clk	*clk_module;
+	struct clk	*clk_apb;
+};
+
+static int sun8i_codec_get_hw_rate(struct snd_pcm_hw_params *params)
+{
+	unsigned int rate = params_rate(params);
+
+	switch (rate) {
+	case 8000:
+	case 7350:
+		return 0x0;
+	case 11025:
+		return 0x1;
+	case 12000:
+		return 0x2;
+	case 16000:
+		return 0x3;
+	case 22050:
+		return 0x4;
+	case 24000:
+		return 0x5;
+	case 32000:
+		return 0x6;
+	case 44100:
+		return 0x7;
+	case 48000:
+		return 0x8;
+	case 96000:
+		return 0x9;
+	case 192000:
+		return 0xa;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int sun8i_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+	struct sun8i_codec *scodec = snd_soc_codec_get_drvdata(dai->codec);
+	unsigned long value;
+
+	/* clock masters */
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBS_CFS: /* DAI Slave */
+		value = 0x0; /* Codec Master */
+		break;
+	case SND_SOC_DAIFMT_CBM_CFM: /* DAI Master */
+		value = 0x1; /* Codec Slave */
+		break;
+	default:
+		return -EINVAL;
+	}
+	regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
+			   BIT(SUN8I_AIF1CLK_CTRL_AIF1_MSTR_MOD),
+			   value << SUN8I_AIF1CLK_CTRL_AIF1_MSTR_MOD);
+
+	/* clock inversion */
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_NF: /* Normal */
+		value = 0x0;
+		break;
+	case SND_SOC_DAIFMT_IB_IF: /* Inversion */
+		value = 0x1;
+		break;
+	default:
+		return -EINVAL;
+	}
+	regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
+			   BIT(SUN8I_AIF1CLK_CTRL_AIF1_BCLK_INV),
+			   value << SUN8I_AIF1CLK_CTRL_AIF1_BCLK_INV);
+	regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
+			   BIT(SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV),
+			   value << SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV);
+
+	/* DAI format */
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		value = 0x0;
+		break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		value = 0x1;
+		break;
+	case SND_SOC_DAIFMT_RIGHT_J:
+		value = 0x2;
+		break;
+	case SND_SOC_DAIFMT_DSP_A:
+	case SND_SOC_DAIFMT_DSP_B:
+		value = 0x3;
+		break;
+	default:
+		return -EINVAL;
+	}
+	regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
+			   BIT(SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT),
+			   value << SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT);
+
+	return 0;
+}
+
+static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *params,
+				 struct snd_soc_dai *dai)
+{
+	int rs_value  = 0;
+	u32 bclk_lrck_div = 0, sample_resolution;
+	int sample_rate = 0;
+	struct sun8i_codec *scodec = snd_soc_codec_get_drvdata(dai->codec);
+
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S16_LE:
+		sample_resolution = 16;
+		break;
+	case SNDRV_PCM_FORMAT_S20_3LE:
+	case SNDRV_PCM_FORMAT_S24_LE:
+	case SNDRV_PCM_FORMAT_S32_LE:
+		sample_resolution = 24;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/*calculate word select bit*/
+	switch (sample_resolution) {
+	case 8:
+		rs_value = 0x0;
+		break;
+	case 16:
+		rs_value = 0x1;
+		break;
+	case 20:
+		rs_value = 0x2;
+		break;
+	case 24:
+		rs_value = 0x3;
+		break;
+	default:
+		break;
+	}
+	regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
+			   0x3 << SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ,
+			   rs_value << SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ);
+
+	/* calculate bclk_lrck_div Ratio */
+	bclk_lrck_div = sample_resolution * 2;
+	switch (bclk_lrck_div) {
+	case 16:
+		bclk_lrck_div = 0;
+		break;
+	case 32:
+		bclk_lrck_div = 1;
+		break;
+	case 64:
+		bclk_lrck_div = 2;
+		break;
+	case 128:
+		bclk_lrck_div = 3;
+		break;
+	case 256:
+		bclk_lrck_div = 4;
+		break;
+	default:
+		break;
+	}
+	regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
+			   0x7 << SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV,
+			   bclk_lrck_div << SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV);
+
+	sample_rate = sun8i_codec_get_hw_rate(params);
+	if (sample_rate < 0)
+		return sample_rate;
+
+	regmap_update_bits(scodec->regmap, SUN8I_SYS_SR_CTRL,
+			   0xf << SUN8I_SYS_SR_CTRL_AIF1_FS,
+			   sample_rate << SUN8I_SYS_SR_CTRL_AIF1_FS);
+	regmap_update_bits(scodec->regmap, SUN8I_SYS_SR_CTRL,
+			   0xf << SUN8I_SYS_SR_CTRL_AIF2_FS,
+			   sample_rate << SUN8I_SYS_SR_CTRL_AIF2_FS);
+
+	return 0;
+}
+
+static const struct snd_kcontrol_new sun8i_output_left_mixer_controls[] = {
+	SOC_DAPM_SINGLE("LSlot 0", SUN8I_DAC_MXR_SRC,
+			SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA0L, 1, 0),
+	SOC_DAPM_SINGLE("LSlot 1", SUN8I_DAC_MXR_SRC,
+			SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA1L, 1, 0),
+	SOC_DAPM_SINGLE("DACL", SUN8I_DAC_MXR_SRC,
+			SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF2DACL, 1, 0),
+	SOC_DAPM_SINGLE("ADCL", SUN8I_DAC_MXR_SRC,
+			SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_ADCL, 1, 0),
+};
+
+static const struct snd_kcontrol_new sun8i_output_right_mixer_controls[] = {
+	SOC_DAPM_SINGLE("RSlot 0", SUN8I_DAC_MXR_SRC,
+			SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA0R, 1, 0),
+	SOC_DAPM_SINGLE("RSlot 1", SUN8I_DAC_MXR_SRC,
+			SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA1R, 1, 0),
+	SOC_DAPM_SINGLE("DACR", SUN8I_DAC_MXR_SRC,
+			SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF2DACR, 1, 0),
+	SOC_DAPM_SINGLE("ADCR", SUN8I_DAC_MXR_SRC,
+			SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR, 1, 0),
+};
+
+static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = {
+	/* Digital parts of the DACs */
+	SND_SOC_DAPM_SUPPLY("DAC", SUN8I_DAC_DIG_CTRL, SUN8I_DAC_DIG_CTRL_ENDA,
+			    0, NULL, 0),
+
+	/* Analog DAC */
+	SND_SOC_DAPM_DAC("Left DAC", "Playback", SUN8I_AIF1_DACDAT_CTRL,
+			 SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA, 0),
+	SND_SOC_DAPM_DAC("Right DAC", "Playback", SUN8I_AIF1_DACDAT_CTRL,
+			 SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA, 0),
+
+	/* DAC Mixers */
+	SND_SOC_DAPM_MIXER("Left DAC Mixer", SND_SOC_NOPM, 0, 0,
+			   sun8i_output_left_mixer_controls,
+			   ARRAY_SIZE(sun8i_output_left_mixer_controls)),
+	SND_SOC_DAPM_MIXER("Right DAC Mixer", SND_SOC_NOPM, 0, 0,
+			   sun8i_output_right_mixer_controls,
+			   ARRAY_SIZE(sun8i_output_right_mixer_controls)),
+
+	/* Clocks */
+	SND_SOC_DAPM_SUPPLY("MODCLK AFI1", SUN8I_MOD_CLK_ENA,
+			    SUN8I_MOD_CLK_ENA_AIF1, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("MODCLK DAC", SUN8I_MOD_CLK_ENA,
+			    SUN8I_MOD_CLK_ENA_DAC, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("AIF1", SUN8I_SYSCLK_CTL,
+			    SUN8I_SYSCLK_CTL_AIF1CLK_ENA, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("SYSCLK", SUN8I_SYSCLK_CTL,
+			    SUN8I_SYSCLK_CTL_SYSCLK_ENA, 0, NULL, 0),
+
+	SND_SOC_DAPM_SUPPLY("AIF1 PLL", SUN8I_SYSCLK_CTL, 0x9, 0, NULL, 0),
+	/* Inversion as 0=AIF1, 1=AIF2 */
+	SND_SOC_DAPM_SUPPLY("SYSCLK AIF1", SUN8I_SYSCLK_CTL,
+			    SUN8I_SYSCLK_CTL_SYSCLK_SRC, 1, NULL, 0),
+
+	/* Module reset */
+	SND_SOC_DAPM_SUPPLY("RST AIF1", SUN8I_MOD_RST_CTL,
+			    SUN8I_MOD_RST_CTL_AIF1, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("RST DAC", SUN8I_MOD_RST_CTL,
+			    SUN8I_MOD_RST_CTL_DAC, 0, NULL, 0),
+
+	/* Headphone outputs */
+	SND_SOC_DAPM_OUTPUT("HPOUTL"),
+	SND_SOC_DAPM_OUTPUT("HPOUTR"),
+
+};
+
+static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = {
+	/* Clock Routes */
+	{ "AIF1", NULL, "SYSCLK AIF1" },
+	{ "AIF1 PLL", NULL, "AIF1" },
+	{ "RST AIF1", NULL, "AIF1 PLL" },
+	{ "MODCLK AFI1", NULL, "RST AIF1" },
+	{ "DAC", NULL, "MODCLK AFI1" },
+
+	{ "RST DAC", NULL, "SYSCLK" },
+	{ "MODCLK DAC", NULL, "RST DAC" },
+	{ "DAC", NULL, "MODCLK DAC" },
+
+	/* DAC Routes */
+	{ "Left DAC", NULL, "DAC" },
+	{ "Right DAC", NULL, "DAC" },
+
+	/* DAC Mixer Routes */
+	{ "Left DAC Mixer", "LSlot 0", "Left DAC"},
+	{ "Right DAC Mixer", "RSlot 0", "Right DAC"},
+
+	/* End of route : HP out */
+	{ "HPOUTL", NULL, "Left DAC Mixer" },
+	{ "HPOUTR", NULL, "Right DAC Mixer" },
+};
+
+static struct snd_soc_dai_ops sun8i_codec_dai_ops = {
+	.hw_params = sun8i_codec_hw_params,
+	.set_fmt = sun8i_set_fmt,
+};
+
+static struct snd_soc_dai_driver sun8i_codec_dai = {
+	.name = "sun8i",
+	/* playback capabilities */
+	.playback = {
+		.stream_name = "Playback",
+		.channels_min = 1,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_8000_192000 |
+			SNDRV_PCM_RATE_KNOT,
+		.formats = SNDRV_PCM_FMTBIT_S8 |
+			SNDRV_PCM_FMTBIT_S16_LE |
+			SNDRV_PCM_FMTBIT_S18_3LE |
+			SNDRV_PCM_FMTBIT_S20_3LE |
+			SNDRV_PCM_FMTBIT_S24_LE |
+			SNDRV_PCM_FMTBIT_S32_LE,
+	},
+	/* pcm operations */
+	.ops = &sun8i_codec_dai_ops,
+};
+EXPORT_SYMBOL(sun8i_codec_dai);
+
+static int sun8i_soc_probe(struct snd_soc_codec *codec)
+{
+	return 0;
+}
+
+/* power down chip */
+static int sun8i_soc_remove(struct snd_soc_codec *codec)
+{
+	return 0;
+}
+
+static struct snd_soc_codec_driver sun8i_soc_codec = {
+	.probe			= sun8i_soc_probe,
+	.remove		= sun8i_soc_remove,
+	.component_driver = {
+		.dapm_widgets		= sun8i_codec_dapm_widgets,
+		.num_dapm_widgets	= ARRAY_SIZE(sun8i_codec_dapm_widgets),
+		.dapm_routes		= sun8i_codec_dapm_routes,
+		.num_dapm_routes	= ARRAY_SIZE(sun8i_codec_dapm_routes),
+	},
+};
+
+static const struct regmap_config sun8i_codec_regmap_config = {
+	.reg_bits	= 32,
+	.reg_stride	= 4,
+	.val_bits	= 32,
+	.max_register	= SUN8I_DAC_MXR_SRC,
+};
+
+static int sun8i_codec_probe(struct platform_device *pdev)
+{
+	struct resource *res_base;
+	struct sun8i_codec *scodec;
+	void __iomem *base;
+
+	scodec = devm_kzalloc(&pdev->dev, sizeof(*scodec), GFP_KERNEL);
+	if (!scodec)
+		return -ENOMEM;
+
+	scodec->dev = &pdev->dev;
+
+	/* Get the clocks from the DT */
+	scodec->clk_module = devm_clk_get(&pdev->dev, "codec");
+	if (IS_ERR(scodec->clk_module)) {
+		dev_err(&pdev->dev, "Failed to get the module clock\n");
+		return PTR_ERR(scodec->clk_module);
+	}
+	if (clk_prepare_enable(scodec->clk_module))
+		pr_err("err:open failed;\n");
+
+	scodec->clk_apb = devm_clk_get(&pdev->dev, "apb");
+	if (IS_ERR(scodec->clk_apb)) {
+		dev_err(&pdev->dev, "Failed to get the apb clock\n");
+		return PTR_ERR(scodec->clk_apb);
+	}
+	if (clk_prepare_enable(scodec->clk_apb))
+		pr_err("err:open failed;\n");
+
+	/* Get base resources, registers and regmap */
+	res_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audio");
+	base = devm_ioremap_resource(&pdev->dev, res_base);
+	if (IS_ERR(base)) {
+		dev_err(&pdev->dev, "Failed to map the registers\n");
+		return PTR_ERR(base);
+	}
+
+	scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
+					       &sun8i_codec_regmap_config);
+	if (IS_ERR(scodec->regmap)) {
+		dev_err(&pdev->dev, "Failed to create our regmap\n");
+		return PTR_ERR(scodec->regmap);
+	}
+
+	/* Set the codec data as driver data */
+	dev_set_drvdata(&pdev->dev, scodec);
+
+	snd_soc_register_codec(&pdev->dev, &sun8i_soc_codec, &sun8i_codec_dai,
+			       1);
+
+	return 0;
+}
+
+static int sun8i_codec_remove(struct platform_device *pdev)
+{
+	struct snd_soc_card *card = platform_get_drvdata(pdev);
+	struct sun8i_codec *scodec = snd_soc_card_get_drvdata(card);
+
+	snd_soc_unregister_codec(&pdev->dev);
+	clk_disable_unprepare(scodec->clk_module);
+	clk_disable_unprepare(scodec->clk_apb);
+
+	return 0;
+}
+
+static const struct of_device_id sun8i_codec_of_match[] = {
+	{ .compatible = "allwinner,sun8i-a33-codec" },
+	{ .compatible = "allwinner,sun8i-a23-codec" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, sun8i_codec_of_match);
+
+static struct platform_driver sun8i_codec_driver = {
+	.driver = {
+		.name = "sun8i-codec",
+		.owner = THIS_MODULE,
+		.of_match_table = sun8i_codec_of_match,
+	},
+	.probe = sun8i_codec_probe,
+	.remove = sun8i_codec_remove,
+};
+module_platform_driver(sun8i_codec_driver);
+
+MODULE_DESCRIPTION("Allwinner A33 (sun8i) codec driver");
+MODULE_AUTHOR("huanxin<huanxin@reuuimllatech.com>");
+MODULE_AUTHOR("Myl?ne Josserand <mylene.josserand@free-electrons.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:sun8i-codec");
-- 
2.9.3

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

* [PATCH 07/14] ASoC: Add sun8i audio card
  2016-10-04  9:46 ` Mylène Josserand
@ 2016-10-04  9:46     ` Mylène Josserand
  -1 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt
  Cc: linux-kernel, dmaengine, linux-arm-kernel, linux-clk, alsa-devel,
	devicetree, linux-sunxi, thomas.petazzoni, mylene.josserand,
	alexandre.belloni

Add the audio card for sun8i SoC. This card links the codec driver
(digital part) with the DAI driver. The analog codec driver is
added as an aux_device.

Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
---
 sound/soc/sunxi/Kconfig  |  14 +++++++
 sound/soc/sunxi/Makefile |   1 +
 sound/soc/sunxi/sun8i.c  | 101 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 116 insertions(+)
 create mode 100644 sound/soc/sunxi/sun8i.c

diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
index 9e287b0..7b97395 100644
--- a/sound/soc/sunxi/Kconfig
+++ b/sound/soc/sunxi/Kconfig
@@ -27,6 +27,20 @@ config SND_SUN4I_SPDIF
 	  Say Y or M to add support for the S/PDIF audio block in the Allwinner
 	  A10 and affiliated SoCs.
 
+config SND_SUN8I
+	tristate "Allwinner SUN6I/SUN8I audio card support"
+	select SND_SUN8I_CODEC
+	select SND_SUN4I_I2S
+	select SND_SUN8I_CODEC_ANALOG
+	select REGMAP_MMIO
+	help
+	  This option enables the audio card for Allwinner A33 (sun8i) SoC.
+	  It enables the DAI driver (SND_SUN4I_I2S), the digital audio
+	  codec driver (SND_SUN8I_CODEC) and the analog codec driver
+	  (SND_SUN8I_CODEC_ANALOG).
+
+	  Say Y or M if you want to add sun8i/6i card support
+
 config SND_SUN8I_CODEC
 	tristate "Allwinner SUN8I audio codec"
 	select REGMAP_MMIO
diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
index 1da63d3..7f1bab9 100644
--- a/sound/soc/sunxi/Makefile
+++ b/sound/soc/sunxi/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
 obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
 obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
+obj-$(CONFIG_SND_SUN8I) += sun8i.o
 obj-$(CONFIG_SND_SUN8I_CODEC) += sun8i-codec.o
 obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
diff --git a/sound/soc/sunxi/sun8i.c b/sound/soc/sunxi/sun8i.c
new file mode 100644
index 0000000..565cd88
--- /dev/null
+++ b/sound/soc/sunxi/sun8i.c
@@ -0,0 +1,101 @@
+/*
+ * ALSA SoC driver for Allwinner sun8i SoC
+ *
+ * Copyright (C) 2016 Mylène Josserand <mylene.josserand@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/firmware.h>
+#include <linux/module.h>
+
+#include <sound/soc.h>
+
+static struct snd_soc_aux_dev sun8i_audio_prcm_aux_devs[] = {
+	{
+		.name = "sun8i-codec-analog",
+		.codec_name = "sun8i-codec-analog.0",
+	},
+};
+
+static struct snd_soc_dai_link sun8i_dai_link = {
+	.name           = "sun4i-i2s",
+	.stream_name    = "Playback",
+	.codec_dai_name = "sun8i",
+	.dai_fmt        = SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S |
+			SND_SOC_DAIFMT_CBM_CFM,
+};
+
+static struct snd_soc_card sun8i_card = {
+	.name           = "sun8i-card",
+	.owner          = THIS_MODULE,
+	.dai_link       = &sun8i_dai_link,
+	.num_links      = 1,
+	.aux_dev	= sun8i_audio_prcm_aux_devs,
+	.num_aux_devs	= ARRAY_SIZE(sun8i_audio_prcm_aux_devs),
+};
+
+static int sun8i_probe(struct platform_device *pdev)
+{
+	struct snd_soc_dai_link *link = &sun8i_dai_link;
+	struct device_node *np = pdev->dev.of_node;
+	int ret;
+
+	/* register the soc card */
+	sun8i_card.dev = &pdev->dev;
+
+	/* Retrieve the audio-codec from DT */
+	link->codec_of_node = of_parse_phandle(np, "allwinner,audio-codec", 0);
+	if (!link->codec_of_node) {
+		dev_err(&pdev->dev, "Missing audio codec\n");
+		return -EINVAL;
+	}
+
+	/* Retrieve DAI from DT */
+	link->cpu_of_node = of_parse_phandle(np, "allwinner,i2s-controller", 0);
+	if (!link->cpu_of_node) {
+		dev_err(&pdev->dev, "Missing I2S controller\n");
+		return -EINVAL;
+	}
+
+	link->platform_of_node = link->cpu_of_node;
+
+	/* Register the sound card */
+	ret = devm_snd_soc_register_card(&pdev->dev, &sun8i_card);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"Soc register card failed %d\n", ret);
+		return ret;
+	}
+
+	return ret;
+}
+
+static const struct of_device_id sun8i_of_match[] = {
+	{ .compatible = "allwinner,sun8i-audio", },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, sun8i_of_match);
+
+static struct platform_driver sun8i_card_driver = {
+	.probe = sun8i_probe,
+	.driver = {
+		.name   = "sun8i-audio",
+		.of_match_table = sun8i_of_match,
+	},
+};
+
+module_platform_driver(sun8i_card_driver);
+
+MODULE_AUTHOR("Mylène Josserand <mylene.josserand@free-electrons.com>");
+MODULE_DESCRIPTION("Allwinner sun8i machine ASoC driver");
+MODULE_LICENSE("GPL v2");
-- 
2.9.3

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

* [PATCH 07/14] ASoC: Add sun8i audio card
@ 2016-10-04  9:46     ` Mylène Josserand
  0 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel

Add the audio card for sun8i SoC. This card links the codec driver
(digital part) with the DAI driver. The analog codec driver is
added as an aux_device.

Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
---
 sound/soc/sunxi/Kconfig  |  14 +++++++
 sound/soc/sunxi/Makefile |   1 +
 sound/soc/sunxi/sun8i.c  | 101 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 116 insertions(+)
 create mode 100644 sound/soc/sunxi/sun8i.c

diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
index 9e287b0..7b97395 100644
--- a/sound/soc/sunxi/Kconfig
+++ b/sound/soc/sunxi/Kconfig
@@ -27,6 +27,20 @@ config SND_SUN4I_SPDIF
 	  Say Y or M to add support for the S/PDIF audio block in the Allwinner
 	  A10 and affiliated SoCs.
 
+config SND_SUN8I
+	tristate "Allwinner SUN6I/SUN8I audio card support"
+	select SND_SUN8I_CODEC
+	select SND_SUN4I_I2S
+	select SND_SUN8I_CODEC_ANALOG
+	select REGMAP_MMIO
+	help
+	  This option enables the audio card for Allwinner A33 (sun8i) SoC.
+	  It enables the DAI driver (SND_SUN4I_I2S), the digital audio
+	  codec driver (SND_SUN8I_CODEC) and the analog codec driver
+	  (SND_SUN8I_CODEC_ANALOG).
+
+	  Say Y or M if you want to add sun8i/6i card support
+
 config SND_SUN8I_CODEC
 	tristate "Allwinner SUN8I audio codec"
 	select REGMAP_MMIO
diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
index 1da63d3..7f1bab9 100644
--- a/sound/soc/sunxi/Makefile
+++ b/sound/soc/sunxi/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
 obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
 obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
+obj-$(CONFIG_SND_SUN8I) += sun8i.o
 obj-$(CONFIG_SND_SUN8I_CODEC) += sun8i-codec.o
 obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
diff --git a/sound/soc/sunxi/sun8i.c b/sound/soc/sunxi/sun8i.c
new file mode 100644
index 0000000..565cd88
--- /dev/null
+++ b/sound/soc/sunxi/sun8i.c
@@ -0,0 +1,101 @@
+/*
+ * ALSA SoC driver for Allwinner sun8i SoC
+ *
+ * Copyright (C) 2016 Myl?ne Josserand <mylene.josserand@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/firmware.h>
+#include <linux/module.h>
+
+#include <sound/soc.h>
+
+static struct snd_soc_aux_dev sun8i_audio_prcm_aux_devs[] = {
+	{
+		.name = "sun8i-codec-analog",
+		.codec_name = "sun8i-codec-analog.0",
+	},
+};
+
+static struct snd_soc_dai_link sun8i_dai_link = {
+	.name           = "sun4i-i2s",
+	.stream_name    = "Playback",
+	.codec_dai_name = "sun8i",
+	.dai_fmt        = SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S |
+			SND_SOC_DAIFMT_CBM_CFM,
+};
+
+static struct snd_soc_card sun8i_card = {
+	.name           = "sun8i-card",
+	.owner          = THIS_MODULE,
+	.dai_link       = &sun8i_dai_link,
+	.num_links      = 1,
+	.aux_dev	= sun8i_audio_prcm_aux_devs,
+	.num_aux_devs	= ARRAY_SIZE(sun8i_audio_prcm_aux_devs),
+};
+
+static int sun8i_probe(struct platform_device *pdev)
+{
+	struct snd_soc_dai_link *link = &sun8i_dai_link;
+	struct device_node *np = pdev->dev.of_node;
+	int ret;
+
+	/* register the soc card */
+	sun8i_card.dev = &pdev->dev;
+
+	/* Retrieve the audio-codec from DT */
+	link->codec_of_node = of_parse_phandle(np, "allwinner,audio-codec", 0);
+	if (!link->codec_of_node) {
+		dev_err(&pdev->dev, "Missing audio codec\n");
+		return -EINVAL;
+	}
+
+	/* Retrieve DAI from DT */
+	link->cpu_of_node = of_parse_phandle(np, "allwinner,i2s-controller", 0);
+	if (!link->cpu_of_node) {
+		dev_err(&pdev->dev, "Missing I2S controller\n");
+		return -EINVAL;
+	}
+
+	link->platform_of_node = link->cpu_of_node;
+
+	/* Register the sound card */
+	ret = devm_snd_soc_register_card(&pdev->dev, &sun8i_card);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"Soc register card failed %d\n", ret);
+		return ret;
+	}
+
+	return ret;
+}
+
+static const struct of_device_id sun8i_of_match[] = {
+	{ .compatible = "allwinner,sun8i-audio", },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, sun8i_of_match);
+
+static struct platform_driver sun8i_card_driver = {
+	.probe = sun8i_probe,
+	.driver = {
+		.name   = "sun8i-audio",
+		.of_match_table = sun8i_of_match,
+	},
+};
+
+module_platform_driver(sun8i_card_driver);
+
+MODULE_AUTHOR("Myl?ne Josserand <mylene.josserand@free-electrons.com>");
+MODULE_DESCRIPTION("Allwinner sun8i machine ASoC driver");
+MODULE_LICENSE("GPL v2");
-- 
2.9.3

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

* [PATCH 08/14] dt-bindings: sound: Add sun8i analog codec documentation
  2016-10-04  9:46 ` Mylène Josserand
@ 2016-10-04  9:46     ` Mylène Josserand
  -1 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt
  Cc: linux-kernel, dmaengine, linux-arm-kernel, linux-clk, alsa-devel,
	devicetree, linux-sunxi, thomas.petazzoni, mylene.josserand,
	alexandre.belloni

Add the documentation for dt-binding of the analog audiocodec
driver for SUN8I SoC.

Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
---
 .../devicetree/bindings/sound/sun8i-codec-analog.txt | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt

diff --git a/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
new file mode 100644
index 0000000..a03ec20
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
@@ -0,0 +1,20 @@
+* Allwinner A23/A33 Analog Codec
+
+This codec must be handled as a PRCM subnode.
+
+Required properties:
+- compatible: must be either "allwinner,sun8i-codec-analog"
+- interrupts: must contain the codec interrupt
+- clocks: a list of phandle + clock-specifer pairs, one for each entry
+  in clock-names.
+- clock-names: should contain followings:
+   - "apb": the parent APB clock for this controller
+   - "codec": the parent module clock
+
+Example, in your prcm subnode:
+codec_analog: codec_analog {
+	compatible = "allwinner,sun8i-codec-analog";
+	interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+	clocks = <&ccu CLK_BUS_CODEC>, <&ccu CLK_AC_DIG>;
+	clock-names = "apb", "codec";
+};
-- 
2.9.3

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

* [PATCH 08/14] dt-bindings: sound: Add sun8i analog codec documentation
@ 2016-10-04  9:46     ` Mylène Josserand
  0 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel

Add the documentation for dt-binding of the analog audiocodec
driver for SUN8I SoC.

Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
---
 .../devicetree/bindings/sound/sun8i-codec-analog.txt | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt

diff --git a/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
new file mode 100644
index 0000000..a03ec20
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
@@ -0,0 +1,20 @@
+* Allwinner A23/A33 Analog Codec
+
+This codec must be handled as a PRCM subnode.
+
+Required properties:
+- compatible: must be either "allwinner,sun8i-codec-analog"
+- interrupts: must contain the codec interrupt
+- clocks: a list of phandle + clock-specifer pairs, one for each entry
+  in clock-names.
+- clock-names: should contain followings:
+   - "apb": the parent APB clock for this controller
+   - "codec": the parent module clock
+
+Example, in your prcm subnode:
+codec_analog: codec_analog {
+	compatible = "allwinner,sun8i-codec-analog";
+	interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+	clocks = <&ccu CLK_BUS_CODEC>, <&ccu CLK_AC_DIG>;
+	clock-names = "apb", "codec";
+};
-- 
2.9.3

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

* [PATCH 09/14] dt-bindings: sound: Add sun8i codec documentation
       [not found] ` <cover.1475569400.git.mylene.josserand-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
  2016-10-07  8:35     ` Icenowy Zheng
@ 2016-10-04  9:46     ` Mylène Josserand
  0 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt
  Cc: linux-kernel, dmaengine, linux-arm-kernel, linux-clk, alsa-devel,
	devicetree, linux-sunxi, thomas.petazzoni, mylene.josserand,
	alexandre.belloni

Add the documentation for dt-binding of the digital audio codec driver
for sun8i SoC.

Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
---
 .../devicetree/bindings/sound/sun8i-codec.txt      | 24 ++++++++++++++++++++++
 1 file changed, 24 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/sun8i-codec.txt

diff --git a/Documentation/devicetree/bindings/sound/sun8i-codec.txt b/Documentation/devicetree/bindings/sound/sun8i-codec.txt
new file mode 100644
index 0000000..1808869
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/sun8i-codec.txt
@@ -0,0 +1,24 @@
+* Allwinner A23/A33 Codec
+
+Required properties:
+- compatible: must be either "allwinner,sun4i-a23-codec" or
+  "allwinner,sun7i-a33-codec"
+- reg: must contain the registers location and length
+- interrupts: must contain the codec interrupt
+- clocks: a list of phandle + clock-specifer pairs, one for each entry
+  in clock-names.
+- clock-names: should contain followings:
+   - "apb": the parent APB clock for this controller
+   - "codec": the parent module clock
+
+Example:
+codec: codec@01c22e00 {
+	#sound-dai-cells = <0>;
+	compatible = "allwinner,sun8i-a33-codec";
+	reg = <0x01c22e00 0x400>; /* SUNXI_AUDIO_PBASE + 0x200 */
+	reg-names = "audio";
+	interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+	clocks = <&ccu CLK_BUS_CODEC>, <&ccu CLK_AC_DIG>;
+	clock-names = "apb", "codec";
+	status = "disabled";
+};
-- 
2.9.3

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

* [PATCH 09/14] dt-bindings: sound: Add sun8i codec documentation
@ 2016-10-04  9:46     ` Mylène Josserand
  0 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8, wens-jdAy2FN1RRM,
	mturquette-rdvid1DuHRBWk0Htik3J/w, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A,
	perex-/Fr2/VpizcU, tiwai-IBi9RG/b67k,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	mylene.josserand-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8

Add the documentation for dt-binding of the digital audio codec driver
for sun8i SoC.

Signed-off-by: Mylène Josserand <mylene.josserand-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
 .../devicetree/bindings/sound/sun8i-codec.txt      | 24 ++++++++++++++++++++++
 1 file changed, 24 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/sun8i-codec.txt

diff --git a/Documentation/devicetree/bindings/sound/sun8i-codec.txt b/Documentation/devicetree/bindings/sound/sun8i-codec.txt
new file mode 100644
index 0000000..1808869
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/sun8i-codec.txt
@@ -0,0 +1,24 @@
+* Allwinner A23/A33 Codec
+
+Required properties:
+- compatible: must be either "allwinner,sun4i-a23-codec" or
+  "allwinner,sun7i-a33-codec"
+- reg: must contain the registers location and length
+- interrupts: must contain the codec interrupt
+- clocks: a list of phandle + clock-specifer pairs, one for each entry
+  in clock-names.
+- clock-names: should contain followings:
+   - "apb": the parent APB clock for this controller
+   - "codec": the parent module clock
+
+Example:
+codec: codec@01c22e00 {
+	#sound-dai-cells = <0>;
+	compatible = "allwinner,sun8i-a33-codec";
+	reg = <0x01c22e00 0x400>; /* SUNXI_AUDIO_PBASE + 0x200 */
+	reg-names = "audio";
+	interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+	clocks = <&ccu CLK_BUS_CODEC>, <&ccu CLK_AC_DIG>;
+	clock-names = "apb", "codec";
+	status = "disabled";
+};
-- 
2.9.3

--
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] 170+ messages in thread

* [PATCH 09/14] dt-bindings: sound: Add sun8i codec documentation
@ 2016-10-04  9:46     ` Mylène Josserand
  0 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel

Add the documentation for dt-binding of the digital audio codec driver
for sun8i SoC.

Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
---
 .../devicetree/bindings/sound/sun8i-codec.txt      | 24 ++++++++++++++++++++++
 1 file changed, 24 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/sun8i-codec.txt

diff --git a/Documentation/devicetree/bindings/sound/sun8i-codec.txt b/Documentation/devicetree/bindings/sound/sun8i-codec.txt
new file mode 100644
index 0000000..1808869
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/sun8i-codec.txt
@@ -0,0 +1,24 @@
+* Allwinner A23/A33 Codec
+
+Required properties:
+- compatible: must be either "allwinner,sun4i-a23-codec" or
+  "allwinner,sun7i-a33-codec"
+- reg: must contain the registers location and length
+- interrupts: must contain the codec interrupt
+- clocks: a list of phandle + clock-specifer pairs, one for each entry
+  in clock-names.
+- clock-names: should contain followings:
+   - "apb": the parent APB clock for this controller
+   - "codec": the parent module clock
+
+Example:
+codec: codec at 01c22e00 {
+	#sound-dai-cells = <0>;
+	compatible = "allwinner,sun8i-a33-codec";
+	reg = <0x01c22e00 0x400>; /* SUNXI_AUDIO_PBASE + 0x200 */
+	reg-names = "audio";
+	interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+	clocks = <&ccu CLK_BUS_CODEC>, <&ccu CLK_AC_DIG>;
+	clock-names = "apb", "codec";
+	status = "disabled";
+};
-- 
2.9.3

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

* [PATCH 10/14] dt-bindings: sound: Add sun8i audio card documentation
       [not found] ` <cover.1475569400.git.mylene.josserand-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
  2016-10-07  8:35     ` Icenowy Zheng
@ 2016-10-04  9:46     ` Mylène Josserand
  0 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt
  Cc: linux-kernel, dmaengine, linux-arm-kernel, linux-clk, alsa-devel,
	devicetree, linux-sunxi, thomas.petazzoni, mylene.josserand,
	alexandre.belloni

Add the documentation for dt-binding of the audio card driver
for sun8i SoC.

Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
---
 Documentation/devicetree/bindings/sound/sun8i-audio.txt | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/sun8i-audio.txt

diff --git a/Documentation/devicetree/bindings/sound/sun8i-audio.txt b/Documentation/devicetree/bindings/sound/sun8i-audio.txt
new file mode 100644
index 0000000..2403983
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/sun8i-audio.txt
@@ -0,0 +1,17 @@
+* Allwinner A23/A33 audio card
+
+This binding implements the A33 audio card.
+
+Required properties:
+- compatible: must be "allwinner,sun8i-audio"
+- allwinner,audio-codec: must have the phandle of the audio codec
+  ("sun8i-a33-codec", for example).
+- allwinner,i2s-controller: must have the phandle of the DAI
+  ("allwinner,sun4i-a10-i2s", for example)
+
+Example:
+sound {
+	compatible = "allwinner,sun8i-audio";
+	allwinner,audio-codec = <&codec>;
+	allwinner,i2s-controller = <&dai>;
+};
-- 
2.9.3

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

* [PATCH 10/14] dt-bindings: sound: Add sun8i audio card documentation
@ 2016-10-04  9:46     ` Mylène Josserand
  0 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8, wens-jdAy2FN1RRM,
	mturquette-rdvid1DuHRBWk0Htik3J/w, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A,
	perex-/Fr2/VpizcU, tiwai-IBi9RG/b67k,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	mylene.josserand-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8

Add the documentation for dt-binding of the audio card driver
for sun8i SoC.

Signed-off-by: Mylène Josserand <mylene.josserand-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
---
 Documentation/devicetree/bindings/sound/sun8i-audio.txt | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/sun8i-audio.txt

diff --git a/Documentation/devicetree/bindings/sound/sun8i-audio.txt b/Documentation/devicetree/bindings/sound/sun8i-audio.txt
new file mode 100644
index 0000000..2403983
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/sun8i-audio.txt
@@ -0,0 +1,17 @@
+* Allwinner A23/A33 audio card
+
+This binding implements the A33 audio card.
+
+Required properties:
+- compatible: must be "allwinner,sun8i-audio"
+- allwinner,audio-codec: must have the phandle of the audio codec
+  ("sun8i-a33-codec", for example).
+- allwinner,i2s-controller: must have the phandle of the DAI
+  ("allwinner,sun4i-a10-i2s", for example)
+
+Example:
+sound {
+	compatible = "allwinner,sun8i-audio";
+	allwinner,audio-codec = <&codec>;
+	allwinner,i2s-controller = <&dai>;
+};
-- 
2.9.3

--
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] 170+ messages in thread

* [PATCH 10/14] dt-bindings: sound: Add sun8i audio card documentation
@ 2016-10-04  9:46     ` Mylène Josserand
  0 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel

Add the documentation for dt-binding of the audio card driver
for sun8i SoC.

Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
---
 Documentation/devicetree/bindings/sound/sun8i-audio.txt | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/sun8i-audio.txt

diff --git a/Documentation/devicetree/bindings/sound/sun8i-audio.txt b/Documentation/devicetree/bindings/sound/sun8i-audio.txt
new file mode 100644
index 0000000..2403983
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/sun8i-audio.txt
@@ -0,0 +1,17 @@
+* Allwinner A23/A33 audio card
+
+This binding implements the A33 audio card.
+
+Required properties:
+- compatible: must be "allwinner,sun8i-audio"
+- allwinner,audio-codec: must have the phandle of the audio codec
+  ("sun8i-a33-codec", for example).
+- allwinner,i2s-controller: must have the phandle of the DAI
+  ("allwinner,sun4i-a10-i2s", for example)
+
+Example:
+sound {
+	compatible = "allwinner,sun8i-audio";
+	allwinner,audio-codec = <&codec>;
+	allwinner,i2s-controller = <&dai>;
+};
-- 
2.9.3

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

* [PATCH 11/14] ARM: dts: sun8i: Add analog codec on prcm node
  2016-10-04  9:46 ` Mylène Josserand
@ 2016-10-04  9:46     ` Mylène Josserand
  -1 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt
  Cc: linux-kernel, dmaengine, linux-arm-kernel, linux-clk, alsa-devel,
	devicetree, linux-sunxi, thomas.petazzoni, mylene.josserand,
	alexandre.belloni

The analog codec for sun8i used PRCM registers so it should be added
in the device tree as a subnode of the prcm entry.

Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
---
 arch/arm/boot/dts/sun8i-a23-a33.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-a23-a33.dtsi b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
index 48fc24f..5197812 100644
--- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi
+++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
@@ -549,6 +549,13 @@
 				compatible = "allwinner,sun6i-a31-clock-reset";
 				#reset-cells = <1>;
 			};
+
+			codec_analog: codec_analog {
+				compatible = "allwinner,sun8i-codec-analog";
+				interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&ccu CLK_BUS_CODEC>, <&ccu CLK_AC_DIG>;
+				clock-names = "apb", "codec";
+			};
 		};
 
 		cpucfg@01f01c00 {
-- 
2.9.3

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

* [PATCH 11/14] ARM: dts: sun8i: Add analog codec on prcm node
@ 2016-10-04  9:46     ` Mylène Josserand
  0 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel

The analog codec for sun8i used PRCM registers so it should be added
in the device tree as a subnode of the prcm entry.

Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
---
 arch/arm/boot/dts/sun8i-a23-a33.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-a23-a33.dtsi b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
index 48fc24f..5197812 100644
--- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi
+++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
@@ -549,6 +549,13 @@
 				compatible = "allwinner,sun6i-a31-clock-reset";
 				#reset-cells = <1>;
 			};
+
+			codec_analog: codec_analog {
+				compatible = "allwinner,sun8i-codec-analog";
+				interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&ccu CLK_BUS_CODEC>, <&ccu CLK_AC_DIG>;
+				clock-names = "apb", "codec";
+			};
 		};
 
 		cpucfg at 01f01c00 {
-- 
2.9.3

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

* [PATCH 12/14] ARM: dts: sun8i: Add audio codec, dai and card for A33
  2016-10-04  9:46 ` Mylène Josserand
@ 2016-10-04  9:46     ` Mylène Josserand
  -1 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt
  Cc: linux-kernel, dmaengine, linux-arm-kernel, linux-clk, alsa-devel,
	devicetree, linux-sunxi, thomas.petazzoni, mylene.josserand,
	alexandre.belloni

Add the audio codec, dai and a sun8i card to be able to use the
audio stream of the builtin codec on sun8i SoC.

Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
---
 arch/arm/boot/dts/sun8i-a33.dtsi | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-a33.dtsi b/arch/arm/boot/dts/sun8i-a33.dtsi
index fd1e1cd..4f8b442 100644
--- a/arch/arm/boot/dts/sun8i-a33.dtsi
+++ b/arch/arm/boot/dts/sun8i-a33.dtsi
@@ -43,6 +43,7 @@
  */
 
 #include "sun8i-a23-a33.dtsi"
+#include <dt-bindings/dma/sun4i-a10.h>
 
 / {
 	cpus {
@@ -69,6 +70,12 @@
 		reg = <0x40000000 0x80000000>;
 	};
 
+	sound {
+		compatible = "allwinner,sun8i-audio";
+		allwinner,audio-codec = <&codec>;
+		allwinner,i2s-controller = <&dai>;
+	};
+
 	soc@01c00000 {
 		tcon0: lcd-controller@01c0c000 {
 			compatible = "allwinner,sun8i-a33-tcon";
@@ -116,6 +123,32 @@
 			reset-names = "ahb";
 		};
 
+		dai: dai@01c22c00 {
+			#sound-dai-cells = <0>;
+			compatible = "allwinner,sun4i-a10-i2s";
+			reg = <0x01c22c00 0x200>;
+			interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_CODEC>, <&ccu CLK_AC_DIG>;
+			clock-names = "apb", "mod";
+			resets = <&ccu RST_BUS_CODEC>;
+			reset-names = "apb_reset";
+			dmas = <&dma 15>, /* AUDIO_CODEC port */
+				<&dma 15>; /* AUDIO_CODEC port */
+			dma-names = "rx", "tx";
+			status = "disabled";
+		};
+
+		codec: codec@01c22e00 {
+			#sound-dai-cells = <0>;
+			compatible = "allwinner,sun8i-a33-codec";
+			reg = <0x01c22e00 0x400>; /* SUNXI_AUDIO_PBASE + 0x200 */
+			reg-names = "audio";
+			interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_CODEC>, <&ccu CLK_AC_DIG>;
+			clock-names = "apb", "codec";
+			status = "disabled";
+		};
+
 		fe0: display-frontend@01e00000 {
 			compatible = "allwinner,sun8i-a33-display-frontend";
 			reg = <0x01e00000 0x20000>;
-- 
2.9.3

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

* [PATCH 12/14] ARM: dts: sun8i: Add audio codec, dai and card for A33
@ 2016-10-04  9:46     ` Mylène Josserand
  0 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel

Add the audio codec, dai and a sun8i card to be able to use the
audio stream of the builtin codec on sun8i SoC.

Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
---
 arch/arm/boot/dts/sun8i-a33.dtsi | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-a33.dtsi b/arch/arm/boot/dts/sun8i-a33.dtsi
index fd1e1cd..4f8b442 100644
--- a/arch/arm/boot/dts/sun8i-a33.dtsi
+++ b/arch/arm/boot/dts/sun8i-a33.dtsi
@@ -43,6 +43,7 @@
  */
 
 #include "sun8i-a23-a33.dtsi"
+#include <dt-bindings/dma/sun4i-a10.h>
 
 / {
 	cpus {
@@ -69,6 +70,12 @@
 		reg = <0x40000000 0x80000000>;
 	};
 
+	sound {
+		compatible = "allwinner,sun8i-audio";
+		allwinner,audio-codec = <&codec>;
+		allwinner,i2s-controller = <&dai>;
+	};
+
 	soc at 01c00000 {
 		tcon0: lcd-controller at 01c0c000 {
 			compatible = "allwinner,sun8i-a33-tcon";
@@ -116,6 +123,32 @@
 			reset-names = "ahb";
 		};
 
+		dai: dai at 01c22c00 {
+			#sound-dai-cells = <0>;
+			compatible = "allwinner,sun4i-a10-i2s";
+			reg = <0x01c22c00 0x200>;
+			interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_CODEC>, <&ccu CLK_AC_DIG>;
+			clock-names = "apb", "mod";
+			resets = <&ccu RST_BUS_CODEC>;
+			reset-names = "apb_reset";
+			dmas = <&dma 15>, /* AUDIO_CODEC port */
+				<&dma 15>; /* AUDIO_CODEC port */
+			dma-names = "rx", "tx";
+			status = "disabled";
+		};
+
+		codec: codec at 01c22e00 {
+			#sound-dai-cells = <0>;
+			compatible = "allwinner,sun8i-a33-codec";
+			reg = <0x01c22e00 0x400>; /* SUNXI_AUDIO_PBASE + 0x200 */
+			reg-names = "audio";
+			interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_CODEC>, <&ccu CLK_AC_DIG>;
+			clock-names = "apb", "codec";
+			status = "disabled";
+		};
+
 		fe0: display-frontend at 01e00000 {
 			compatible = "allwinner,sun8i-a33-display-frontend";
 			reg = <0x01e00000 0x20000>;
-- 
2.9.3

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

* [PATCH 13/14] ARM: dts: sun8i: parrot: Enable audio nodes
  2016-10-04  9:46 ` Mylène Josserand
@ 2016-10-04  9:46     ` Mylène Josserand
  -1 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt
  Cc: linux-kernel, dmaengine, linux-arm-kernel, linux-clk, alsa-devel,
	devicetree, linux-sunxi, thomas.petazzoni, mylene.josserand,
	alexandre.belloni

Enable the audio codec and the audio dai for the sun8i R16 Parrot board.

Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
---
 arch/arm/boot/dts/sun8i-r16-parrot.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-r16-parrot.dts b/arch/arm/boot/dts/sun8i-r16-parrot.dts
index 47553e5..7becead 100644
--- a/arch/arm/boot/dts/sun8i-r16-parrot.dts
+++ b/arch/arm/boot/dts/sun8i-r16-parrot.dts
@@ -84,6 +84,14 @@
 
 };
 
+&codec {
+	status = "okay";
+};
+
+&dai {
+	status = "okay";
+};
+
 &ehci0 {
 	status = "okay";
 };
-- 
2.9.3

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

* [PATCH 13/14] ARM: dts: sun8i: parrot: Enable audio nodes
@ 2016-10-04  9:46     ` Mylène Josserand
  0 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel

Enable the audio codec and the audio dai for the sun8i R16 Parrot board.

Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
---
 arch/arm/boot/dts/sun8i-r16-parrot.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-r16-parrot.dts b/arch/arm/boot/dts/sun8i-r16-parrot.dts
index 47553e5..7becead 100644
--- a/arch/arm/boot/dts/sun8i-r16-parrot.dts
+++ b/arch/arm/boot/dts/sun8i-r16-parrot.dts
@@ -84,6 +84,14 @@
 
 };
 
+&codec {
+	status = "okay";
+};
+
+&dai {
+	status = "okay";
+};
+
 &ehci0 {
 	status = "okay";
 };
-- 
2.9.3

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

* [PATCH 14/14] ARM: dts: sun8i: sinlinx: Enable audio nodes
  2016-10-04  9:46 ` Mylène Josserand
@ 2016-10-04  9:46     ` Mylène Josserand
  -1 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt
  Cc: linux-kernel, dmaengine, linux-arm-kernel, linux-clk, alsa-devel,
	devicetree, linux-sunxi, thomas.petazzoni, mylene.josserand,
	alexandre.belloni

Enable the audio codec and the audio dai for the sun8i A33 sinlinx board.

Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
---
 arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
index fef6abc..b03ca5e 100644
--- a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
+++ b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
@@ -63,6 +63,14 @@
 	};
 };
 
+&codec {
+	status = "okay";
+};
+
+&dai {
+	status = "okay";
+};
+
 &ehci0 {
 	status = "okay";
 };
-- 
2.9.3

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

* [PATCH 14/14] ARM: dts: sun8i: sinlinx: Enable audio nodes
@ 2016-10-04  9:46     ` Mylène Josserand
  0 siblings, 0 replies; 170+ messages in thread
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel

Enable the audio codec and the audio dai for the sun8i A33 sinlinx board.

Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
---
 arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
index fef6abc..b03ca5e 100644
--- a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
+++ b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
@@ -63,6 +63,14 @@
 	};
 };
 
+&codec {
+	status = "okay";
+};
+
+&dai {
+	status = "okay";
+};
+
 &ehci0 {
 	status = "okay";
 };
-- 
2.9.3

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

* Re: [PATCH 07/14] ASoC: Add sun8i audio card
@ 2016-10-04 10:16       ` Code Kipper
  0 siblings, 0 replies; 170+ messages in thread
From: Code Kipper @ 2016-10-04 10:16 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul, Maxime Ripard, Chen-Yu Tsai, mturquette, sboyd,
	Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai,
	Lee Jones, mark.rutland, Rob Herring, linux-kernel, dmaengine,
	linux-arm-kernel, linux-clk, alsa-devel, devicetree, linux-sunxi,
	thomas.petazzoni, alexandre.belloni

On 4 October 2016 at 11:46, Mylène Josserand
<mylene.josserand@free-electrons.com> wrote:
> Add the audio card for sun8i SoC. This card links the codec driver
> (digital part) with the DAI driver. The analog codec driver is
> added as an aux_device.
>
> Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
> ---
>  sound/soc/sunxi/Kconfig  |  14 +++++++
>  sound/soc/sunxi/Makefile |   1 +
>  sound/soc/sunxi/sun8i.c  | 101 +++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 116 insertions(+)
>  create mode 100644 sound/soc/sunxi/sun8i.c
>
> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
> index 9e287b0..7b97395 100644
> --- a/sound/soc/sunxi/Kconfig
> +++ b/sound/soc/sunxi/Kconfig
> @@ -27,6 +27,20 @@ config SND_SUN4I_SPDIF
>           Say Y or M to add support for the S/PDIF audio block in the Allwinner
>           A10 and affiliated SoCs.
>
> +config SND_SUN8I
> +       tristate "Allwinner SUN6I/SUN8I audio card support"
> +       select SND_SUN8I_CODEC
> +       select SND_SUN4I_I2S
> +       select SND_SUN8I_CODEC_ANALOG
> +       select REGMAP_MMIO
> +       help
> +         This option enables the audio card for Allwinner A33 (sun8i) SoC.
> +         It enables the DAI driver (SND_SUN4I_I2S), the digital audio
> +         codec driver (SND_SUN8I_CODEC) and the analog codec driver
> +         (SND_SUN8I_CODEC_ANALOG).
> +
> +         Say Y or M if you want to add sun8i/6i card support
> +
>  config SND_SUN8I_CODEC
>         tristate "Allwinner SUN8I audio codec"
>         select REGMAP_MMIO
> diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
> index 1da63d3..7f1bab9 100644
> --- a/sound/soc/sunxi/Makefile
> +++ b/sound/soc/sunxi/Makefile
> @@ -1,5 +1,6 @@
>  obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
>  obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
>  obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
> +obj-$(CONFIG_SND_SUN8I) += sun8i.o
Great work with this...I've been battling with the audio codec for the
h3 for a while and it looks like almost everything that I need is
delivered here.
>  obj-$(CONFIG_SND_SUN8I_CODEC) += sun8i-codec.o
>  obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
> diff --git a/sound/soc/sunxi/sun8i.c b/sound/soc/sunxi/sun8i.c
> new file mode 100644
> index 0000000..565cd88
> --- /dev/null
> +++ b/sound/soc/sunxi/sun8i.c
> @@ -0,0 +1,101 @@
> +/*
> + * ALSA SoC driver for Allwinner sun8i SoC
> + *
> + * Copyright (C) 2016 Mylène Josserand <mylene.josserand@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/firmware.h>
> +#include <linux/module.h>
> +
> +#include <sound/soc.h>
> +
> +static struct snd_soc_aux_dev sun8i_audio_prcm_aux_devs[] = {
> +       {
> +               .name = "sun8i-codec-analog",
> +               .codec_name = "sun8i-codec-analog.0",
> +       },
> +};
> +
> +static struct snd_soc_dai_link sun8i_dai_link = {
> +       .name           = "sun4i-i2s",
> +       .stream_name    = "Playback",
> +       .codec_dai_name = "sun8i",
> +       .dai_fmt        = SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S |
> +                       SND_SOC_DAIFMT_CBM_CFM,
> +};
> +
> +static struct snd_soc_card sun8i_card = {
> +       .name           = "sun8i-card",
> +       .owner          = THIS_MODULE,
> +       .dai_link       = &sun8i_dai_link,
> +       .num_links      = 1,
> +       .aux_dev        = sun8i_audio_prcm_aux_devs,
> +       .num_aux_devs   = ARRAY_SIZE(sun8i_audio_prcm_aux_devs),
> +};
> +
> +static int sun8i_probe(struct platform_device *pdev)
> +{
> +       struct snd_soc_dai_link *link = &sun8i_dai_link;
> +       struct device_node *np = pdev->dev.of_node;
> +       int ret;
> +
> +       /* register the soc card */
> +       sun8i_card.dev = &pdev->dev;
> +
> +       /* Retrieve the audio-codec from DT */
> +       link->codec_of_node = of_parse_phandle(np, "allwinner,audio-codec", 0);
> +       if (!link->codec_of_node) {
> +               dev_err(&pdev->dev, "Missing audio codec\n");
> +               return -EINVAL;
> +       }
> +
> +       /* Retrieve DAI from DT */
> +       link->cpu_of_node = of_parse_phandle(np, "allwinner,i2s-controller", 0);
> +       if (!link->cpu_of_node) {
> +               dev_err(&pdev->dev, "Missing I2S controller\n");
> +               return -EINVAL;
> +       }
> +
My one question is that we have sun8i-a23 and sun8i-a33, and I think
we need to distinguish them here. The sun8i-a23 doesn't use the i2s
block but does use the prcm.
> +       link->platform_of_node = link->cpu_of_node;
> +
> +       /* Register the sound card */
> +       ret = devm_snd_soc_register_card(&pdev->dev, &sun8i_card);
> +       if (ret) {
> +               dev_err(&pdev->dev,
> +                       "Soc register card failed %d\n", ret);
> +               return ret;
> +       }
> +
> +       return ret;
> +}
> +
> +static const struct of_device_id sun8i_of_match[] = {
> +       { .compatible = "allwinner,sun8i-audio", },
> +       {},
> +};
> +
> +MODULE_DEVICE_TABLE(of, sun8i_of_match);
> +
> +static struct platform_driver sun8i_card_driver = {
> +       .probe = sun8i_probe,
> +       .driver = {
> +               .name   = "sun8i-audio",
> +               .of_match_table = sun8i_of_match,
> +       },
> +};
> +
> +module_platform_driver(sun8i_card_driver);
> +
> +MODULE_AUTHOR("Mylène Josserand <mylene.josserand@free-electrons.com>");
> +MODULE_DESCRIPTION("Allwinner sun8i machine ASoC driver");
> +MODULE_LICENSE("GPL v2");
> --
> 2.9.3
>

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

* Re: [PATCH 07/14] ASoC: Add sun8i audio card
@ 2016-10-04 10:16       ` Code Kipper
  0 siblings, 0 replies; 170+ messages in thread
From: Code Kipper @ 2016-10-04 10:16 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul-ral2JQCrhuEAvxtiuMwx3w, Maxime Ripard, Chen-Yu Tsai,
	mturquette-rdvid1DuHRBWk0Htik3J/w, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
	Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai,
	Lee Jones, mark.rutland-5wv7dgnIgG8, Rob Herring,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	dmaengine-u79uwXL29TY76Z2rM5mHXA, linux-arm-kernel,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw, devicetree, linux-sunxi,
	thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8

On 4 October 2016 at 11:46, Mylène Josserand
<mylene.josserand-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> Add the audio card for sun8i SoC. This card links the codec driver
> (digital part) with the DAI driver. The analog codec driver is
> added as an aux_device.
>
> Signed-off-by: Mylène Josserand <mylene.josserand-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> ---
>  sound/soc/sunxi/Kconfig  |  14 +++++++
>  sound/soc/sunxi/Makefile |   1 +
>  sound/soc/sunxi/sun8i.c  | 101 +++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 116 insertions(+)
>  create mode 100644 sound/soc/sunxi/sun8i.c
>
> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
> index 9e287b0..7b97395 100644
> --- a/sound/soc/sunxi/Kconfig
> +++ b/sound/soc/sunxi/Kconfig
> @@ -27,6 +27,20 @@ config SND_SUN4I_SPDIF
>           Say Y or M to add support for the S/PDIF audio block in the Allwinner
>           A10 and affiliated SoCs.
>
> +config SND_SUN8I
> +       tristate "Allwinner SUN6I/SUN8I audio card support"
> +       select SND_SUN8I_CODEC
> +       select SND_SUN4I_I2S
> +       select SND_SUN8I_CODEC_ANALOG
> +       select REGMAP_MMIO
> +       help
> +         This option enables the audio card for Allwinner A33 (sun8i) SoC.
> +         It enables the DAI driver (SND_SUN4I_I2S), the digital audio
> +         codec driver (SND_SUN8I_CODEC) and the analog codec driver
> +         (SND_SUN8I_CODEC_ANALOG).
> +
> +         Say Y or M if you want to add sun8i/6i card support
> +
>  config SND_SUN8I_CODEC
>         tristate "Allwinner SUN8I audio codec"
>         select REGMAP_MMIO
> diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
> index 1da63d3..7f1bab9 100644
> --- a/sound/soc/sunxi/Makefile
> +++ b/sound/soc/sunxi/Makefile
> @@ -1,5 +1,6 @@
>  obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
>  obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
>  obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
> +obj-$(CONFIG_SND_SUN8I) += sun8i.o
Great work with this...I've been battling with the audio codec for the
h3 for a while and it looks like almost everything that I need is
delivered here.
>  obj-$(CONFIG_SND_SUN8I_CODEC) += sun8i-codec.o
>  obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
> diff --git a/sound/soc/sunxi/sun8i.c b/sound/soc/sunxi/sun8i.c
> new file mode 100644
> index 0000000..565cd88
> --- /dev/null
> +++ b/sound/soc/sunxi/sun8i.c
> @@ -0,0 +1,101 @@
> +/*
> + * ALSA SoC driver for Allwinner sun8i SoC
> + *
> + * Copyright (C) 2016 Mylène Josserand <mylene.josserand@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/firmware.h>
> +#include <linux/module.h>
> +
> +#include <sound/soc.h>
> +
> +static struct snd_soc_aux_dev sun8i_audio_prcm_aux_devs[] = {
> +       {
> +               .name = "sun8i-codec-analog",
> +               .codec_name = "sun8i-codec-analog.0",
> +       },
> +};
> +
> +static struct snd_soc_dai_link sun8i_dai_link = {
> +       .name           = "sun4i-i2s",
> +       .stream_name    = "Playback",
> +       .codec_dai_name = "sun8i",
> +       .dai_fmt        = SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S |
> +                       SND_SOC_DAIFMT_CBM_CFM,
> +};
> +
> +static struct snd_soc_card sun8i_card = {
> +       .name           = "sun8i-card",
> +       .owner          = THIS_MODULE,
> +       .dai_link       = &sun8i_dai_link,
> +       .num_links      = 1,
> +       .aux_dev        = sun8i_audio_prcm_aux_devs,
> +       .num_aux_devs   = ARRAY_SIZE(sun8i_audio_prcm_aux_devs),
> +};
> +
> +static int sun8i_probe(struct platform_device *pdev)
> +{
> +       struct snd_soc_dai_link *link = &sun8i_dai_link;
> +       struct device_node *np = pdev->dev.of_node;
> +       int ret;
> +
> +       /* register the soc card */
> +       sun8i_card.dev = &pdev->dev;
> +
> +       /* Retrieve the audio-codec from DT */
> +       link->codec_of_node = of_parse_phandle(np, "allwinner,audio-codec", 0);
> +       if (!link->codec_of_node) {
> +               dev_err(&pdev->dev, "Missing audio codec\n");
> +               return -EINVAL;
> +       }
> +
> +       /* Retrieve DAI from DT */
> +       link->cpu_of_node = of_parse_phandle(np, "allwinner,i2s-controller", 0);
> +       if (!link->cpu_of_node) {
> +               dev_err(&pdev->dev, "Missing I2S controller\n");
> +               return -EINVAL;
> +       }
> +
My one question is that we have sun8i-a23 and sun8i-a33, and I think
we need to distinguish them here. The sun8i-a23 doesn't use the i2s
block but does use the prcm.
> +       link->platform_of_node = link->cpu_of_node;
> +
> +       /* Register the sound card */
> +       ret = devm_snd_soc_register_card(&pdev->dev, &sun8i_card);
> +       if (ret) {
> +               dev_err(&pdev->dev,
> +                       "Soc register card failed %d\n", ret);
> +               return ret;
> +       }
> +
> +       return ret;
> +}
> +
> +static const struct of_device_id sun8i_of_match[] = {
> +       { .compatible = "allwinner,sun8i-audio", },
> +       {},
> +};
> +
> +MODULE_DEVICE_TABLE(of, sun8i_of_match);
> +
> +static struct platform_driver sun8i_card_driver = {
> +       .probe = sun8i_probe,
> +       .driver = {
> +               .name   = "sun8i-audio",
> +               .of_match_table = sun8i_of_match,
> +       },
> +};
> +
> +module_platform_driver(sun8i_card_driver);
> +
> +MODULE_AUTHOR("Mylène Josserand <mylene.josserand-wi1+55ScJUtKEb57/3fJTGGXanvQGlWp@public.gmane.orgm>");
> +MODULE_DESCRIPTION("Allwinner sun8i machine ASoC driver");
> +MODULE_LICENSE("GPL v2");
> --
> 2.9.3
>
--
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] 170+ messages in thread

* Re: [PATCH 07/14] ASoC: Add sun8i audio card
@ 2016-10-04 10:16       ` Code Kipper
  0 siblings, 0 replies; 170+ messages in thread
From: Code Kipper @ 2016-10-04 10:16 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul, Maxime Ripard, Chen-Yu Tsai, mturquette, sboyd,
	Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai,
	Lee Jones, mark.rutland, Rob Herring, linux-kernel, dmaengine,
	linux-arm-kernel, linux-clk, alsa-devel, devicetree, linux-sunxi,
	thomas.petazzoni, alexandre.belloni

On 4 October 2016 at 11:46, Myl=C3=A8ne Josserand
<mylene.josserand@free-electrons.com> wrote:
> Add the audio card for sun8i SoC. This card links the codec driver
> (digital part) with the DAI driver. The analog codec driver is
> added as an aux_device.
>
> Signed-off-by: Myl=C3=A8ne Josserand <mylene.josserand@free-electrons.com=
>
> ---
>  sound/soc/sunxi/Kconfig  |  14 +++++++
>  sound/soc/sunxi/Makefile |   1 +
>  sound/soc/sunxi/sun8i.c  | 101 +++++++++++++++++++++++++++++++++++++++++=
++++++
>  3 files changed, 116 insertions(+)
>  create mode 100644 sound/soc/sunxi/sun8i.c
>
> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
> index 9e287b0..7b97395 100644
> --- a/sound/soc/sunxi/Kconfig
> +++ b/sound/soc/sunxi/Kconfig
> @@ -27,6 +27,20 @@ config SND_SUN4I_SPDIF
>           Say Y or M to add support for the S/PDIF audio block in the All=
winner
>           A10 and affiliated SoCs.
>
> +config SND_SUN8I
> +       tristate "Allwinner SUN6I/SUN8I audio card support"
> +       select SND_SUN8I_CODEC
> +       select SND_SUN4I_I2S
> +       select SND_SUN8I_CODEC_ANALOG
> +       select REGMAP_MMIO
> +       help
> +         This option enables the audio card for Allwinner A33 (sun8i) So=
C.
> +         It enables the DAI driver (SND_SUN4I_I2S), the digital audio
> +         codec driver (SND_SUN8I_CODEC) and the analog codec driver
> +         (SND_SUN8I_CODEC_ANALOG).
> +
> +         Say Y or M if you want to add sun8i/6i card support
> +
>  config SND_SUN8I_CODEC
>         tristate "Allwinner SUN8I audio codec"
>         select REGMAP_MMIO
> diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
> index 1da63d3..7f1bab9 100644
> --- a/sound/soc/sunxi/Makefile
> +++ b/sound/soc/sunxi/Makefile
> @@ -1,5 +1,6 @@
>  obj-$(CONFIG_SND_SUN4I_CODEC) +=3D sun4i-codec.o
>  obj-$(CONFIG_SND_SUN4I_I2S) +=3D sun4i-i2s.o
>  obj-$(CONFIG_SND_SUN4I_SPDIF) +=3D sun4i-spdif.o
> +obj-$(CONFIG_SND_SUN8I) +=3D sun8i.o
Great work with this...I've been battling with the audio codec for the
h3 for a while and it looks like almost everything that I need is
delivered here.
>  obj-$(CONFIG_SND_SUN8I_CODEC) +=3D sun8i-codec.o
>  obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) +=3D sun8i-codec-analog.o
> diff --git a/sound/soc/sunxi/sun8i.c b/sound/soc/sunxi/sun8i.c
> new file mode 100644
> index 0000000..565cd88
> --- /dev/null
> +++ b/sound/soc/sunxi/sun8i.c
> @@ -0,0 +1,101 @@
> +/*
> + * ALSA SoC driver for Allwinner sun8i SoC
> + *
> + * Copyright (C) 2016 Myl=C3=A8ne Josserand <mylene.josserand@free-elect=
rons.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/firmware.h>
> +#include <linux/module.h>
> +
> +#include <sound/soc.h>
> +
> +static struct snd_soc_aux_dev sun8i_audio_prcm_aux_devs[] =3D {
> +       {
> +               .name =3D "sun8i-codec-analog",
> +               .codec_name =3D "sun8i-codec-analog.0",
> +       },
> +};
> +
> +static struct snd_soc_dai_link sun8i_dai_link =3D {
> +       .name           =3D "sun4i-i2s",
> +       .stream_name    =3D "Playback",
> +       .codec_dai_name =3D "sun8i",
> +       .dai_fmt        =3D SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S |
> +                       SND_SOC_DAIFMT_CBM_CFM,
> +};
> +
> +static struct snd_soc_card sun8i_card =3D {
> +       .name           =3D "sun8i-card",
> +       .owner          =3D THIS_MODULE,
> +       .dai_link       =3D &sun8i_dai_link,
> +       .num_links      =3D 1,
> +       .aux_dev        =3D sun8i_audio_prcm_aux_devs,
> +       .num_aux_devs   =3D ARRAY_SIZE(sun8i_audio_prcm_aux_devs),
> +};
> +
> +static int sun8i_probe(struct platform_device *pdev)
> +{
> +       struct snd_soc_dai_link *link =3D &sun8i_dai_link;
> +       struct device_node *np =3D pdev->dev.of_node;
> +       int ret;
> +
> +       /* register the soc card */
> +       sun8i_card.dev =3D &pdev->dev;
> +
> +       /* Retrieve the audio-codec from DT */
> +       link->codec_of_node =3D of_parse_phandle(np, "allwinner,audio-cod=
ec", 0);
> +       if (!link->codec_of_node) {
> +               dev_err(&pdev->dev, "Missing audio codec\n");
> +               return -EINVAL;
> +       }
> +
> +       /* Retrieve DAI from DT */
> +       link->cpu_of_node =3D of_parse_phandle(np, "allwinner,i2s-control=
ler", 0);
> +       if (!link->cpu_of_node) {
> +               dev_err(&pdev->dev, "Missing I2S controller\n");
> +               return -EINVAL;
> +       }
> +
My one question is that we have sun8i-a23 and sun8i-a33, and I think
we need to distinguish them here. The sun8i-a23 doesn't use the i2s
block but does use the prcm.
> +       link->platform_of_node =3D link->cpu_of_node;
> +
> +       /* Register the sound card */
> +       ret =3D devm_snd_soc_register_card(&pdev->dev, &sun8i_card);
> +       if (ret) {
> +               dev_err(&pdev->dev,
> +                       "Soc register card failed %d\n", ret);
> +               return ret;
> +       }
> +
> +       return ret;
> +}
> +
> +static const struct of_device_id sun8i_of_match[] =3D {
> +       { .compatible =3D "allwinner,sun8i-audio", },
> +       {},
> +};
> +
> +MODULE_DEVICE_TABLE(of, sun8i_of_match);
> +
> +static struct platform_driver sun8i_card_driver =3D {
> +       .probe =3D sun8i_probe,
> +       .driver =3D {
> +               .name   =3D "sun8i-audio",
> +               .of_match_table =3D sun8i_of_match,
> +       },
> +};
> +
> +module_platform_driver(sun8i_card_driver);
> +
> +MODULE_AUTHOR("Myl=C3=A8ne Josserand <mylene.josserand@free-electrons.co=
m>");
> +MODULE_DESCRIPTION("Allwinner sun8i machine ASoC driver");
> +MODULE_LICENSE("GPL v2");
> --
> 2.9.3
>

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

* [PATCH 07/14] ASoC: Add sun8i audio card
@ 2016-10-04 10:16       ` Code Kipper
  0 siblings, 0 replies; 170+ messages in thread
From: Code Kipper @ 2016-10-04 10:16 UTC (permalink / raw)
  To: linux-arm-kernel

On 4 October 2016 at 11:46, Myl?ne Josserand
<mylene.josserand@free-electrons.com> wrote:
> Add the audio card for sun8i SoC. This card links the codec driver
> (digital part) with the DAI driver. The analog codec driver is
> added as an aux_device.
>
> Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
> ---
>  sound/soc/sunxi/Kconfig  |  14 +++++++
>  sound/soc/sunxi/Makefile |   1 +
>  sound/soc/sunxi/sun8i.c  | 101 +++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 116 insertions(+)
>  create mode 100644 sound/soc/sunxi/sun8i.c
>
> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
> index 9e287b0..7b97395 100644
> --- a/sound/soc/sunxi/Kconfig
> +++ b/sound/soc/sunxi/Kconfig
> @@ -27,6 +27,20 @@ config SND_SUN4I_SPDIF
>           Say Y or M to add support for the S/PDIF audio block in the Allwinner
>           A10 and affiliated SoCs.
>
> +config SND_SUN8I
> +       tristate "Allwinner SUN6I/SUN8I audio card support"
> +       select SND_SUN8I_CODEC
> +       select SND_SUN4I_I2S
> +       select SND_SUN8I_CODEC_ANALOG
> +       select REGMAP_MMIO
> +       help
> +         This option enables the audio card for Allwinner A33 (sun8i) SoC.
> +         It enables the DAI driver (SND_SUN4I_I2S), the digital audio
> +         codec driver (SND_SUN8I_CODEC) and the analog codec driver
> +         (SND_SUN8I_CODEC_ANALOG).
> +
> +         Say Y or M if you want to add sun8i/6i card support
> +
>  config SND_SUN8I_CODEC
>         tristate "Allwinner SUN8I audio codec"
>         select REGMAP_MMIO
> diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
> index 1da63d3..7f1bab9 100644
> --- a/sound/soc/sunxi/Makefile
> +++ b/sound/soc/sunxi/Makefile
> @@ -1,5 +1,6 @@
>  obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
>  obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
>  obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
> +obj-$(CONFIG_SND_SUN8I) += sun8i.o
Great work with this...I've been battling with the audio codec for the
h3 for a while and it looks like almost everything that I need is
delivered here.
>  obj-$(CONFIG_SND_SUN8I_CODEC) += sun8i-codec.o
>  obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
> diff --git a/sound/soc/sunxi/sun8i.c b/sound/soc/sunxi/sun8i.c
> new file mode 100644
> index 0000000..565cd88
> --- /dev/null
> +++ b/sound/soc/sunxi/sun8i.c
> @@ -0,0 +1,101 @@
> +/*
> + * ALSA SoC driver for Allwinner sun8i SoC
> + *
> + * Copyright (C) 2016 Myl?ne Josserand <mylene.josserand@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/firmware.h>
> +#include <linux/module.h>
> +
> +#include <sound/soc.h>
> +
> +static struct snd_soc_aux_dev sun8i_audio_prcm_aux_devs[] = {
> +       {
> +               .name = "sun8i-codec-analog",
> +               .codec_name = "sun8i-codec-analog.0",
> +       },
> +};
> +
> +static struct snd_soc_dai_link sun8i_dai_link = {
> +       .name           = "sun4i-i2s",
> +       .stream_name    = "Playback",
> +       .codec_dai_name = "sun8i",
> +       .dai_fmt        = SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S |
> +                       SND_SOC_DAIFMT_CBM_CFM,
> +};
> +
> +static struct snd_soc_card sun8i_card = {
> +       .name           = "sun8i-card",
> +       .owner          = THIS_MODULE,
> +       .dai_link       = &sun8i_dai_link,
> +       .num_links      = 1,
> +       .aux_dev        = sun8i_audio_prcm_aux_devs,
> +       .num_aux_devs   = ARRAY_SIZE(sun8i_audio_prcm_aux_devs),
> +};
> +
> +static int sun8i_probe(struct platform_device *pdev)
> +{
> +       struct snd_soc_dai_link *link = &sun8i_dai_link;
> +       struct device_node *np = pdev->dev.of_node;
> +       int ret;
> +
> +       /* register the soc card */
> +       sun8i_card.dev = &pdev->dev;
> +
> +       /* Retrieve the audio-codec from DT */
> +       link->codec_of_node = of_parse_phandle(np, "allwinner,audio-codec", 0);
> +       if (!link->codec_of_node) {
> +               dev_err(&pdev->dev, "Missing audio codec\n");
> +               return -EINVAL;
> +       }
> +
> +       /* Retrieve DAI from DT */
> +       link->cpu_of_node = of_parse_phandle(np, "allwinner,i2s-controller", 0);
> +       if (!link->cpu_of_node) {
> +               dev_err(&pdev->dev, "Missing I2S controller\n");
> +               return -EINVAL;
> +       }
> +
My one question is that we have sun8i-a23 and sun8i-a33, and I think
we need to distinguish them here. The sun8i-a23 doesn't use the i2s
block but does use the prcm.
> +       link->platform_of_node = link->cpu_of_node;
> +
> +       /* Register the sound card */
> +       ret = devm_snd_soc_register_card(&pdev->dev, &sun8i_card);
> +       if (ret) {
> +               dev_err(&pdev->dev,
> +                       "Soc register card failed %d\n", ret);
> +               return ret;
> +       }
> +
> +       return ret;
> +}
> +
> +static const struct of_device_id sun8i_of_match[] = {
> +       { .compatible = "allwinner,sun8i-audio", },
> +       {},
> +};
> +
> +MODULE_DEVICE_TABLE(of, sun8i_of_match);
> +
> +static struct platform_driver sun8i_card_driver = {
> +       .probe = sun8i_probe,
> +       .driver = {
> +               .name   = "sun8i-audio",
> +               .of_match_table = sun8i_of_match,
> +       },
> +};
> +
> +module_platform_driver(sun8i_card_driver);
> +
> +MODULE_AUTHOR("Myl?ne Josserand <mylene.josserand@free-electrons.com>");
> +MODULE_DESCRIPTION("Allwinner sun8i machine ASoC driver");
> +MODULE_LICENSE("GPL v2");
> --
> 2.9.3
>

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

* Re: [PATCH 04/14] ASoC: Add sun8i analog codec driver
@ 2016-10-04 10:21       ` Code Kipper
  0 siblings, 0 replies; 170+ messages in thread
From: Code Kipper @ 2016-10-04 10:21 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul, Maxime Ripard, Chen-Yu Tsai, mturquette, sboyd,
	Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai,
	Lee Jones, mark.rutland, Rob Herring, thomas.petazzoni,
	devicetree, alsa-devel, linux-kernel, linux-sunxi,
	alexandre.belloni, dmaengine, linux-clk, linux-arm-kernel

On 4 October 2016 at 11:46, Mylène Josserand
<mylene.josserand@free-electrons.com> wrote:
> Add the analog part of the sun8i (A33) codec driver. This driver
> implements all the analog part of the codec using PRCM registers.
>
> The read/write regmap functions must be handled in a custom way as
> the PRCM register behaves as "mailbox" register.
>
> Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
> ---
>  sound/soc/sunxi/Kconfig              |   7 +
>  sound/soc/sunxi/Makefile             |   1 +
>  sound/soc/sunxi/sun8i-codec-analog.c | 304 +++++++++++++++++++++++++++++++++++
>  3 files changed, 312 insertions(+)
>  create mode 100644 sound/soc/sunxi/sun8i-codec-analog.c
>
> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
> index dd23682..7aee95a 100644
> --- a/sound/soc/sunxi/Kconfig
> +++ b/sound/soc/sunxi/Kconfig
> @@ -26,4 +26,11 @@ config SND_SUN4I_SPDIF
>         help
>           Say Y or M to add support for the S/PDIF audio block in the Allwinner
>           A10 and affiliated SoCs.
> +
> +config SND_SUN8I_CODEC_ANALOG
> +       tristate "Allwinner SUN8I analog codec"
> +       select REGMAP_MMIO
> +        help
> +         Say Y or M if you want to add sun8i analog audiocodec support
> +
>  endmenu
> diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
> index 604c7b84..241c0df 100644
> --- a/sound/soc/sunxi/Makefile
> +++ b/sound/soc/sunxi/Makefile
> @@ -1,3 +1,4 @@
>  obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
>  obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
>  obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
> +obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
> diff --git a/sound/soc/sunxi/sun8i-codec-analog.c b/sound/soc/sunxi/sun8i-codec-analog.c
> new file mode 100644
> index 0000000..be3d540
> --- /dev/null
> +++ b/sound/soc/sunxi/sun8i-codec-analog.c
> @@ -0,0 +1,304 @@
> +/*
> + * This driver supports the analog controls for the internal codec
> + * found in Allwinner's A31s, A33 and A23 SoCs.
> + *
> + * Copyright 2016 Chen-Yu Tsai <wens@csie.org>
> + * Copyright 2016 Mylène Josserand <mylene.josserand@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/io.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +
> +#include <sound/soc.h>
> +#include <sound/soc-dapm.h>
> +#include <sound/tlv.h>
> +
> +/* Codec analog control register offsets and bit fields */
> +#define SUN8I_ADDA_HP_VOLC                             0x00
> +#define SUN8I_ADDA_HP_VOLC_PA_CLK_GATE                 7
> +#define SUN8I_ADDA_HP_VOLC_HP_VOL                      0
> +#define SUN8I_ADDA_LOMIXSC                             0x01
> +#define SUN8I_ADDA_LOMIXSC_MIC1                        6
> +#define SUN8I_ADDA_LOMIXSC_MIC2                        5
> +#define SUN8I_ADDA_LOMIXSC_PHONE                       4
> +#define SUN8I_ADDA_LOMIXSC_PHONEN                      3
> +#define SUN8I_ADDA_LOMIXSC_LINEINL                     2
> +#define SUN8I_ADDA_LOMIXSC_DACL                        1
> +#define SUN8I_ADDA_LOMIXSC_DACR                        0
> +#define SUN8I_ADDA_ROMIXSC                             0x02
> +#define SUN8I_ADDA_ROMIXSC_MIC1                        6
> +#define SUN8I_ADDA_ROMIXSC_MIC2                        5
> +#define SUN8I_ADDA_ROMIXSC_PHONE                       4
> +#define SUN8I_ADDA_ROMIXSC_PHONEP                      3
> +#define SUN8I_ADDA_ROMIXSC_LINEINR                     2
> +#define SUN8I_ADDA_ROMIXSC_DACR                        1
> +#define SUN8I_ADDA_ROMIXSC_DACL                        0
> +#define SUN8I_ADDA_DAC_PA_SRC                          0x03
> +#define SUN8I_ADDA_DAC_PA_SRC_DACAREN                  7
> +#define SUN8I_ADDA_DAC_PA_SRC_DACALEN                  6
> +#define SUN8I_ADDA_DAC_PA_SRC_RMIXEN                   5
> +#define SUN8I_ADDA_DAC_PA_SRC_LMIXEN                   4
> +#define SUN8I_ADDA_DAC_PA_SRC_RHPPAMUTE                3
> +#define SUN8I_ADDA_DAC_PA_SRC_LHPPAMUTE                2
> +#define SUN8I_ADDA_DAC_PA_SRC_RHPIS                    1
> +#define SUN8I_ADDA_DAC_PA_SRC_LHPIS                    0
> +#define SUN8I_ADDA_PHONEIN_GCTRL                       0x04
> +#define SUN8I_ADDA_PHONEIN_GCTRL_PHONEPG               4
> +#define SUN8I_ADDA_PHONEIN_GCTRL_PHONENG               0
> +#define SUN8I_ADDA_LINEIN_GCTRL                        0x05
> +#define SUN8I_ADDA_LINEIN_GCTRL_LINEING                4
> +#define SUN8I_ADDA_LINEIN_GCTRL_PHONEG                 0
> +#define SUN8I_ADDA_MICIN_GCTRL                         0x06
> +#define SUN8I_ADDA_MICIN_GCTRL_MIC1G                   4
> +#define SUN8I_ADDA_MICIN_GCTRL_MIC2G                   0
> +#define SUN8I_ADDA_PAEN_HP_CTRL                        0x07
> +#define SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN                 7
> +#define SUN8I_ADDA_PAEN_HP_CTRL_HPCOM_FC               5
> +#define SUN8I_ADDA_PAEN_HP_CTRL_COMPTEN                4
> +#define SUN8I_ADDA_PAEN_HP_CTRL_PA_ANTI_POP_CTRL       2
> +#define SUN8I_ADDA_PAEN_HP_CTRL_LTRNMUTE               1
> +#define SUN8I_ADDA_PAEN_HP_CTRL_RTLNMUTE               0
> +#define SUN8I_ADDA_PHONEOUT_CTRL                       0x08
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTG             5
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTEN            4
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS3            3
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS2            2
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS1            1
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS0            0
> +#define SUN8I_ADDA_PHONE_GAIN_CTRL                     0x09
> +#define SUN8I_ADDA_PHONE_GAIN_CTRL_PHONEPREG           0
> +#define SUN8I_ADDA_MIC2G_CTRL                          0x0a
> +#define SUN8I_ADDA_MIC2G_CTRL_MIC2AMPEN                7
> +#define SUN8I_ADDA_MIC2G_CTRL_MIC2BOOST                4
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL                  0x0b
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIASEN       7
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MMICBIASEN       6
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIAS_MODE    5
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1AMPEN        3
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1BOOST        0
> +#define SUN8I_ADDA_PA_ANTI_POP_CTRL                    0x0e
> +#define SUN8I_ADDA_ADC_AP_EN                           0x0f
> +
> +/* Analog control register access bits */
> +#define ADDA_PR                                0x0 /* PRCM base + 0x1c0 */
> +#define ADDA_PR_RESET                          BIT(28)
> +#define ADDA_PR_WRITE                          BIT(24)
> +#define ADDA_PR_ADDR_SHIFT                     16
> +#define ADDA_PR_ADDR_MASK                      GENMASK(4, 0)
> +#define ADDA_PR_DATA_IN_SHIFT                  8
> +#define ADDA_PR_DATA_IN_MASK                   GENMASK(7, 0)
> +#define ADDA_PR_DATA_OUT_SHIFT                 0
> +#define ADDA_PR_DATA_OUT_MASK                  GENMASK(7, 0)
> +
> +/* regmap access bits */
> +static int adda_reg_read(void *context, unsigned int reg, unsigned int *val)
> +{
> +       void __iomem *base = context;
> +       u32 tmp;
> +
> +       tmp = readl(base);
> +
> +       /* De-assert reset */
> +       writel(tmp | ADDA_PR_RESET, base);
> +
> +       tmp &= ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT);
> +       tmp |= reg << ADDA_PR_ADDR_SHIFT;
> +       writel(tmp, base);
> +
> +       *val = readl(base) & ADDA_PR_DATA_OUT_MASK;
> +
> +       return 0;
> +}
> +
> +static int adda_reg_write(void *context, unsigned int reg, unsigned int val)
> +{
> +       void __iomem *base = context;
> +       u32 tmp;
> +
> +       tmp = readl(base);
> +       /* De-assert reset */
> +       writel(tmp | ADDA_PR_RESET, base);
> +
> +       /* Write the address */
> +       tmp &= ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT);
> +       tmp |= reg << ADDA_PR_ADDR_SHIFT;
> +       writel(tmp, base);
> +
> +       /* Write the value */
> +       tmp &= ~(ADDA_PR_DATA_IN_MASK << ADDA_PR_DATA_IN_SHIFT);
> +       tmp |= val << ADDA_PR_DATA_IN_SHIFT;
> +       writel(tmp, base);
> +
> +       /* Indicate that the previous value must be written */
> +       writel(readl(base) | ADDA_PR_WRITE, base);
> +
> +       /* Reset the write bit */
> +       writel(readl(base) & ~(ADDA_PR_WRITE), base);
> +
> +       return 0;
> +}
> +
> +struct regmap_config adda_pr_regmap_cfg = {
> +       .name           = "adda-pr",
> +       .reg_bits       = 5,
> +       .reg_stride     = 1,
> +       .val_bits       = 8,
> +       .reg_read       = adda_reg_read,
> +       .reg_write      = adda_reg_write,
> +       .fast_io        = true,
> +       .max_register   = 24,
> +};
> +
> +static DECLARE_TLV_DB_SCALE(sun8i_codec_headphone_volume_scale, -6300, 100, 1);
> +
> +static const struct snd_kcontrol_new sun8i_analog_widgets[] = {
> +       SOC_SINGLE_TLV("Headphone Volume", SUN8I_ADDA_HP_VOLC,
> +                      SUN8I_ADDA_HP_VOLC_HP_VOL, 0x3F, 0,
> +                      sun8i_codec_headphone_volume_scale),
> +
> +       /* Playback Switch */
> +       SOC_DOUBLE("DAC Playback Switch", SUN8I_ADDA_DAC_PA_SRC,
> +                  SUN8I_ADDA_DAC_PA_SRC_DACALEN, SUN8I_ADDA_DAC_PA_SRC_DACAREN,
> +                  1, 0),
> +
> +       SOC_DOUBLE("Headphone Playback Switch", SUN8I_ADDA_DAC_PA_SRC,
> +                  SUN8I_ADDA_DAC_PA_SRC_LHPPAMUTE,
> +                  SUN8I_ADDA_DAC_PA_SRC_RHPPAMUTE, 1, 0),
> +};
> +
> +/* headphone controls */
> +static const char * const sun8i_codec_hp_src_enum_text[] = {
> +       "DAC", "Mixer",
> +};
> +
> +static SOC_ENUM_DOUBLE_DECL(sun8i_codec_hp_src_enum,
> +                           SUN8I_ADDA_DAC_PA_SRC,
> +                           SUN8I_ADDA_DAC_PA_SRC_LHPIS,
> +                           SUN8I_ADDA_DAC_PA_SRC_RHPIS,
> +                           sun8i_codec_hp_src_enum_text);
> +
> +static const struct snd_kcontrol_new sun8i_codec_hp_src[] = {
> +       SOC_DAPM_ENUM("Headphone Source Playback Route",
> +                     sun8i_codec_hp_src_enum),
> +};
> +
> +static const struct snd_kcontrol_new sun8i_codec_mixer_controls[] = {
> +       SOC_DAPM_SINGLE("DAC Left Playback Switch",
> +                       SUN8I_ADDA_LOMIXSC,
> +                       SUN8I_ADDA_LOMIXSC_DACL, 1, 0),
> +       SOC_DAPM_SINGLE("DAC Right Playback Switch",
> +                       SUN8I_ADDA_ROMIXSC,
> +                       SUN8I_ADDA_ROMIXSC_DACR, 1, 0),
> +       SOC_DAPM_SINGLE("DAC Reversed Left Playback Switch",
> +                       SUN8I_ADDA_LOMIXSC,
> +                       SUN8I_ADDA_LOMIXSC_DACR, 1, 0),
> +       SOC_DAPM_SINGLE("DAC Reversed Right Playback Switch",
> +                       SUN8I_ADDA_ROMIXSC,
> +                       SUN8I_ADDA_ROMIXSC_DACL, 1, 0),
> +};
> +
> +static const struct snd_soc_dapm_widget sun8i_codec_analog_dapm_widgets[] = {
> +       /* Mixers */
> +       SOC_MIXER_ARRAY("Left Mixer", SUN8I_ADDA_DAC_PA_SRC,
> +                       SUN8I_ADDA_DAC_PA_SRC_LMIXEN, 0,
> +                       sun8i_codec_mixer_controls),
> +       SOC_MIXER_ARRAY("Right Mixer", SUN8I_ADDA_DAC_PA_SRC,
> +                       SUN8I_ADDA_DAC_PA_SRC_RMIXEN, 0,
> +                       sun8i_codec_mixer_controls),
> +
> +       /* Headphone output path */
> +       SND_SOC_DAPM_MUX("Headphone Source Playback Route",
> +                        SND_SOC_NOPM, 0, 0, sun8i_codec_hp_src),
> +       SND_SOC_DAPM_OUT_DRV("Headphone Amp", SUN8I_ADDA_PAEN_HP_CTRL,
> +                            SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN, 0, NULL, 0),
> +
> +       /* Headphone outputs */
> +       SND_SOC_DAPM_OUTPUT("HP"),
> +
> +};
> +
> +static const struct snd_soc_dapm_route sun8i_codec_analog_dapm_routes[] = {
> +       /* Left Mixer Routes */
> +       { "Left Mixer", "DAC Playback Switch", "Left DAC" },
> +       { "Left Mixer", "DAC Reversed Left Playback Switch", "Right DAC" },
> +
> +       /* Right Mixer Routes */
> +       { "Right Mixer", "DAC Playback Switch", "Right DAC" },
> +       { "Right Mixer", "DAC Reversed Right Playback Switch", "Left DAC" },
> +
> +       /* Headphone Routes */
> +       { "Headphone Source Playback Route", "DAC", "Left DAC" },
> +       { "Headphone Source Playback Route", "DAC", "Right DAC" },
> +       { "Headphone Source Playback Route", "Mixer", "Left Mixer" },
> +       { "Headphone Source Playback Route", "Mixer", "Right Mixer" },
> +       { "Headphone Amp", NULL, "Headphone Source Playback Route" },
> +       { "HP", NULL, "Headphone Amp" },
> +};
> +
> +static const struct snd_soc_component_driver sun8i_codec_analog_cmpnt_drv = {
> +       .name                   = "sun8i-codec-analog",
> +       .controls               = sun8i_analog_widgets,
> +       .num_controls           = ARRAY_SIZE(sun8i_analog_widgets),
> +       .dapm_widgets           = sun8i_codec_analog_dapm_widgets,
> +       .num_dapm_widgets       = ARRAY_SIZE(sun8i_codec_analog_dapm_widgets),
> +       .dapm_routes            = sun8i_codec_analog_dapm_routes,
> +       .num_dapm_routes        = ARRAY_SIZE(sun8i_codec_analog_dapm_routes),
> +};
> +
> +static const struct of_device_id sun8i_codec_analog_of_match[] = {
> +       { .compatible = "allwinner,sun8i-codec-analog", },
> +       {}
> +};
> +MODULE_DEVICE_TABLE(of, sun8i_codec_analog_of_match);
> +
> +static int sun8i_codec_analog_probe(struct platform_device *pdev)
> +{
> +       struct resource *res;
> +       struct regmap *regmap;
> +       void __iomem *base;
> +
> +       /* Get PRCM resources and registers */
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       base = devm_ioremap_resource(&pdev->dev, res);
> +       if (IS_ERR(base)) {
> +               dev_err(&pdev->dev, "Failed to map PRCM registers\n");
> +               return PTR_ERR(base);
> +       }
> +
> +       regmap = devm_regmap_init(&pdev->dev, NULL, base, &adda_pr_regmap_cfg);
> +       if (IS_ERR(regmap)) {
> +               dev_err(&pdev->dev, "Regmap initialisation failed\n");
> +               return PTR_ERR(regmap);
> +       }
> +
> +       return devm_snd_soc_register_component(&pdev->dev,
> +                                              &sun8i_codec_analog_cmpnt_drv,
> +                                              NULL, 0);
> +}
> +
> +static struct platform_driver sun8i_codec_analog_driver = {
> +       .driver = {
> +               .name = "sun8i-codec-analog",
> +               .of_match_table = sun8i_codec_analog_of_match,
> +       },
> +       .probe = sun8i_codec_analog_probe,
> +};
> +module_platform_driver(sun8i_codec_analog_driver);
> +
> +MODULE_DESCRIPTION("Allwinner A31s/A33/A23 codec analog controls driver");
Does the A31s have the prcm for the codec?, as I was under the
impression that it was the same as the A31 and I can't seem to find a
datasheet for that SoC. You could also add H3 and A64 here.
CK
> +MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
> +MODULE_AUTHOR("Mylène Josserand <mylene.josserand@free-electrons.com>");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:sun8i-codec-analog");
> --
> 2.9.3
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 04/14] ASoC: Add sun8i analog codec driver
@ 2016-10-04 10:21       ` Code Kipper
  0 siblings, 0 replies; 170+ messages in thread
From: Code Kipper @ 2016-10-04 10:21 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul-ral2JQCrhuEAvxtiuMwx3w, Maxime Ripard, Chen-Yu Tsai,
	mturquette-rdvid1DuHRBWk0Htik3J/w, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
	Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai,
	Lee Jones, mark.rutland-5wv7dgnIgG8, Rob Herring,
	thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8, devicetree,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, linux-sunxi,
	alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA, linux-arm-kernel

On 4 October 2016 at 11:46, Mylène Josserand
<mylene.josserand-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> Add the analog part of the sun8i (A33) codec driver. This driver
> implements all the analog part of the codec using PRCM registers.
>
> The read/write regmap functions must be handled in a custom way as
> the PRCM register behaves as "mailbox" register.
>
> Signed-off-by: Mylène Josserand <mylene.josserand-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> ---
>  sound/soc/sunxi/Kconfig              |   7 +
>  sound/soc/sunxi/Makefile             |   1 +
>  sound/soc/sunxi/sun8i-codec-analog.c | 304 +++++++++++++++++++++++++++++++++++
>  3 files changed, 312 insertions(+)
>  create mode 100644 sound/soc/sunxi/sun8i-codec-analog.c
>
> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
> index dd23682..7aee95a 100644
> --- a/sound/soc/sunxi/Kconfig
> +++ b/sound/soc/sunxi/Kconfig
> @@ -26,4 +26,11 @@ config SND_SUN4I_SPDIF
>         help
>           Say Y or M to add support for the S/PDIF audio block in the Allwinner
>           A10 and affiliated SoCs.
> +
> +config SND_SUN8I_CODEC_ANALOG
> +       tristate "Allwinner SUN8I analog codec"
> +       select REGMAP_MMIO
> +        help
> +         Say Y or M if you want to add sun8i analog audiocodec support
> +
>  endmenu
> diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
> index 604c7b84..241c0df 100644
> --- a/sound/soc/sunxi/Makefile
> +++ b/sound/soc/sunxi/Makefile
> @@ -1,3 +1,4 @@
>  obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
>  obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
>  obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
> +obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
> diff --git a/sound/soc/sunxi/sun8i-codec-analog.c b/sound/soc/sunxi/sun8i-codec-analog.c
> new file mode 100644
> index 0000000..be3d540
> --- /dev/null
> +++ b/sound/soc/sunxi/sun8i-codec-analog.c
> @@ -0,0 +1,304 @@
> +/*
> + * This driver supports the analog controls for the internal codec
> + * found in Allwinner's A31s, A33 and A23 SoCs.
> + *
> + * Copyright 2016 Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
> + * Copyright 2016 Mylène Josserand <mylene.josserand@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/io.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +
> +#include <sound/soc.h>
> +#include <sound/soc-dapm.h>
> +#include <sound/tlv.h>
> +
> +/* Codec analog control register offsets and bit fields */
> +#define SUN8I_ADDA_HP_VOLC                             0x00
> +#define SUN8I_ADDA_HP_VOLC_PA_CLK_GATE                 7
> +#define SUN8I_ADDA_HP_VOLC_HP_VOL                      0
> +#define SUN8I_ADDA_LOMIXSC                             0x01
> +#define SUN8I_ADDA_LOMIXSC_MIC1                        6
> +#define SUN8I_ADDA_LOMIXSC_MIC2                        5
> +#define SUN8I_ADDA_LOMIXSC_PHONE                       4
> +#define SUN8I_ADDA_LOMIXSC_PHONEN                      3
> +#define SUN8I_ADDA_LOMIXSC_LINEINL                     2
> +#define SUN8I_ADDA_LOMIXSC_DACL                        1
> +#define SUN8I_ADDA_LOMIXSC_DACR                        0
> +#define SUN8I_ADDA_ROMIXSC                             0x02
> +#define SUN8I_ADDA_ROMIXSC_MIC1                        6
> +#define SUN8I_ADDA_ROMIXSC_MIC2                        5
> +#define SUN8I_ADDA_ROMIXSC_PHONE                       4
> +#define SUN8I_ADDA_ROMIXSC_PHONEP                      3
> +#define SUN8I_ADDA_ROMIXSC_LINEINR                     2
> +#define SUN8I_ADDA_ROMIXSC_DACR                        1
> +#define SUN8I_ADDA_ROMIXSC_DACL                        0
> +#define SUN8I_ADDA_DAC_PA_SRC                          0x03
> +#define SUN8I_ADDA_DAC_PA_SRC_DACAREN                  7
> +#define SUN8I_ADDA_DAC_PA_SRC_DACALEN                  6
> +#define SUN8I_ADDA_DAC_PA_SRC_RMIXEN                   5
> +#define SUN8I_ADDA_DAC_PA_SRC_LMIXEN                   4
> +#define SUN8I_ADDA_DAC_PA_SRC_RHPPAMUTE                3
> +#define SUN8I_ADDA_DAC_PA_SRC_LHPPAMUTE                2
> +#define SUN8I_ADDA_DAC_PA_SRC_RHPIS                    1
> +#define SUN8I_ADDA_DAC_PA_SRC_LHPIS                    0
> +#define SUN8I_ADDA_PHONEIN_GCTRL                       0x04
> +#define SUN8I_ADDA_PHONEIN_GCTRL_PHONEPG               4
> +#define SUN8I_ADDA_PHONEIN_GCTRL_PHONENG               0
> +#define SUN8I_ADDA_LINEIN_GCTRL                        0x05
> +#define SUN8I_ADDA_LINEIN_GCTRL_LINEING                4
> +#define SUN8I_ADDA_LINEIN_GCTRL_PHONEG                 0
> +#define SUN8I_ADDA_MICIN_GCTRL                         0x06
> +#define SUN8I_ADDA_MICIN_GCTRL_MIC1G                   4
> +#define SUN8I_ADDA_MICIN_GCTRL_MIC2G                   0
> +#define SUN8I_ADDA_PAEN_HP_CTRL                        0x07
> +#define SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN                 7
> +#define SUN8I_ADDA_PAEN_HP_CTRL_HPCOM_FC               5
> +#define SUN8I_ADDA_PAEN_HP_CTRL_COMPTEN                4
> +#define SUN8I_ADDA_PAEN_HP_CTRL_PA_ANTI_POP_CTRL       2
> +#define SUN8I_ADDA_PAEN_HP_CTRL_LTRNMUTE               1
> +#define SUN8I_ADDA_PAEN_HP_CTRL_RTLNMUTE               0
> +#define SUN8I_ADDA_PHONEOUT_CTRL                       0x08
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTG             5
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTEN            4
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS3            3
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS2            2
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS1            1
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS0            0
> +#define SUN8I_ADDA_PHONE_GAIN_CTRL                     0x09
> +#define SUN8I_ADDA_PHONE_GAIN_CTRL_PHONEPREG           0
> +#define SUN8I_ADDA_MIC2G_CTRL                          0x0a
> +#define SUN8I_ADDA_MIC2G_CTRL_MIC2AMPEN                7
> +#define SUN8I_ADDA_MIC2G_CTRL_MIC2BOOST                4
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL                  0x0b
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIASEN       7
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MMICBIASEN       6
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIAS_MODE    5
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1AMPEN        3
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1BOOST        0
> +#define SUN8I_ADDA_PA_ANTI_POP_CTRL                    0x0e
> +#define SUN8I_ADDA_ADC_AP_EN                           0x0f
> +
> +/* Analog control register access bits */
> +#define ADDA_PR                                0x0 /* PRCM base + 0x1c0 */
> +#define ADDA_PR_RESET                          BIT(28)
> +#define ADDA_PR_WRITE                          BIT(24)
> +#define ADDA_PR_ADDR_SHIFT                     16
> +#define ADDA_PR_ADDR_MASK                      GENMASK(4, 0)
> +#define ADDA_PR_DATA_IN_SHIFT                  8
> +#define ADDA_PR_DATA_IN_MASK                   GENMASK(7, 0)
> +#define ADDA_PR_DATA_OUT_SHIFT                 0
> +#define ADDA_PR_DATA_OUT_MASK                  GENMASK(7, 0)
> +
> +/* regmap access bits */
> +static int adda_reg_read(void *context, unsigned int reg, unsigned int *val)
> +{
> +       void __iomem *base = context;
> +       u32 tmp;
> +
> +       tmp = readl(base);
> +
> +       /* De-assert reset */
> +       writel(tmp | ADDA_PR_RESET, base);
> +
> +       tmp &= ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT);
> +       tmp |= reg << ADDA_PR_ADDR_SHIFT;
> +       writel(tmp, base);
> +
> +       *val = readl(base) & ADDA_PR_DATA_OUT_MASK;
> +
> +       return 0;
> +}
> +
> +static int adda_reg_write(void *context, unsigned int reg, unsigned int val)
> +{
> +       void __iomem *base = context;
> +       u32 tmp;
> +
> +       tmp = readl(base);
> +       /* De-assert reset */
> +       writel(tmp | ADDA_PR_RESET, base);
> +
> +       /* Write the address */
> +       tmp &= ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT);
> +       tmp |= reg << ADDA_PR_ADDR_SHIFT;
> +       writel(tmp, base);
> +
> +       /* Write the value */
> +       tmp &= ~(ADDA_PR_DATA_IN_MASK << ADDA_PR_DATA_IN_SHIFT);
> +       tmp |= val << ADDA_PR_DATA_IN_SHIFT;
> +       writel(tmp, base);
> +
> +       /* Indicate that the previous value must be written */
> +       writel(readl(base) | ADDA_PR_WRITE, base);
> +
> +       /* Reset the write bit */
> +       writel(readl(base) & ~(ADDA_PR_WRITE), base);
> +
> +       return 0;
> +}
> +
> +struct regmap_config adda_pr_regmap_cfg = {
> +       .name           = "adda-pr",
> +       .reg_bits       = 5,
> +       .reg_stride     = 1,
> +       .val_bits       = 8,
> +       .reg_read       = adda_reg_read,
> +       .reg_write      = adda_reg_write,
> +       .fast_io        = true,
> +       .max_register   = 24,
> +};
> +
> +static DECLARE_TLV_DB_SCALE(sun8i_codec_headphone_volume_scale, -6300, 100, 1);
> +
> +static const struct snd_kcontrol_new sun8i_analog_widgets[] = {
> +       SOC_SINGLE_TLV("Headphone Volume", SUN8I_ADDA_HP_VOLC,
> +                      SUN8I_ADDA_HP_VOLC_HP_VOL, 0x3F, 0,
> +                      sun8i_codec_headphone_volume_scale),
> +
> +       /* Playback Switch */
> +       SOC_DOUBLE("DAC Playback Switch", SUN8I_ADDA_DAC_PA_SRC,
> +                  SUN8I_ADDA_DAC_PA_SRC_DACALEN, SUN8I_ADDA_DAC_PA_SRC_DACAREN,
> +                  1, 0),
> +
> +       SOC_DOUBLE("Headphone Playback Switch", SUN8I_ADDA_DAC_PA_SRC,
> +                  SUN8I_ADDA_DAC_PA_SRC_LHPPAMUTE,
> +                  SUN8I_ADDA_DAC_PA_SRC_RHPPAMUTE, 1, 0),
> +};
> +
> +/* headphone controls */
> +static const char * const sun8i_codec_hp_src_enum_text[] = {
> +       "DAC", "Mixer",
> +};
> +
> +static SOC_ENUM_DOUBLE_DECL(sun8i_codec_hp_src_enum,
> +                           SUN8I_ADDA_DAC_PA_SRC,
> +                           SUN8I_ADDA_DAC_PA_SRC_LHPIS,
> +                           SUN8I_ADDA_DAC_PA_SRC_RHPIS,
> +                           sun8i_codec_hp_src_enum_text);
> +
> +static const struct snd_kcontrol_new sun8i_codec_hp_src[] = {
> +       SOC_DAPM_ENUM("Headphone Source Playback Route",
> +                     sun8i_codec_hp_src_enum),
> +};
> +
> +static const struct snd_kcontrol_new sun8i_codec_mixer_controls[] = {
> +       SOC_DAPM_SINGLE("DAC Left Playback Switch",
> +                       SUN8I_ADDA_LOMIXSC,
> +                       SUN8I_ADDA_LOMIXSC_DACL, 1, 0),
> +       SOC_DAPM_SINGLE("DAC Right Playback Switch",
> +                       SUN8I_ADDA_ROMIXSC,
> +                       SUN8I_ADDA_ROMIXSC_DACR, 1, 0),
> +       SOC_DAPM_SINGLE("DAC Reversed Left Playback Switch",
> +                       SUN8I_ADDA_LOMIXSC,
> +                       SUN8I_ADDA_LOMIXSC_DACR, 1, 0),
> +       SOC_DAPM_SINGLE("DAC Reversed Right Playback Switch",
> +                       SUN8I_ADDA_ROMIXSC,
> +                       SUN8I_ADDA_ROMIXSC_DACL, 1, 0),
> +};
> +
> +static const struct snd_soc_dapm_widget sun8i_codec_analog_dapm_widgets[] = {
> +       /* Mixers */
> +       SOC_MIXER_ARRAY("Left Mixer", SUN8I_ADDA_DAC_PA_SRC,
> +                       SUN8I_ADDA_DAC_PA_SRC_LMIXEN, 0,
> +                       sun8i_codec_mixer_controls),
> +       SOC_MIXER_ARRAY("Right Mixer", SUN8I_ADDA_DAC_PA_SRC,
> +                       SUN8I_ADDA_DAC_PA_SRC_RMIXEN, 0,
> +                       sun8i_codec_mixer_controls),
> +
> +       /* Headphone output path */
> +       SND_SOC_DAPM_MUX("Headphone Source Playback Route",
> +                        SND_SOC_NOPM, 0, 0, sun8i_codec_hp_src),
> +       SND_SOC_DAPM_OUT_DRV("Headphone Amp", SUN8I_ADDA_PAEN_HP_CTRL,
> +                            SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN, 0, NULL, 0),
> +
> +       /* Headphone outputs */
> +       SND_SOC_DAPM_OUTPUT("HP"),
> +
> +};
> +
> +static const struct snd_soc_dapm_route sun8i_codec_analog_dapm_routes[] = {
> +       /* Left Mixer Routes */
> +       { "Left Mixer", "DAC Playback Switch", "Left DAC" },
> +       { "Left Mixer", "DAC Reversed Left Playback Switch", "Right DAC" },
> +
> +       /* Right Mixer Routes */
> +       { "Right Mixer", "DAC Playback Switch", "Right DAC" },
> +       { "Right Mixer", "DAC Reversed Right Playback Switch", "Left DAC" },
> +
> +       /* Headphone Routes */
> +       { "Headphone Source Playback Route", "DAC", "Left DAC" },
> +       { "Headphone Source Playback Route", "DAC", "Right DAC" },
> +       { "Headphone Source Playback Route", "Mixer", "Left Mixer" },
> +       { "Headphone Source Playback Route", "Mixer", "Right Mixer" },
> +       { "Headphone Amp", NULL, "Headphone Source Playback Route" },
> +       { "HP", NULL, "Headphone Amp" },
> +};
> +
> +static const struct snd_soc_component_driver sun8i_codec_analog_cmpnt_drv = {
> +       .name                   = "sun8i-codec-analog",
> +       .controls               = sun8i_analog_widgets,
> +       .num_controls           = ARRAY_SIZE(sun8i_analog_widgets),
> +       .dapm_widgets           = sun8i_codec_analog_dapm_widgets,
> +       .num_dapm_widgets       = ARRAY_SIZE(sun8i_codec_analog_dapm_widgets),
> +       .dapm_routes            = sun8i_codec_analog_dapm_routes,
> +       .num_dapm_routes        = ARRAY_SIZE(sun8i_codec_analog_dapm_routes),
> +};
> +
> +static const struct of_device_id sun8i_codec_analog_of_match[] = {
> +       { .compatible = "allwinner,sun8i-codec-analog", },
> +       {}
> +};
> +MODULE_DEVICE_TABLE(of, sun8i_codec_analog_of_match);
> +
> +static int sun8i_codec_analog_probe(struct platform_device *pdev)
> +{
> +       struct resource *res;
> +       struct regmap *regmap;
> +       void __iomem *base;
> +
> +       /* Get PRCM resources and registers */
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       base = devm_ioremap_resource(&pdev->dev, res);
> +       if (IS_ERR(base)) {
> +               dev_err(&pdev->dev, "Failed to map PRCM registers\n");
> +               return PTR_ERR(base);
> +       }
> +
> +       regmap = devm_regmap_init(&pdev->dev, NULL, base, &adda_pr_regmap_cfg);
> +       if (IS_ERR(regmap)) {
> +               dev_err(&pdev->dev, "Regmap initialisation failed\n");
> +               return PTR_ERR(regmap);
> +       }
> +
> +       return devm_snd_soc_register_component(&pdev->dev,
> +                                              &sun8i_codec_analog_cmpnt_drv,
> +                                              NULL, 0);
> +}
> +
> +static struct platform_driver sun8i_codec_analog_driver = {
> +       .driver = {
> +               .name = "sun8i-codec-analog",
> +               .of_match_table = sun8i_codec_analog_of_match,
> +       },
> +       .probe = sun8i_codec_analog_probe,
> +};
> +module_platform_driver(sun8i_codec_analog_driver);
> +
> +MODULE_DESCRIPTION("Allwinner A31s/A33/A23 codec analog controls driver");
Does the A31s have the prcm for the codec?, as I was under the
impression that it was the same as the A31 and I can't seem to find a
datasheet for that SoC. You could also add H3 and A64 here.
CK
> +MODULE_AUTHOR("Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>");
> +MODULE_AUTHOR("Mylène Josserand <mylene.josserand-wi1+55ScJUtKEb57/3fJTGGXanvQGlWp@public.gmane.orgm>");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:sun8i-codec-analog");
> --
> 2.9.3
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

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

* Re: [PATCH 04/14] ASoC: Add sun8i analog codec driver
@ 2016-10-04 10:21       ` Code Kipper
  0 siblings, 0 replies; 170+ messages in thread
From: Code Kipper @ 2016-10-04 10:21 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul, Maxime Ripard, Chen-Yu Tsai, mturquette, sboyd,
	Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai,
	Lee Jones, mark.rutland, Rob Herring, thomas.petazzoni,
	devicetree, alsa-devel, linux-kernel, linux-sunxi,
	alexandre.belloni, dmaengine, linux-clk, linux-arm-kernel

On 4 October 2016 at 11:46, Myl=C3=A8ne Josserand
<mylene.josserand@free-electrons.com> wrote:
> Add the analog part of the sun8i (A33) codec driver. This driver
> implements all the analog part of the codec using PRCM registers.
>
> The read/write regmap functions must be handled in a custom way as
> the PRCM register behaves as "mailbox" register.
>
> Signed-off-by: Myl=C3=A8ne Josserand <mylene.josserand@free-electrons.com=
>
> ---
>  sound/soc/sunxi/Kconfig              |   7 +
>  sound/soc/sunxi/Makefile             |   1 +
>  sound/soc/sunxi/sun8i-codec-analog.c | 304 +++++++++++++++++++++++++++++=
++++++
>  3 files changed, 312 insertions(+)
>  create mode 100644 sound/soc/sunxi/sun8i-codec-analog.c
>
> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
> index dd23682..7aee95a 100644
> --- a/sound/soc/sunxi/Kconfig
> +++ b/sound/soc/sunxi/Kconfig
> @@ -26,4 +26,11 @@ config SND_SUN4I_SPDIF
>         help
>           Say Y or M to add support for the S/PDIF audio block in the All=
winner
>           A10 and affiliated SoCs.
> +
> +config SND_SUN8I_CODEC_ANALOG
> +       tristate "Allwinner SUN8I analog codec"
> +       select REGMAP_MMIO
> +        help
> +         Say Y or M if you want to add sun8i analog audiocodec support
> +
>  endmenu
> diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
> index 604c7b84..241c0df 100644
> --- a/sound/soc/sunxi/Makefile
> +++ b/sound/soc/sunxi/Makefile
> @@ -1,3 +1,4 @@
>  obj-$(CONFIG_SND_SUN4I_CODEC) +=3D sun4i-codec.o
>  obj-$(CONFIG_SND_SUN4I_I2S) +=3D sun4i-i2s.o
>  obj-$(CONFIG_SND_SUN4I_SPDIF) +=3D sun4i-spdif.o
> +obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) +=3D sun8i-codec-analog.o
> diff --git a/sound/soc/sunxi/sun8i-codec-analog.c b/sound/soc/sunxi/sun8i=
-codec-analog.c
> new file mode 100644
> index 0000000..be3d540
> --- /dev/null
> +++ b/sound/soc/sunxi/sun8i-codec-analog.c
> @@ -0,0 +1,304 @@
> +/*
> + * This driver supports the analog controls for the internal codec
> + * found in Allwinner's A31s, A33 and A23 SoCs.
> + *
> + * Copyright 2016 Chen-Yu Tsai <wens@csie.org>
> + * Copyright 2016 Myl=C3=A8ne Josserand <mylene.josserand@free-electrons=
.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/io.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +
> +#include <sound/soc.h>
> +#include <sound/soc-dapm.h>
> +#include <sound/tlv.h>
> +
> +/* Codec analog control register offsets and bit fields */
> +#define SUN8I_ADDA_HP_VOLC                             0x00
> +#define SUN8I_ADDA_HP_VOLC_PA_CLK_GATE                 7
> +#define SUN8I_ADDA_HP_VOLC_HP_VOL                      0
> +#define SUN8I_ADDA_LOMIXSC                             0x01
> +#define SUN8I_ADDA_LOMIXSC_MIC1                        6
> +#define SUN8I_ADDA_LOMIXSC_MIC2                        5
> +#define SUN8I_ADDA_LOMIXSC_PHONE                       4
> +#define SUN8I_ADDA_LOMIXSC_PHONEN                      3
> +#define SUN8I_ADDA_LOMIXSC_LINEINL                     2
> +#define SUN8I_ADDA_LOMIXSC_DACL                        1
> +#define SUN8I_ADDA_LOMIXSC_DACR                        0
> +#define SUN8I_ADDA_ROMIXSC                             0x02
> +#define SUN8I_ADDA_ROMIXSC_MIC1                        6
> +#define SUN8I_ADDA_ROMIXSC_MIC2                        5
> +#define SUN8I_ADDA_ROMIXSC_PHONE                       4
> +#define SUN8I_ADDA_ROMIXSC_PHONEP                      3
> +#define SUN8I_ADDA_ROMIXSC_LINEINR                     2
> +#define SUN8I_ADDA_ROMIXSC_DACR                        1
> +#define SUN8I_ADDA_ROMIXSC_DACL                        0
> +#define SUN8I_ADDA_DAC_PA_SRC                          0x03
> +#define SUN8I_ADDA_DAC_PA_SRC_DACAREN                  7
> +#define SUN8I_ADDA_DAC_PA_SRC_DACALEN                  6
> +#define SUN8I_ADDA_DAC_PA_SRC_RMIXEN                   5
> +#define SUN8I_ADDA_DAC_PA_SRC_LMIXEN                   4
> +#define SUN8I_ADDA_DAC_PA_SRC_RHPPAMUTE                3
> +#define SUN8I_ADDA_DAC_PA_SRC_LHPPAMUTE                2
> +#define SUN8I_ADDA_DAC_PA_SRC_RHPIS                    1
> +#define SUN8I_ADDA_DAC_PA_SRC_LHPIS                    0
> +#define SUN8I_ADDA_PHONEIN_GCTRL                       0x04
> +#define SUN8I_ADDA_PHONEIN_GCTRL_PHONEPG               4
> +#define SUN8I_ADDA_PHONEIN_GCTRL_PHONENG               0
> +#define SUN8I_ADDA_LINEIN_GCTRL                        0x05
> +#define SUN8I_ADDA_LINEIN_GCTRL_LINEING                4
> +#define SUN8I_ADDA_LINEIN_GCTRL_PHONEG                 0
> +#define SUN8I_ADDA_MICIN_GCTRL                         0x06
> +#define SUN8I_ADDA_MICIN_GCTRL_MIC1G                   4
> +#define SUN8I_ADDA_MICIN_GCTRL_MIC2G                   0
> +#define SUN8I_ADDA_PAEN_HP_CTRL                        0x07
> +#define SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN                 7
> +#define SUN8I_ADDA_PAEN_HP_CTRL_HPCOM_FC               5
> +#define SUN8I_ADDA_PAEN_HP_CTRL_COMPTEN                4
> +#define SUN8I_ADDA_PAEN_HP_CTRL_PA_ANTI_POP_CTRL       2
> +#define SUN8I_ADDA_PAEN_HP_CTRL_LTRNMUTE               1
> +#define SUN8I_ADDA_PAEN_HP_CTRL_RTLNMUTE               0
> +#define SUN8I_ADDA_PHONEOUT_CTRL                       0x08
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTG             5
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTEN            4
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS3            3
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS2            2
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS1            1
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS0            0
> +#define SUN8I_ADDA_PHONE_GAIN_CTRL                     0x09
> +#define SUN8I_ADDA_PHONE_GAIN_CTRL_PHONEPREG           0
> +#define SUN8I_ADDA_MIC2G_CTRL                          0x0a
> +#define SUN8I_ADDA_MIC2G_CTRL_MIC2AMPEN                7
> +#define SUN8I_ADDA_MIC2G_CTRL_MIC2BOOST                4
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL                  0x0b
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIASEN       7
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MMICBIASEN       6
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIAS_MODE    5
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1AMPEN        3
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1BOOST        0
> +#define SUN8I_ADDA_PA_ANTI_POP_CTRL                    0x0e
> +#define SUN8I_ADDA_ADC_AP_EN                           0x0f
> +
> +/* Analog control register access bits */
> +#define ADDA_PR                                0x0 /* PRCM base + 0x1c0 =
*/
> +#define ADDA_PR_RESET                          BIT(28)
> +#define ADDA_PR_WRITE                          BIT(24)
> +#define ADDA_PR_ADDR_SHIFT                     16
> +#define ADDA_PR_ADDR_MASK                      GENMASK(4, 0)
> +#define ADDA_PR_DATA_IN_SHIFT                  8
> +#define ADDA_PR_DATA_IN_MASK                   GENMASK(7, 0)
> +#define ADDA_PR_DATA_OUT_SHIFT                 0
> +#define ADDA_PR_DATA_OUT_MASK                  GENMASK(7, 0)
> +
> +/* regmap access bits */
> +static int adda_reg_read(void *context, unsigned int reg, unsigned int *=
val)
> +{
> +       void __iomem *base =3D context;
> +       u32 tmp;
> +
> +       tmp =3D readl(base);
> +
> +       /* De-assert reset */
> +       writel(tmp | ADDA_PR_RESET, base);
> +
> +       tmp &=3D ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT);
> +       tmp |=3D reg << ADDA_PR_ADDR_SHIFT;
> +       writel(tmp, base);
> +
> +       *val =3D readl(base) & ADDA_PR_DATA_OUT_MASK;
> +
> +       return 0;
> +}
> +
> +static int adda_reg_write(void *context, unsigned int reg, unsigned int =
val)
> +{
> +       void __iomem *base =3D context;
> +       u32 tmp;
> +
> +       tmp =3D readl(base);
> +       /* De-assert reset */
> +       writel(tmp | ADDA_PR_RESET, base);
> +
> +       /* Write the address */
> +       tmp &=3D ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT);
> +       tmp |=3D reg << ADDA_PR_ADDR_SHIFT;
> +       writel(tmp, base);
> +
> +       /* Write the value */
> +       tmp &=3D ~(ADDA_PR_DATA_IN_MASK << ADDA_PR_DATA_IN_SHIFT);
> +       tmp |=3D val << ADDA_PR_DATA_IN_SHIFT;
> +       writel(tmp, base);
> +
> +       /* Indicate that the previous value must be written */
> +       writel(readl(base) | ADDA_PR_WRITE, base);
> +
> +       /* Reset the write bit */
> +       writel(readl(base) & ~(ADDA_PR_WRITE), base);
> +
> +       return 0;
> +}
> +
> +struct regmap_config adda_pr_regmap_cfg =3D {
> +       .name           =3D "adda-pr",
> +       .reg_bits       =3D 5,
> +       .reg_stride     =3D 1,
> +       .val_bits       =3D 8,
> +       .reg_read       =3D adda_reg_read,
> +       .reg_write      =3D adda_reg_write,
> +       .fast_io        =3D true,
> +       .max_register   =3D 24,
> +};
> +
> +static DECLARE_TLV_DB_SCALE(sun8i_codec_headphone_volume_scale, -6300, 1=
00, 1);
> +
> +static const struct snd_kcontrol_new sun8i_analog_widgets[] =3D {
> +       SOC_SINGLE_TLV("Headphone Volume", SUN8I_ADDA_HP_VOLC,
> +                      SUN8I_ADDA_HP_VOLC_HP_VOL, 0x3F, 0,
> +                      sun8i_codec_headphone_volume_scale),
> +
> +       /* Playback Switch */
> +       SOC_DOUBLE("DAC Playback Switch", SUN8I_ADDA_DAC_PA_SRC,
> +                  SUN8I_ADDA_DAC_PA_SRC_DACALEN, SUN8I_ADDA_DAC_PA_SRC_D=
ACAREN,
> +                  1, 0),
> +
> +       SOC_DOUBLE("Headphone Playback Switch", SUN8I_ADDA_DAC_PA_SRC,
> +                  SUN8I_ADDA_DAC_PA_SRC_LHPPAMUTE,
> +                  SUN8I_ADDA_DAC_PA_SRC_RHPPAMUTE, 1, 0),
> +};
> +
> +/* headphone controls */
> +static const char * const sun8i_codec_hp_src_enum_text[] =3D {
> +       "DAC", "Mixer",
> +};
> +
> +static SOC_ENUM_DOUBLE_DECL(sun8i_codec_hp_src_enum,
> +                           SUN8I_ADDA_DAC_PA_SRC,
> +                           SUN8I_ADDA_DAC_PA_SRC_LHPIS,
> +                           SUN8I_ADDA_DAC_PA_SRC_RHPIS,
> +                           sun8i_codec_hp_src_enum_text);
> +
> +static const struct snd_kcontrol_new sun8i_codec_hp_src[] =3D {
> +       SOC_DAPM_ENUM("Headphone Source Playback Route",
> +                     sun8i_codec_hp_src_enum),
> +};
> +
> +static const struct snd_kcontrol_new sun8i_codec_mixer_controls[] =3D {
> +       SOC_DAPM_SINGLE("DAC Left Playback Switch",
> +                       SUN8I_ADDA_LOMIXSC,
> +                       SUN8I_ADDA_LOMIXSC_DACL, 1, 0),
> +       SOC_DAPM_SINGLE("DAC Right Playback Switch",
> +                       SUN8I_ADDA_ROMIXSC,
> +                       SUN8I_ADDA_ROMIXSC_DACR, 1, 0),
> +       SOC_DAPM_SINGLE("DAC Reversed Left Playback Switch",
> +                       SUN8I_ADDA_LOMIXSC,
> +                       SUN8I_ADDA_LOMIXSC_DACR, 1, 0),
> +       SOC_DAPM_SINGLE("DAC Reversed Right Playback Switch",
> +                       SUN8I_ADDA_ROMIXSC,
> +                       SUN8I_ADDA_ROMIXSC_DACL, 1, 0),
> +};
> +
> +static const struct snd_soc_dapm_widget sun8i_codec_analog_dapm_widgets[=
] =3D {
> +       /* Mixers */
> +       SOC_MIXER_ARRAY("Left Mixer", SUN8I_ADDA_DAC_PA_SRC,
> +                       SUN8I_ADDA_DAC_PA_SRC_LMIXEN, 0,
> +                       sun8i_codec_mixer_controls),
> +       SOC_MIXER_ARRAY("Right Mixer", SUN8I_ADDA_DAC_PA_SRC,
> +                       SUN8I_ADDA_DAC_PA_SRC_RMIXEN, 0,
> +                       sun8i_codec_mixer_controls),
> +
> +       /* Headphone output path */
> +       SND_SOC_DAPM_MUX("Headphone Source Playback Route",
> +                        SND_SOC_NOPM, 0, 0, sun8i_codec_hp_src),
> +       SND_SOC_DAPM_OUT_DRV("Headphone Amp", SUN8I_ADDA_PAEN_HP_CTRL,
> +                            SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN, 0, NULL, 0),
> +
> +       /* Headphone outputs */
> +       SND_SOC_DAPM_OUTPUT("HP"),
> +
> +};
> +
> +static const struct snd_soc_dapm_route sun8i_codec_analog_dapm_routes[] =
=3D {
> +       /* Left Mixer Routes */
> +       { "Left Mixer", "DAC Playback Switch", "Left DAC" },
> +       { "Left Mixer", "DAC Reversed Left Playback Switch", "Right DAC" =
},
> +
> +       /* Right Mixer Routes */
> +       { "Right Mixer", "DAC Playback Switch", "Right DAC" },
> +       { "Right Mixer", "DAC Reversed Right Playback Switch", "Left DAC"=
 },
> +
> +       /* Headphone Routes */
> +       { "Headphone Source Playback Route", "DAC", "Left DAC" },
> +       { "Headphone Source Playback Route", "DAC", "Right DAC" },
> +       { "Headphone Source Playback Route", "Mixer", "Left Mixer" },
> +       { "Headphone Source Playback Route", "Mixer", "Right Mixer" },
> +       { "Headphone Amp", NULL, "Headphone Source Playback Route" },
> +       { "HP", NULL, "Headphone Amp" },
> +};
> +
> +static const struct snd_soc_component_driver sun8i_codec_analog_cmpnt_dr=
v =3D {
> +       .name                   =3D "sun8i-codec-analog",
> +       .controls               =3D sun8i_analog_widgets,
> +       .num_controls           =3D ARRAY_SIZE(sun8i_analog_widgets),
> +       .dapm_widgets           =3D sun8i_codec_analog_dapm_widgets,
> +       .num_dapm_widgets       =3D ARRAY_SIZE(sun8i_codec_analog_dapm_wi=
dgets),
> +       .dapm_routes            =3D sun8i_codec_analog_dapm_routes,
> +       .num_dapm_routes        =3D ARRAY_SIZE(sun8i_codec_analog_dapm_ro=
utes),
> +};
> +
> +static const struct of_device_id sun8i_codec_analog_of_match[] =3D {
> +       { .compatible =3D "allwinner,sun8i-codec-analog", },
> +       {}
> +};
> +MODULE_DEVICE_TABLE(of, sun8i_codec_analog_of_match);
> +
> +static int sun8i_codec_analog_probe(struct platform_device *pdev)
> +{
> +       struct resource *res;
> +       struct regmap *regmap;
> +       void __iomem *base;
> +
> +       /* Get PRCM resources and registers */
> +       res =3D platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       base =3D devm_ioremap_resource(&pdev->dev, res);
> +       if (IS_ERR(base)) {
> +               dev_err(&pdev->dev, "Failed to map PRCM registers\n");
> +               return PTR_ERR(base);
> +       }
> +
> +       regmap =3D devm_regmap_init(&pdev->dev, NULL, base, &adda_pr_regm=
ap_cfg);
> +       if (IS_ERR(regmap)) {
> +               dev_err(&pdev->dev, "Regmap initialisation failed\n");
> +               return PTR_ERR(regmap);
> +       }
> +
> +       return devm_snd_soc_register_component(&pdev->dev,
> +                                              &sun8i_codec_analog_cmpnt_=
drv,
> +                                              NULL, 0);
> +}
> +
> +static struct platform_driver sun8i_codec_analog_driver =3D {
> +       .driver =3D {
> +               .name =3D "sun8i-codec-analog",
> +               .of_match_table =3D sun8i_codec_analog_of_match,
> +       },
> +       .probe =3D sun8i_codec_analog_probe,
> +};
> +module_platform_driver(sun8i_codec_analog_driver);
> +
> +MODULE_DESCRIPTION("Allwinner A31s/A33/A23 codec analog controls driver"=
);
Does the A31s have the prcm for the codec?, as I was under the
impression that it was the same as the A31 and I can't seem to find a
datasheet for that SoC. You could also add H3 and A64 here.
CK
> +MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
> +MODULE_AUTHOR("Myl=C3=A8ne Josserand <mylene.josserand@free-electrons.co=
m>");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:sun8i-codec-analog");
> --
> 2.9.3
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 04/14] ASoC: Add sun8i analog codec driver
@ 2016-10-04 10:21       ` Code Kipper
  0 siblings, 0 replies; 170+ messages in thread
From: Code Kipper @ 2016-10-04 10:21 UTC (permalink / raw)
  To: linux-arm-kernel

On 4 October 2016 at 11:46, Myl?ne Josserand
<mylene.josserand@free-electrons.com> wrote:
> Add the analog part of the sun8i (A33) codec driver. This driver
> implements all the analog part of the codec using PRCM registers.
>
> The read/write regmap functions must be handled in a custom way as
> the PRCM register behaves as "mailbox" register.
>
> Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
> ---
>  sound/soc/sunxi/Kconfig              |   7 +
>  sound/soc/sunxi/Makefile             |   1 +
>  sound/soc/sunxi/sun8i-codec-analog.c | 304 +++++++++++++++++++++++++++++++++++
>  3 files changed, 312 insertions(+)
>  create mode 100644 sound/soc/sunxi/sun8i-codec-analog.c
>
> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
> index dd23682..7aee95a 100644
> --- a/sound/soc/sunxi/Kconfig
> +++ b/sound/soc/sunxi/Kconfig
> @@ -26,4 +26,11 @@ config SND_SUN4I_SPDIF
>         help
>           Say Y or M to add support for the S/PDIF audio block in the Allwinner
>           A10 and affiliated SoCs.
> +
> +config SND_SUN8I_CODEC_ANALOG
> +       tristate "Allwinner SUN8I analog codec"
> +       select REGMAP_MMIO
> +        help
> +         Say Y or M if you want to add sun8i analog audiocodec support
> +
>  endmenu
> diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
> index 604c7b84..241c0df 100644
> --- a/sound/soc/sunxi/Makefile
> +++ b/sound/soc/sunxi/Makefile
> @@ -1,3 +1,4 @@
>  obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
>  obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
>  obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
> +obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
> diff --git a/sound/soc/sunxi/sun8i-codec-analog.c b/sound/soc/sunxi/sun8i-codec-analog.c
> new file mode 100644
> index 0000000..be3d540
> --- /dev/null
> +++ b/sound/soc/sunxi/sun8i-codec-analog.c
> @@ -0,0 +1,304 @@
> +/*
> + * This driver supports the analog controls for the internal codec
> + * found in Allwinner's A31s, A33 and A23 SoCs.
> + *
> + * Copyright 2016 Chen-Yu Tsai <wens@csie.org>
> + * Copyright 2016 Myl?ne Josserand <mylene.josserand@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/io.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +
> +#include <sound/soc.h>
> +#include <sound/soc-dapm.h>
> +#include <sound/tlv.h>
> +
> +/* Codec analog control register offsets and bit fields */
> +#define SUN8I_ADDA_HP_VOLC                             0x00
> +#define SUN8I_ADDA_HP_VOLC_PA_CLK_GATE                 7
> +#define SUN8I_ADDA_HP_VOLC_HP_VOL                      0
> +#define SUN8I_ADDA_LOMIXSC                             0x01
> +#define SUN8I_ADDA_LOMIXSC_MIC1                        6
> +#define SUN8I_ADDA_LOMIXSC_MIC2                        5
> +#define SUN8I_ADDA_LOMIXSC_PHONE                       4
> +#define SUN8I_ADDA_LOMIXSC_PHONEN                      3
> +#define SUN8I_ADDA_LOMIXSC_LINEINL                     2
> +#define SUN8I_ADDA_LOMIXSC_DACL                        1
> +#define SUN8I_ADDA_LOMIXSC_DACR                        0
> +#define SUN8I_ADDA_ROMIXSC                             0x02
> +#define SUN8I_ADDA_ROMIXSC_MIC1                        6
> +#define SUN8I_ADDA_ROMIXSC_MIC2                        5
> +#define SUN8I_ADDA_ROMIXSC_PHONE                       4
> +#define SUN8I_ADDA_ROMIXSC_PHONEP                      3
> +#define SUN8I_ADDA_ROMIXSC_LINEINR                     2
> +#define SUN8I_ADDA_ROMIXSC_DACR                        1
> +#define SUN8I_ADDA_ROMIXSC_DACL                        0
> +#define SUN8I_ADDA_DAC_PA_SRC                          0x03
> +#define SUN8I_ADDA_DAC_PA_SRC_DACAREN                  7
> +#define SUN8I_ADDA_DAC_PA_SRC_DACALEN                  6
> +#define SUN8I_ADDA_DAC_PA_SRC_RMIXEN                   5
> +#define SUN8I_ADDA_DAC_PA_SRC_LMIXEN                   4
> +#define SUN8I_ADDA_DAC_PA_SRC_RHPPAMUTE                3
> +#define SUN8I_ADDA_DAC_PA_SRC_LHPPAMUTE                2
> +#define SUN8I_ADDA_DAC_PA_SRC_RHPIS                    1
> +#define SUN8I_ADDA_DAC_PA_SRC_LHPIS                    0
> +#define SUN8I_ADDA_PHONEIN_GCTRL                       0x04
> +#define SUN8I_ADDA_PHONEIN_GCTRL_PHONEPG               4
> +#define SUN8I_ADDA_PHONEIN_GCTRL_PHONENG               0
> +#define SUN8I_ADDA_LINEIN_GCTRL                        0x05
> +#define SUN8I_ADDA_LINEIN_GCTRL_LINEING                4
> +#define SUN8I_ADDA_LINEIN_GCTRL_PHONEG                 0
> +#define SUN8I_ADDA_MICIN_GCTRL                         0x06
> +#define SUN8I_ADDA_MICIN_GCTRL_MIC1G                   4
> +#define SUN8I_ADDA_MICIN_GCTRL_MIC2G                   0
> +#define SUN8I_ADDA_PAEN_HP_CTRL                        0x07
> +#define SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN                 7
> +#define SUN8I_ADDA_PAEN_HP_CTRL_HPCOM_FC               5
> +#define SUN8I_ADDA_PAEN_HP_CTRL_COMPTEN                4
> +#define SUN8I_ADDA_PAEN_HP_CTRL_PA_ANTI_POP_CTRL       2
> +#define SUN8I_ADDA_PAEN_HP_CTRL_LTRNMUTE               1
> +#define SUN8I_ADDA_PAEN_HP_CTRL_RTLNMUTE               0
> +#define SUN8I_ADDA_PHONEOUT_CTRL                       0x08
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTG             5
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTEN            4
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS3            3
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS2            2
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS1            1
> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS0            0
> +#define SUN8I_ADDA_PHONE_GAIN_CTRL                     0x09
> +#define SUN8I_ADDA_PHONE_GAIN_CTRL_PHONEPREG           0
> +#define SUN8I_ADDA_MIC2G_CTRL                          0x0a
> +#define SUN8I_ADDA_MIC2G_CTRL_MIC2AMPEN                7
> +#define SUN8I_ADDA_MIC2G_CTRL_MIC2BOOST                4
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL                  0x0b
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIASEN       7
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MMICBIASEN       6
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIAS_MODE    5
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1AMPEN        3
> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1BOOST        0
> +#define SUN8I_ADDA_PA_ANTI_POP_CTRL                    0x0e
> +#define SUN8I_ADDA_ADC_AP_EN                           0x0f
> +
> +/* Analog control register access bits */
> +#define ADDA_PR                                0x0 /* PRCM base + 0x1c0 */
> +#define ADDA_PR_RESET                          BIT(28)
> +#define ADDA_PR_WRITE                          BIT(24)
> +#define ADDA_PR_ADDR_SHIFT                     16
> +#define ADDA_PR_ADDR_MASK                      GENMASK(4, 0)
> +#define ADDA_PR_DATA_IN_SHIFT                  8
> +#define ADDA_PR_DATA_IN_MASK                   GENMASK(7, 0)
> +#define ADDA_PR_DATA_OUT_SHIFT                 0
> +#define ADDA_PR_DATA_OUT_MASK                  GENMASK(7, 0)
> +
> +/* regmap access bits */
> +static int adda_reg_read(void *context, unsigned int reg, unsigned int *val)
> +{
> +       void __iomem *base = context;
> +       u32 tmp;
> +
> +       tmp = readl(base);
> +
> +       /* De-assert reset */
> +       writel(tmp | ADDA_PR_RESET, base);
> +
> +       tmp &= ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT);
> +       tmp |= reg << ADDA_PR_ADDR_SHIFT;
> +       writel(tmp, base);
> +
> +       *val = readl(base) & ADDA_PR_DATA_OUT_MASK;
> +
> +       return 0;
> +}
> +
> +static int adda_reg_write(void *context, unsigned int reg, unsigned int val)
> +{
> +       void __iomem *base = context;
> +       u32 tmp;
> +
> +       tmp = readl(base);
> +       /* De-assert reset */
> +       writel(tmp | ADDA_PR_RESET, base);
> +
> +       /* Write the address */
> +       tmp &= ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT);
> +       tmp |= reg << ADDA_PR_ADDR_SHIFT;
> +       writel(tmp, base);
> +
> +       /* Write the value */
> +       tmp &= ~(ADDA_PR_DATA_IN_MASK << ADDA_PR_DATA_IN_SHIFT);
> +       tmp |= val << ADDA_PR_DATA_IN_SHIFT;
> +       writel(tmp, base);
> +
> +       /* Indicate that the previous value must be written */
> +       writel(readl(base) | ADDA_PR_WRITE, base);
> +
> +       /* Reset the write bit */
> +       writel(readl(base) & ~(ADDA_PR_WRITE), base);
> +
> +       return 0;
> +}
> +
> +struct regmap_config adda_pr_regmap_cfg = {
> +       .name           = "adda-pr",
> +       .reg_bits       = 5,
> +       .reg_stride     = 1,
> +       .val_bits       = 8,
> +       .reg_read       = adda_reg_read,
> +       .reg_write      = adda_reg_write,
> +       .fast_io        = true,
> +       .max_register   = 24,
> +};
> +
> +static DECLARE_TLV_DB_SCALE(sun8i_codec_headphone_volume_scale, -6300, 100, 1);
> +
> +static const struct snd_kcontrol_new sun8i_analog_widgets[] = {
> +       SOC_SINGLE_TLV("Headphone Volume", SUN8I_ADDA_HP_VOLC,
> +                      SUN8I_ADDA_HP_VOLC_HP_VOL, 0x3F, 0,
> +                      sun8i_codec_headphone_volume_scale),
> +
> +       /* Playback Switch */
> +       SOC_DOUBLE("DAC Playback Switch", SUN8I_ADDA_DAC_PA_SRC,
> +                  SUN8I_ADDA_DAC_PA_SRC_DACALEN, SUN8I_ADDA_DAC_PA_SRC_DACAREN,
> +                  1, 0),
> +
> +       SOC_DOUBLE("Headphone Playback Switch", SUN8I_ADDA_DAC_PA_SRC,
> +                  SUN8I_ADDA_DAC_PA_SRC_LHPPAMUTE,
> +                  SUN8I_ADDA_DAC_PA_SRC_RHPPAMUTE, 1, 0),
> +};
> +
> +/* headphone controls */
> +static const char * const sun8i_codec_hp_src_enum_text[] = {
> +       "DAC", "Mixer",
> +};
> +
> +static SOC_ENUM_DOUBLE_DECL(sun8i_codec_hp_src_enum,
> +                           SUN8I_ADDA_DAC_PA_SRC,
> +                           SUN8I_ADDA_DAC_PA_SRC_LHPIS,
> +                           SUN8I_ADDA_DAC_PA_SRC_RHPIS,
> +                           sun8i_codec_hp_src_enum_text);
> +
> +static const struct snd_kcontrol_new sun8i_codec_hp_src[] = {
> +       SOC_DAPM_ENUM("Headphone Source Playback Route",
> +                     sun8i_codec_hp_src_enum),
> +};
> +
> +static const struct snd_kcontrol_new sun8i_codec_mixer_controls[] = {
> +       SOC_DAPM_SINGLE("DAC Left Playback Switch",
> +                       SUN8I_ADDA_LOMIXSC,
> +                       SUN8I_ADDA_LOMIXSC_DACL, 1, 0),
> +       SOC_DAPM_SINGLE("DAC Right Playback Switch",
> +                       SUN8I_ADDA_ROMIXSC,
> +                       SUN8I_ADDA_ROMIXSC_DACR, 1, 0),
> +       SOC_DAPM_SINGLE("DAC Reversed Left Playback Switch",
> +                       SUN8I_ADDA_LOMIXSC,
> +                       SUN8I_ADDA_LOMIXSC_DACR, 1, 0),
> +       SOC_DAPM_SINGLE("DAC Reversed Right Playback Switch",
> +                       SUN8I_ADDA_ROMIXSC,
> +                       SUN8I_ADDA_ROMIXSC_DACL, 1, 0),
> +};
> +
> +static const struct snd_soc_dapm_widget sun8i_codec_analog_dapm_widgets[] = {
> +       /* Mixers */
> +       SOC_MIXER_ARRAY("Left Mixer", SUN8I_ADDA_DAC_PA_SRC,
> +                       SUN8I_ADDA_DAC_PA_SRC_LMIXEN, 0,
> +                       sun8i_codec_mixer_controls),
> +       SOC_MIXER_ARRAY("Right Mixer", SUN8I_ADDA_DAC_PA_SRC,
> +                       SUN8I_ADDA_DAC_PA_SRC_RMIXEN, 0,
> +                       sun8i_codec_mixer_controls),
> +
> +       /* Headphone output path */
> +       SND_SOC_DAPM_MUX("Headphone Source Playback Route",
> +                        SND_SOC_NOPM, 0, 0, sun8i_codec_hp_src),
> +       SND_SOC_DAPM_OUT_DRV("Headphone Amp", SUN8I_ADDA_PAEN_HP_CTRL,
> +                            SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN, 0, NULL, 0),
> +
> +       /* Headphone outputs */
> +       SND_SOC_DAPM_OUTPUT("HP"),
> +
> +};
> +
> +static const struct snd_soc_dapm_route sun8i_codec_analog_dapm_routes[] = {
> +       /* Left Mixer Routes */
> +       { "Left Mixer", "DAC Playback Switch", "Left DAC" },
> +       { "Left Mixer", "DAC Reversed Left Playback Switch", "Right DAC" },
> +
> +       /* Right Mixer Routes */
> +       { "Right Mixer", "DAC Playback Switch", "Right DAC" },
> +       { "Right Mixer", "DAC Reversed Right Playback Switch", "Left DAC" },
> +
> +       /* Headphone Routes */
> +       { "Headphone Source Playback Route", "DAC", "Left DAC" },
> +       { "Headphone Source Playback Route", "DAC", "Right DAC" },
> +       { "Headphone Source Playback Route", "Mixer", "Left Mixer" },
> +       { "Headphone Source Playback Route", "Mixer", "Right Mixer" },
> +       { "Headphone Amp", NULL, "Headphone Source Playback Route" },
> +       { "HP", NULL, "Headphone Amp" },
> +};
> +
> +static const struct snd_soc_component_driver sun8i_codec_analog_cmpnt_drv = {
> +       .name                   = "sun8i-codec-analog",
> +       .controls               = sun8i_analog_widgets,
> +       .num_controls           = ARRAY_SIZE(sun8i_analog_widgets),
> +       .dapm_widgets           = sun8i_codec_analog_dapm_widgets,
> +       .num_dapm_widgets       = ARRAY_SIZE(sun8i_codec_analog_dapm_widgets),
> +       .dapm_routes            = sun8i_codec_analog_dapm_routes,
> +       .num_dapm_routes        = ARRAY_SIZE(sun8i_codec_analog_dapm_routes),
> +};
> +
> +static const struct of_device_id sun8i_codec_analog_of_match[] = {
> +       { .compatible = "allwinner,sun8i-codec-analog", },
> +       {}
> +};
> +MODULE_DEVICE_TABLE(of, sun8i_codec_analog_of_match);
> +
> +static int sun8i_codec_analog_probe(struct platform_device *pdev)
> +{
> +       struct resource *res;
> +       struct regmap *regmap;
> +       void __iomem *base;
> +
> +       /* Get PRCM resources and registers */
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       base = devm_ioremap_resource(&pdev->dev, res);
> +       if (IS_ERR(base)) {
> +               dev_err(&pdev->dev, "Failed to map PRCM registers\n");
> +               return PTR_ERR(base);
> +       }
> +
> +       regmap = devm_regmap_init(&pdev->dev, NULL, base, &adda_pr_regmap_cfg);
> +       if (IS_ERR(regmap)) {
> +               dev_err(&pdev->dev, "Regmap initialisation failed\n");
> +               return PTR_ERR(regmap);
> +       }
> +
> +       return devm_snd_soc_register_component(&pdev->dev,
> +                                              &sun8i_codec_analog_cmpnt_drv,
> +                                              NULL, 0);
> +}
> +
> +static struct platform_driver sun8i_codec_analog_driver = {
> +       .driver = {
> +               .name = "sun8i-codec-analog",
> +               .of_match_table = sun8i_codec_analog_of_match,
> +       },
> +       .probe = sun8i_codec_analog_probe,
> +};
> +module_platform_driver(sun8i_codec_analog_driver);
> +
> +MODULE_DESCRIPTION("Allwinner A31s/A33/A23 codec analog controls driver");
Does the A31s have the prcm for the codec?, as I was under the
impression that it was the same as the A31 and I can't seem to find a
datasheet for that SoC. You could also add H3 and A64 here.
CK
> +MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
> +MODULE_AUTHOR("Myl?ne Josserand <mylene.josserand@free-electrons.com>");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:sun8i-codec-analog");
> --
> 2.9.3
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 08/14] dt-bindings: sound: Add sun8i analog codec documentation
@ 2016-10-04 10:32       ` Mark Brown
  0 siblings, 0 replies; 170+ messages in thread
From: Mark Brown @ 2016-10-04 10:32 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	perex, tiwai, lee.jones, mark.rutland, robh+dt, linux-kernel,
	dmaengine, linux-arm-kernel, linux-clk, alsa-devel, devicetree,
	linux-sunxi, thomas.petazzoni, alexandre.belloni

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

On Tue, Oct 04, 2016 at 11:46:21AM +0200, Mylène Josserand wrote:

> +* Allwinner A23/A33 Analog Codec
> +
> +This codec must be handled as a PRCM subnode.

What does this mean - how does one handle something as a "PRCM subnode"?

Please use subject lines matching the style for the subsystem.  This
makes it easier for people to identify relevant patches.

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

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

* Re: [PATCH 08/14] dt-bindings: sound: Add sun8i analog codec documentation
@ 2016-10-04 10:32       ` Mark Brown
  0 siblings, 0 replies; 170+ messages in thread
From: Mark Brown @ 2016-10-04 10:32 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8, wens-jdAy2FN1RRM,
	mturquette-rdvid1DuHRBWk0Htik3J/w, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, perex-/Fr2/VpizcU,
	tiwai-IBi9RG/b67k, lee.jones-QSEj5FYQhm4dnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8

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

On Tue, Oct 04, 2016 at 11:46:21AM +0200, Mylène Josserand wrote:

> +* Allwinner A23/A33 Analog Codec
> +
> +This codec must be handled as a PRCM subnode.

What does this mean - how does one handle something as a "PRCM subnode"?

Please use subject lines matching the style for the subsystem.  This
makes it easier for people to identify relevant patches.

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

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

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

* [PATCH 08/14] dt-bindings: sound: Add sun8i analog codec documentation
@ 2016-10-04 10:32       ` Mark Brown
  0 siblings, 0 replies; 170+ messages in thread
From: Mark Brown @ 2016-10-04 10:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 04, 2016 at 11:46:21AM +0200, Myl?ne Josserand wrote:

> +* Allwinner A23/A33 Analog Codec
> +
> +This codec must be handled as a PRCM subnode.

What does this mean - how does one handle something as a "PRCM subnode"?

Please use subject lines matching the style for the subsystem.  This
makes it easier for people to identify relevant patches.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 455 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161004/c28f6542/attachment.sig>

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

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
  2016-10-04  9:46     ` Mylène Josserand
  (?)
@ 2016-10-04 10:40       ` Jean-Francois Moine
  -1 siblings, 0 replies; 170+ messages in thread
From: Jean-Francois Moine @ 2016-10-04 10:40 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt,
	thomas.petazzoni, devicetree, alsa-devel, linux-kernel,
	linux-sunxi, alexandre.belloni, dmaengine, linux-clk,
	linux-arm-kernel

On Tue,  4 Oct 2016 11:46:14 +0200
Mylène Josserand <mylene.josserand@free-electrons.com> wrote:

> Add the case of a burst of 4 which is handled by the SoC.
> 
> Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
> ---
>  drivers/dma/sun6i-dma.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> index 8346199..0485204 100644
> --- a/drivers/dma/sun6i-dma.c
> +++ b/drivers/dma/sun6i-dma.c
> @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
>  	switch (maxburst) {
>  	case 1:
>  		return 0;
> +	case 4:
> +		return 1;
>  	case 8:
>  		return 2;
>  	default:
> -- 
> 2.9.3

This patch has already been rejected by Maxime in the threads
	http://www.spinics.net/lists/dmaengine/msg08610.html
and
	http://www.spinics.net/lists/dmaengine/msg08719.html

I hope you will find the way he wants for this maxburst to be added.

-- 
Ken ar c'hentañ	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

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

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-10-04 10:40       ` Jean-Francois Moine
  0 siblings, 0 replies; 170+ messages in thread
From: Jean-Francois Moine @ 2016-10-04 10:40 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt,
	thomas.petazzoni, devicetree, alsa-devel, linux-kernel,
	linux-sunxi, alexandre.belloni, dmaengine, linux-clk,
	linux-arm-kernel

On Tue,  4 Oct 2016 11:46:14 +0200
Myl=E8ne Josserand <mylene.josserand@free-electrons.com> wrote:

> Add the case of a burst of 4 which is handled by the SoC.
>=20
> Signed-off-by: Myl=E8ne Josserand <mylene.josserand@free-electrons.com>
> ---
>  drivers/dma/sun6i-dma.c | 2 ++
>  1 file changed, 2 insertions(+)
>=20
> diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> index 8346199..0485204 100644
> --- a/drivers/dma/sun6i-dma.c
> +++ b/drivers/dma/sun6i-dma.c
> @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
>  	switch (maxburst) {
>  	case 1:
>  		return 0;
> +	case 4:
> +		return 1;
>  	case 8:
>  		return 2;
>  	default:
> --=20
> 2.9.3

This patch has already been rejected by Maxime in the threads
	http://www.spinics.net/lists/dmaengine/msg08610.html
and
	http://www.spinics.net/lists/dmaengine/msg08719.html

I hope you will find the way he wants for this maxburst to be added.

--=20
Ken ar c'henta=F1	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

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

* [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-10-04 10:40       ` Jean-Francois Moine
  0 siblings, 0 replies; 170+ messages in thread
From: Jean-Francois Moine @ 2016-10-04 10:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue,  4 Oct 2016 11:46:14 +0200
Myl?ne Josserand <mylene.josserand@free-electrons.com> wrote:

> Add the case of a burst of 4 which is handled by the SoC.
> 
> Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
> ---
>  drivers/dma/sun6i-dma.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> index 8346199..0485204 100644
> --- a/drivers/dma/sun6i-dma.c
> +++ b/drivers/dma/sun6i-dma.c
> @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
>  	switch (maxburst) {
>  	case 1:
>  		return 0;
> +	case 4:
> +		return 1;
>  	case 8:
>  		return 2;
>  	default:
> -- 
> 2.9.3

This patch has already been rejected by Maxime in the threads
	http://www.spinics.net/lists/dmaengine/msg08610.html
and
	http://www.spinics.net/lists/dmaengine/msg08719.html

I hope you will find the way he wants for this maxburst to be added.

-- 
Ken ar c'henta?	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

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

* Re: [PATCH 05/14] mfd: sun6i-prcm: Add sun8i analog codec as subnode
  2016-10-04  9:46     ` Mylène Josserand
  (?)
@ 2016-10-04 10:52       ` Jean-Francois Moine
  -1 siblings, 0 replies; 170+ messages in thread
From: Jean-Francois Moine @ 2016-10-04 10:52 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt,
	thomas.petazzoni, devicetree, alsa-devel, linux-kernel,
	linux-sunxi, alexandre.belloni, dmaengine, linux-clk,
	linux-arm-kernel

On Tue,  4 Oct 2016 11:46:18 +0200
Mylène Josserand <mylene.josserand@free-electrons.com> wrote:

> The sun8i audio codec is using PRCM registers to configure all the
> analog part of the audio codec. It is added as a subnode of the PRCM
> with his resource (offset of 0x1c0).
> 
> Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
> ---
>  drivers/mfd/sun6i-prcm.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
	[snip]

I was heard that the PRCM as a MFD would disappear.

-- 
Ken ar c'hentañ	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

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

* Re: [PATCH 05/14] mfd: sun6i-prcm: Add sun8i analog codec as subnode
@ 2016-10-04 10:52       ` Jean-Francois Moine
  0 siblings, 0 replies; 170+ messages in thread
From: Jean-Francois Moine @ 2016-10-04 10:52 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt,
	thomas.petazzoni, devicetree, alsa-devel, linux-kernel,
	linux-sunxi, alexandre.belloni, dmaengine, linux-clk,
	linux-arm-kernel

On Tue,  4 Oct 2016 11:46:18 +0200
Myl=E8ne Josserand <mylene.josserand@free-electrons.com> wrote:

> The sun8i audio codec is using PRCM registers to configure all the
> analog part of the audio codec. It is added as a subnode of the PRCM
> with his resource (offset of 0x1c0).
>=20
> Signed-off-by: Myl=E8ne Josserand <mylene.josserand@free-electrons.com>
> ---
>  drivers/mfd/sun6i-prcm.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
	[snip]

I was heard that the PRCM as a MFD would disappear.

--=20
Ken ar c'henta=F1	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

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

* [PATCH 05/14] mfd: sun6i-prcm: Add sun8i analog codec as subnode
@ 2016-10-04 10:52       ` Jean-Francois Moine
  0 siblings, 0 replies; 170+ messages in thread
From: Jean-Francois Moine @ 2016-10-04 10:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue,  4 Oct 2016 11:46:18 +0200
Myl?ne Josserand <mylene.josserand@free-electrons.com> wrote:

> The sun8i audio codec is using PRCM registers to configure all the
> analog part of the audio codec. It is added as a subnode of the PRCM
> with his resource (offset of 0x1c0).
> 
> Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
> ---
>  drivers/mfd/sun6i-prcm.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
	[snip]

I was heard that the PRCM as a MFD would disappear.

-- 
Ken ar c'henta?	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

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

* Re: [PATCH 04/14] ASoC: Add sun8i analog codec driver
  2016-10-04 10:21       ` Code Kipper
  (?)
  (?)
@ 2016-10-04 10:56         ` Chen-Yu Tsai
  -1 siblings, 0 replies; 170+ messages in thread
From: Chen-Yu Tsai @ 2016-10-04 10:56 UTC (permalink / raw)
  To: Code Kipper
  Cc: Mylène Josserand, Vinod Koul, Maxime Ripard, Chen-Yu Tsai,
	Michael Turquette, Stephen Boyd, Liam Girdwood, Mark Brown,
	Jaroslav Kysela, Takashi Iwai, Lee Jones, Mark Rutland,
	Rob Herring, Thomas Petazzoni, devicetree, Linux-ALSA,
	linux-kernel, linux-sunxi, Alexandre Belloni, dmaengine,
	linux-clk, linux-arm-kernel

On Tue, Oct 4, 2016 at 6:21 PM, Code Kipper <codekipper@gmail.com> wrote:
> On 4 October 2016 at 11:46, Mylène Josserand
> <mylene.josserand@free-electrons.com> wrote:
>> Add the analog part of the sun8i (A33) codec driver. This driver
>> implements all the analog part of the codec using PRCM registers.
>>
>> The read/write regmap functions must be handled in a custom way as
>> the PRCM register behaves as "mailbox" register.
>>
>> Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
>> ---
>>  sound/soc/sunxi/Kconfig              |   7 +
>>  sound/soc/sunxi/Makefile             |   1 +
>>  sound/soc/sunxi/sun8i-codec-analog.c | 304 +++++++++++++++++++++++++++++++++++
>>  3 files changed, 312 insertions(+)
>>  create mode 100644 sound/soc/sunxi/sun8i-codec-analog.c
>>
>> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
>> index dd23682..7aee95a 100644
>> --- a/sound/soc/sunxi/Kconfig
>> +++ b/sound/soc/sunxi/Kconfig
>> @@ -26,4 +26,11 @@ config SND_SUN4I_SPDIF
>>         help
>>           Say Y or M to add support for the S/PDIF audio block in the Allwinner
>>           A10 and affiliated SoCs.
>> +
>> +config SND_SUN8I_CODEC_ANALOG
>> +       tristate "Allwinner SUN8I analog codec"
>> +       select REGMAP_MMIO
>> +        help
>> +         Say Y or M if you want to add sun8i analog audiocodec support
>> +
>>  endmenu
>> diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
>> index 604c7b84..241c0df 100644
>> --- a/sound/soc/sunxi/Makefile
>> +++ b/sound/soc/sunxi/Makefile
>> @@ -1,3 +1,4 @@
>>  obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
>>  obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
>>  obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
>> +obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
>> diff --git a/sound/soc/sunxi/sun8i-codec-analog.c b/sound/soc/sunxi/sun8i-codec-analog.c
>> new file mode 100644
>> index 0000000..be3d540
>> --- /dev/null
>> +++ b/sound/soc/sunxi/sun8i-codec-analog.c
>> @@ -0,0 +1,304 @@
>> +/*
>> + * This driver supports the analog controls for the internal codec
>> + * found in Allwinner's A31s, A33 and A23 SoCs.
>> + *
>> + * Copyright 2016 Chen-Yu Tsai <wens@csie.org>
>> + * Copyright 2016 Mylène Josserand <mylene.josserand@free-electrons.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + */
>> +
>> +#include <linux/module.h>
>> +#include <linux/io.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/regmap.h>
>> +
>> +#include <sound/soc.h>
>> +#include <sound/soc-dapm.h>
>> +#include <sound/tlv.h>
>> +
>> +/* Codec analog control register offsets and bit fields */
>> +#define SUN8I_ADDA_HP_VOLC                             0x00
>> +#define SUN8I_ADDA_HP_VOLC_PA_CLK_GATE                 7
>> +#define SUN8I_ADDA_HP_VOLC_HP_VOL                      0
>> +#define SUN8I_ADDA_LOMIXSC                             0x01
>> +#define SUN8I_ADDA_LOMIXSC_MIC1                        6
>> +#define SUN8I_ADDA_LOMIXSC_MIC2                        5
>> +#define SUN8I_ADDA_LOMIXSC_PHONE                       4
>> +#define SUN8I_ADDA_LOMIXSC_PHONEN                      3
>> +#define SUN8I_ADDA_LOMIXSC_LINEINL                     2
>> +#define SUN8I_ADDA_LOMIXSC_DACL                        1
>> +#define SUN8I_ADDA_LOMIXSC_DACR                        0
>> +#define SUN8I_ADDA_ROMIXSC                             0x02
>> +#define SUN8I_ADDA_ROMIXSC_MIC1                        6
>> +#define SUN8I_ADDA_ROMIXSC_MIC2                        5
>> +#define SUN8I_ADDA_ROMIXSC_PHONE                       4
>> +#define SUN8I_ADDA_ROMIXSC_PHONEP                      3
>> +#define SUN8I_ADDA_ROMIXSC_LINEINR                     2
>> +#define SUN8I_ADDA_ROMIXSC_DACR                        1
>> +#define SUN8I_ADDA_ROMIXSC_DACL                        0
>> +#define SUN8I_ADDA_DAC_PA_SRC                          0x03
>> +#define SUN8I_ADDA_DAC_PA_SRC_DACAREN                  7
>> +#define SUN8I_ADDA_DAC_PA_SRC_DACALEN                  6
>> +#define SUN8I_ADDA_DAC_PA_SRC_RMIXEN                   5
>> +#define SUN8I_ADDA_DAC_PA_SRC_LMIXEN                   4
>> +#define SUN8I_ADDA_DAC_PA_SRC_RHPPAMUTE                3
>> +#define SUN8I_ADDA_DAC_PA_SRC_LHPPAMUTE                2
>> +#define SUN8I_ADDA_DAC_PA_SRC_RHPIS                    1
>> +#define SUN8I_ADDA_DAC_PA_SRC_LHPIS                    0
>> +#define SUN8I_ADDA_PHONEIN_GCTRL                       0x04
>> +#define SUN8I_ADDA_PHONEIN_GCTRL_PHONEPG               4
>> +#define SUN8I_ADDA_PHONEIN_GCTRL_PHONENG               0
>> +#define SUN8I_ADDA_LINEIN_GCTRL                        0x05
>> +#define SUN8I_ADDA_LINEIN_GCTRL_LINEING                4
>> +#define SUN8I_ADDA_LINEIN_GCTRL_PHONEG                 0
>> +#define SUN8I_ADDA_MICIN_GCTRL                         0x06
>> +#define SUN8I_ADDA_MICIN_GCTRL_MIC1G                   4
>> +#define SUN8I_ADDA_MICIN_GCTRL_MIC2G                   0
>> +#define SUN8I_ADDA_PAEN_HP_CTRL                        0x07
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN                 7
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_HPCOM_FC               5
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_COMPTEN                4
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_PA_ANTI_POP_CTRL       2
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_LTRNMUTE               1
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_RTLNMUTE               0
>> +#define SUN8I_ADDA_PHONEOUT_CTRL                       0x08
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTG             5
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTEN            4
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS3            3
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS2            2
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS1            1
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS0            0
>> +#define SUN8I_ADDA_PHONE_GAIN_CTRL                     0x09
>> +#define SUN8I_ADDA_PHONE_GAIN_CTRL_PHONEPREG           0
>> +#define SUN8I_ADDA_MIC2G_CTRL                          0x0a
>> +#define SUN8I_ADDA_MIC2G_CTRL_MIC2AMPEN                7
>> +#define SUN8I_ADDA_MIC2G_CTRL_MIC2BOOST                4
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL                  0x0b
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIASEN       7
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MMICBIASEN       6
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIAS_MODE    5
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1AMPEN        3
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1BOOST        0
>> +#define SUN8I_ADDA_PA_ANTI_POP_CTRL                    0x0e
>> +#define SUN8I_ADDA_ADC_AP_EN                           0x0f
>> +
>> +/* Analog control register access bits */
>> +#define ADDA_PR                                0x0 /* PRCM base + 0x1c0 */
>> +#define ADDA_PR_RESET                          BIT(28)
>> +#define ADDA_PR_WRITE                          BIT(24)
>> +#define ADDA_PR_ADDR_SHIFT                     16
>> +#define ADDA_PR_ADDR_MASK                      GENMASK(4, 0)
>> +#define ADDA_PR_DATA_IN_SHIFT                  8
>> +#define ADDA_PR_DATA_IN_MASK                   GENMASK(7, 0)
>> +#define ADDA_PR_DATA_OUT_SHIFT                 0
>> +#define ADDA_PR_DATA_OUT_MASK                  GENMASK(7, 0)
>> +
>> +/* regmap access bits */
>> +static int adda_reg_read(void *context, unsigned int reg, unsigned int *val)
>> +{
>> +       void __iomem *base = context;
>> +       u32 tmp;
>> +
>> +       tmp = readl(base);
>> +
>> +       /* De-assert reset */
>> +       writel(tmp | ADDA_PR_RESET, base);
>> +
>> +       tmp &= ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT);
>> +       tmp |= reg << ADDA_PR_ADDR_SHIFT;
>> +       writel(tmp, base);
>> +
>> +       *val = readl(base) & ADDA_PR_DATA_OUT_MASK;
>> +
>> +       return 0;
>> +}
>> +
>> +static int adda_reg_write(void *context, unsigned int reg, unsigned int val)
>> +{
>> +       void __iomem *base = context;
>> +       u32 tmp;
>> +
>> +       tmp = readl(base);
>> +       /* De-assert reset */
>> +       writel(tmp | ADDA_PR_RESET, base);
>> +
>> +       /* Write the address */
>> +       tmp &= ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT);
>> +       tmp |= reg << ADDA_PR_ADDR_SHIFT;
>> +       writel(tmp, base);
>> +
>> +       /* Write the value */
>> +       tmp &= ~(ADDA_PR_DATA_IN_MASK << ADDA_PR_DATA_IN_SHIFT);
>> +       tmp |= val << ADDA_PR_DATA_IN_SHIFT;
>> +       writel(tmp, base);
>> +
>> +       /* Indicate that the previous value must be written */
>> +       writel(readl(base) | ADDA_PR_WRITE, base);
>> +
>> +       /* Reset the write bit */
>> +       writel(readl(base) & ~(ADDA_PR_WRITE), base);
>> +
>> +       return 0;
>> +}
>> +
>> +struct regmap_config adda_pr_regmap_cfg = {
>> +       .name           = "adda-pr",
>> +       .reg_bits       = 5,
>> +       .reg_stride     = 1,
>> +       .val_bits       = 8,
>> +       .reg_read       = adda_reg_read,
>> +       .reg_write      = adda_reg_write,
>> +       .fast_io        = true,
>> +       .max_register   = 24,
>> +};
>> +
>> +static DECLARE_TLV_DB_SCALE(sun8i_codec_headphone_volume_scale, -6300, 100, 1);
>> +
>> +static const struct snd_kcontrol_new sun8i_analog_widgets[] = {
>> +       SOC_SINGLE_TLV("Headphone Volume", SUN8I_ADDA_HP_VOLC,
>> +                      SUN8I_ADDA_HP_VOLC_HP_VOL, 0x3F, 0,
>> +                      sun8i_codec_headphone_volume_scale),
>> +
>> +       /* Playback Switch */
>> +       SOC_DOUBLE("DAC Playback Switch", SUN8I_ADDA_DAC_PA_SRC,
>> +                  SUN8I_ADDA_DAC_PA_SRC_DACALEN, SUN8I_ADDA_DAC_PA_SRC_DACAREN,
>> +                  1, 0),
>> +
>> +       SOC_DOUBLE("Headphone Playback Switch", SUN8I_ADDA_DAC_PA_SRC,
>> +                  SUN8I_ADDA_DAC_PA_SRC_LHPPAMUTE,
>> +                  SUN8I_ADDA_DAC_PA_SRC_RHPPAMUTE, 1, 0),
>> +};
>> +
>> +/* headphone controls */
>> +static const char * const sun8i_codec_hp_src_enum_text[] = {
>> +       "DAC", "Mixer",
>> +};
>> +
>> +static SOC_ENUM_DOUBLE_DECL(sun8i_codec_hp_src_enum,
>> +                           SUN8I_ADDA_DAC_PA_SRC,
>> +                           SUN8I_ADDA_DAC_PA_SRC_LHPIS,
>> +                           SUN8I_ADDA_DAC_PA_SRC_RHPIS,
>> +                           sun8i_codec_hp_src_enum_text);
>> +
>> +static const struct snd_kcontrol_new sun8i_codec_hp_src[] = {
>> +       SOC_DAPM_ENUM("Headphone Source Playback Route",
>> +                     sun8i_codec_hp_src_enum),
>> +};
>> +
>> +static const struct snd_kcontrol_new sun8i_codec_mixer_controls[] = {
>> +       SOC_DAPM_SINGLE("DAC Left Playback Switch",
>> +                       SUN8I_ADDA_LOMIXSC,
>> +                       SUN8I_ADDA_LOMIXSC_DACL, 1, 0),
>> +       SOC_DAPM_SINGLE("DAC Right Playback Switch",
>> +                       SUN8I_ADDA_ROMIXSC,
>> +                       SUN8I_ADDA_ROMIXSC_DACR, 1, 0),
>> +       SOC_DAPM_SINGLE("DAC Reversed Left Playback Switch",
>> +                       SUN8I_ADDA_LOMIXSC,
>> +                       SUN8I_ADDA_LOMIXSC_DACR, 1, 0),
>> +       SOC_DAPM_SINGLE("DAC Reversed Right Playback Switch",
>> +                       SUN8I_ADDA_ROMIXSC,
>> +                       SUN8I_ADDA_ROMIXSC_DACL, 1, 0),
>> +};
>> +
>> +static const struct snd_soc_dapm_widget sun8i_codec_analog_dapm_widgets[] = {
>> +       /* Mixers */
>> +       SOC_MIXER_ARRAY("Left Mixer", SUN8I_ADDA_DAC_PA_SRC,
>> +                       SUN8I_ADDA_DAC_PA_SRC_LMIXEN, 0,
>> +                       sun8i_codec_mixer_controls),
>> +       SOC_MIXER_ARRAY("Right Mixer", SUN8I_ADDA_DAC_PA_SRC,
>> +                       SUN8I_ADDA_DAC_PA_SRC_RMIXEN, 0,
>> +                       sun8i_codec_mixer_controls),
>> +
>> +       /* Headphone output path */
>> +       SND_SOC_DAPM_MUX("Headphone Source Playback Route",
>> +                        SND_SOC_NOPM, 0, 0, sun8i_codec_hp_src),
>> +       SND_SOC_DAPM_OUT_DRV("Headphone Amp", SUN8I_ADDA_PAEN_HP_CTRL,
>> +                            SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN, 0, NULL, 0),
>> +
>> +       /* Headphone outputs */
>> +       SND_SOC_DAPM_OUTPUT("HP"),
>> +
>> +};
>> +
>> +static const struct snd_soc_dapm_route sun8i_codec_analog_dapm_routes[] = {
>> +       /* Left Mixer Routes */
>> +       { "Left Mixer", "DAC Playback Switch", "Left DAC" },
>> +       { "Left Mixer", "DAC Reversed Left Playback Switch", "Right DAC" },
>> +
>> +       /* Right Mixer Routes */
>> +       { "Right Mixer", "DAC Playback Switch", "Right DAC" },
>> +       { "Right Mixer", "DAC Reversed Right Playback Switch", "Left DAC" },
>> +
>> +       /* Headphone Routes */
>> +       { "Headphone Source Playback Route", "DAC", "Left DAC" },
>> +       { "Headphone Source Playback Route", "DAC", "Right DAC" },
>> +       { "Headphone Source Playback Route", "Mixer", "Left Mixer" },
>> +       { "Headphone Source Playback Route", "Mixer", "Right Mixer" },
>> +       { "Headphone Amp", NULL, "Headphone Source Playback Route" },
>> +       { "HP", NULL, "Headphone Amp" },
>> +};
>> +
>> +static const struct snd_soc_component_driver sun8i_codec_analog_cmpnt_drv = {
>> +       .name                   = "sun8i-codec-analog",
>> +       .controls               = sun8i_analog_widgets,
>> +       .num_controls           = ARRAY_SIZE(sun8i_analog_widgets),
>> +       .dapm_widgets           = sun8i_codec_analog_dapm_widgets,
>> +       .num_dapm_widgets       = ARRAY_SIZE(sun8i_codec_analog_dapm_widgets),
>> +       .dapm_routes            = sun8i_codec_analog_dapm_routes,
>> +       .num_dapm_routes        = ARRAY_SIZE(sun8i_codec_analog_dapm_routes),
>> +};
>> +
>> +static const struct of_device_id sun8i_codec_analog_of_match[] = {
>> +       { .compatible = "allwinner,sun8i-codec-analog", },
>> +       {}
>> +};
>> +MODULE_DEVICE_TABLE(of, sun8i_codec_analog_of_match);
>> +
>> +static int sun8i_codec_analog_probe(struct platform_device *pdev)
>> +{
>> +       struct resource *res;
>> +       struct regmap *regmap;
>> +       void __iomem *base;
>> +
>> +       /* Get PRCM resources and registers */
>> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> +       base = devm_ioremap_resource(&pdev->dev, res);
>> +       if (IS_ERR(base)) {
>> +               dev_err(&pdev->dev, "Failed to map PRCM registers\n");
>> +               return PTR_ERR(base);
>> +       }
>> +
>> +       regmap = devm_regmap_init(&pdev->dev, NULL, base, &adda_pr_regmap_cfg);
>> +       if (IS_ERR(regmap)) {
>> +               dev_err(&pdev->dev, "Regmap initialisation failed\n");
>> +               return PTR_ERR(regmap);
>> +       }
>> +
>> +       return devm_snd_soc_register_component(&pdev->dev,
>> +                                              &sun8i_codec_analog_cmpnt_drv,
>> +                                              NULL, 0);
>> +}
>> +
>> +static struct platform_driver sun8i_codec_analog_driver = {
>> +       .driver = {
>> +               .name = "sun8i-codec-analog",
>> +               .of_match_table = sun8i_codec_analog_of_match,
>> +       },
>> +       .probe = sun8i_codec_analog_probe,
>> +};
>> +module_platform_driver(sun8i_codec_analog_driver);
>> +
>> +MODULE_DESCRIPTION("Allwinner A31s/A33/A23 codec analog controls driver");
> Does the A31s have the prcm for the codec?, as I was under the
> impression that it was the same as the A31 and I can't seem to find a
> datasheet for that SoC. You could also add H3 and A64 here.

Yes it does, which is why I made this driver.

You can find the datasheet for the A31s in Allwinner's Github repo:

    https://github.com/allwinner-zh/documents

ChenYu

> CK
>> +MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
>> +MODULE_AUTHOR("Mylène Josserand <mylene.josserand@free-electrons.com>");
>> +MODULE_LICENSE("GPL");
>> +MODULE_ALIAS("platform:sun8i-codec-analog");
>> --
>> 2.9.3
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 04/14] ASoC: Add sun8i analog codec driver
@ 2016-10-04 10:56         ` Chen-Yu Tsai
  0 siblings, 0 replies; 170+ messages in thread
From: Chen-Yu Tsai @ 2016-10-04 10:56 UTC (permalink / raw)
  To: Code Kipper
  Cc: Mylène Josserand, Vinod Koul, Maxime Ripard, Chen-Yu Tsai,
	Michael Turquette, Stephen Boyd, Liam Girdwood, Mark Brown,
	Jaroslav Kysela, Takashi Iwai, Lee Jones, Mark Rutland,
	Rob Herring, Thomas Petazzoni, devicetree, Linux-ALSA,
	linux-kernel, linux-sunxi

On Tue, Oct 4, 2016 at 6:21 PM, Code Kipper <codekipper@gmail.com> wrote:
> On 4 October 2016 at 11:46, Mylène Josserand
> <mylene.josserand@free-electrons.com> wrote:
>> Add the analog part of the sun8i (A33) codec driver. This driver
>> implements all the analog part of the codec using PRCM registers.
>>
>> The read/write regmap functions must be handled in a custom way as
>> the PRCM register behaves as "mailbox" register.
>>
>> Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
>> ---
>>  sound/soc/sunxi/Kconfig              |   7 +
>>  sound/soc/sunxi/Makefile             |   1 +
>>  sound/soc/sunxi/sun8i-codec-analog.c | 304 +++++++++++++++++++++++++++++++++++
>>  3 files changed, 312 insertions(+)
>>  create mode 100644 sound/soc/sunxi/sun8i-codec-analog.c
>>
>> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
>> index dd23682..7aee95a 100644
>> --- a/sound/soc/sunxi/Kconfig
>> +++ b/sound/soc/sunxi/Kconfig
>> @@ -26,4 +26,11 @@ config SND_SUN4I_SPDIF
>>         help
>>           Say Y or M to add support for the S/PDIF audio block in the Allwinner
>>           A10 and affiliated SoCs.
>> +
>> +config SND_SUN8I_CODEC_ANALOG
>> +       tristate "Allwinner SUN8I analog codec"
>> +       select REGMAP_MMIO
>> +        help
>> +         Say Y or M if you want to add sun8i analog audiocodec support
>> +
>>  endmenu
>> diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
>> index 604c7b84..241c0df 100644
>> --- a/sound/soc/sunxi/Makefile
>> +++ b/sound/soc/sunxi/Makefile
>> @@ -1,3 +1,4 @@
>>  obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
>>  obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
>>  obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
>> +obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
>> diff --git a/sound/soc/sunxi/sun8i-codec-analog.c b/sound/soc/sunxi/sun8i-codec-analog.c
>> new file mode 100644
>> index 0000000..be3d540
>> --- /dev/null
>> +++ b/sound/soc/sunxi/sun8i-codec-analog.c
>> @@ -0,0 +1,304 @@
>> +/*
>> + * This driver supports the analog controls for the internal codec
>> + * found in Allwinner's A31s, A33 and A23 SoCs.
>> + *
>> + * Copyright 2016 Chen-Yu Tsai <wens@csie.org>
>> + * Copyright 2016 Mylène Josserand <mylene.josserand@free-electrons.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + */
>> +
>> +#include <linux/module.h>
>> +#include <linux/io.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/regmap.h>
>> +
>> +#include <sound/soc.h>
>> +#include <sound/soc-dapm.h>
>> +#include <sound/tlv.h>
>> +
>> +/* Codec analog control register offsets and bit fields */
>> +#define SUN8I_ADDA_HP_VOLC                             0x00
>> +#define SUN8I_ADDA_HP_VOLC_PA_CLK_GATE                 7
>> +#define SUN8I_ADDA_HP_VOLC_HP_VOL                      0
>> +#define SUN8I_ADDA_LOMIXSC                             0x01
>> +#define SUN8I_ADDA_LOMIXSC_MIC1                        6
>> +#define SUN8I_ADDA_LOMIXSC_MIC2                        5
>> +#define SUN8I_ADDA_LOMIXSC_PHONE                       4
>> +#define SUN8I_ADDA_LOMIXSC_PHONEN                      3
>> +#define SUN8I_ADDA_LOMIXSC_LINEINL                     2
>> +#define SUN8I_ADDA_LOMIXSC_DACL                        1
>> +#define SUN8I_ADDA_LOMIXSC_DACR                        0
>> +#define SUN8I_ADDA_ROMIXSC                             0x02
>> +#define SUN8I_ADDA_ROMIXSC_MIC1                        6
>> +#define SUN8I_ADDA_ROMIXSC_MIC2                        5
>> +#define SUN8I_ADDA_ROMIXSC_PHONE                       4
>> +#define SUN8I_ADDA_ROMIXSC_PHONEP                      3
>> +#define SUN8I_ADDA_ROMIXSC_LINEINR                     2
>> +#define SUN8I_ADDA_ROMIXSC_DACR                        1
>> +#define SUN8I_ADDA_ROMIXSC_DACL                        0
>> +#define SUN8I_ADDA_DAC_PA_SRC                          0x03
>> +#define SUN8I_ADDA_DAC_PA_SRC_DACAREN                  7
>> +#define SUN8I_ADDA_DAC_PA_SRC_DACALEN                  6
>> +#define SUN8I_ADDA_DAC_PA_SRC_RMIXEN                   5
>> +#define SUN8I_ADDA_DAC_PA_SRC_LMIXEN                   4
>> +#define SUN8I_ADDA_DAC_PA_SRC_RHPPAMUTE                3
>> +#define SUN8I_ADDA_DAC_PA_SRC_LHPPAMUTE                2
>> +#define SUN8I_ADDA_DAC_PA_SRC_RHPIS                    1
>> +#define SUN8I_ADDA_DAC_PA_SRC_LHPIS                    0
>> +#define SUN8I_ADDA_PHONEIN_GCTRL                       0x04
>> +#define SUN8I_ADDA_PHONEIN_GCTRL_PHONEPG               4
>> +#define SUN8I_ADDA_PHONEIN_GCTRL_PHONENG               0
>> +#define SUN8I_ADDA_LINEIN_GCTRL                        0x05
>> +#define SUN8I_ADDA_LINEIN_GCTRL_LINEING                4
>> +#define SUN8I_ADDA_LINEIN_GCTRL_PHONEG                 0
>> +#define SUN8I_ADDA_MICIN_GCTRL                         0x06
>> +#define SUN8I_ADDA_MICIN_GCTRL_MIC1G                   4
>> +#define SUN8I_ADDA_MICIN_GCTRL_MIC2G                   0
>> +#define SUN8I_ADDA_PAEN_HP_CTRL                        0x07
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN                 7
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_HPCOM_FC               5
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_COMPTEN                4
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_PA_ANTI_POP_CTRL       2
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_LTRNMUTE               1
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_RTLNMUTE               0
>> +#define SUN8I_ADDA_PHONEOUT_CTRL                       0x08
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTG             5
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTEN            4
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS3            3
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS2            2
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS1            1
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS0            0
>> +#define SUN8I_ADDA_PHONE_GAIN_CTRL                     0x09
>> +#define SUN8I_ADDA_PHONE_GAIN_CTRL_PHONEPREG           0
>> +#define SUN8I_ADDA_MIC2G_CTRL                          0x0a
>> +#define SUN8I_ADDA_MIC2G_CTRL_MIC2AMPEN                7
>> +#define SUN8I_ADDA_MIC2G_CTRL_MIC2BOOST                4
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL                  0x0b
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIASEN       7
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MMICBIASEN       6
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIAS_MODE    5
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1AMPEN        3
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1BOOST        0
>> +#define SUN8I_ADDA_PA_ANTI_POP_CTRL                    0x0e
>> +#define SUN8I_ADDA_ADC_AP_EN                           0x0f
>> +
>> +/* Analog control register access bits */
>> +#define ADDA_PR                                0x0 /* PRCM base + 0x1c0 */
>> +#define ADDA_PR_RESET                          BIT(28)
>> +#define ADDA_PR_WRITE                          BIT(24)
>> +#define ADDA_PR_ADDR_SHIFT                     16
>> +#define ADDA_PR_ADDR_MASK                      GENMASK(4, 0)
>> +#define ADDA_PR_DATA_IN_SHIFT                  8
>> +#define ADDA_PR_DATA_IN_MASK                   GENMASK(7, 0)
>> +#define ADDA_PR_DATA_OUT_SHIFT                 0
>> +#define ADDA_PR_DATA_OUT_MASK                  GENMASK(7, 0)
>> +
>> +/* regmap access bits */
>> +static int adda_reg_read(void *context, unsigned int reg, unsigned int *val)
>> +{
>> +       void __iomem *base = context;
>> +       u32 tmp;
>> +
>> +       tmp = readl(base);
>> +
>> +       /* De-assert reset */
>> +       writel(tmp | ADDA_PR_RESET, base);
>> +
>> +       tmp &= ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT);
>> +       tmp |= reg << ADDA_PR_ADDR_SHIFT;
>> +       writel(tmp, base);
>> +
>> +       *val = readl(base) & ADDA_PR_DATA_OUT_MASK;
>> +
>> +       return 0;
>> +}
>> +
>> +static int adda_reg_write(void *context, unsigned int reg, unsigned int val)
>> +{
>> +       void __iomem *base = context;
>> +       u32 tmp;
>> +
>> +       tmp = readl(base);
>> +       /* De-assert reset */
>> +       writel(tmp | ADDA_PR_RESET, base);
>> +
>> +       /* Write the address */
>> +       tmp &= ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT);
>> +       tmp |= reg << ADDA_PR_ADDR_SHIFT;
>> +       writel(tmp, base);
>> +
>> +       /* Write the value */
>> +       tmp &= ~(ADDA_PR_DATA_IN_MASK << ADDA_PR_DATA_IN_SHIFT);
>> +       tmp |= val << ADDA_PR_DATA_IN_SHIFT;
>> +       writel(tmp, base);
>> +
>> +       /* Indicate that the previous value must be written */
>> +       writel(readl(base) | ADDA_PR_WRITE, base);
>> +
>> +       /* Reset the write bit */
>> +       writel(readl(base) & ~(ADDA_PR_WRITE), base);
>> +
>> +       return 0;
>> +}
>> +
>> +struct regmap_config adda_pr_regmap_cfg = {
>> +       .name           = "adda-pr",
>> +       .reg_bits       = 5,
>> +       .reg_stride     = 1,
>> +       .val_bits       = 8,
>> +       .reg_read       = adda_reg_read,
>> +       .reg_write      = adda_reg_write,
>> +       .fast_io        = true,
>> +       .max_register   = 24,
>> +};
>> +
>> +static DECLARE_TLV_DB_SCALE(sun8i_codec_headphone_volume_scale, -6300, 100, 1);
>> +
>> +static const struct snd_kcontrol_new sun8i_analog_widgets[] = {
>> +       SOC_SINGLE_TLV("Headphone Volume", SUN8I_ADDA_HP_VOLC,
>> +                      SUN8I_ADDA_HP_VOLC_HP_VOL, 0x3F, 0,
>> +                      sun8i_codec_headphone_volume_scale),
>> +
>> +       /* Playback Switch */
>> +       SOC_DOUBLE("DAC Playback Switch", SUN8I_ADDA_DAC_PA_SRC,
>> +                  SUN8I_ADDA_DAC_PA_SRC_DACALEN, SUN8I_ADDA_DAC_PA_SRC_DACAREN,
>> +                  1, 0),
>> +
>> +       SOC_DOUBLE("Headphone Playback Switch", SUN8I_ADDA_DAC_PA_SRC,
>> +                  SUN8I_ADDA_DAC_PA_SRC_LHPPAMUTE,
>> +                  SUN8I_ADDA_DAC_PA_SRC_RHPPAMUTE, 1, 0),
>> +};
>> +
>> +/* headphone controls */
>> +static const char * const sun8i_codec_hp_src_enum_text[] = {
>> +       "DAC", "Mixer",
>> +};
>> +
>> +static SOC_ENUM_DOUBLE_DECL(sun8i_codec_hp_src_enum,
>> +                           SUN8I_ADDA_DAC_PA_SRC,
>> +                           SUN8I_ADDA_DAC_PA_SRC_LHPIS,
>> +                           SUN8I_ADDA_DAC_PA_SRC_RHPIS,
>> +                           sun8i_codec_hp_src_enum_text);
>> +
>> +static const struct snd_kcontrol_new sun8i_codec_hp_src[] = {
>> +       SOC_DAPM_ENUM("Headphone Source Playback Route",
>> +                     sun8i_codec_hp_src_enum),
>> +};
>> +
>> +static const struct snd_kcontrol_new sun8i_codec_mixer_controls[] = {
>> +       SOC_DAPM_SINGLE("DAC Left Playback Switch",
>> +                       SUN8I_ADDA_LOMIXSC,
>> +                       SUN8I_ADDA_LOMIXSC_DACL, 1, 0),
>> +       SOC_DAPM_SINGLE("DAC Right Playback Switch",
>> +                       SUN8I_ADDA_ROMIXSC,
>> +                       SUN8I_ADDA_ROMIXSC_DACR, 1, 0),
>> +       SOC_DAPM_SINGLE("DAC Reversed Left Playback Switch",
>> +                       SUN8I_ADDA_LOMIXSC,
>> +                       SUN8I_ADDA_LOMIXSC_DACR, 1, 0),
>> +       SOC_DAPM_SINGLE("DAC Reversed Right Playback Switch",
>> +                       SUN8I_ADDA_ROMIXSC,
>> +                       SUN8I_ADDA_ROMIXSC_DACL, 1, 0),
>> +};
>> +
>> +static const struct snd_soc_dapm_widget sun8i_codec_analog_dapm_widgets[] = {
>> +       /* Mixers */
>> +       SOC_MIXER_ARRAY("Left Mixer", SUN8I_ADDA_DAC_PA_SRC,
>> +                       SUN8I_ADDA_DAC_PA_SRC_LMIXEN, 0,
>> +                       sun8i_codec_mixer_controls),
>> +       SOC_MIXER_ARRAY("Right Mixer", SUN8I_ADDA_DAC_PA_SRC,
>> +                       SUN8I_ADDA_DAC_PA_SRC_RMIXEN, 0,
>> +                       sun8i_codec_mixer_controls),
>> +
>> +       /* Headphone output path */
>> +       SND_SOC_DAPM_MUX("Headphone Source Playback Route",
>> +                        SND_SOC_NOPM, 0, 0, sun8i_codec_hp_src),
>> +       SND_SOC_DAPM_OUT_DRV("Headphone Amp", SUN8I_ADDA_PAEN_HP_CTRL,
>> +                            SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN, 0, NULL, 0),
>> +
>> +       /* Headphone outputs */
>> +       SND_SOC_DAPM_OUTPUT("HP"),
>> +
>> +};
>> +
>> +static const struct snd_soc_dapm_route sun8i_codec_analog_dapm_routes[] = {
>> +       /* Left Mixer Routes */
>> +       { "Left Mixer", "DAC Playback Switch", "Left DAC" },
>> +       { "Left Mixer", "DAC Reversed Left Playback Switch", "Right DAC" },
>> +
>> +       /* Right Mixer Routes */
>> +       { "Right Mixer", "DAC Playback Switch", "Right DAC" },
>> +       { "Right Mixer", "DAC Reversed Right Playback Switch", "Left DAC" },
>> +
>> +       /* Headphone Routes */
>> +       { "Headphone Source Playback Route", "DAC", "Left DAC" },
>> +       { "Headphone Source Playback Route", "DAC", "Right DAC" },
>> +       { "Headphone Source Playback Route", "Mixer", "Left Mixer" },
>> +       { "Headphone Source Playback Route", "Mixer", "Right Mixer" },
>> +       { "Headphone Amp", NULL, "Headphone Source Playback Route" },
>> +       { "HP", NULL, "Headphone Amp" },
>> +};
>> +
>> +static const struct snd_soc_component_driver sun8i_codec_analog_cmpnt_drv = {
>> +       .name                   = "sun8i-codec-analog",
>> +       .controls               = sun8i_analog_widgets,
>> +       .num_controls           = ARRAY_SIZE(sun8i_analog_widgets),
>> +       .dapm_widgets           = sun8i_codec_analog_dapm_widgets,
>> +       .num_dapm_widgets       = ARRAY_SIZE(sun8i_codec_analog_dapm_widgets),
>> +       .dapm_routes            = sun8i_codec_analog_dapm_routes,
>> +       .num_dapm_routes        = ARRAY_SIZE(sun8i_codec_analog_dapm_routes),
>> +};
>> +
>> +static const struct of_device_id sun8i_codec_analog_of_match[] = {
>> +       { .compatible = "allwinner,sun8i-codec-analog", },
>> +       {}
>> +};
>> +MODULE_DEVICE_TABLE(of, sun8i_codec_analog_of_match);
>> +
>> +static int sun8i_codec_analog_probe(struct platform_device *pdev)
>> +{
>> +       struct resource *res;
>> +       struct regmap *regmap;
>> +       void __iomem *base;
>> +
>> +       /* Get PRCM resources and registers */
>> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> +       base = devm_ioremap_resource(&pdev->dev, res);
>> +       if (IS_ERR(base)) {
>> +               dev_err(&pdev->dev, "Failed to map PRCM registers\n");
>> +               return PTR_ERR(base);
>> +       }
>> +
>> +       regmap = devm_regmap_init(&pdev->dev, NULL, base, &adda_pr_regmap_cfg);
>> +       if (IS_ERR(regmap)) {
>> +               dev_err(&pdev->dev, "Regmap initialisation failed\n");
>> +               return PTR_ERR(regmap);
>> +       }
>> +
>> +       return devm_snd_soc_register_component(&pdev->dev,
>> +                                              &sun8i_codec_analog_cmpnt_drv,
>> +                                              NULL, 0);
>> +}
>> +
>> +static struct platform_driver sun8i_codec_analog_driver = {
>> +       .driver = {
>> +               .name = "sun8i-codec-analog",
>> +               .of_match_table = sun8i_codec_analog_of_match,
>> +       },
>> +       .probe = sun8i_codec_analog_probe,
>> +};
>> +module_platform_driver(sun8i_codec_analog_driver);
>> +
>> +MODULE_DESCRIPTION("Allwinner A31s/A33/A23 codec analog controls driver");
> Does the A31s have the prcm for the codec?, as I was under the
> impression that it was the same as the A31 and I can't seem to find a
> datasheet for that SoC. You could also add H3 and A64 here.

Yes it does, which is why I made this driver.

You can find the datasheet for the A31s in Allwinner's Github repo:

    https://github.com/allwinner-zh/documents

ChenYu

> CK
>> +MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
>> +MODULE_AUTHOR("Mylène Josserand <mylene.josserand@free-electrons.com>");
>> +MODULE_LICENSE("GPL");
>> +MODULE_ALIAS("platform:sun8i-codec-analog");
>> --
>> 2.9.3
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 04/14] ASoC: Add sun8i analog codec driver
@ 2016-10-04 10:56         ` Chen-Yu Tsai
  0 siblings, 0 replies; 170+ messages in thread
From: Chen-Yu Tsai @ 2016-10-04 10:56 UTC (permalink / raw)
  To: Code Kipper
  Cc: Mylène Josserand, Vinod Koul, Maxime Ripard, Chen-Yu Tsai,
	Michael Turquette, Stephen Boyd, Liam Girdwood, Mark Brown,
	Jaroslav Kysela, Takashi Iwai, Lee Jones, Mark Rutland,
	Rob Herring, Thomas Petazzoni, devicetree, Linux-ALSA,
	linux-kernel, linux-sunxi, Alexandre Belloni, dmaengine,
	linux-clk, linux-arm-kernel

On Tue, Oct 4, 2016 at 6:21 PM, Code Kipper <codekipper@gmail.com> wrote:
> On 4 October 2016 at 11:46, Myl=C3=A8ne Josserand
> <mylene.josserand@free-electrons.com> wrote:
>> Add the analog part of the sun8i (A33) codec driver. This driver
>> implements all the analog part of the codec using PRCM registers.
>>
>> The read/write regmap functions must be handled in a custom way as
>> the PRCM register behaves as "mailbox" register.
>>
>> Signed-off-by: Myl=C3=A8ne Josserand <mylene.josserand@free-electrons.co=
m>
>> ---
>>  sound/soc/sunxi/Kconfig              |   7 +
>>  sound/soc/sunxi/Makefile             |   1 +
>>  sound/soc/sunxi/sun8i-codec-analog.c | 304 ++++++++++++++++++++++++++++=
+++++++
>>  3 files changed, 312 insertions(+)
>>  create mode 100644 sound/soc/sunxi/sun8i-codec-analog.c
>>
>> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
>> index dd23682..7aee95a 100644
>> --- a/sound/soc/sunxi/Kconfig
>> +++ b/sound/soc/sunxi/Kconfig
>> @@ -26,4 +26,11 @@ config SND_SUN4I_SPDIF
>>         help
>>           Say Y or M to add support for the S/PDIF audio block in the Al=
lwinner
>>           A10 and affiliated SoCs.
>> +
>> +config SND_SUN8I_CODEC_ANALOG
>> +       tristate "Allwinner SUN8I analog codec"
>> +       select REGMAP_MMIO
>> +        help
>> +         Say Y or M if you want to add sun8i analog audiocodec support
>> +
>>  endmenu
>> diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
>> index 604c7b84..241c0df 100644
>> --- a/sound/soc/sunxi/Makefile
>> +++ b/sound/soc/sunxi/Makefile
>> @@ -1,3 +1,4 @@
>>  obj-$(CONFIG_SND_SUN4I_CODEC) +=3D sun4i-codec.o
>>  obj-$(CONFIG_SND_SUN4I_I2S) +=3D sun4i-i2s.o
>>  obj-$(CONFIG_SND_SUN4I_SPDIF) +=3D sun4i-spdif.o
>> +obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) +=3D sun8i-codec-analog.o
>> diff --git a/sound/soc/sunxi/sun8i-codec-analog.c b/sound/soc/sunxi/sun8=
i-codec-analog.c
>> new file mode 100644
>> index 0000000..be3d540
>> --- /dev/null
>> +++ b/sound/soc/sunxi/sun8i-codec-analog.c
>> @@ -0,0 +1,304 @@
>> +/*
>> + * This driver supports the analog controls for the internal codec
>> + * found in Allwinner's A31s, A33 and A23 SoCs.
>> + *
>> + * Copyright 2016 Chen-Yu Tsai <wens@csie.org>
>> + * Copyright 2016 Myl=C3=A8ne Josserand <mylene.josserand@free-electron=
s.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + */
>> +
>> +#include <linux/module.h>
>> +#include <linux/io.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/regmap.h>
>> +
>> +#include <sound/soc.h>
>> +#include <sound/soc-dapm.h>
>> +#include <sound/tlv.h>
>> +
>> +/* Codec analog control register offsets and bit fields */
>> +#define SUN8I_ADDA_HP_VOLC                             0x00
>> +#define SUN8I_ADDA_HP_VOLC_PA_CLK_GATE                 7
>> +#define SUN8I_ADDA_HP_VOLC_HP_VOL                      0
>> +#define SUN8I_ADDA_LOMIXSC                             0x01
>> +#define SUN8I_ADDA_LOMIXSC_MIC1                        6
>> +#define SUN8I_ADDA_LOMIXSC_MIC2                        5
>> +#define SUN8I_ADDA_LOMIXSC_PHONE                       4
>> +#define SUN8I_ADDA_LOMIXSC_PHONEN                      3
>> +#define SUN8I_ADDA_LOMIXSC_LINEINL                     2
>> +#define SUN8I_ADDA_LOMIXSC_DACL                        1
>> +#define SUN8I_ADDA_LOMIXSC_DACR                        0
>> +#define SUN8I_ADDA_ROMIXSC                             0x02
>> +#define SUN8I_ADDA_ROMIXSC_MIC1                        6
>> +#define SUN8I_ADDA_ROMIXSC_MIC2                        5
>> +#define SUN8I_ADDA_ROMIXSC_PHONE                       4
>> +#define SUN8I_ADDA_ROMIXSC_PHONEP                      3
>> +#define SUN8I_ADDA_ROMIXSC_LINEINR                     2
>> +#define SUN8I_ADDA_ROMIXSC_DACR                        1
>> +#define SUN8I_ADDA_ROMIXSC_DACL                        0
>> +#define SUN8I_ADDA_DAC_PA_SRC                          0x03
>> +#define SUN8I_ADDA_DAC_PA_SRC_DACAREN                  7
>> +#define SUN8I_ADDA_DAC_PA_SRC_DACALEN                  6
>> +#define SUN8I_ADDA_DAC_PA_SRC_RMIXEN                   5
>> +#define SUN8I_ADDA_DAC_PA_SRC_LMIXEN                   4
>> +#define SUN8I_ADDA_DAC_PA_SRC_RHPPAMUTE                3
>> +#define SUN8I_ADDA_DAC_PA_SRC_LHPPAMUTE                2
>> +#define SUN8I_ADDA_DAC_PA_SRC_RHPIS                    1
>> +#define SUN8I_ADDA_DAC_PA_SRC_LHPIS                    0
>> +#define SUN8I_ADDA_PHONEIN_GCTRL                       0x04
>> +#define SUN8I_ADDA_PHONEIN_GCTRL_PHONEPG               4
>> +#define SUN8I_ADDA_PHONEIN_GCTRL_PHONENG               0
>> +#define SUN8I_ADDA_LINEIN_GCTRL                        0x05
>> +#define SUN8I_ADDA_LINEIN_GCTRL_LINEING                4
>> +#define SUN8I_ADDA_LINEIN_GCTRL_PHONEG                 0
>> +#define SUN8I_ADDA_MICIN_GCTRL                         0x06
>> +#define SUN8I_ADDA_MICIN_GCTRL_MIC1G                   4
>> +#define SUN8I_ADDA_MICIN_GCTRL_MIC2G                   0
>> +#define SUN8I_ADDA_PAEN_HP_CTRL                        0x07
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN                 7
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_HPCOM_FC               5
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_COMPTEN                4
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_PA_ANTI_POP_CTRL       2
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_LTRNMUTE               1
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_RTLNMUTE               0
>> +#define SUN8I_ADDA_PHONEOUT_CTRL                       0x08
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTG             5
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTEN            4
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS3            3
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS2            2
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS1            1
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS0            0
>> +#define SUN8I_ADDA_PHONE_GAIN_CTRL                     0x09
>> +#define SUN8I_ADDA_PHONE_GAIN_CTRL_PHONEPREG           0
>> +#define SUN8I_ADDA_MIC2G_CTRL                          0x0a
>> +#define SUN8I_ADDA_MIC2G_CTRL_MIC2AMPEN                7
>> +#define SUN8I_ADDA_MIC2G_CTRL_MIC2BOOST                4
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL                  0x0b
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIASEN       7
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MMICBIASEN       6
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIAS_MODE    5
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1AMPEN        3
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1BOOST        0
>> +#define SUN8I_ADDA_PA_ANTI_POP_CTRL                    0x0e
>> +#define SUN8I_ADDA_ADC_AP_EN                           0x0f
>> +
>> +/* Analog control register access bits */
>> +#define ADDA_PR                                0x0 /* PRCM base + 0x1c0=
 */
>> +#define ADDA_PR_RESET                          BIT(28)
>> +#define ADDA_PR_WRITE                          BIT(24)
>> +#define ADDA_PR_ADDR_SHIFT                     16
>> +#define ADDA_PR_ADDR_MASK                      GENMASK(4, 0)
>> +#define ADDA_PR_DATA_IN_SHIFT                  8
>> +#define ADDA_PR_DATA_IN_MASK                   GENMASK(7, 0)
>> +#define ADDA_PR_DATA_OUT_SHIFT                 0
>> +#define ADDA_PR_DATA_OUT_MASK                  GENMASK(7, 0)
>> +
>> +/* regmap access bits */
>> +static int adda_reg_read(void *context, unsigned int reg, unsigned int =
*val)
>> +{
>> +       void __iomem *base =3D context;
>> +       u32 tmp;
>> +
>> +       tmp =3D readl(base);
>> +
>> +       /* De-assert reset */
>> +       writel(tmp | ADDA_PR_RESET, base);
>> +
>> +       tmp &=3D ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT);
>> +       tmp |=3D reg << ADDA_PR_ADDR_SHIFT;
>> +       writel(tmp, base);
>> +
>> +       *val =3D readl(base) & ADDA_PR_DATA_OUT_MASK;
>> +
>> +       return 0;
>> +}
>> +
>> +static int adda_reg_write(void *context, unsigned int reg, unsigned int=
 val)
>> +{
>> +       void __iomem *base =3D context;
>> +       u32 tmp;
>> +
>> +       tmp =3D readl(base);
>> +       /* De-assert reset */
>> +       writel(tmp | ADDA_PR_RESET, base);
>> +
>> +       /* Write the address */
>> +       tmp &=3D ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT);
>> +       tmp |=3D reg << ADDA_PR_ADDR_SHIFT;
>> +       writel(tmp, base);
>> +
>> +       /* Write the value */
>> +       tmp &=3D ~(ADDA_PR_DATA_IN_MASK << ADDA_PR_DATA_IN_SHIFT);
>> +       tmp |=3D val << ADDA_PR_DATA_IN_SHIFT;
>> +       writel(tmp, base);
>> +
>> +       /* Indicate that the previous value must be written */
>> +       writel(readl(base) | ADDA_PR_WRITE, base);
>> +
>> +       /* Reset the write bit */
>> +       writel(readl(base) & ~(ADDA_PR_WRITE), base);
>> +
>> +       return 0;
>> +}
>> +
>> +struct regmap_config adda_pr_regmap_cfg =3D {
>> +       .name           =3D "adda-pr",
>> +       .reg_bits       =3D 5,
>> +       .reg_stride     =3D 1,
>> +       .val_bits       =3D 8,
>> +       .reg_read       =3D adda_reg_read,
>> +       .reg_write      =3D adda_reg_write,
>> +       .fast_io        =3D true,
>> +       .max_register   =3D 24,
>> +};
>> +
>> +static DECLARE_TLV_DB_SCALE(sun8i_codec_headphone_volume_scale, -6300, =
100, 1);
>> +
>> +static const struct snd_kcontrol_new sun8i_analog_widgets[] =3D {
>> +       SOC_SINGLE_TLV("Headphone Volume", SUN8I_ADDA_HP_VOLC,
>> +                      SUN8I_ADDA_HP_VOLC_HP_VOL, 0x3F, 0,
>> +                      sun8i_codec_headphone_volume_scale),
>> +
>> +       /* Playback Switch */
>> +       SOC_DOUBLE("DAC Playback Switch", SUN8I_ADDA_DAC_PA_SRC,
>> +                  SUN8I_ADDA_DAC_PA_SRC_DACALEN, SUN8I_ADDA_DAC_PA_SRC_=
DACAREN,
>> +                  1, 0),
>> +
>> +       SOC_DOUBLE("Headphone Playback Switch", SUN8I_ADDA_DAC_PA_SRC,
>> +                  SUN8I_ADDA_DAC_PA_SRC_LHPPAMUTE,
>> +                  SUN8I_ADDA_DAC_PA_SRC_RHPPAMUTE, 1, 0),
>> +};
>> +
>> +/* headphone controls */
>> +static const char * const sun8i_codec_hp_src_enum_text[] =3D {
>> +       "DAC", "Mixer",
>> +};
>> +
>> +static SOC_ENUM_DOUBLE_DECL(sun8i_codec_hp_src_enum,
>> +                           SUN8I_ADDA_DAC_PA_SRC,
>> +                           SUN8I_ADDA_DAC_PA_SRC_LHPIS,
>> +                           SUN8I_ADDA_DAC_PA_SRC_RHPIS,
>> +                           sun8i_codec_hp_src_enum_text);
>> +
>> +static const struct snd_kcontrol_new sun8i_codec_hp_src[] =3D {
>> +       SOC_DAPM_ENUM("Headphone Source Playback Route",
>> +                     sun8i_codec_hp_src_enum),
>> +};
>> +
>> +static const struct snd_kcontrol_new sun8i_codec_mixer_controls[] =3D {
>> +       SOC_DAPM_SINGLE("DAC Left Playback Switch",
>> +                       SUN8I_ADDA_LOMIXSC,
>> +                       SUN8I_ADDA_LOMIXSC_DACL, 1, 0),
>> +       SOC_DAPM_SINGLE("DAC Right Playback Switch",
>> +                       SUN8I_ADDA_ROMIXSC,
>> +                       SUN8I_ADDA_ROMIXSC_DACR, 1, 0),
>> +       SOC_DAPM_SINGLE("DAC Reversed Left Playback Switch",
>> +                       SUN8I_ADDA_LOMIXSC,
>> +                       SUN8I_ADDA_LOMIXSC_DACR, 1, 0),
>> +       SOC_DAPM_SINGLE("DAC Reversed Right Playback Switch",
>> +                       SUN8I_ADDA_ROMIXSC,
>> +                       SUN8I_ADDA_ROMIXSC_DACL, 1, 0),
>> +};
>> +
>> +static const struct snd_soc_dapm_widget sun8i_codec_analog_dapm_widgets=
[] =3D {
>> +       /* Mixers */
>> +       SOC_MIXER_ARRAY("Left Mixer", SUN8I_ADDA_DAC_PA_SRC,
>> +                       SUN8I_ADDA_DAC_PA_SRC_LMIXEN, 0,
>> +                       sun8i_codec_mixer_controls),
>> +       SOC_MIXER_ARRAY("Right Mixer", SUN8I_ADDA_DAC_PA_SRC,
>> +                       SUN8I_ADDA_DAC_PA_SRC_RMIXEN, 0,
>> +                       sun8i_codec_mixer_controls),
>> +
>> +       /* Headphone output path */
>> +       SND_SOC_DAPM_MUX("Headphone Source Playback Route",
>> +                        SND_SOC_NOPM, 0, 0, sun8i_codec_hp_src),
>> +       SND_SOC_DAPM_OUT_DRV("Headphone Amp", SUN8I_ADDA_PAEN_HP_CTRL,
>> +                            SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN, 0, NULL, 0)=
,
>> +
>> +       /* Headphone outputs */
>> +       SND_SOC_DAPM_OUTPUT("HP"),
>> +
>> +};
>> +
>> +static const struct snd_soc_dapm_route sun8i_codec_analog_dapm_routes[]=
 =3D {
>> +       /* Left Mixer Routes */
>> +       { "Left Mixer", "DAC Playback Switch", "Left DAC" },
>> +       { "Left Mixer", "DAC Reversed Left Playback Switch", "Right DAC"=
 },
>> +
>> +       /* Right Mixer Routes */
>> +       { "Right Mixer", "DAC Playback Switch", "Right DAC" },
>> +       { "Right Mixer", "DAC Reversed Right Playback Switch", "Left DAC=
" },
>> +
>> +       /* Headphone Routes */
>> +       { "Headphone Source Playback Route", "DAC", "Left DAC" },
>> +       { "Headphone Source Playback Route", "DAC", "Right DAC" },
>> +       { "Headphone Source Playback Route", "Mixer", "Left Mixer" },
>> +       { "Headphone Source Playback Route", "Mixer", "Right Mixer" },
>> +       { "Headphone Amp", NULL, "Headphone Source Playback Route" },
>> +       { "HP", NULL, "Headphone Amp" },
>> +};
>> +
>> +static const struct snd_soc_component_driver sun8i_codec_analog_cmpnt_d=
rv =3D {
>> +       .name                   =3D "sun8i-codec-analog",
>> +       .controls               =3D sun8i_analog_widgets,
>> +       .num_controls           =3D ARRAY_SIZE(sun8i_analog_widgets),
>> +       .dapm_widgets           =3D sun8i_codec_analog_dapm_widgets,
>> +       .num_dapm_widgets       =3D ARRAY_SIZE(sun8i_codec_analog_dapm_w=
idgets),
>> +       .dapm_routes            =3D sun8i_codec_analog_dapm_routes,
>> +       .num_dapm_routes        =3D ARRAY_SIZE(sun8i_codec_analog_dapm_r=
outes),
>> +};
>> +
>> +static const struct of_device_id sun8i_codec_analog_of_match[] =3D {
>> +       { .compatible =3D "allwinner,sun8i-codec-analog", },
>> +       {}
>> +};
>> +MODULE_DEVICE_TABLE(of, sun8i_codec_analog_of_match);
>> +
>> +static int sun8i_codec_analog_probe(struct platform_device *pdev)
>> +{
>> +       struct resource *res;
>> +       struct regmap *regmap;
>> +       void __iomem *base;
>> +
>> +       /* Get PRCM resources and registers */
>> +       res =3D platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> +       base =3D devm_ioremap_resource(&pdev->dev, res);
>> +       if (IS_ERR(base)) {
>> +               dev_err(&pdev->dev, "Failed to map PRCM registers\n");
>> +               return PTR_ERR(base);
>> +       }
>> +
>> +       regmap =3D devm_regmap_init(&pdev->dev, NULL, base, &adda_pr_reg=
map_cfg);
>> +       if (IS_ERR(regmap)) {
>> +               dev_err(&pdev->dev, "Regmap initialisation failed\n");
>> +               return PTR_ERR(regmap);
>> +       }
>> +
>> +       return devm_snd_soc_register_component(&pdev->dev,
>> +                                              &sun8i_codec_analog_cmpnt=
_drv,
>> +                                              NULL, 0);
>> +}
>> +
>> +static struct platform_driver sun8i_codec_analog_driver =3D {
>> +       .driver =3D {
>> +               .name =3D "sun8i-codec-analog",
>> +               .of_match_table =3D sun8i_codec_analog_of_match,
>> +       },
>> +       .probe =3D sun8i_codec_analog_probe,
>> +};
>> +module_platform_driver(sun8i_codec_analog_driver);
>> +
>> +MODULE_DESCRIPTION("Allwinner A31s/A33/A23 codec analog controls driver=
");
> Does the A31s have the prcm for the codec?, as I was under the
> impression that it was the same as the A31 and I can't seem to find a
> datasheet for that SoC. You could also add H3 and A64 here.

Yes it does, which is why I made this driver.

You can find the datasheet for the A31s in Allwinner's Github repo:

    https://github.com/allwinner-zh/documents

ChenYu

> CK
>> +MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
>> +MODULE_AUTHOR("Myl=C3=A8ne Josserand <mylene.josserand@free-electrons.c=
om>");
>> +MODULE_LICENSE("GPL");
>> +MODULE_ALIAS("platform:sun8i-codec-analog");
>> --
>> 2.9.3
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 04/14] ASoC: Add sun8i analog codec driver
@ 2016-10-04 10:56         ` Chen-Yu Tsai
  0 siblings, 0 replies; 170+ messages in thread
From: Chen-Yu Tsai @ 2016-10-04 10:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 4, 2016 at 6:21 PM, Code Kipper <codekipper@gmail.com> wrote:
> On 4 October 2016 at 11:46, Myl?ne Josserand
> <mylene.josserand@free-electrons.com> wrote:
>> Add the analog part of the sun8i (A33) codec driver. This driver
>> implements all the analog part of the codec using PRCM registers.
>>
>> The read/write regmap functions must be handled in a custom way as
>> the PRCM register behaves as "mailbox" register.
>>
>> Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
>> ---
>>  sound/soc/sunxi/Kconfig              |   7 +
>>  sound/soc/sunxi/Makefile             |   1 +
>>  sound/soc/sunxi/sun8i-codec-analog.c | 304 +++++++++++++++++++++++++++++++++++
>>  3 files changed, 312 insertions(+)
>>  create mode 100644 sound/soc/sunxi/sun8i-codec-analog.c
>>
>> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
>> index dd23682..7aee95a 100644
>> --- a/sound/soc/sunxi/Kconfig
>> +++ b/sound/soc/sunxi/Kconfig
>> @@ -26,4 +26,11 @@ config SND_SUN4I_SPDIF
>>         help
>>           Say Y or M to add support for the S/PDIF audio block in the Allwinner
>>           A10 and affiliated SoCs.
>> +
>> +config SND_SUN8I_CODEC_ANALOG
>> +       tristate "Allwinner SUN8I analog codec"
>> +       select REGMAP_MMIO
>> +        help
>> +         Say Y or M if you want to add sun8i analog audiocodec support
>> +
>>  endmenu
>> diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
>> index 604c7b84..241c0df 100644
>> --- a/sound/soc/sunxi/Makefile
>> +++ b/sound/soc/sunxi/Makefile
>> @@ -1,3 +1,4 @@
>>  obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
>>  obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
>>  obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
>> +obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
>> diff --git a/sound/soc/sunxi/sun8i-codec-analog.c b/sound/soc/sunxi/sun8i-codec-analog.c
>> new file mode 100644
>> index 0000000..be3d540
>> --- /dev/null
>> +++ b/sound/soc/sunxi/sun8i-codec-analog.c
>> @@ -0,0 +1,304 @@
>> +/*
>> + * This driver supports the analog controls for the internal codec
>> + * found in Allwinner's A31s, A33 and A23 SoCs.
>> + *
>> + * Copyright 2016 Chen-Yu Tsai <wens@csie.org>
>> + * Copyright 2016 Myl?ne Josserand <mylene.josserand@free-electrons.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + */
>> +
>> +#include <linux/module.h>
>> +#include <linux/io.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/regmap.h>
>> +
>> +#include <sound/soc.h>
>> +#include <sound/soc-dapm.h>
>> +#include <sound/tlv.h>
>> +
>> +/* Codec analog control register offsets and bit fields */
>> +#define SUN8I_ADDA_HP_VOLC                             0x00
>> +#define SUN8I_ADDA_HP_VOLC_PA_CLK_GATE                 7
>> +#define SUN8I_ADDA_HP_VOLC_HP_VOL                      0
>> +#define SUN8I_ADDA_LOMIXSC                             0x01
>> +#define SUN8I_ADDA_LOMIXSC_MIC1                        6
>> +#define SUN8I_ADDA_LOMIXSC_MIC2                        5
>> +#define SUN8I_ADDA_LOMIXSC_PHONE                       4
>> +#define SUN8I_ADDA_LOMIXSC_PHONEN                      3
>> +#define SUN8I_ADDA_LOMIXSC_LINEINL                     2
>> +#define SUN8I_ADDA_LOMIXSC_DACL                        1
>> +#define SUN8I_ADDA_LOMIXSC_DACR                        0
>> +#define SUN8I_ADDA_ROMIXSC                             0x02
>> +#define SUN8I_ADDA_ROMIXSC_MIC1                        6
>> +#define SUN8I_ADDA_ROMIXSC_MIC2                        5
>> +#define SUN8I_ADDA_ROMIXSC_PHONE                       4
>> +#define SUN8I_ADDA_ROMIXSC_PHONEP                      3
>> +#define SUN8I_ADDA_ROMIXSC_LINEINR                     2
>> +#define SUN8I_ADDA_ROMIXSC_DACR                        1
>> +#define SUN8I_ADDA_ROMIXSC_DACL                        0
>> +#define SUN8I_ADDA_DAC_PA_SRC                          0x03
>> +#define SUN8I_ADDA_DAC_PA_SRC_DACAREN                  7
>> +#define SUN8I_ADDA_DAC_PA_SRC_DACALEN                  6
>> +#define SUN8I_ADDA_DAC_PA_SRC_RMIXEN                   5
>> +#define SUN8I_ADDA_DAC_PA_SRC_LMIXEN                   4
>> +#define SUN8I_ADDA_DAC_PA_SRC_RHPPAMUTE                3
>> +#define SUN8I_ADDA_DAC_PA_SRC_LHPPAMUTE                2
>> +#define SUN8I_ADDA_DAC_PA_SRC_RHPIS                    1
>> +#define SUN8I_ADDA_DAC_PA_SRC_LHPIS                    0
>> +#define SUN8I_ADDA_PHONEIN_GCTRL                       0x04
>> +#define SUN8I_ADDA_PHONEIN_GCTRL_PHONEPG               4
>> +#define SUN8I_ADDA_PHONEIN_GCTRL_PHONENG               0
>> +#define SUN8I_ADDA_LINEIN_GCTRL                        0x05
>> +#define SUN8I_ADDA_LINEIN_GCTRL_LINEING                4
>> +#define SUN8I_ADDA_LINEIN_GCTRL_PHONEG                 0
>> +#define SUN8I_ADDA_MICIN_GCTRL                         0x06
>> +#define SUN8I_ADDA_MICIN_GCTRL_MIC1G                   4
>> +#define SUN8I_ADDA_MICIN_GCTRL_MIC2G                   0
>> +#define SUN8I_ADDA_PAEN_HP_CTRL                        0x07
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN                 7
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_HPCOM_FC               5
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_COMPTEN                4
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_PA_ANTI_POP_CTRL       2
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_LTRNMUTE               1
>> +#define SUN8I_ADDA_PAEN_HP_CTRL_RTLNMUTE               0
>> +#define SUN8I_ADDA_PHONEOUT_CTRL                       0x08
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTG             5
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTEN            4
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS3            3
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS2            2
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS1            1
>> +#define SUN8I_ADDA_PHONEOUT_CTRL_PHONEOUTS0            0
>> +#define SUN8I_ADDA_PHONE_GAIN_CTRL                     0x09
>> +#define SUN8I_ADDA_PHONE_GAIN_CTRL_PHONEPREG           0
>> +#define SUN8I_ADDA_MIC2G_CTRL                          0x0a
>> +#define SUN8I_ADDA_MIC2G_CTRL_MIC2AMPEN                7
>> +#define SUN8I_ADDA_MIC2G_CTRL_MIC2BOOST                4
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL                  0x0b
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIASEN       7
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MMICBIASEN       6
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_HMICBIAS_MODE    5
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1AMPEN        3
>> +#define SUN8I_ADDA_MIC1G_MICBIAS_CTRL_MIC1BOOST        0
>> +#define SUN8I_ADDA_PA_ANTI_POP_CTRL                    0x0e
>> +#define SUN8I_ADDA_ADC_AP_EN                           0x0f
>> +
>> +/* Analog control register access bits */
>> +#define ADDA_PR                                0x0 /* PRCM base + 0x1c0 */
>> +#define ADDA_PR_RESET                          BIT(28)
>> +#define ADDA_PR_WRITE                          BIT(24)
>> +#define ADDA_PR_ADDR_SHIFT                     16
>> +#define ADDA_PR_ADDR_MASK                      GENMASK(4, 0)
>> +#define ADDA_PR_DATA_IN_SHIFT                  8
>> +#define ADDA_PR_DATA_IN_MASK                   GENMASK(7, 0)
>> +#define ADDA_PR_DATA_OUT_SHIFT                 0
>> +#define ADDA_PR_DATA_OUT_MASK                  GENMASK(7, 0)
>> +
>> +/* regmap access bits */
>> +static int adda_reg_read(void *context, unsigned int reg, unsigned int *val)
>> +{
>> +       void __iomem *base = context;
>> +       u32 tmp;
>> +
>> +       tmp = readl(base);
>> +
>> +       /* De-assert reset */
>> +       writel(tmp | ADDA_PR_RESET, base);
>> +
>> +       tmp &= ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT);
>> +       tmp |= reg << ADDA_PR_ADDR_SHIFT;
>> +       writel(tmp, base);
>> +
>> +       *val = readl(base) & ADDA_PR_DATA_OUT_MASK;
>> +
>> +       return 0;
>> +}
>> +
>> +static int adda_reg_write(void *context, unsigned int reg, unsigned int val)
>> +{
>> +       void __iomem *base = context;
>> +       u32 tmp;
>> +
>> +       tmp = readl(base);
>> +       /* De-assert reset */
>> +       writel(tmp | ADDA_PR_RESET, base);
>> +
>> +       /* Write the address */
>> +       tmp &= ~(ADDA_PR_ADDR_MASK << ADDA_PR_ADDR_SHIFT);
>> +       tmp |= reg << ADDA_PR_ADDR_SHIFT;
>> +       writel(tmp, base);
>> +
>> +       /* Write the value */
>> +       tmp &= ~(ADDA_PR_DATA_IN_MASK << ADDA_PR_DATA_IN_SHIFT);
>> +       tmp |= val << ADDA_PR_DATA_IN_SHIFT;
>> +       writel(tmp, base);
>> +
>> +       /* Indicate that the previous value must be written */
>> +       writel(readl(base) | ADDA_PR_WRITE, base);
>> +
>> +       /* Reset the write bit */
>> +       writel(readl(base) & ~(ADDA_PR_WRITE), base);
>> +
>> +       return 0;
>> +}
>> +
>> +struct regmap_config adda_pr_regmap_cfg = {
>> +       .name           = "adda-pr",
>> +       .reg_bits       = 5,
>> +       .reg_stride     = 1,
>> +       .val_bits       = 8,
>> +       .reg_read       = adda_reg_read,
>> +       .reg_write      = adda_reg_write,
>> +       .fast_io        = true,
>> +       .max_register   = 24,
>> +};
>> +
>> +static DECLARE_TLV_DB_SCALE(sun8i_codec_headphone_volume_scale, -6300, 100, 1);
>> +
>> +static const struct snd_kcontrol_new sun8i_analog_widgets[] = {
>> +       SOC_SINGLE_TLV("Headphone Volume", SUN8I_ADDA_HP_VOLC,
>> +                      SUN8I_ADDA_HP_VOLC_HP_VOL, 0x3F, 0,
>> +                      sun8i_codec_headphone_volume_scale),
>> +
>> +       /* Playback Switch */
>> +       SOC_DOUBLE("DAC Playback Switch", SUN8I_ADDA_DAC_PA_SRC,
>> +                  SUN8I_ADDA_DAC_PA_SRC_DACALEN, SUN8I_ADDA_DAC_PA_SRC_DACAREN,
>> +                  1, 0),
>> +
>> +       SOC_DOUBLE("Headphone Playback Switch", SUN8I_ADDA_DAC_PA_SRC,
>> +                  SUN8I_ADDA_DAC_PA_SRC_LHPPAMUTE,
>> +                  SUN8I_ADDA_DAC_PA_SRC_RHPPAMUTE, 1, 0),
>> +};
>> +
>> +/* headphone controls */
>> +static const char * const sun8i_codec_hp_src_enum_text[] = {
>> +       "DAC", "Mixer",
>> +};
>> +
>> +static SOC_ENUM_DOUBLE_DECL(sun8i_codec_hp_src_enum,
>> +                           SUN8I_ADDA_DAC_PA_SRC,
>> +                           SUN8I_ADDA_DAC_PA_SRC_LHPIS,
>> +                           SUN8I_ADDA_DAC_PA_SRC_RHPIS,
>> +                           sun8i_codec_hp_src_enum_text);
>> +
>> +static const struct snd_kcontrol_new sun8i_codec_hp_src[] = {
>> +       SOC_DAPM_ENUM("Headphone Source Playback Route",
>> +                     sun8i_codec_hp_src_enum),
>> +};
>> +
>> +static const struct snd_kcontrol_new sun8i_codec_mixer_controls[] = {
>> +       SOC_DAPM_SINGLE("DAC Left Playback Switch",
>> +                       SUN8I_ADDA_LOMIXSC,
>> +                       SUN8I_ADDA_LOMIXSC_DACL, 1, 0),
>> +       SOC_DAPM_SINGLE("DAC Right Playback Switch",
>> +                       SUN8I_ADDA_ROMIXSC,
>> +                       SUN8I_ADDA_ROMIXSC_DACR, 1, 0),
>> +       SOC_DAPM_SINGLE("DAC Reversed Left Playback Switch",
>> +                       SUN8I_ADDA_LOMIXSC,
>> +                       SUN8I_ADDA_LOMIXSC_DACR, 1, 0),
>> +       SOC_DAPM_SINGLE("DAC Reversed Right Playback Switch",
>> +                       SUN8I_ADDA_ROMIXSC,
>> +                       SUN8I_ADDA_ROMIXSC_DACL, 1, 0),
>> +};
>> +
>> +static const struct snd_soc_dapm_widget sun8i_codec_analog_dapm_widgets[] = {
>> +       /* Mixers */
>> +       SOC_MIXER_ARRAY("Left Mixer", SUN8I_ADDA_DAC_PA_SRC,
>> +                       SUN8I_ADDA_DAC_PA_SRC_LMIXEN, 0,
>> +                       sun8i_codec_mixer_controls),
>> +       SOC_MIXER_ARRAY("Right Mixer", SUN8I_ADDA_DAC_PA_SRC,
>> +                       SUN8I_ADDA_DAC_PA_SRC_RMIXEN, 0,
>> +                       sun8i_codec_mixer_controls),
>> +
>> +       /* Headphone output path */
>> +       SND_SOC_DAPM_MUX("Headphone Source Playback Route",
>> +                        SND_SOC_NOPM, 0, 0, sun8i_codec_hp_src),
>> +       SND_SOC_DAPM_OUT_DRV("Headphone Amp", SUN8I_ADDA_PAEN_HP_CTRL,
>> +                            SUN8I_ADDA_PAEN_HP_CTRL_HPPAEN, 0, NULL, 0),
>> +
>> +       /* Headphone outputs */
>> +       SND_SOC_DAPM_OUTPUT("HP"),
>> +
>> +};
>> +
>> +static const struct snd_soc_dapm_route sun8i_codec_analog_dapm_routes[] = {
>> +       /* Left Mixer Routes */
>> +       { "Left Mixer", "DAC Playback Switch", "Left DAC" },
>> +       { "Left Mixer", "DAC Reversed Left Playback Switch", "Right DAC" },
>> +
>> +       /* Right Mixer Routes */
>> +       { "Right Mixer", "DAC Playback Switch", "Right DAC" },
>> +       { "Right Mixer", "DAC Reversed Right Playback Switch", "Left DAC" },
>> +
>> +       /* Headphone Routes */
>> +       { "Headphone Source Playback Route", "DAC", "Left DAC" },
>> +       { "Headphone Source Playback Route", "DAC", "Right DAC" },
>> +       { "Headphone Source Playback Route", "Mixer", "Left Mixer" },
>> +       { "Headphone Source Playback Route", "Mixer", "Right Mixer" },
>> +       { "Headphone Amp", NULL, "Headphone Source Playback Route" },
>> +       { "HP", NULL, "Headphone Amp" },
>> +};
>> +
>> +static const struct snd_soc_component_driver sun8i_codec_analog_cmpnt_drv = {
>> +       .name                   = "sun8i-codec-analog",
>> +       .controls               = sun8i_analog_widgets,
>> +       .num_controls           = ARRAY_SIZE(sun8i_analog_widgets),
>> +       .dapm_widgets           = sun8i_codec_analog_dapm_widgets,
>> +       .num_dapm_widgets       = ARRAY_SIZE(sun8i_codec_analog_dapm_widgets),
>> +       .dapm_routes            = sun8i_codec_analog_dapm_routes,
>> +       .num_dapm_routes        = ARRAY_SIZE(sun8i_codec_analog_dapm_routes),
>> +};
>> +
>> +static const struct of_device_id sun8i_codec_analog_of_match[] = {
>> +       { .compatible = "allwinner,sun8i-codec-analog", },
>> +       {}
>> +};
>> +MODULE_DEVICE_TABLE(of, sun8i_codec_analog_of_match);
>> +
>> +static int sun8i_codec_analog_probe(struct platform_device *pdev)
>> +{
>> +       struct resource *res;
>> +       struct regmap *regmap;
>> +       void __iomem *base;
>> +
>> +       /* Get PRCM resources and registers */
>> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> +       base = devm_ioremap_resource(&pdev->dev, res);
>> +       if (IS_ERR(base)) {
>> +               dev_err(&pdev->dev, "Failed to map PRCM registers\n");
>> +               return PTR_ERR(base);
>> +       }
>> +
>> +       regmap = devm_regmap_init(&pdev->dev, NULL, base, &adda_pr_regmap_cfg);
>> +       if (IS_ERR(regmap)) {
>> +               dev_err(&pdev->dev, "Regmap initialisation failed\n");
>> +               return PTR_ERR(regmap);
>> +       }
>> +
>> +       return devm_snd_soc_register_component(&pdev->dev,
>> +                                              &sun8i_codec_analog_cmpnt_drv,
>> +                                              NULL, 0);
>> +}
>> +
>> +static struct platform_driver sun8i_codec_analog_driver = {
>> +       .driver = {
>> +               .name = "sun8i-codec-analog",
>> +               .of_match_table = sun8i_codec_analog_of_match,
>> +       },
>> +       .probe = sun8i_codec_analog_probe,
>> +};
>> +module_platform_driver(sun8i_codec_analog_driver);
>> +
>> +MODULE_DESCRIPTION("Allwinner A31s/A33/A23 codec analog controls driver");
> Does the A31s have the prcm for the codec?, as I was under the
> impression that it was the same as the A31 and I can't seem to find a
> datasheet for that SoC. You could also add H3 and A64 here.

Yes it does, which is why I made this driver.

You can find the datasheet for the A31s in Allwinner's Github repo:

    https://github.com/allwinner-zh/documents

ChenYu

> CK
>> +MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
>> +MODULE_AUTHOR("Myl?ne Josserand <mylene.josserand@free-electrons.com>");
>> +MODULE_LICENSE("GPL");
>> +MODULE_ALIAS("platform:sun8i-codec-analog");
>> --
>> 2.9.3
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 07/14] ASoC: Add sun8i audio card
  2016-10-04 10:16       ` Code Kipper
  (?)
  (?)
@ 2016-10-04 10:59         ` Chen-Yu Tsai
  -1 siblings, 0 replies; 170+ messages in thread
From: Chen-Yu Tsai @ 2016-10-04 10:59 UTC (permalink / raw)
  To: Code Kipper
  Cc: Mylène Josserand, Vinod Koul, Maxime Ripard, Chen-Yu Tsai,
	Michael Turquette, Stephen Boyd, Liam Girdwood, Mark Brown,
	Jaroslav Kysela, Takashi Iwai, Lee Jones, Mark Rutland,
	Rob Herring, linux-kernel, dmaengine, linux-arm-kernel,
	linux-clk, Linux-ALSA, devicetree, linux-sunxi, Thomas Petazzoni,
	Alexandre Belloni

On Tue, Oct 4, 2016 at 6:16 PM, Code Kipper <codekipper@gmail.com> wrote:
> On 4 October 2016 at 11:46, Mylène Josserand
> <mylene.josserand@free-electrons.com> wrote:
>> Add the audio card for sun8i SoC. This card links the codec driver
>> (digital part) with the DAI driver. The analog codec driver is
>> added as an aux_device.
>>
>> Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
>> ---
>>  sound/soc/sunxi/Kconfig  |  14 +++++++
>>  sound/soc/sunxi/Makefile |   1 +
>>  sound/soc/sunxi/sun8i.c  | 101 +++++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 116 insertions(+)
>>  create mode 100644 sound/soc/sunxi/sun8i.c
>>
>> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
>> index 9e287b0..7b97395 100644
>> --- a/sound/soc/sunxi/Kconfig
>> +++ b/sound/soc/sunxi/Kconfig
>> @@ -27,6 +27,20 @@ config SND_SUN4I_SPDIF
>>           Say Y or M to add support for the S/PDIF audio block in the Allwinner
>>           A10 and affiliated SoCs.
>>
>> +config SND_SUN8I
>> +       tristate "Allwinner SUN6I/SUN8I audio card support"
>> +       select SND_SUN8I_CODEC
>> +       select SND_SUN4I_I2S
>> +       select SND_SUN8I_CODEC_ANALOG
>> +       select REGMAP_MMIO
>> +       help
>> +         This option enables the audio card for Allwinner A33 (sun8i) SoC.
>> +         It enables the DAI driver (SND_SUN4I_I2S), the digital audio
>> +         codec driver (SND_SUN8I_CODEC) and the analog codec driver
>> +         (SND_SUN8I_CODEC_ANALOG).
>> +
>> +         Say Y or M if you want to add sun8i/6i card support
>> +
>>  config SND_SUN8I_CODEC
>>         tristate "Allwinner SUN8I audio codec"
>>         select REGMAP_MMIO
>> diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
>> index 1da63d3..7f1bab9 100644
>> --- a/sound/soc/sunxi/Makefile
>> +++ b/sound/soc/sunxi/Makefile
>> @@ -1,5 +1,6 @@
>>  obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
>>  obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
>>  obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
>> +obj-$(CONFIG_SND_SUN8I) += sun8i.o
> Great work with this...I've been battling with the audio codec for the
> h3 for a while and it looks like almost everything that I need is
> delivered here.
>>  obj-$(CONFIG_SND_SUN8I_CODEC) += sun8i-codec.o
>>  obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
>> diff --git a/sound/soc/sunxi/sun8i.c b/sound/soc/sunxi/sun8i.c
>> new file mode 100644
>> index 0000000..565cd88
>> --- /dev/null
>> +++ b/sound/soc/sunxi/sun8i.c
>> @@ -0,0 +1,101 @@
>> +/*
>> + * ALSA SoC driver for Allwinner sun8i SoC
>> + *
>> + * Copyright (C) 2016 Mylène Josserand <mylene.josserand@free-electrons.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + */
>> +
>> +#include <linux/firmware.h>
>> +#include <linux/module.h>
>> +
>> +#include <sound/soc.h>
>> +
>> +static struct snd_soc_aux_dev sun8i_audio_prcm_aux_devs[] = {
>> +       {
>> +               .name = "sun8i-codec-analog",
>> +               .codec_name = "sun8i-codec-analog.0",
>> +       },
>> +};
>> +
>> +static struct snd_soc_dai_link sun8i_dai_link = {
>> +       .name           = "sun4i-i2s",
>> +       .stream_name    = "Playback",
>> +       .codec_dai_name = "sun8i",
>> +       .dai_fmt        = SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S |
>> +                       SND_SOC_DAIFMT_CBM_CFM,
>> +};
>> +
>> +static struct snd_soc_card sun8i_card = {
>> +       .name           = "sun8i-card",
>> +       .owner          = THIS_MODULE,
>> +       .dai_link       = &sun8i_dai_link,
>> +       .num_links      = 1,
>> +       .aux_dev        = sun8i_audio_prcm_aux_devs,
>> +       .num_aux_devs   = ARRAY_SIZE(sun8i_audio_prcm_aux_devs),
>> +};
>> +
>> +static int sun8i_probe(struct platform_device *pdev)
>> +{
>> +       struct snd_soc_dai_link *link = &sun8i_dai_link;
>> +       struct device_node *np = pdev->dev.of_node;
>> +       int ret;
>> +
>> +       /* register the soc card */
>> +       sun8i_card.dev = &pdev->dev;
>> +
>> +       /* Retrieve the audio-codec from DT */
>> +       link->codec_of_node = of_parse_phandle(np, "allwinner,audio-codec", 0);
>> +       if (!link->codec_of_node) {
>> +               dev_err(&pdev->dev, "Missing audio codec\n");
>> +               return -EINVAL;
>> +       }
>> +
>> +       /* Retrieve DAI from DT */
>> +       link->cpu_of_node = of_parse_phandle(np, "allwinner,i2s-controller", 0);
>> +       if (!link->cpu_of_node) {
>> +               dev_err(&pdev->dev, "Missing I2S controller\n");
>> +               return -EINVAL;
>> +       }
>> +
> My one question is that we have sun8i-a23 and sun8i-a33, and I think
> we need to distinguish them here. The sun8i-a23 doesn't use the i2s
> block but does use the prcm.

Agreed. Both the A23 and H3 follow the A31s, that is the codec is similar
to the A10/A31, but the analog controls are moved to the PRCM. We should
support these kinds with the existing codec driver.

ChenYu

>> +       link->platform_of_node = link->cpu_of_node;
>> +
>> +       /* Register the sound card */
>> +       ret = devm_snd_soc_register_card(&pdev->dev, &sun8i_card);
>> +       if (ret) {
>> +               dev_err(&pdev->dev,
>> +                       "Soc register card failed %d\n", ret);
>> +               return ret;
>> +       }
>> +
>> +       return ret;
>> +}
>> +
>> +static const struct of_device_id sun8i_of_match[] = {
>> +       { .compatible = "allwinner,sun8i-audio", },
>> +       {},
>> +};
>> +
>> +MODULE_DEVICE_TABLE(of, sun8i_of_match);
>> +
>> +static struct platform_driver sun8i_card_driver = {
>> +       .probe = sun8i_probe,
>> +       .driver = {
>> +               .name   = "sun8i-audio",
>> +               .of_match_table = sun8i_of_match,
>> +       },
>> +};
>> +
>> +module_platform_driver(sun8i_card_driver);
>> +
>> +MODULE_AUTHOR("Mylène Josserand <mylene.josserand@free-electrons.com>");
>> +MODULE_DESCRIPTION("Allwinner sun8i machine ASoC driver");
>> +MODULE_LICENSE("GPL v2");
>> --
>> 2.9.3
>>

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

* Re: [PATCH 07/14] ASoC: Add sun8i audio card
@ 2016-10-04 10:59         ` Chen-Yu Tsai
  0 siblings, 0 replies; 170+ messages in thread
From: Chen-Yu Tsai @ 2016-10-04 10:59 UTC (permalink / raw)
  To: Code Kipper
  Cc: Mylène Josserand, Vinod Koul, Maxime Ripard, Chen-Yu Tsai,
	Michael Turquette, Stephen Boyd, Liam Girdwood, Mark Brown,
	Jaroslav Kysela, Takashi Iwai, Lee Jones, Mark Rutland,
	Rob Herring, linux-kernel, dmaengine, linux-arm-kernel,
	linux-clk, Linux-ALSA

On Tue, Oct 4, 2016 at 6:16 PM, Code Kipper <codekipper@gmail.com> wrote:
> On 4 October 2016 at 11:46, Mylène Josserand
> <mylene.josserand@free-electrons.com> wrote:
>> Add the audio card for sun8i SoC. This card links the codec driver
>> (digital part) with the DAI driver. The analog codec driver is
>> added as an aux_device.
>>
>> Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
>> ---
>>  sound/soc/sunxi/Kconfig  |  14 +++++++
>>  sound/soc/sunxi/Makefile |   1 +
>>  sound/soc/sunxi/sun8i.c  | 101 +++++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 116 insertions(+)
>>  create mode 100644 sound/soc/sunxi/sun8i.c
>>
>> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
>> index 9e287b0..7b97395 100644
>> --- a/sound/soc/sunxi/Kconfig
>> +++ b/sound/soc/sunxi/Kconfig
>> @@ -27,6 +27,20 @@ config SND_SUN4I_SPDIF
>>           Say Y or M to add support for the S/PDIF audio block in the Allwinner
>>           A10 and affiliated SoCs.
>>
>> +config SND_SUN8I
>> +       tristate "Allwinner SUN6I/SUN8I audio card support"
>> +       select SND_SUN8I_CODEC
>> +       select SND_SUN4I_I2S
>> +       select SND_SUN8I_CODEC_ANALOG
>> +       select REGMAP_MMIO
>> +       help
>> +         This option enables the audio card for Allwinner A33 (sun8i) SoC.
>> +         It enables the DAI driver (SND_SUN4I_I2S), the digital audio
>> +         codec driver (SND_SUN8I_CODEC) and the analog codec driver
>> +         (SND_SUN8I_CODEC_ANALOG).
>> +
>> +         Say Y or M if you want to add sun8i/6i card support
>> +
>>  config SND_SUN8I_CODEC
>>         tristate "Allwinner SUN8I audio codec"
>>         select REGMAP_MMIO
>> diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
>> index 1da63d3..7f1bab9 100644
>> --- a/sound/soc/sunxi/Makefile
>> +++ b/sound/soc/sunxi/Makefile
>> @@ -1,5 +1,6 @@
>>  obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
>>  obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
>>  obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
>> +obj-$(CONFIG_SND_SUN8I) += sun8i.o
> Great work with this...I've been battling with the audio codec for the
> h3 for a while and it looks like almost everything that I need is
> delivered here.
>>  obj-$(CONFIG_SND_SUN8I_CODEC) += sun8i-codec.o
>>  obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
>> diff --git a/sound/soc/sunxi/sun8i.c b/sound/soc/sunxi/sun8i.c
>> new file mode 100644
>> index 0000000..565cd88
>> --- /dev/null
>> +++ b/sound/soc/sunxi/sun8i.c
>> @@ -0,0 +1,101 @@
>> +/*
>> + * ALSA SoC driver for Allwinner sun8i SoC
>> + *
>> + * Copyright (C) 2016 Mylène Josserand <mylene.josserand@free-electrons.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + */
>> +
>> +#include <linux/firmware.h>
>> +#include <linux/module.h>
>> +
>> +#include <sound/soc.h>
>> +
>> +static struct snd_soc_aux_dev sun8i_audio_prcm_aux_devs[] = {
>> +       {
>> +               .name = "sun8i-codec-analog",
>> +               .codec_name = "sun8i-codec-analog.0",
>> +       },
>> +};
>> +
>> +static struct snd_soc_dai_link sun8i_dai_link = {
>> +       .name           = "sun4i-i2s",
>> +       .stream_name    = "Playback",
>> +       .codec_dai_name = "sun8i",
>> +       .dai_fmt        = SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S |
>> +                       SND_SOC_DAIFMT_CBM_CFM,
>> +};
>> +
>> +static struct snd_soc_card sun8i_card = {
>> +       .name           = "sun8i-card",
>> +       .owner          = THIS_MODULE,
>> +       .dai_link       = &sun8i_dai_link,
>> +       .num_links      = 1,
>> +       .aux_dev        = sun8i_audio_prcm_aux_devs,
>> +       .num_aux_devs   = ARRAY_SIZE(sun8i_audio_prcm_aux_devs),
>> +};
>> +
>> +static int sun8i_probe(struct platform_device *pdev)
>> +{
>> +       struct snd_soc_dai_link *link = &sun8i_dai_link;
>> +       struct device_node *np = pdev->dev.of_node;
>> +       int ret;
>> +
>> +       /* register the soc card */
>> +       sun8i_card.dev = &pdev->dev;
>> +
>> +       /* Retrieve the audio-codec from DT */
>> +       link->codec_of_node = of_parse_phandle(np, "allwinner,audio-codec", 0);
>> +       if (!link->codec_of_node) {
>> +               dev_err(&pdev->dev, "Missing audio codec\n");
>> +               return -EINVAL;
>> +       }
>> +
>> +       /* Retrieve DAI from DT */
>> +       link->cpu_of_node = of_parse_phandle(np, "allwinner,i2s-controller", 0);
>> +       if (!link->cpu_of_node) {
>> +               dev_err(&pdev->dev, "Missing I2S controller\n");
>> +               return -EINVAL;
>> +       }
>> +
> My one question is that we have sun8i-a23 and sun8i-a33, and I think
> we need to distinguish them here. The sun8i-a23 doesn't use the i2s
> block but does use the prcm.

Agreed. Both the A23 and H3 follow the A31s, that is the codec is similar
to the A10/A31, but the analog controls are moved to the PRCM. We should
support these kinds with the existing codec driver.

ChenYu

>> +       link->platform_of_node = link->cpu_of_node;
>> +
>> +       /* Register the sound card */
>> +       ret = devm_snd_soc_register_card(&pdev->dev, &sun8i_card);
>> +       if (ret) {
>> +               dev_err(&pdev->dev,
>> +                       "Soc register card failed %d\n", ret);
>> +               return ret;
>> +       }
>> +
>> +       return ret;
>> +}
>> +
>> +static const struct of_device_id sun8i_of_match[] = {
>> +       { .compatible = "allwinner,sun8i-audio", },
>> +       {},
>> +};
>> +
>> +MODULE_DEVICE_TABLE(of, sun8i_of_match);
>> +
>> +static struct platform_driver sun8i_card_driver = {
>> +       .probe = sun8i_probe,
>> +       .driver = {
>> +               .name   = "sun8i-audio",
>> +               .of_match_table = sun8i_of_match,
>> +       },
>> +};
>> +
>> +module_platform_driver(sun8i_card_driver);
>> +
>> +MODULE_AUTHOR("Mylène Josserand <mylene.josserand@free-electrons.com>");
>> +MODULE_DESCRIPTION("Allwinner sun8i machine ASoC driver");
>> +MODULE_LICENSE("GPL v2");
>> --
>> 2.9.3
>>

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

* Re: [PATCH 07/14] ASoC: Add sun8i audio card
@ 2016-10-04 10:59         ` Chen-Yu Tsai
  0 siblings, 0 replies; 170+ messages in thread
From: Chen-Yu Tsai @ 2016-10-04 10:59 UTC (permalink / raw)
  To: Code Kipper
  Cc: Mylène Josserand, Vinod Koul, Maxime Ripard, Chen-Yu Tsai,
	Michael Turquette, Stephen Boyd, Liam Girdwood, Mark Brown,
	Jaroslav Kysela, Takashi Iwai, Lee Jones, Mark Rutland,
	Rob Herring, linux-kernel, dmaengine, linux-arm-kernel,
	linux-clk, Linux-ALSA, devicetree, linux-sunxi, Thomas Petazzoni,
	Alexandre Belloni

On Tue, Oct 4, 2016 at 6:16 PM, Code Kipper <codekipper@gmail.com> wrote:
> On 4 October 2016 at 11:46, Myl=C3=A8ne Josserand
> <mylene.josserand@free-electrons.com> wrote:
>> Add the audio card for sun8i SoC. This card links the codec driver
>> (digital part) with the DAI driver. The analog codec driver is
>> added as an aux_device.
>>
>> Signed-off-by: Myl=C3=A8ne Josserand <mylene.josserand@free-electrons.co=
m>
>> ---
>>  sound/soc/sunxi/Kconfig  |  14 +++++++
>>  sound/soc/sunxi/Makefile |   1 +
>>  sound/soc/sunxi/sun8i.c  | 101 ++++++++++++++++++++++++++++++++++++++++=
+++++++
>>  3 files changed, 116 insertions(+)
>>  create mode 100644 sound/soc/sunxi/sun8i.c
>>
>> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
>> index 9e287b0..7b97395 100644
>> --- a/sound/soc/sunxi/Kconfig
>> +++ b/sound/soc/sunxi/Kconfig
>> @@ -27,6 +27,20 @@ config SND_SUN4I_SPDIF
>>           Say Y or M to add support for the S/PDIF audio block in the Al=
lwinner
>>           A10 and affiliated SoCs.
>>
>> +config SND_SUN8I
>> +       tristate "Allwinner SUN6I/SUN8I audio card support"
>> +       select SND_SUN8I_CODEC
>> +       select SND_SUN4I_I2S
>> +       select SND_SUN8I_CODEC_ANALOG
>> +       select REGMAP_MMIO
>> +       help
>> +         This option enables the audio card for Allwinner A33 (sun8i) S=
oC.
>> +         It enables the DAI driver (SND_SUN4I_I2S), the digital audio
>> +         codec driver (SND_SUN8I_CODEC) and the analog codec driver
>> +         (SND_SUN8I_CODEC_ANALOG).
>> +
>> +         Say Y or M if you want to add sun8i/6i card support
>> +
>>  config SND_SUN8I_CODEC
>>         tristate "Allwinner SUN8I audio codec"
>>         select REGMAP_MMIO
>> diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
>> index 1da63d3..7f1bab9 100644
>> --- a/sound/soc/sunxi/Makefile
>> +++ b/sound/soc/sunxi/Makefile
>> @@ -1,5 +1,6 @@
>>  obj-$(CONFIG_SND_SUN4I_CODEC) +=3D sun4i-codec.o
>>  obj-$(CONFIG_SND_SUN4I_I2S) +=3D sun4i-i2s.o
>>  obj-$(CONFIG_SND_SUN4I_SPDIF) +=3D sun4i-spdif.o
>> +obj-$(CONFIG_SND_SUN8I) +=3D sun8i.o
> Great work with this...I've been battling with the audio codec for the
> h3 for a while and it looks like almost everything that I need is
> delivered here.
>>  obj-$(CONFIG_SND_SUN8I_CODEC) +=3D sun8i-codec.o
>>  obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) +=3D sun8i-codec-analog.o
>> diff --git a/sound/soc/sunxi/sun8i.c b/sound/soc/sunxi/sun8i.c
>> new file mode 100644
>> index 0000000..565cd88
>> --- /dev/null
>> +++ b/sound/soc/sunxi/sun8i.c
>> @@ -0,0 +1,101 @@
>> +/*
>> + * ALSA SoC driver for Allwinner sun8i SoC
>> + *
>> + * Copyright (C) 2016 Myl=C3=A8ne Josserand <mylene.josserand@free-elec=
trons.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + */
>> +
>> +#include <linux/firmware.h>
>> +#include <linux/module.h>
>> +
>> +#include <sound/soc.h>
>> +
>> +static struct snd_soc_aux_dev sun8i_audio_prcm_aux_devs[] =3D {
>> +       {
>> +               .name =3D "sun8i-codec-analog",
>> +               .codec_name =3D "sun8i-codec-analog.0",
>> +       },
>> +};
>> +
>> +static struct snd_soc_dai_link sun8i_dai_link =3D {
>> +       .name           =3D "sun4i-i2s",
>> +       .stream_name    =3D "Playback",
>> +       .codec_dai_name =3D "sun8i",
>> +       .dai_fmt        =3D SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S |
>> +                       SND_SOC_DAIFMT_CBM_CFM,
>> +};
>> +
>> +static struct snd_soc_card sun8i_card =3D {
>> +       .name           =3D "sun8i-card",
>> +       .owner          =3D THIS_MODULE,
>> +       .dai_link       =3D &sun8i_dai_link,
>> +       .num_links      =3D 1,
>> +       .aux_dev        =3D sun8i_audio_prcm_aux_devs,
>> +       .num_aux_devs   =3D ARRAY_SIZE(sun8i_audio_prcm_aux_devs),
>> +};
>> +
>> +static int sun8i_probe(struct platform_device *pdev)
>> +{
>> +       struct snd_soc_dai_link *link =3D &sun8i_dai_link;
>> +       struct device_node *np =3D pdev->dev.of_node;
>> +       int ret;
>> +
>> +       /* register the soc card */
>> +       sun8i_card.dev =3D &pdev->dev;
>> +
>> +       /* Retrieve the audio-codec from DT */
>> +       link->codec_of_node =3D of_parse_phandle(np, "allwinner,audio-co=
dec", 0);
>> +       if (!link->codec_of_node) {
>> +               dev_err(&pdev->dev, "Missing audio codec\n");
>> +               return -EINVAL;
>> +       }
>> +
>> +       /* Retrieve DAI from DT */
>> +       link->cpu_of_node =3D of_parse_phandle(np, "allwinner,i2s-contro=
ller", 0);
>> +       if (!link->cpu_of_node) {
>> +               dev_err(&pdev->dev, "Missing I2S controller\n");
>> +               return -EINVAL;
>> +       }
>> +
> My one question is that we have sun8i-a23 and sun8i-a33, and I think
> we need to distinguish them here. The sun8i-a23 doesn't use the i2s
> block but does use the prcm.

Agreed. Both the A23 and H3 follow the A31s, that is the codec is similar
to the A10/A31, but the analog controls are moved to the PRCM. We should
support these kinds with the existing codec driver.

ChenYu

>> +       link->platform_of_node =3D link->cpu_of_node;
>> +
>> +       /* Register the sound card */
>> +       ret =3D devm_snd_soc_register_card(&pdev->dev, &sun8i_card);
>> +       if (ret) {
>> +               dev_err(&pdev->dev,
>> +                       "Soc register card failed %d\n", ret);
>> +               return ret;
>> +       }
>> +
>> +       return ret;
>> +}
>> +
>> +static const struct of_device_id sun8i_of_match[] =3D {
>> +       { .compatible =3D "allwinner,sun8i-audio", },
>> +       {},
>> +};
>> +
>> +MODULE_DEVICE_TABLE(of, sun8i_of_match);
>> +
>> +static struct platform_driver sun8i_card_driver =3D {
>> +       .probe =3D sun8i_probe,
>> +       .driver =3D {
>> +               .name   =3D "sun8i-audio",
>> +               .of_match_table =3D sun8i_of_match,
>> +       },
>> +};
>> +
>> +module_platform_driver(sun8i_card_driver);
>> +
>> +MODULE_AUTHOR("Myl=C3=A8ne Josserand <mylene.josserand@free-electrons.c=
om>");
>> +MODULE_DESCRIPTION("Allwinner sun8i machine ASoC driver");
>> +MODULE_LICENSE("GPL v2");
>> --
>> 2.9.3
>>

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

* [PATCH 07/14] ASoC: Add sun8i audio card
@ 2016-10-04 10:59         ` Chen-Yu Tsai
  0 siblings, 0 replies; 170+ messages in thread
From: Chen-Yu Tsai @ 2016-10-04 10:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 4, 2016 at 6:16 PM, Code Kipper <codekipper@gmail.com> wrote:
> On 4 October 2016 at 11:46, Myl?ne Josserand
> <mylene.josserand@free-electrons.com> wrote:
>> Add the audio card for sun8i SoC. This card links the codec driver
>> (digital part) with the DAI driver. The analog codec driver is
>> added as an aux_device.
>>
>> Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
>> ---
>>  sound/soc/sunxi/Kconfig  |  14 +++++++
>>  sound/soc/sunxi/Makefile |   1 +
>>  sound/soc/sunxi/sun8i.c  | 101 +++++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 116 insertions(+)
>>  create mode 100644 sound/soc/sunxi/sun8i.c
>>
>> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
>> index 9e287b0..7b97395 100644
>> --- a/sound/soc/sunxi/Kconfig
>> +++ b/sound/soc/sunxi/Kconfig
>> @@ -27,6 +27,20 @@ config SND_SUN4I_SPDIF
>>           Say Y or M to add support for the S/PDIF audio block in the Allwinner
>>           A10 and affiliated SoCs.
>>
>> +config SND_SUN8I
>> +       tristate "Allwinner SUN6I/SUN8I audio card support"
>> +       select SND_SUN8I_CODEC
>> +       select SND_SUN4I_I2S
>> +       select SND_SUN8I_CODEC_ANALOG
>> +       select REGMAP_MMIO
>> +       help
>> +         This option enables the audio card for Allwinner A33 (sun8i) SoC.
>> +         It enables the DAI driver (SND_SUN4I_I2S), the digital audio
>> +         codec driver (SND_SUN8I_CODEC) and the analog codec driver
>> +         (SND_SUN8I_CODEC_ANALOG).
>> +
>> +         Say Y or M if you want to add sun8i/6i card support
>> +
>>  config SND_SUN8I_CODEC
>>         tristate "Allwinner SUN8I audio codec"
>>         select REGMAP_MMIO
>> diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
>> index 1da63d3..7f1bab9 100644
>> --- a/sound/soc/sunxi/Makefile
>> +++ b/sound/soc/sunxi/Makefile
>> @@ -1,5 +1,6 @@
>>  obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
>>  obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
>>  obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
>> +obj-$(CONFIG_SND_SUN8I) += sun8i.o
> Great work with this...I've been battling with the audio codec for the
> h3 for a while and it looks like almost everything that I need is
> delivered here.
>>  obj-$(CONFIG_SND_SUN8I_CODEC) += sun8i-codec.o
>>  obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
>> diff --git a/sound/soc/sunxi/sun8i.c b/sound/soc/sunxi/sun8i.c
>> new file mode 100644
>> index 0000000..565cd88
>> --- /dev/null
>> +++ b/sound/soc/sunxi/sun8i.c
>> @@ -0,0 +1,101 @@
>> +/*
>> + * ALSA SoC driver for Allwinner sun8i SoC
>> + *
>> + * Copyright (C) 2016 Myl?ne Josserand <mylene.josserand@free-electrons.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + */
>> +
>> +#include <linux/firmware.h>
>> +#include <linux/module.h>
>> +
>> +#include <sound/soc.h>
>> +
>> +static struct snd_soc_aux_dev sun8i_audio_prcm_aux_devs[] = {
>> +       {
>> +               .name = "sun8i-codec-analog",
>> +               .codec_name = "sun8i-codec-analog.0",
>> +       },
>> +};
>> +
>> +static struct snd_soc_dai_link sun8i_dai_link = {
>> +       .name           = "sun4i-i2s",
>> +       .stream_name    = "Playback",
>> +       .codec_dai_name = "sun8i",
>> +       .dai_fmt        = SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S |
>> +                       SND_SOC_DAIFMT_CBM_CFM,
>> +};
>> +
>> +static struct snd_soc_card sun8i_card = {
>> +       .name           = "sun8i-card",
>> +       .owner          = THIS_MODULE,
>> +       .dai_link       = &sun8i_dai_link,
>> +       .num_links      = 1,
>> +       .aux_dev        = sun8i_audio_prcm_aux_devs,
>> +       .num_aux_devs   = ARRAY_SIZE(sun8i_audio_prcm_aux_devs),
>> +};
>> +
>> +static int sun8i_probe(struct platform_device *pdev)
>> +{
>> +       struct snd_soc_dai_link *link = &sun8i_dai_link;
>> +       struct device_node *np = pdev->dev.of_node;
>> +       int ret;
>> +
>> +       /* register the soc card */
>> +       sun8i_card.dev = &pdev->dev;
>> +
>> +       /* Retrieve the audio-codec from DT */
>> +       link->codec_of_node = of_parse_phandle(np, "allwinner,audio-codec", 0);
>> +       if (!link->codec_of_node) {
>> +               dev_err(&pdev->dev, "Missing audio codec\n");
>> +               return -EINVAL;
>> +       }
>> +
>> +       /* Retrieve DAI from DT */
>> +       link->cpu_of_node = of_parse_phandle(np, "allwinner,i2s-controller", 0);
>> +       if (!link->cpu_of_node) {
>> +               dev_err(&pdev->dev, "Missing I2S controller\n");
>> +               return -EINVAL;
>> +       }
>> +
> My one question is that we have sun8i-a23 and sun8i-a33, and I think
> we need to distinguish them here. The sun8i-a23 doesn't use the i2s
> block but does use the prcm.

Agreed. Both the A23 and H3 follow the A31s, that is the codec is similar
to the A10/A31, but the analog controls are moved to the PRCM. We should
support these kinds with the existing codec driver.

ChenYu

>> +       link->platform_of_node = link->cpu_of_node;
>> +
>> +       /* Register the sound card */
>> +       ret = devm_snd_soc_register_card(&pdev->dev, &sun8i_card);
>> +       if (ret) {
>> +               dev_err(&pdev->dev,
>> +                       "Soc register card failed %d\n", ret);
>> +               return ret;
>> +       }
>> +
>> +       return ret;
>> +}
>> +
>> +static const struct of_device_id sun8i_of_match[] = {
>> +       { .compatible = "allwinner,sun8i-audio", },
>> +       {},
>> +};
>> +
>> +MODULE_DEVICE_TABLE(of, sun8i_of_match);
>> +
>> +static struct platform_driver sun8i_card_driver = {
>> +       .probe = sun8i_probe,
>> +       .driver = {
>> +               .name   = "sun8i-audio",
>> +               .of_match_table = sun8i_of_match,
>> +       },
>> +};
>> +
>> +module_platform_driver(sun8i_card_driver);
>> +
>> +MODULE_AUTHOR("Myl?ne Josserand <mylene.josserand@free-electrons.com>");
>> +MODULE_DESCRIPTION("Allwinner sun8i machine ASoC driver");
>> +MODULE_LICENSE("GPL v2");
>> --
>> 2.9.3
>>

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

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-10-04 12:12         ` Thomas Petazzoni
  0 siblings, 0 replies; 170+ messages in thread
From: Thomas Petazzoni @ 2016-10-04 12:12 UTC (permalink / raw)
  To: Jean-Francois Moine
  Cc: Mylène Josserand, vinod.koul, maxime.ripard, wens,
	mturquette, sboyd, lgirdwood, broonie, perex, tiwai, lee.jones,
	mark.rutland, robh+dt, devicetree, alsa-devel, linux-kernel,
	linux-sunxi, alexandre.belloni, dmaengine, linux-clk,
	linux-arm-kernel

Hello,

On Tue, 4 Oct 2016 12:40:11 +0200, Jean-Francois Moine wrote:

> > Add the case of a burst of 4 which is handled by the SoC.
> > 
> > Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
> > ---
> >  drivers/dma/sun6i-dma.c | 2 ++
> >  1 file changed, 2 insertions(+)
> > 
> > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> > index 8346199..0485204 100644
> > --- a/drivers/dma/sun6i-dma.c
> > +++ b/drivers/dma/sun6i-dma.c
> > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
> >  	switch (maxburst) {
> >  	case 1:
> >  		return 0;
> > +	case 4:
> > +		return 1;
> >  	case 8:
> >  		return 2;
> >  	default:
> > -- 
> > 2.9.3  
> 
> This patch has already been rejected by Maxime in the threads
> 	http://www.spinics.net/lists/dmaengine/msg08610.html
> and
> 	http://www.spinics.net/lists/dmaengine/msg08719.html
> 
> I hope you will find the way he wants for this maxburst to be added.

I was about to reply to Mylene's e-mail, suggesting that she should add
a comment in the code (and maybe in the commit log) to explain why this
addition is needed, and also that even though the schematics say that
value "1" (max burst size of 4 bytes) is reserved, it is in fact
incorrect. The Allwinner BSP code is really using this value, and it's
the value that makes audio work, so we believe the datasheet is simply
incorrect.

We already discussed it with Maxime, so I believe he should agree this
time. But I would suggest to have such details explained in the commit
log and in a comment in the code.

Best regards,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-10-04 12:12         ` Thomas Petazzoni
  0 siblings, 0 replies; 170+ messages in thread
From: Thomas Petazzoni @ 2016-10-04 12:12 UTC (permalink / raw)
  To: Jean-Francois Moine
  Cc: Mylène Josserand, vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8, wens-jdAy2FN1RRM,
	mturquette-rdvid1DuHRBWk0Htik3J/w, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A,
	perex-/Fr2/VpizcU, tiwai-IBi9RG/b67k,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

Hello,

On Tue, 4 Oct 2016 12:40:11 +0200, Jean-Francois Moine wrote:

> > Add the case of a burst of 4 which is handled by the SoC.
> > 
> > Signed-off-by: Mylène Josserand <mylene.josserand-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> > ---
> >  drivers/dma/sun6i-dma.c | 2 ++
> >  1 file changed, 2 insertions(+)
> > 
> > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> > index 8346199..0485204 100644
> > --- a/drivers/dma/sun6i-dma.c
> > +++ b/drivers/dma/sun6i-dma.c
> > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
> >  	switch (maxburst) {
> >  	case 1:
> >  		return 0;
> > +	case 4:
> > +		return 1;
> >  	case 8:
> >  		return 2;
> >  	default:
> > -- 
> > 2.9.3  
> 
> This patch has already been rejected by Maxime in the threads
> 	http://www.spinics.net/lists/dmaengine/msg08610.html
> and
> 	http://www.spinics.net/lists/dmaengine/msg08719.html
> 
> I hope you will find the way he wants for this maxburst to be added.

I was about to reply to Mylene's e-mail, suggesting that she should add
a comment in the code (and maybe in the commit log) to explain why this
addition is needed, and also that even though the schematics say that
value "1" (max burst size of 4 bytes) is reserved, it is in fact
incorrect. The Allwinner BSP code is really using this value, and it's
the value that makes audio work, so we believe the datasheet is simply
incorrect.

We already discussed it with Maxime, so I believe he should agree this
time. But I would suggest to have such details explained in the commit
log and in a comment in the code.

Best regards,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
--
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] 170+ messages in thread

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-10-04 12:12         ` Thomas Petazzoni
  0 siblings, 0 replies; 170+ messages in thread
From: Thomas Petazzoni @ 2016-10-04 12:12 UTC (permalink / raw)
  To: Jean-Francois Moine
  Cc: Mylène Josserand, vinod.koul, maxime.ripard, wens,
	mturquette, sboyd, lgirdwood, broonie, perex, tiwai, lee.jones,
	mark.rutland, robh+dt, devicetree, alsa-devel, linux-kernel,
	linux-sunxi, alexandre.belloni, dmaengine, linux-clk,
	linux-arm-kernel

Hello,

On Tue, 4 Oct 2016 12:40:11 +0200, Jean-Francois Moine wrote:

> > Add the case of a burst of 4 which is handled by the SoC.
> >=20
> > Signed-off-by: Myl=C3=A8ne Josserand <mylene.josserand@free-electrons.c=
om>
> > ---
> >  drivers/dma/sun6i-dma.c | 2 ++
> >  1 file changed, 2 insertions(+)
> >=20
> > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> > index 8346199..0485204 100644
> > --- a/drivers/dma/sun6i-dma.c
> > +++ b/drivers/dma/sun6i-dma.c
> > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
> >  	switch (maxburst) {
> >  	case 1:
> >  		return 0;
> > +	case 4:
> > +		return 1;
> >  	case 8:
> >  		return 2;
> >  	default:
> > --=20
> > 2.9.3 =20
>=20
> This patch has already been rejected by Maxime in the threads
> 	http://www.spinics.net/lists/dmaengine/msg08610.html
> and
> 	http://www.spinics.net/lists/dmaengine/msg08719.html
>=20
> I hope you will find the way he wants for this maxburst to be added.

I was about to reply to Mylene's e-mail, suggesting that she should add
a comment in the code (and maybe in the commit log) to explain why this
addition is needed, and also that even though the schematics say that
value "1" (max burst size of 4 bytes) is reserved, it is in fact
incorrect. The Allwinner BSP code is really using this value, and it's
the value that makes audio work, so we believe the datasheet is simply
incorrect.

We already discussed it with Maxime, so I believe he should agree this
time. But I would suggest to have such details explained in the commit
log and in a comment in the code.

Best regards,

Thomas
--=20
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-10-04 12:12         ` Thomas Petazzoni
  0 siblings, 0 replies; 170+ messages in thread
From: Thomas Petazzoni @ 2016-10-04 12:12 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On Tue, 4 Oct 2016 12:40:11 +0200, Jean-Francois Moine wrote:

> > Add the case of a burst of 4 which is handled by the SoC.
> > 
> > Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
> > ---
> >  drivers/dma/sun6i-dma.c | 2 ++
> >  1 file changed, 2 insertions(+)
> > 
> > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> > index 8346199..0485204 100644
> > --- a/drivers/dma/sun6i-dma.c
> > +++ b/drivers/dma/sun6i-dma.c
> > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
> >  	switch (maxburst) {
> >  	case 1:
> >  		return 0;
> > +	case 4:
> > +		return 1;
> >  	case 8:
> >  		return 2;
> >  	default:
> > -- 
> > 2.9.3  
> 
> This patch has already been rejected by Maxime in the threads
> 	http://www.spinics.net/lists/dmaengine/msg08610.html
> and
> 	http://www.spinics.net/lists/dmaengine/msg08719.html
> 
> I hope you will find the way he wants for this maxburst to be added.

I was about to reply to Mylene's e-mail, suggesting that she should add
a comment in the code (and maybe in the commit log) to explain why this
addition is needed, and also that even though the schematics say that
value "1" (max burst size of 4 bytes) is reserved, it is in fact
incorrect. The Allwinner BSP code is really using this value, and it's
the value that makes audio work, so we believe the datasheet is simply
incorrect.

We already discussed it with Maxime, so I believe he should agree this
time. But I would suggest to have such details explained in the commit
log and in a comment in the code.

Best regards,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* Re: [PATCH 02/14] clk: ccu-sun8i-a33: Add CLK_SET_RATE_PARENT to ac-dig
@ 2016-10-04 12:12       ` Thomas Petazzoni
  0 siblings, 0 replies; 170+ messages in thread
From: Thomas Petazzoni @ 2016-10-04 12:12 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt,
	linux-kernel, dmaengine, linux-arm-kernel, linux-clk, alsa-devel,
	devicetree, linux-sunxi, alexandre.belloni

Hello,

On Tue,  4 Oct 2016 11:46:15 +0200, Mylène Josserand wrote:
> Add the flag CLK_SET_RATE_PARENT to 'ac-dig' clock.

There is no need to repeat the commit title inside the commit log
itself. What would be more useful is to explain *why* this is needed.

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* Re: [PATCH 02/14] clk: ccu-sun8i-a33: Add CLK_SET_RATE_PARENT to ac-dig
@ 2016-10-04 12:12       ` Thomas Petazzoni
  0 siblings, 0 replies; 170+ messages in thread
From: Thomas Petazzoni @ 2016-10-04 12:12 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8, wens-jdAy2FN1RRM,
	mturquette-rdvid1DuHRBWk0Htik3J/w, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A,
	perex-/Fr2/VpizcU, tiwai-IBi9RG/b67k,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8

Hello,

On Tue,  4 Oct 2016 11:46:15 +0200, Mylène Josserand wrote:
> Add the flag CLK_SET_RATE_PARENT to 'ac-dig' clock.

There is no need to repeat the commit title inside the commit log
itself. What would be more useful is to explain *why* this is needed.

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
--
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] 170+ messages in thread

* Re: [PATCH 02/14] clk: ccu-sun8i-a33: Add CLK_SET_RATE_PARENT to ac-dig
@ 2016-10-04 12:12       ` Thomas Petazzoni
  0 siblings, 0 replies; 170+ messages in thread
From: Thomas Petazzoni @ 2016-10-04 12:12 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt,
	linux-kernel, dmaengine, linux-arm-kernel, linux-clk, alsa-devel,
	devicetree, linux-sunxi, alexandre.belloni

Hello,

On Tue,  4 Oct 2016 11:46:15 +0200, Myl=C3=A8ne Josserand wrote:
> Add the flag CLK_SET_RATE_PARENT to 'ac-dig' clock.

There is no need to repeat the commit title inside the commit log
itself. What would be more useful is to explain *why* this is needed.

Thomas
--=20
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* [PATCH 02/14] clk: ccu-sun8i-a33: Add CLK_SET_RATE_PARENT to ac-dig
@ 2016-10-04 12:12       ` Thomas Petazzoni
  0 siblings, 0 replies; 170+ messages in thread
From: Thomas Petazzoni @ 2016-10-04 12:12 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On Tue,  4 Oct 2016 11:46:15 +0200, Myl?ne Josserand wrote:
> Add the flag CLK_SET_RATE_PARENT to 'ac-dig' clock.

There is no need to repeat the commit title inside the commit log
itself. What would be more useful is to explain *why* this is needed.

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* Re: [PATCH 03/14] ASoC: sun4i-i2s: Add apb reset
  2016-10-04  9:46     ` Mylène Josserand
  (?)
@ 2016-10-04 12:15       ` Thomas Petazzoni
  -1 siblings, 0 replies; 170+ messages in thread
From: Thomas Petazzoni @ 2016-10-04 12:15 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt,
	linux-kernel, dmaengine, linux-arm-kernel, linux-clk, alsa-devel,
	devicetree, linux-sunxi, alexandre.belloni

Hello,

On Tue,  4 Oct 2016 11:46:16 +0200, Mylène Josserand wrote:

>  #include <sound/dmaengine_pcm.h>
>  #include <sound/pcm_params.h>
> @@ -589,6 +590,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>  {
>  	struct sun4i_i2s *i2s;
>  	struct resource *res;
> +	struct reset_control *reset_apb;
>  	void __iomem *regs;
>  	int irq, ret;
>  
> @@ -626,7 +628,19 @@ 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);
>  	}
> -	
> +
> +	reset_apb = devm_reset_control_get(&pdev->dev, "apb_reset");

I believe this is a change in the Device Tree binding, since you're
adding support for a new resource. Perhaps the Device Tree binding
documentation should be updated accordingly?

> +	if (IS_ERR(reset_apb)) {
> +		dev_err(&pdev->dev, "Can't get apb reset\n");
> +		return PTR_ERR(i2s->mod_clk);

This should be:

		return PTR_ERR(reset_apb);

> +	}
> +
> +	ret = reset_control_deassert(reset_apb);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "Can't deassert apb reset (%d)\n", ret);
> +		return ret;
> +	}

Do you need to re-assert the reset line in the ->remove() hook?

Best regards,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* Re: [PATCH 03/14] ASoC: sun4i-i2s: Add apb reset
@ 2016-10-04 12:15       ` Thomas Petazzoni
  0 siblings, 0 replies; 170+ messages in thread
From: Thomas Petazzoni @ 2016-10-04 12:15 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt,
	linux-kernel, dmaengine, linux-arm-kernel, linux-clk, alsa-devel,
	devicetree, linux-sunxi, alexandre.belloni

Hello,

On Tue,  4 Oct 2016 11:46:16 +0200, Myl=C3=A8ne Josserand wrote:

>  #include <sound/dmaengine_pcm.h>
>  #include <sound/pcm_params.h>
> @@ -589,6 +590,7 @@ static int sun4i_i2s_probe(struct platform_device *pd=
ev)
>  {
>  	struct sun4i_i2s *i2s;
>  	struct resource *res;
> +	struct reset_control *reset_apb;
>  	void __iomem *regs;
>  	int irq, ret;
> =20
> @@ -626,7 +628,19 @@ static int sun4i_i2s_probe(struct platform_device *p=
dev)
>  		dev_err(&pdev->dev, "Can't get our mod clock\n");
>  		return PTR_ERR(i2s->mod_clk);
>  	}
> -=09
> +
> +	reset_apb =3D devm_reset_control_get(&pdev->dev, "apb_reset");

I believe this is a change in the Device Tree binding, since you're
adding support for a new resource. Perhaps the Device Tree binding
documentation should be updated accordingly?

> +	if (IS_ERR(reset_apb)) {
> +		dev_err(&pdev->dev, "Can't get apb reset\n");
> +		return PTR_ERR(i2s->mod_clk);

This should be:

		return PTR_ERR(reset_apb);

> +	}
> +
> +	ret =3D reset_control_deassert(reset_apb);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "Can't deassert apb reset (%d)\n", ret);
> +		return ret;
> +	}

Do you need to re-assert the reset line in the ->remove() hook?

Best regards,

Thomas
--=20
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* [PATCH 03/14] ASoC: sun4i-i2s: Add apb reset
@ 2016-10-04 12:15       ` Thomas Petazzoni
  0 siblings, 0 replies; 170+ messages in thread
From: Thomas Petazzoni @ 2016-10-04 12:15 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On Tue,  4 Oct 2016 11:46:16 +0200, Myl?ne Josserand wrote:

>  #include <sound/dmaengine_pcm.h>
>  #include <sound/pcm_params.h>
> @@ -589,6 +590,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>  {
>  	struct sun4i_i2s *i2s;
>  	struct resource *res;
> +	struct reset_control *reset_apb;
>  	void __iomem *regs;
>  	int irq, ret;
>  
> @@ -626,7 +628,19 @@ 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);
>  	}
> -	
> +
> +	reset_apb = devm_reset_control_get(&pdev->dev, "apb_reset");

I believe this is a change in the Device Tree binding, since you're
adding support for a new resource. Perhaps the Device Tree binding
documentation should be updated accordingly?

> +	if (IS_ERR(reset_apb)) {
> +		dev_err(&pdev->dev, "Can't get apb reset\n");
> +		return PTR_ERR(i2s->mod_clk);

This should be:

		return PTR_ERR(reset_apb);

> +	}
> +
> +	ret = reset_control_deassert(reset_apb);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "Can't deassert apb reset (%d)\n", ret);
> +		return ret;
> +	}

Do you need to re-assert the reset line in the ->remove() hook?

Best regards,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* Re: [PATCH 03/14] ASoC: sun4i-i2s: Add apb reset
  2016-10-04  9:46     ` Mylène Josserand
  (?)
@ 2016-10-04 12:22       ` Code Kipper
  -1 siblings, 0 replies; 170+ messages in thread
From: Code Kipper @ 2016-10-04 12:22 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul, Maxime Ripard, Chen-Yu Tsai, mturquette, sboyd,
	Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai,
	Lee Jones, mark.rutland, Rob Herring, thomas.petazzoni,
	devicetree, alsa-devel, linux-kernel, linux-sunxi,
	alexandre.belloni, dmaengine, linux-clk, linux-arm-kernel

On 4 October 2016 at 11:46, Mylène Josserand
<mylene.josserand@free-electrons.com> wrote:
> Add APB deassert function for sun4i-i2s driver.
>
> Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
> ---
>  sound/soc/sunxi/sun4i-i2s.c | 16 +++++++++++++++-
>  1 file changed, 15 insertions(+), 1 deletion(-)
>
> diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
> index 687a8f8..f3f7026 100644
> --- a/sound/soc/sunxi/sun4i-i2s.c
> +++ b/sound/soc/sunxi/sun4i-i2s.c
> @@ -17,6 +17,7 @@
>  #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>
> @@ -589,6 +590,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>  {
>         struct sun4i_i2s *i2s;
>         struct resource *res;
> +       struct reset_control *reset_apb;
>         void __iomem *regs;
>         int irq, ret;
>
> @@ -626,7 +628,19 @@ 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);
>         }
> -
> +
> +       reset_apb = devm_reset_control_get(&pdev->dev, "apb_reset");
> +       if (IS_ERR(reset_apb)) {
> +               dev_err(&pdev->dev, "Can't get apb reset\n");
> +               return PTR_ERR(i2s->mod_clk);
> +       }
> +
> +       ret = reset_control_deassert(reset_apb);
> +       if (ret < 0) {
> +               dev_err(&pdev->dev, "Can't deassert apb reset (%d)\n", ret);
> +               return ret;
> +       }
> +
Is this functionality only required for A31 and onwards?,
CK
>         i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG;
>         i2s->playback_dma_data.maxburst = 4;
>
> --
> 2.9.3
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 03/14] ASoC: sun4i-i2s: Add apb reset
@ 2016-10-04 12:22       ` Code Kipper
  0 siblings, 0 replies; 170+ messages in thread
From: Code Kipper @ 2016-10-04 12:22 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul, Maxime Ripard, Chen-Yu Tsai, mturquette, sboyd,
	Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai,
	Lee Jones, mark.rutland, Rob Herring, thomas.petazzoni,
	devicetree, alsa-devel, linux-kernel, linux-sunxi,
	alexandre.belloni, dmaengine, linux-clk, linux-arm-kernel

On 4 October 2016 at 11:46, Myl=C3=A8ne Josserand
<mylene.josserand@free-electrons.com> wrote:
> Add APB deassert function for sun4i-i2s driver.
>
> Signed-off-by: Myl=C3=A8ne Josserand <mylene.josserand@free-electrons.com=
>
> ---
>  sound/soc/sunxi/sun4i-i2s.c | 16 +++++++++++++++-
>  1 file changed, 15 insertions(+), 1 deletion(-)
>
> diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
> index 687a8f8..f3f7026 100644
> --- a/sound/soc/sunxi/sun4i-i2s.c
> +++ b/sound/soc/sunxi/sun4i-i2s.c
> @@ -17,6 +17,7 @@
>  #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>
> @@ -589,6 +590,7 @@ static int sun4i_i2s_probe(struct platform_device *pd=
ev)
>  {
>         struct sun4i_i2s *i2s;
>         struct resource *res;
> +       struct reset_control *reset_apb;
>         void __iomem *regs;
>         int irq, ret;
>
> @@ -626,7 +628,19 @@ static int sun4i_i2s_probe(struct platform_device *p=
dev)
>                 dev_err(&pdev->dev, "Can't get our mod clock\n");
>                 return PTR_ERR(i2s->mod_clk);
>         }
> -
> +
> +       reset_apb =3D devm_reset_control_get(&pdev->dev, "apb_reset");
> +       if (IS_ERR(reset_apb)) {
> +               dev_err(&pdev->dev, "Can't get apb reset\n");
> +               return PTR_ERR(i2s->mod_clk);
> +       }
> +
> +       ret =3D reset_control_deassert(reset_apb);
> +       if (ret < 0) {
> +               dev_err(&pdev->dev, "Can't deassert apb reset (%d)\n", re=
t);
> +               return ret;
> +       }
> +
Is this functionality only required for A31 and onwards?,
CK
>         i2s->playback_dma_data.addr =3D res->start + SUN4I_I2S_FIFO_TX_RE=
G;
>         i2s->playback_dma_data.maxburst =3D 4;
>
> --
> 2.9.3
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 03/14] ASoC: sun4i-i2s: Add apb reset
@ 2016-10-04 12:22       ` Code Kipper
  0 siblings, 0 replies; 170+ messages in thread
From: Code Kipper @ 2016-10-04 12:22 UTC (permalink / raw)
  To: linux-arm-kernel

On 4 October 2016 at 11:46, Myl?ne Josserand
<mylene.josserand@free-electrons.com> wrote:
> Add APB deassert function for sun4i-i2s driver.
>
> Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
> ---
>  sound/soc/sunxi/sun4i-i2s.c | 16 +++++++++++++++-
>  1 file changed, 15 insertions(+), 1 deletion(-)
>
> diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
> index 687a8f8..f3f7026 100644
> --- a/sound/soc/sunxi/sun4i-i2s.c
> +++ b/sound/soc/sunxi/sun4i-i2s.c
> @@ -17,6 +17,7 @@
>  #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>
> @@ -589,6 +590,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>  {
>         struct sun4i_i2s *i2s;
>         struct resource *res;
> +       struct reset_control *reset_apb;
>         void __iomem *regs;
>         int irq, ret;
>
> @@ -626,7 +628,19 @@ 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);
>         }
> -
> +
> +       reset_apb = devm_reset_control_get(&pdev->dev, "apb_reset");
> +       if (IS_ERR(reset_apb)) {
> +               dev_err(&pdev->dev, "Can't get apb reset\n");
> +               return PTR_ERR(i2s->mod_clk);
> +       }
> +
> +       ret = reset_control_deassert(reset_apb);
> +       if (ret < 0) {
> +               dev_err(&pdev->dev, "Can't deassert apb reset (%d)\n", ret);
> +               return ret;
> +       }
> +
Is this functionality only required for A31 and onwards?,
CK
>         i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG;
>         i2s->playback_dma_data.maxburst = 4;
>
> --
> 2.9.3
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 07/14] ASoC: Add sun8i audio card
  2016-10-04  9:46     ` Mylène Josserand
  (?)
@ 2016-10-04 12:25       ` Thomas Petazzoni
  -1 siblings, 0 replies; 170+ messages in thread
From: Thomas Petazzoni @ 2016-10-04 12:25 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt,
	linux-kernel, dmaengine, linux-arm-kernel, linux-clk, alsa-devel,
	devicetree, linux-sunxi, alexandre.belloni

Hello,

On Tue,  4 Oct 2016 11:46:20 +0200, Mylène Josserand wrote:

> +config SND_SUN8I
> +	tristate "Allwinner SUN6I/SUN8I audio card support"
> +	select SND_SUN8I_CODEC
> +	select SND_SUN4I_I2S
> +	select SND_SUN8I_CODEC_ANALOG
> +	select REGMAP_MMIO

I believe you need a:

	depends on OF

since you're unconditionally using some DT-related functionality in the
driver code.

> +#include <linux/firmware.h>

Do you really need this header file? I don't see anything
firmware-loading related in the driver.

> +static int sun8i_probe(struct platform_device *pdev)
> +{
> +	struct snd_soc_dai_link *link = &sun8i_dai_link;
> +	struct device_node *np = pdev->dev.of_node;
> +	int ret;
> +
> +	/* register the soc card */
> +	sun8i_card.dev = &pdev->dev;
> +
> +	/* Retrieve the audio-codec from DT */
> +	link->codec_of_node = of_parse_phandle(np, "allwinner,audio-codec", 0);

Whenever you're using of_parse_phandle(), you must have a corresponding
of_node_put() to release the reference to the Device Tree node. So I
guess this should be done 1/ in the error path of ->probe(), and 2/
during the ->remove() hook.

Best regards,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* Re: [PATCH 07/14] ASoC: Add sun8i audio card
@ 2016-10-04 12:25       ` Thomas Petazzoni
  0 siblings, 0 replies; 170+ messages in thread
From: Thomas Petazzoni @ 2016-10-04 12:25 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt,
	linux-kernel, dmaengine, linux-arm-kernel, linux-clk, alsa-devel,
	devicetree, linux-sunxi, alexandre.belloni

Hello,

On Tue,  4 Oct 2016 11:46:20 +0200, Myl=C3=A8ne Josserand wrote:

> +config SND_SUN8I
> +	tristate "Allwinner SUN6I/SUN8I audio card support"
> +	select SND_SUN8I_CODEC
> +	select SND_SUN4I_I2S
> +	select SND_SUN8I_CODEC_ANALOG
> +	select REGMAP_MMIO

I believe you need a:

	depends on OF

since you're unconditionally using some DT-related functionality in the
driver code.

> +#include <linux/firmware.h>

Do you really need this header file? I don't see anything
firmware-loading related in the driver.

> +static int sun8i_probe(struct platform_device *pdev)
> +{
> +	struct snd_soc_dai_link *link =3D &sun8i_dai_link;
> +	struct device_node *np =3D pdev->dev.of_node;
> +	int ret;
> +
> +	/* register the soc card */
> +	sun8i_card.dev =3D &pdev->dev;
> +
> +	/* Retrieve the audio-codec from DT */
> +	link->codec_of_node =3D of_parse_phandle(np, "allwinner,audio-codec", 0=
);

Whenever you're using of_parse_phandle(), you must have a corresponding
of_node_put() to release the reference to the Device Tree node. So I
guess this should be done 1/ in the error path of ->probe(), and 2/
during the ->remove() hook.

Best regards,

Thomas
--=20
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* [PATCH 07/14] ASoC: Add sun8i audio card
@ 2016-10-04 12:25       ` Thomas Petazzoni
  0 siblings, 0 replies; 170+ messages in thread
From: Thomas Petazzoni @ 2016-10-04 12:25 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On Tue,  4 Oct 2016 11:46:20 +0200, Myl?ne Josserand wrote:

> +config SND_SUN8I
> +	tristate "Allwinner SUN6I/SUN8I audio card support"
> +	select SND_SUN8I_CODEC
> +	select SND_SUN4I_I2S
> +	select SND_SUN8I_CODEC_ANALOG
> +	select REGMAP_MMIO

I believe you need a:

	depends on OF

since you're unconditionally using some DT-related functionality in the
driver code.

> +#include <linux/firmware.h>

Do you really need this header file? I don't see anything
firmware-loading related in the driver.

> +static int sun8i_probe(struct platform_device *pdev)
> +{
> +	struct snd_soc_dai_link *link = &sun8i_dai_link;
> +	struct device_node *np = pdev->dev.of_node;
> +	int ret;
> +
> +	/* register the soc card */
> +	sun8i_card.dev = &pdev->dev;
> +
> +	/* Retrieve the audio-codec from DT */
> +	link->codec_of_node = of_parse_phandle(np, "allwinner,audio-codec", 0);

Whenever you're using of_parse_phandle(), you must have a corresponding
of_node_put() to release the reference to the Device Tree node. So I
guess this should be done 1/ in the error path of ->probe(), and 2/
during the ->remove() hook.

Best regards,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* Re: [PATCH 06/14] ASoC: Add sun8i digital audio codec
  2016-10-04  9:46     ` Mylène Josserand
  (?)
@ 2016-10-04 12:40       ` Thomas Petazzoni
  -1 siblings, 0 replies; 170+ messages in thread
From: Thomas Petazzoni @ 2016-10-04 12:40 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt,
	linux-kernel, dmaengine, linux-arm-kernel, linux-clk, alsa-devel,
	devicetree, linux-sunxi, alexandre.belloni

Hello,

On Tue,  4 Oct 2016 11:46:19 +0200, Mylène Josserand wrote:
> Add the digital sun8i audio codec which handles the base register
> (without DAI).

I'm not sure what you mean by "which handles the base register".

> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
> index 7aee95a..9e287b0 100644
> --- a/sound/soc/sunxi/Kconfig
> +++ b/sound/soc/sunxi/Kconfig
> @@ -27,6 +27,15 @@ config SND_SUN4I_SPDIF
>  	  Say Y or M to add support for the S/PDIF audio block in the Allwinner
>  	  A10 and affiliated SoCs.
>  
> +config SND_SUN8I_CODEC
> +	tristate "Allwinner SUN8I audio codec"
> +	select REGMAP_MMIO
> +        help

Indentation issue here, it should be intended with one tab, not spaces.

You probably also want a "depends on OF" here.

> +/* CODEC_OFFSET represents the offset of the codec registers
> + * and not all the DAI registers
> + */

This is not the proper comment style I believe for audio code, it
should be:

/*
 * ...
 */

> +#define CODEC_OFFSET				0x200

Do you really need this CODEC_OFFSET macro? Why not simply use directly
the right offsets? I.e instead of:

  #define SUN8I_SYSCLK_CTL			(0x20c - CODEC_OFFSET)

use:

  #define SUN8I_SYSCLK_CTL			0xc

> +#define CODEC_BASSADDRESS			0x01c22c00

This define is not used anywhere.

> +#define SUN8I_SYSCLK_CTL			(0x20c - CODEC_OFFSET)
> +#define SUN8I_SYSCLK_CTL_AIF1CLK_ENA		(11)
> +#define SUN8I_SYSCLK_CTL_SYSCLK_ENA		(3)
> +#define SUN8I_SYSCLK_CTL_SYSCLK_SRC		(0)

Parenthesis around single values are not really useful.

> +#define SUN8I_MOD_CLK_ENA			(0x210 - CODEC_OFFSET)
> +#define SUN8I_MOD_CLK_ENA_AIF1			(15)
> +#define SUN8I_MOD_CLK_ENA_DAC			(2)
> +#define SUN8I_MOD_RST_CTL			(0x214 - CODEC_OFFSET)
> +#define SUN8I_MOD_RST_CTL_AIF1			(15)
> +#define SUN8I_MOD_RST_CTL_DAC			(2)
> +#define SUN8I_SYS_SR_CTRL			(0x218 - CODEC_OFFSET)
> +#define SUN8I_SYS_SR_CTRL_AIF1_FS		(12)
> +#define SUN8I_SYS_SR_CTRL_AIF2_FS		(8)
> +#define SUN8I_AIF1CLK_CTRL			(0x240 - CODEC_OFFSET)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_MSTR_MOD	(15)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_INV	(14)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV	(13)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV	(9)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV	(6)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ	(4)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT	(2)
> +#define SUN8I_AIF1_DACDAT_CTRL			(0x248 - CODEC_OFFSET)
> +#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA	(15)
> +#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA	(14)
> +#define SUN8I_DAC_DIG_CTRL			(0x320 - CODEC_OFFSET)
> +#define SUN8I_DAC_DIG_CTRL_ENDA		(15)
> +#define SUN8I_DAC_MXR_SRC			(0x330 - CODEC_OFFSET)
> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA0L (15)
> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA1L (14)
> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF2DACL (13)
> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_ADCL	(12)
> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA0R (11)
> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA1R (10)
> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF2DACR (9)
> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR	(8)

Indentation of the value is not very clean for those last defines.

> +static int sun8i_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
> +{
> +	struct sun8i_codec *scodec = snd_soc_codec_get_drvdata(dai->codec);
> +	unsigned long value;

I'm not sure "unsigned long" is a very good choice here, it's going to
be a 64 bits integer on 64 bits platform. I'd suggest to use "u32",
which also seems to be what's used in _set_fmt() function of the
sun4i-i2s.c driver.


> +static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,
> +				 struct snd_pcm_hw_params *params,
> +				 struct snd_soc_dai *dai)
> +{
> +	int rs_value  = 0;

Two spaces before the = sign, not needed. Is the initialization to 0
really needed? Also, this should be a u32.

> +	regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
> +			   0x3 << SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ,

Maybe a #define value to replace the hardcoded 0x3 ?

> +			   rs_value << SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ);
> +
> +	/* calculate bclk_lrck_div Ratio */
> +	bclk_lrck_div = sample_resolution * 2;
> +	switch (bclk_lrck_div) {
> +	case 16:
> +		bclk_lrck_div = 0;
> +		break;
> +	case 32:
> +		bclk_lrck_div = 1;
> +		break;
> +	case 64:
> +		bclk_lrck_div = 2;
> +		break;
> +	case 128:
> +		bclk_lrck_div = 3;
> +		break;
> +	case 256:
> +		bclk_lrck_div = 4;
> +		break;

This could quite easily be replaced by a formula, if you don't care
about error checking:

	bclk_lrck_div = log2(bclk_lrck_div) - 4;

Of course, if you care about error checking, this switch is nicer.

> +	default:

So there's no error checking if the value is not supported?

> +		break;
> +	}
> +	regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
> +			   0x7 << SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV,

#define to replace the hard-coded 0x7 ?

> +			   bclk_lrck_div << SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV);
> +
> +	sample_rate = sun8i_codec_get_hw_rate(params);
> +	if (sample_rate < 0)
> +		return sample_rate;
> +
> +	regmap_update_bits(scodec->regmap, SUN8I_SYS_SR_CTRL,
> +			   0xf << SUN8I_SYS_SR_CTRL_AIF1_FS,

Ditto 0xf

> +			   sample_rate << SUN8I_SYS_SR_CTRL_AIF1_FS);
> +	regmap_update_bits(scodec->regmap, SUN8I_SYS_SR_CTRL,
> +			   0xf << SUN8I_SYS_SR_CTRL_AIF2_FS,

Ditto 0xf.


> +static struct snd_soc_dai_driver sun8i_codec_dai = {
> +	.name = "sun8i",
> +	/* playback capabilities */
> +	.playback = {
> +		.stream_name = "Playback",
> +		.channels_min = 1,
> +		.channels_max = 2,
> +		.rates = SNDRV_PCM_RATE_8000_192000 |
> +			SNDRV_PCM_RATE_KNOT,
> +		.formats = SNDRV_PCM_FMTBIT_S8 |
> +			SNDRV_PCM_FMTBIT_S16_LE |
> +			SNDRV_PCM_FMTBIT_S18_3LE |
> +			SNDRV_PCM_FMTBIT_S20_3LE |
> +			SNDRV_PCM_FMTBIT_S24_LE |
> +			SNDRV_PCM_FMTBIT_S32_LE,
> +	},
> +	/* pcm operations */
> +	.ops = &sun8i_codec_dai_ops,
> +};
> +EXPORT_SYMBOL(sun8i_codec_dai);

This EXPORT_SYMBOL looks wrong. First because it doesn't seem to be
used outside of this module. And second because using EXPORT_SYMBOL on
a function defined as static doesn't make much sense, as the "static"
qualifier limits the visibility of the symbol to the current
compilation unit.

> +
> +static int sun8i_soc_probe(struct snd_soc_codec *codec)
> +{
> +	return 0;
> +}
> +
> +/* power down chip */
> +static int sun8i_soc_remove(struct snd_soc_codec *codec)
> +{
> +	return 0;
> +}

I believe you can remove those stub functions.

> +
> +static struct snd_soc_codec_driver sun8i_soc_codec = {
> +	.probe			= sun8i_soc_probe,
> +	.remove		= sun8i_soc_remove,

And remove these.

> +	.component_driver = {
> +		.dapm_widgets		= sun8i_codec_dapm_widgets,
> +		.num_dapm_widgets	= ARRAY_SIZE(sun8i_codec_dapm_widgets),
> +		.dapm_routes		= sun8i_codec_dapm_routes,
> +		.num_dapm_routes	= ARRAY_SIZE(sun8i_codec_dapm_routes),

I'm probably missing something, but in the sun4i-codec.c driver, those
fields are initialized directly in the snd_soc_codec_driver structure,
not in the .component_driver sub-structure.


> +static int sun8i_codec_probe(struct platform_device *pdev)
> +{
> +	struct resource *res_base;
> +	struct sun8i_codec *scodec;
> +	void __iomem *base;
> +
> +	scodec = devm_kzalloc(&pdev->dev, sizeof(*scodec), GFP_KERNEL);
> +	if (!scodec)
> +		return -ENOMEM;
> +
> +	scodec->dev = &pdev->dev;
> +
> +	/* Get the clocks from the DT */
> +	scodec->clk_module = devm_clk_get(&pdev->dev, "codec");
> +	if (IS_ERR(scodec->clk_module)) {
> +		dev_err(&pdev->dev, "Failed to get the module clock\n");
> +		return PTR_ERR(scodec->clk_module);
> +	}
> +	if (clk_prepare_enable(scodec->clk_module))
> +		pr_err("err:open failed;\n");

Grr, pr_err, not good. Plus you want to return with an error from the
probe() function.

> +
> +	scodec->clk_apb = devm_clk_get(&pdev->dev, "apb");
> +	if (IS_ERR(scodec->clk_apb)) {
> +		dev_err(&pdev->dev, "Failed to get the apb clock\n");
> +		return PTR_ERR(scodec->clk_apb);
> +	}
> +	if (clk_prepare_enable(scodec->clk_apb))
> +		pr_err("err:open failed;\n");

Ditto. + unprepare/disable the previous clock.

> +
> +	/* Get base resources, registers and regmap */
> +	res_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audio");
> +	base = devm_ioremap_resource(&pdev->dev, res_base);
> +	if (IS_ERR(base)) {
> +		dev_err(&pdev->dev, "Failed to map the registers\n");
> +		return PTR_ERR(base);
> +	}
> +
> +	scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
> +					       &sun8i_codec_regmap_config);
> +	if (IS_ERR(scodec->regmap)) {
> +		dev_err(&pdev->dev, "Failed to create our regmap\n");
> +		return PTR_ERR(scodec->regmap);
> +	}
> +
> +	/* Set the codec data as driver data */
> +	dev_set_drvdata(&pdev->dev, scodec);

Use:

	platform_set_drvdata(pdev, scodec)

> +
> +	snd_soc_register_codec(&pdev->dev, &sun8i_soc_codec, &sun8i_codec_dai,
> +			       1);

That's a matter of taste, but I find the "1" alone on its own line a
bit weird. Maybe move &sun8i_codec_dai on the second line as well. But
again, it's mainly a matter of taste, so Mark might disagree here.

> +
> +	return 0;
> +}
> +
> +static int sun8i_codec_remove(struct platform_device *pdev)
> +{
> +	struct snd_soc_card *card = platform_get_drvdata(pdev);
> +	struct sun8i_codec *scodec = snd_soc_card_get_drvdata(card);
> +
> +	snd_soc_unregister_codec(&pdev->dev);
> +	clk_disable_unprepare(scodec->clk_module);
> +	clk_disable_unprepare(scodec->clk_apb);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id sun8i_codec_of_match[] = {
> +	{ .compatible = "allwinner,sun8i-a33-codec" },
> +	{ .compatible = "allwinner,sun8i-a23-codec" },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, sun8i_codec_of_match);
> +
> +static struct platform_driver sun8i_codec_driver = {
> +	.driver = {
> +		.name = "sun8i-codec",
> +		.owner = THIS_MODULE,
> +		.of_match_table = sun8i_codec_of_match,
> +	},
> +	.probe = sun8i_codec_probe,
> +	.remove = sun8i_codec_remove,
> +};
> +module_platform_driver(sun8i_codec_driver);
> +
> +MODULE_DESCRIPTION("Allwinner A33 (sun8i) codec driver");
> +MODULE_AUTHOR("huanxin<huanxin@reuuimllatech.com>");

Space between the name and the e-mail address.

> +MODULE_AUTHOR("Mylène Josserand <mylene.josserand@free-electrons.com>");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:sun8i-codec");

Thanks,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* Re: [PATCH 06/14] ASoC: Add sun8i digital audio codec
@ 2016-10-04 12:40       ` Thomas Petazzoni
  0 siblings, 0 replies; 170+ messages in thread
From: Thomas Petazzoni @ 2016-10-04 12:40 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt,
	linux-kernel, dmaengine, linux-arm-kernel, linux-clk, alsa-devel,
	devicetree, linux-sunxi, alexandre.belloni

Hello,

On Tue,  4 Oct 2016 11:46:19 +0200, Myl=C3=A8ne Josserand wrote:
> Add the digital sun8i audio codec which handles the base register
> (without DAI).

I'm not sure what you mean by "which handles the base register".

> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
> index 7aee95a..9e287b0 100644
> --- a/sound/soc/sunxi/Kconfig
> +++ b/sound/soc/sunxi/Kconfig
> @@ -27,6 +27,15 @@ config SND_SUN4I_SPDIF
>  	  Say Y or M to add support for the S/PDIF audio block in the Allwinner
>  	  A10 and affiliated SoCs.
> =20
> +config SND_SUN8I_CODEC
> +	tristate "Allwinner SUN8I audio codec"
> +	select REGMAP_MMIO
> +        help

Indentation issue here, it should be intended with one tab, not spaces.

You probably also want a "depends on OF" here.

> +/* CODEC_OFFSET represents the offset of the codec registers
> + * and not all the DAI registers
> + */

This is not the proper comment style I believe for audio code, it
should be:

/*
 * ...
 */

> +#define CODEC_OFFSET				0x200

Do you really need this CODEC_OFFSET macro? Why not simply use directly
the right offsets? I.e instead of:

  #define SUN8I_SYSCLK_CTL			(0x20c - CODEC_OFFSET)

use:

  #define SUN8I_SYSCLK_CTL			0xc

> +#define CODEC_BASSADDRESS			0x01c22c00

This define is not used anywhere.

> +#define SUN8I_SYSCLK_CTL			(0x20c - CODEC_OFFSET)
> +#define SUN8I_SYSCLK_CTL_AIF1CLK_ENA		(11)
> +#define SUN8I_SYSCLK_CTL_SYSCLK_ENA		(3)
> +#define SUN8I_SYSCLK_CTL_SYSCLK_SRC		(0)

Parenthesis around single values are not really useful.

> +#define SUN8I_MOD_CLK_ENA			(0x210 - CODEC_OFFSET)
> +#define SUN8I_MOD_CLK_ENA_AIF1			(15)
> +#define SUN8I_MOD_CLK_ENA_DAC			(2)
> +#define SUN8I_MOD_RST_CTL			(0x214 - CODEC_OFFSET)
> +#define SUN8I_MOD_RST_CTL_AIF1			(15)
> +#define SUN8I_MOD_RST_CTL_DAC			(2)
> +#define SUN8I_SYS_SR_CTRL			(0x218 - CODEC_OFFSET)
> +#define SUN8I_SYS_SR_CTRL_AIF1_FS		(12)
> +#define SUN8I_SYS_SR_CTRL_AIF2_FS		(8)
> +#define SUN8I_AIF1CLK_CTRL			(0x240 - CODEC_OFFSET)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_MSTR_MOD	(15)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_INV	(14)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV	(13)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV	(9)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV	(6)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ	(4)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT	(2)
> +#define SUN8I_AIF1_DACDAT_CTRL			(0x248 - CODEC_OFFSET)
> +#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA	(15)
> +#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA	(14)
> +#define SUN8I_DAC_DIG_CTRL			(0x320 - CODEC_OFFSET)
> +#define SUN8I_DAC_DIG_CTRL_ENDA		(15)
> +#define SUN8I_DAC_MXR_SRC			(0x330 - CODEC_OFFSET)
> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA0L (15)
> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA1L (14)
> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF2DACL (13)
> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_ADCL	(12)
> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA0R (11)
> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA1R (10)
> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF2DACR (9)
> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR	(8)

Indentation of the value is not very clean for those last defines.

> +static int sun8i_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
> +{
> +	struct sun8i_codec *scodec =3D snd_soc_codec_get_drvdata(dai->codec);
> +	unsigned long value;

I'm not sure "unsigned long" is a very good choice here, it's going to
be a 64 bits integer on 64 bits platform. I'd suggest to use "u32",
which also seems to be what's used in _set_fmt() function of the
sun4i-i2s.c driver.


> +static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,
> +				 struct snd_pcm_hw_params *params,
> +				 struct snd_soc_dai *dai)
> +{
> +	int rs_value  =3D 0;

Two spaces before the =3D sign, not needed. Is the initialization to 0
really needed? Also, this should be a u32.

> +	regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
> +			   0x3 << SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ,

Maybe a #define value to replace the hardcoded 0x3 ?

> +			   rs_value << SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ);
> +
> +	/* calculate bclk_lrck_div Ratio */
> +	bclk_lrck_div =3D sample_resolution * 2;
> +	switch (bclk_lrck_div) {
> +	case 16:
> +		bclk_lrck_div =3D 0;
> +		break;
> +	case 32:
> +		bclk_lrck_div =3D 1;
> +		break;
> +	case 64:
> +		bclk_lrck_div =3D 2;
> +		break;
> +	case 128:
> +		bclk_lrck_div =3D 3;
> +		break;
> +	case 256:
> +		bclk_lrck_div =3D 4;
> +		break;

This could quite easily be replaced by a formula, if you don't care
about error checking:

	bclk_lrck_div =3D log2(bclk_lrck_div) - 4;

Of course, if you care about error checking, this switch is nicer.

> +	default:

So there's no error checking if the value is not supported?

> +		break;
> +	}
> +	regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
> +			   0x7 << SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV,

#define to replace the hard-coded 0x7 ?

> +			   bclk_lrck_div << SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV);
> +
> +	sample_rate =3D sun8i_codec_get_hw_rate(params);
> +	if (sample_rate < 0)
> +		return sample_rate;
> +
> +	regmap_update_bits(scodec->regmap, SUN8I_SYS_SR_CTRL,
> +			   0xf << SUN8I_SYS_SR_CTRL_AIF1_FS,

Ditto 0xf

> +			   sample_rate << SUN8I_SYS_SR_CTRL_AIF1_FS);
> +	regmap_update_bits(scodec->regmap, SUN8I_SYS_SR_CTRL,
> +			   0xf << SUN8I_SYS_SR_CTRL_AIF2_FS,

Ditto 0xf.


> +static struct snd_soc_dai_driver sun8i_codec_dai =3D {
> +	.name =3D "sun8i",
> +	/* playback capabilities */
> +	.playback =3D {
> +		.stream_name =3D "Playback",
> +		.channels_min =3D 1,
> +		.channels_max =3D 2,
> +		.rates =3D SNDRV_PCM_RATE_8000_192000 |
> +			SNDRV_PCM_RATE_KNOT,
> +		.formats =3D SNDRV_PCM_FMTBIT_S8 |
> +			SNDRV_PCM_FMTBIT_S16_LE |
> +			SNDRV_PCM_FMTBIT_S18_3LE |
> +			SNDRV_PCM_FMTBIT_S20_3LE |
> +			SNDRV_PCM_FMTBIT_S24_LE |
> +			SNDRV_PCM_FMTBIT_S32_LE,
> +	},
> +	/* pcm operations */
> +	.ops =3D &sun8i_codec_dai_ops,
> +};
> +EXPORT_SYMBOL(sun8i_codec_dai);

This EXPORT_SYMBOL looks wrong. First because it doesn't seem to be
used outside of this module. And second because using EXPORT_SYMBOL on
a function defined as static doesn't make much sense, as the "static"
qualifier limits the visibility of the symbol to the current
compilation unit.

> +
> +static int sun8i_soc_probe(struct snd_soc_codec *codec)
> +{
> +	return 0;
> +}
> +
> +/* power down chip */
> +static int sun8i_soc_remove(struct snd_soc_codec *codec)
> +{
> +	return 0;
> +}

I believe you can remove those stub functions.

> +
> +static struct snd_soc_codec_driver sun8i_soc_codec =3D {
> +	.probe			=3D sun8i_soc_probe,
> +	.remove		=3D sun8i_soc_remove,

And remove these.

> +	.component_driver =3D {
> +		.dapm_widgets		=3D sun8i_codec_dapm_widgets,
> +		.num_dapm_widgets	=3D ARRAY_SIZE(sun8i_codec_dapm_widgets),
> +		.dapm_routes		=3D sun8i_codec_dapm_routes,
> +		.num_dapm_routes	=3D ARRAY_SIZE(sun8i_codec_dapm_routes),

I'm probably missing something, but in the sun4i-codec.c driver, those
fields are initialized directly in the snd_soc_codec_driver structure,
not in the .component_driver sub-structure.


> +static int sun8i_codec_probe(struct platform_device *pdev)
> +{
> +	struct resource *res_base;
> +	struct sun8i_codec *scodec;
> +	void __iomem *base;
> +
> +	scodec =3D devm_kzalloc(&pdev->dev, sizeof(*scodec), GFP_KERNEL);
> +	if (!scodec)
> +		return -ENOMEM;
> +
> +	scodec->dev =3D &pdev->dev;
> +
> +	/* Get the clocks from the DT */
> +	scodec->clk_module =3D devm_clk_get(&pdev->dev, "codec");
> +	if (IS_ERR(scodec->clk_module)) {
> +		dev_err(&pdev->dev, "Failed to get the module clock\n");
> +		return PTR_ERR(scodec->clk_module);
> +	}
> +	if (clk_prepare_enable(scodec->clk_module))
> +		pr_err("err:open failed;\n");

Grr, pr_err, not good. Plus you want to return with an error from the
probe() function.

> +
> +	scodec->clk_apb =3D devm_clk_get(&pdev->dev, "apb");
> +	if (IS_ERR(scodec->clk_apb)) {
> +		dev_err(&pdev->dev, "Failed to get the apb clock\n");
> +		return PTR_ERR(scodec->clk_apb);
> +	}
> +	if (clk_prepare_enable(scodec->clk_apb))
> +		pr_err("err:open failed;\n");

Ditto. + unprepare/disable the previous clock.

> +
> +	/* Get base resources, registers and regmap */
> +	res_base =3D platform_get_resource_byname(pdev, IORESOURCE_MEM, "audio"=
);
> +	base =3D devm_ioremap_resource(&pdev->dev, res_base);
> +	if (IS_ERR(base)) {
> +		dev_err(&pdev->dev, "Failed to map the registers\n");
> +		return PTR_ERR(base);
> +	}
> +
> +	scodec->regmap =3D devm_regmap_init_mmio(&pdev->dev, base,
> +					       &sun8i_codec_regmap_config);
> +	if (IS_ERR(scodec->regmap)) {
> +		dev_err(&pdev->dev, "Failed to create our regmap\n");
> +		return PTR_ERR(scodec->regmap);
> +	}
> +
> +	/* Set the codec data as driver data */
> +	dev_set_drvdata(&pdev->dev, scodec);

Use:

	platform_set_drvdata(pdev, scodec)

> +
> +	snd_soc_register_codec(&pdev->dev, &sun8i_soc_codec, &sun8i_codec_dai,
> +			       1);

That's a matter of taste, but I find the "1" alone on its own line a
bit weird. Maybe move &sun8i_codec_dai on the second line as well. But
again, it's mainly a matter of taste, so Mark might disagree here.

> +
> +	return 0;
> +}
> +
> +static int sun8i_codec_remove(struct platform_device *pdev)
> +{
> +	struct snd_soc_card *card =3D platform_get_drvdata(pdev);
> +	struct sun8i_codec *scodec =3D snd_soc_card_get_drvdata(card);
> +
> +	snd_soc_unregister_codec(&pdev->dev);
> +	clk_disable_unprepare(scodec->clk_module);
> +	clk_disable_unprepare(scodec->clk_apb);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id sun8i_codec_of_match[] =3D {
> +	{ .compatible =3D "allwinner,sun8i-a33-codec" },
> +	{ .compatible =3D "allwinner,sun8i-a23-codec" },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, sun8i_codec_of_match);
> +
> +static struct platform_driver sun8i_codec_driver =3D {
> +	.driver =3D {
> +		.name =3D "sun8i-codec",
> +		.owner =3D THIS_MODULE,
> +		.of_match_table =3D sun8i_codec_of_match,
> +	},
> +	.probe =3D sun8i_codec_probe,
> +	.remove =3D sun8i_codec_remove,
> +};
> +module_platform_driver(sun8i_codec_driver);
> +
> +MODULE_DESCRIPTION("Allwinner A33 (sun8i) codec driver");
> +MODULE_AUTHOR("huanxin<huanxin@reuuimllatech.com>");

Space between the name and the e-mail address.

> +MODULE_AUTHOR("Myl=C3=A8ne Josserand <mylene.josserand@free-electrons.co=
m>");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:sun8i-codec");

Thanks,

Thomas
--=20
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* [PATCH 06/14] ASoC: Add sun8i digital audio codec
@ 2016-10-04 12:40       ` Thomas Petazzoni
  0 siblings, 0 replies; 170+ messages in thread
From: Thomas Petazzoni @ 2016-10-04 12:40 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On Tue,  4 Oct 2016 11:46:19 +0200, Myl?ne Josserand wrote:
> Add the digital sun8i audio codec which handles the base register
> (without DAI).

I'm not sure what you mean by "which handles the base register".

> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
> index 7aee95a..9e287b0 100644
> --- a/sound/soc/sunxi/Kconfig
> +++ b/sound/soc/sunxi/Kconfig
> @@ -27,6 +27,15 @@ config SND_SUN4I_SPDIF
>  	  Say Y or M to add support for the S/PDIF audio block in the Allwinner
>  	  A10 and affiliated SoCs.
>  
> +config SND_SUN8I_CODEC
> +	tristate "Allwinner SUN8I audio codec"
> +	select REGMAP_MMIO
> +        help

Indentation issue here, it should be intended with one tab, not spaces.

You probably also want a "depends on OF" here.

> +/* CODEC_OFFSET represents the offset of the codec registers
> + * and not all the DAI registers
> + */

This is not the proper comment style I believe for audio code, it
should be:

/*
 * ...
 */

> +#define CODEC_OFFSET				0x200

Do you really need this CODEC_OFFSET macro? Why not simply use directly
the right offsets? I.e instead of:

  #define SUN8I_SYSCLK_CTL			(0x20c - CODEC_OFFSET)

use:

  #define SUN8I_SYSCLK_CTL			0xc

> +#define CODEC_BASSADDRESS			0x01c22c00

This define is not used anywhere.

> +#define SUN8I_SYSCLK_CTL			(0x20c - CODEC_OFFSET)
> +#define SUN8I_SYSCLK_CTL_AIF1CLK_ENA		(11)
> +#define SUN8I_SYSCLK_CTL_SYSCLK_ENA		(3)
> +#define SUN8I_SYSCLK_CTL_SYSCLK_SRC		(0)

Parenthesis around single values are not really useful.

> +#define SUN8I_MOD_CLK_ENA			(0x210 - CODEC_OFFSET)
> +#define SUN8I_MOD_CLK_ENA_AIF1			(15)
> +#define SUN8I_MOD_CLK_ENA_DAC			(2)
> +#define SUN8I_MOD_RST_CTL			(0x214 - CODEC_OFFSET)
> +#define SUN8I_MOD_RST_CTL_AIF1			(15)
> +#define SUN8I_MOD_RST_CTL_DAC			(2)
> +#define SUN8I_SYS_SR_CTRL			(0x218 - CODEC_OFFSET)
> +#define SUN8I_SYS_SR_CTRL_AIF1_FS		(12)
> +#define SUN8I_SYS_SR_CTRL_AIF2_FS		(8)
> +#define SUN8I_AIF1CLK_CTRL			(0x240 - CODEC_OFFSET)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_MSTR_MOD	(15)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_INV	(14)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV	(13)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV	(9)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV	(6)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ	(4)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT	(2)
> +#define SUN8I_AIF1_DACDAT_CTRL			(0x248 - CODEC_OFFSET)
> +#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA	(15)
> +#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA	(14)
> +#define SUN8I_DAC_DIG_CTRL			(0x320 - CODEC_OFFSET)
> +#define SUN8I_DAC_DIG_CTRL_ENDA		(15)
> +#define SUN8I_DAC_MXR_SRC			(0x330 - CODEC_OFFSET)
> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA0L (15)
> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA1L (14)
> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF2DACL (13)
> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_ADCL	(12)
> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA0R (11)
> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA1R (10)
> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF2DACR (9)
> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR	(8)

Indentation of the value is not very clean for those last defines.

> +static int sun8i_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
> +{
> +	struct sun8i_codec *scodec = snd_soc_codec_get_drvdata(dai->codec);
> +	unsigned long value;

I'm not sure "unsigned long" is a very good choice here, it's going to
be a 64 bits integer on 64 bits platform. I'd suggest to use "u32",
which also seems to be what's used in _set_fmt() function of the
sun4i-i2s.c driver.


> +static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,
> +				 struct snd_pcm_hw_params *params,
> +				 struct snd_soc_dai *dai)
> +{
> +	int rs_value  = 0;

Two spaces before the = sign, not needed. Is the initialization to 0
really needed? Also, this should be a u32.

> +	regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
> +			   0x3 << SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ,

Maybe a #define value to replace the hardcoded 0x3 ?

> +			   rs_value << SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ);
> +
> +	/* calculate bclk_lrck_div Ratio */
> +	bclk_lrck_div = sample_resolution * 2;
> +	switch (bclk_lrck_div) {
> +	case 16:
> +		bclk_lrck_div = 0;
> +		break;
> +	case 32:
> +		bclk_lrck_div = 1;
> +		break;
> +	case 64:
> +		bclk_lrck_div = 2;
> +		break;
> +	case 128:
> +		bclk_lrck_div = 3;
> +		break;
> +	case 256:
> +		bclk_lrck_div = 4;
> +		break;

This could quite easily be replaced by a formula, if you don't care
about error checking:

	bclk_lrck_div = log2(bclk_lrck_div) - 4;

Of course, if you care about error checking, this switch is nicer.

> +	default:

So there's no error checking if the value is not supported?

> +		break;
> +	}
> +	regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
> +			   0x7 << SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV,

#define to replace the hard-coded 0x7 ?

> +			   bclk_lrck_div << SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV);
> +
> +	sample_rate = sun8i_codec_get_hw_rate(params);
> +	if (sample_rate < 0)
> +		return sample_rate;
> +
> +	regmap_update_bits(scodec->regmap, SUN8I_SYS_SR_CTRL,
> +			   0xf << SUN8I_SYS_SR_CTRL_AIF1_FS,

Ditto 0xf

> +			   sample_rate << SUN8I_SYS_SR_CTRL_AIF1_FS);
> +	regmap_update_bits(scodec->regmap, SUN8I_SYS_SR_CTRL,
> +			   0xf << SUN8I_SYS_SR_CTRL_AIF2_FS,

Ditto 0xf.


> +static struct snd_soc_dai_driver sun8i_codec_dai = {
> +	.name = "sun8i",
> +	/* playback capabilities */
> +	.playback = {
> +		.stream_name = "Playback",
> +		.channels_min = 1,
> +		.channels_max = 2,
> +		.rates = SNDRV_PCM_RATE_8000_192000 |
> +			SNDRV_PCM_RATE_KNOT,
> +		.formats = SNDRV_PCM_FMTBIT_S8 |
> +			SNDRV_PCM_FMTBIT_S16_LE |
> +			SNDRV_PCM_FMTBIT_S18_3LE |
> +			SNDRV_PCM_FMTBIT_S20_3LE |
> +			SNDRV_PCM_FMTBIT_S24_LE |
> +			SNDRV_PCM_FMTBIT_S32_LE,
> +	},
> +	/* pcm operations */
> +	.ops = &sun8i_codec_dai_ops,
> +};
> +EXPORT_SYMBOL(sun8i_codec_dai);

This EXPORT_SYMBOL looks wrong. First because it doesn't seem to be
used outside of this module. And second because using EXPORT_SYMBOL on
a function defined as static doesn't make much sense, as the "static"
qualifier limits the visibility of the symbol to the current
compilation unit.

> +
> +static int sun8i_soc_probe(struct snd_soc_codec *codec)
> +{
> +	return 0;
> +}
> +
> +/* power down chip */
> +static int sun8i_soc_remove(struct snd_soc_codec *codec)
> +{
> +	return 0;
> +}

I believe you can remove those stub functions.

> +
> +static struct snd_soc_codec_driver sun8i_soc_codec = {
> +	.probe			= sun8i_soc_probe,
> +	.remove		= sun8i_soc_remove,

And remove these.

> +	.component_driver = {
> +		.dapm_widgets		= sun8i_codec_dapm_widgets,
> +		.num_dapm_widgets	= ARRAY_SIZE(sun8i_codec_dapm_widgets),
> +		.dapm_routes		= sun8i_codec_dapm_routes,
> +		.num_dapm_routes	= ARRAY_SIZE(sun8i_codec_dapm_routes),

I'm probably missing something, but in the sun4i-codec.c driver, those
fields are initialized directly in the snd_soc_codec_driver structure,
not in the .component_driver sub-structure.


> +static int sun8i_codec_probe(struct platform_device *pdev)
> +{
> +	struct resource *res_base;
> +	struct sun8i_codec *scodec;
> +	void __iomem *base;
> +
> +	scodec = devm_kzalloc(&pdev->dev, sizeof(*scodec), GFP_KERNEL);
> +	if (!scodec)
> +		return -ENOMEM;
> +
> +	scodec->dev = &pdev->dev;
> +
> +	/* Get the clocks from the DT */
> +	scodec->clk_module = devm_clk_get(&pdev->dev, "codec");
> +	if (IS_ERR(scodec->clk_module)) {
> +		dev_err(&pdev->dev, "Failed to get the module clock\n");
> +		return PTR_ERR(scodec->clk_module);
> +	}
> +	if (clk_prepare_enable(scodec->clk_module))
> +		pr_err("err:open failed;\n");

Grr, pr_err, not good. Plus you want to return with an error from the
probe() function.

> +
> +	scodec->clk_apb = devm_clk_get(&pdev->dev, "apb");
> +	if (IS_ERR(scodec->clk_apb)) {
> +		dev_err(&pdev->dev, "Failed to get the apb clock\n");
> +		return PTR_ERR(scodec->clk_apb);
> +	}
> +	if (clk_prepare_enable(scodec->clk_apb))
> +		pr_err("err:open failed;\n");

Ditto. + unprepare/disable the previous clock.

> +
> +	/* Get base resources, registers and regmap */
> +	res_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audio");
> +	base = devm_ioremap_resource(&pdev->dev, res_base);
> +	if (IS_ERR(base)) {
> +		dev_err(&pdev->dev, "Failed to map the registers\n");
> +		return PTR_ERR(base);
> +	}
> +
> +	scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
> +					       &sun8i_codec_regmap_config);
> +	if (IS_ERR(scodec->regmap)) {
> +		dev_err(&pdev->dev, "Failed to create our regmap\n");
> +		return PTR_ERR(scodec->regmap);
> +	}
> +
> +	/* Set the codec data as driver data */
> +	dev_set_drvdata(&pdev->dev, scodec);

Use:

	platform_set_drvdata(pdev, scodec)

> +
> +	snd_soc_register_codec(&pdev->dev, &sun8i_soc_codec, &sun8i_codec_dai,
> +			       1);

That's a matter of taste, but I find the "1" alone on its own line a
bit weird. Maybe move &sun8i_codec_dai on the second line as well. But
again, it's mainly a matter of taste, so Mark might disagree here.

> +
> +	return 0;
> +}
> +
> +static int sun8i_codec_remove(struct platform_device *pdev)
> +{
> +	struct snd_soc_card *card = platform_get_drvdata(pdev);
> +	struct sun8i_codec *scodec = snd_soc_card_get_drvdata(card);
> +
> +	snd_soc_unregister_codec(&pdev->dev);
> +	clk_disable_unprepare(scodec->clk_module);
> +	clk_disable_unprepare(scodec->clk_apb);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id sun8i_codec_of_match[] = {
> +	{ .compatible = "allwinner,sun8i-a33-codec" },
> +	{ .compatible = "allwinner,sun8i-a23-codec" },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, sun8i_codec_of_match);
> +
> +static struct platform_driver sun8i_codec_driver = {
> +	.driver = {
> +		.name = "sun8i-codec",
> +		.owner = THIS_MODULE,
> +		.of_match_table = sun8i_codec_of_match,
> +	},
> +	.probe = sun8i_codec_probe,
> +	.remove = sun8i_codec_remove,
> +};
> +module_platform_driver(sun8i_codec_driver);
> +
> +MODULE_DESCRIPTION("Allwinner A33 (sun8i) codec driver");
> +MODULE_AUTHOR("huanxin<huanxin@reuuimllatech.com>");

Space between the name and the e-mail address.

> +MODULE_AUTHOR("Myl?ne Josserand <mylene.josserand@free-electrons.com>");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:sun8i-codec");

Thanks,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* Re: [PATCH 06/14] ASoC: Add sun8i digital audio codec
@ 2016-10-04 13:07         ` Mark Brown
  0 siblings, 0 replies; 170+ messages in thread
From: Mark Brown @ 2016-10-04 13:07 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Mylène Josserand, vinod.koul, maxime.ripard, wens,
	mturquette, sboyd, lgirdwood, perex, tiwai, lee.jones,
	mark.rutland, robh+dt, linux-kernel, dmaengine, linux-arm-kernel,
	linux-clk, alsa-devel, devicetree, linux-sunxi,
	alexandre.belloni

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

On Tue, Oct 04, 2016 at 02:40:08PM +0200, Thomas Petazzoni wrote:

> > +/* CODEC_OFFSET represents the offset of the codec registers
> > + * and not all the DAI registers
> > + */

> This is not the proper comment style I believe for audio code, it
> should be:

> /*
>  * ...
>  */

I don't care, IIRC that's something from CodingStyle which checkpatch
moans about.

> > +	/* pcm operations */
> > +	.ops = &sun8i_codec_dai_ops,
> > +};
> > +EXPORT_SYMBOL(sun8i_codec_dai);

> This EXPORT_SYMBOL looks wrong. First because it doesn't seem to be
> used outside of this module. And second because using EXPORT_SYMBOL on
> a function defined as static doesn't make much sense, as the "static"
> qualifier limits the visibility of the symbol to the current
> compilation unit.

Also all the ASoC code is _GPL so a non-GPL export is an issue.

> > +	.component_driver = {
> > +		.dapm_widgets		= sun8i_codec_dapm_widgets,
> > +		.num_dapm_widgets	= ARRAY_SIZE(sun8i_codec_dapm_widgets),
> > +		.dapm_routes		= sun8i_codec_dapm_routes,
> > +		.num_dapm_routes	= ARRAY_SIZE(sun8i_codec_dapm_routes),

> I'm probably missing something, but in the sun4i-codec.c driver, those
> fields are initialized directly in the snd_soc_codec_driver structure,
> not in the .component_driver sub-structure.

We're in the process of pushing everything out to component level, this
update should be made in the old code if it's not happened already.

> > +	if (clk_prepare_enable(scodec->clk_module))
> > +		pr_err("err:open failed;\n");

> Grr, pr_err, not good. Plus you want to return with an error from the
> probe() function.

Also when printing an error message use dev_err().

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

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

* Re: [PATCH 06/14] ASoC: Add sun8i digital audio codec
@ 2016-10-04 13:07         ` Mark Brown
  0 siblings, 0 replies; 170+ messages in thread
From: Mark Brown @ 2016-10-04 13:07 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Mylène Josserand, vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8, wens-jdAy2FN1RRM,
	mturquette-rdvid1DuHRBWk0Htik3J/w, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, perex-/Fr2/VpizcU,
	tiwai-IBi9RG/b67k, lee.jones-QSEj5FYQhm4dnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8

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

On Tue, Oct 04, 2016 at 02:40:08PM +0200, Thomas Petazzoni wrote:

> > +/* CODEC_OFFSET represents the offset of the codec registers
> > + * and not all the DAI registers
> > + */

> This is not the proper comment style I believe for audio code, it
> should be:

> /*
>  * ...
>  */

I don't care, IIRC that's something from CodingStyle which checkpatch
moans about.

> > +	/* pcm operations */
> > +	.ops = &sun8i_codec_dai_ops,
> > +};
> > +EXPORT_SYMBOL(sun8i_codec_dai);

> This EXPORT_SYMBOL looks wrong. First because it doesn't seem to be
> used outside of this module. And second because using EXPORT_SYMBOL on
> a function defined as static doesn't make much sense, as the "static"
> qualifier limits the visibility of the symbol to the current
> compilation unit.

Also all the ASoC code is _GPL so a non-GPL export is an issue.

> > +	.component_driver = {
> > +		.dapm_widgets		= sun8i_codec_dapm_widgets,
> > +		.num_dapm_widgets	= ARRAY_SIZE(sun8i_codec_dapm_widgets),
> > +		.dapm_routes		= sun8i_codec_dapm_routes,
> > +		.num_dapm_routes	= ARRAY_SIZE(sun8i_codec_dapm_routes),

> I'm probably missing something, but in the sun4i-codec.c driver, those
> fields are initialized directly in the snd_soc_codec_driver structure,
> not in the .component_driver sub-structure.

We're in the process of pushing everything out to component level, this
update should be made in the old code if it's not happened already.

> > +	if (clk_prepare_enable(scodec->clk_module))
> > +		pr_err("err:open failed;\n");

> Grr, pr_err, not good. Plus you want to return with an error from the
> probe() function.

Also when printing an error message use dev_err().

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

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

* [PATCH 06/14] ASoC: Add sun8i digital audio codec
@ 2016-10-04 13:07         ` Mark Brown
  0 siblings, 0 replies; 170+ messages in thread
From: Mark Brown @ 2016-10-04 13:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 04, 2016 at 02:40:08PM +0200, Thomas Petazzoni wrote:

> > +/* CODEC_OFFSET represents the offset of the codec registers
> > + * and not all the DAI registers
> > + */

> This is not the proper comment style I believe for audio code, it
> should be:

> /*
>  * ...
>  */

I don't care, IIRC that's something from CodingStyle which checkpatch
moans about.

> > +	/* pcm operations */
> > +	.ops = &sun8i_codec_dai_ops,
> > +};
> > +EXPORT_SYMBOL(sun8i_codec_dai);

> This EXPORT_SYMBOL looks wrong. First because it doesn't seem to be
> used outside of this module. And second because using EXPORT_SYMBOL on
> a function defined as static doesn't make much sense, as the "static"
> qualifier limits the visibility of the symbol to the current
> compilation unit.

Also all the ASoC code is _GPL so a non-GPL export is an issue.

> > +	.component_driver = {
> > +		.dapm_widgets		= sun8i_codec_dapm_widgets,
> > +		.num_dapm_widgets	= ARRAY_SIZE(sun8i_codec_dapm_widgets),
> > +		.dapm_routes		= sun8i_codec_dapm_routes,
> > +		.num_dapm_routes	= ARRAY_SIZE(sun8i_codec_dapm_routes),

> I'm probably missing something, but in the sun4i-codec.c driver, those
> fields are initialized directly in the snd_soc_codec_driver structure,
> not in the .component_driver sub-structure.

We're in the process of pushing everything out to component level, this
update should be made in the old code if it's not happened already.

> > +	if (clk_prepare_enable(scodec->clk_module))
> > +		pr_err("err:open failed;\n");

> Grr, pr_err, not good. Plus you want to return with an error from the
> probe() function.

Also when printing an error message use dev_err().
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 455 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161004/4287ed0a/attachment.sig>

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

* Re: [PATCH 06/14] ASoC: Add sun8i digital audio codec
  2016-10-04 13:07         ` Mark Brown
@ 2016-10-04 13:16           ` Thomas Petazzoni
  -1 siblings, 0 replies; 170+ messages in thread
From: Thomas Petazzoni @ 2016-10-04 13:16 UTC (permalink / raw)
  To: Mark Brown
  Cc: Mylène Josserand, vinod.koul, maxime.ripard, wens,
	mturquette, sboyd, lgirdwood, perex, tiwai, lee.jones,
	mark.rutland, robh+dt, linux-kernel, dmaengine, linux-arm-kernel,
	linux-clk, alsa-devel, devicetree, linux-sunxi,
	alexandre.belloni

Hello,

On Tue, 4 Oct 2016 15:07:27 +0200, Mark Brown wrote:

> > /*
> >  * ...
> >  */  
> 
> I don't care, IIRC that's something from CodingStyle which checkpatch
> moans about.

Correct. The

/* ..
 * ..
 */

style is mandatory for net/ and crypto code, but not in the rest of the
kernel.

> > I'm probably missing something, but in the sun4i-codec.c driver, those
> > fields are initialized directly in the snd_soc_codec_driver structure,
> > not in the .component_driver sub-structure.  
> 
> We're in the process of pushing everything out to component level, this
> update should be made in the old code if it's not happened already.

OK.

> > > +	if (clk_prepare_enable(scodec->clk_module))
> > > +		pr_err("err:open failed;\n");  
> 
> > Grr, pr_err, not good. Plus you want to return with an error from the
> > probe() function.  
> 
> Also when printing an error message use dev_err().

That's why I said "Grr, pr_err, not good" :)

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* [PATCH 06/14] ASoC: Add sun8i digital audio codec
@ 2016-10-04 13:16           ` Thomas Petazzoni
  0 siblings, 0 replies; 170+ messages in thread
From: Thomas Petazzoni @ 2016-10-04 13:16 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On Tue, 4 Oct 2016 15:07:27 +0200, Mark Brown wrote:

> > /*
> >  * ...
> >  */  
> 
> I don't care, IIRC that's something from CodingStyle which checkpatch
> moans about.

Correct. The

/* ..
 * ..
 */

style is mandatory for net/ and crypto code, but not in the rest of the
kernel.

> > I'm probably missing something, but in the sun4i-codec.c driver, those
> > fields are initialized directly in the snd_soc_codec_driver structure,
> > not in the .component_driver sub-structure.  
> 
> We're in the process of pushing everything out to component level, this
> update should be made in the old code if it's not happened already.

OK.

> > > +	if (clk_prepare_enable(scodec->clk_module))
> > > +		pr_err("err:open failed;\n");  
> 
> > Grr, pr_err, not good. Plus you want to return with an error from the
> > probe() function.  
> 
> Also when printing an error message use dev_err().

That's why I said "Grr, pr_err, not good" :)

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-10-04 13:46           ` Jean-Francois Moine
  0 siblings, 0 replies; 170+ messages in thread
From: Jean-Francois Moine @ 2016-10-04 13:46 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Mylène Josserand, vinod.koul, maxime.ripard, wens,
	mturquette, sboyd, lgirdwood, broonie, perex, tiwai, lee.jones,
	mark.rutland, robh+dt, devicetree, alsa-devel, linux-kernel,
	linux-sunxi, alexandre.belloni, dmaengine, linux-clk,
	linux-arm-kernel

On Tue, 4 Oct 2016 14:12:21 +0200
Thomas Petazzoni <thomas.petazzoni@free-electrons.com> wrote:

> > > Add the case of a burst of 4 which is handled by the SoC.
> > > 
> > > Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
> > > ---
> > >  drivers/dma/sun6i-dma.c | 2 ++
> > >  1 file changed, 2 insertions(+)
> > > 
> > > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> > > index 8346199..0485204 100644
> > > --- a/drivers/dma/sun6i-dma.c
> > > +++ b/drivers/dma/sun6i-dma.c
> > > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
> > >  	switch (maxburst) {
> > >  	case 1:
> > >  		return 0;
> > > +	case 4:
> > > +		return 1;
> > >  	case 8:
> > >  		return 2;
> > >  	default:
> > > -- 
> > > 2.9.3  
> > 
> > This patch has already been rejected by Maxime in the threads
> > 	http://www.spinics.net/lists/dmaengine/msg08610.html
> > and
> > 	http://www.spinics.net/lists/dmaengine/msg08719.html
> > 
> > I hope you will find the way he wants for this maxburst to be added.
> 
> I was about to reply to Mylene's e-mail, suggesting that she should add
> a comment in the code (and maybe in the commit log) to explain why this
> addition is needed, and also that even though the schematics say that
> value "1" (max burst size of 4 bytes) is reserved, it is in fact
> incorrect. The Allwinner BSP code is really using this value, and it's
> the value that makes audio work, so we believe the datasheet is simply
> incorrect.
> 
> We already discussed it with Maxime, so I believe he should agree this
> time. But I would suggest to have such details explained in the commit
> log and in a comment in the code.

Strange. Looking at the datasheets of the A23, A31, A33, A83T and H3
(these are the SoCs using the DMA sun6i), only the H3 can have 4 as the
burst size (the doc is unclear for the A31).

Well, I was submitting for the H3, Mylène is submitting for the A33.
So, what about the A23, A31 and A83T?

-- 
Ken ar c'hentañ	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

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

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-10-04 13:46           ` Jean-Francois Moine
  0 siblings, 0 replies; 170+ messages in thread
From: Jean-Francois Moine @ 2016-10-04 13:46 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Mylène Josserand, vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8, wens-jdAy2FN1RRM,
	mturquette-rdvid1DuHRBWk0Htik3J/w, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A,
	perex-/Fr2/VpizcU, tiwai-IBi9RG/b67k,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Tue, 4 Oct 2016 14:12:21 +0200
Thomas Petazzoni <thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:

> > > Add the case of a burst of 4 which is handled by the SoC.
> > > 
> > > Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
> > > ---
> > >  drivers/dma/sun6i-dma.c | 2 ++
> > >  1 file changed, 2 insertions(+)
> > > 
> > > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> > > index 8346199..0485204 100644
> > > --- a/drivers/dma/sun6i-dma.c
> > > +++ b/drivers/dma/sun6i-dma.c
> > > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
> > >  	switch (maxburst) {
> > >  	case 1:
> > >  		return 0;
> > > +	case 4:
> > > +		return 1;
> > >  	case 8:
> > >  		return 2;
> > >  	default:
> > > -- 
> > > 2.9.3  
> > 
> > This patch has already been rejected by Maxime in the threads
> > 	http://www.spinics.net/lists/dmaengine/msg08610.html
> > and
> > 	http://www.spinics.net/lists/dmaengine/msg08719.html
> > 
> > I hope you will find the way he wants for this maxburst to be added.
> 
> I was about to reply to Mylene's e-mail, suggesting that she should add
> a comment in the code (and maybe in the commit log) to explain why this
> addition is needed, and also that even though the schematics say that
> value "1" (max burst size of 4 bytes) is reserved, it is in fact
> incorrect. The Allwinner BSP code is really using this value, and it's
> the value that makes audio work, so we believe the datasheet is simply
> incorrect.
> 
> We already discussed it with Maxime, so I believe he should agree this
> time. But I would suggest to have such details explained in the commit
> log and in a comment in the code.

Strange. Looking at the datasheets of the A23, A31, A33, A83T and H3
(these are the SoCs using the DMA sun6i), only the H3 can have 4 as the
burst size (the doc is unclear for the A31).

Well, I was submitting for the H3, Mylène is submitting for the A33.
So, what about the A23, A31 and A83T?

-- 
Ken ar c'hentañ	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

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

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-10-04 13:46           ` Jean-Francois Moine
  0 siblings, 0 replies; 170+ messages in thread
From: Jean-Francois Moine @ 2016-10-04 13:46 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Mylène Josserand, vinod.koul, maxime.ripard, wens,
	mturquette, sboyd, lgirdwood, broonie, perex, tiwai, lee.jones,
	mark.rutland, robh+dt, devicetree, alsa-devel, linux-kernel,
	linux-sunxi, alexandre.belloni, dmaengine, linux-clk,
	linux-arm-kernel

On Tue, 4 Oct 2016 14:12:21 +0200
Thomas Petazzoni <thomas.petazzoni@free-electrons.com> wrote:

> > > Add the case of a burst of 4 which is handled by the SoC.
> > >=20
> > > Signed-off-by: Myl=E8ne Josserand <mylene.josserand@free-electrons.co=
m>
> > > ---
> > >  drivers/dma/sun6i-dma.c | 2 ++
> > >  1 file changed, 2 insertions(+)
> > >=20
> > > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> > > index 8346199..0485204 100644
> > > --- a/drivers/dma/sun6i-dma.c
> > > +++ b/drivers/dma/sun6i-dma.c
> > > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
> > >  	switch (maxburst) {
> > >  	case 1:
> > >  		return 0;
> > > +	case 4:
> > > +		return 1;
> > >  	case 8:
> > >  		return 2;
> > >  	default:
> > > --=20
> > > 2.9.3 =20
> >=20
> > This patch has already been rejected by Maxime in the threads
> > 	http://www.spinics.net/lists/dmaengine/msg08610.html
> > and
> > 	http://www.spinics.net/lists/dmaengine/msg08719.html
> >=20
> > I hope you will find the way he wants for this maxburst to be added.
>=20
> I was about to reply to Mylene's e-mail, suggesting that she should add
> a comment in the code (and maybe in the commit log) to explain why this
> addition is needed, and also that even though the schematics say that
> value "1" (max burst size of 4 bytes) is reserved, it is in fact
> incorrect. The Allwinner BSP code is really using this value, and it's
> the value that makes audio work, so we believe the datasheet is simply
> incorrect.
>=20
> We already discussed it with Maxime, so I believe he should agree this
> time. But I would suggest to have such details explained in the commit
> log and in a comment in the code.

Strange. Looking at the datasheets of the A23, A31, A33, A83T and H3
(these are the SoCs using the DMA sun6i), only the H3 can have 4 as the
burst size (the doc is unclear for the A31).

Well, I was submitting for the H3, Myl=E8ne is submitting for the A33.
So, what about the A23, A31 and A83T?

--=20
Ken ar c'henta=F1	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

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

* [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-10-04 13:46           ` Jean-Francois Moine
  0 siblings, 0 replies; 170+ messages in thread
From: Jean-Francois Moine @ 2016-10-04 13:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 4 Oct 2016 14:12:21 +0200
Thomas Petazzoni <thomas.petazzoni@free-electrons.com> wrote:

> > > Add the case of a burst of 4 which is handled by the SoC.
> > > 
> > > Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
> > > ---
> > >  drivers/dma/sun6i-dma.c | 2 ++
> > >  1 file changed, 2 insertions(+)
> > > 
> > > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> > > index 8346199..0485204 100644
> > > --- a/drivers/dma/sun6i-dma.c
> > > +++ b/drivers/dma/sun6i-dma.c
> > > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
> > >  	switch (maxburst) {
> > >  	case 1:
> > >  		return 0;
> > > +	case 4:
> > > +		return 1;
> > >  	case 8:
> > >  		return 2;
> > >  	default:
> > > -- 
> > > 2.9.3  
> > 
> > This patch has already been rejected by Maxime in the threads
> > 	http://www.spinics.net/lists/dmaengine/msg08610.html
> > and
> > 	http://www.spinics.net/lists/dmaengine/msg08719.html
> > 
> > I hope you will find the way he wants for this maxburst to be added.
> 
> I was about to reply to Mylene's e-mail, suggesting that she should add
> a comment in the code (and maybe in the commit log) to explain why this
> addition is needed, and also that even though the schematics say that
> value "1" (max burst size of 4 bytes) is reserved, it is in fact
> incorrect. The Allwinner BSP code is really using this value, and it's
> the value that makes audio work, so we believe the datasheet is simply
> incorrect.
> 
> We already discussed it with Maxime, so I believe he should agree this
> time. But I would suggest to have such details explained in the commit
> log and in a comment in the code.

Strange. Looking at the datasheets of the A23, A31, A33, A83T and H3
(these are the SoCs using the DMA sun6i), only the H3 can have 4 as the
burst size (the doc is unclear for the A31).

Well, I was submitting for the H3, Myl?ne is submitting for the A33.
So, what about the A23, A31 and A83T?

-- 
Ken ar c'henta?	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

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

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-10-04 15:40             ` Vinod Koul
  0 siblings, 0 replies; 170+ messages in thread
From: Vinod Koul @ 2016-10-04 15:40 UTC (permalink / raw)
  To: Jean-Francois Moine
  Cc: Thomas Petazzoni, Mylène Josserand, maxime.ripard, wens,
	mturquette, sboyd, lgirdwood, broonie, perex, tiwai, lee.jones,
	mark.rutland, robh+dt, devicetree, alsa-devel, linux-kernel,
	linux-sunxi, alexandre.belloni, dmaengine, linux-clk,
	linux-arm-kernel

On Tue, Oct 04, 2016 at 03:46:51PM +0200, Jean-Francois Moine wrote:
> On Tue, 4 Oct 2016 14:12:21 +0200
> Thomas Petazzoni <thomas.petazzoni@free-electrons.com> wrote:
> 
> > > > Add the case of a burst of 4 which is handled by the SoC.
> > > > 
> > > > Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
> > > > ---
> > > >  drivers/dma/sun6i-dma.c | 2 ++
> > > >  1 file changed, 2 insertions(+)
> > > > 
> > > > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> > > > index 8346199..0485204 100644
> > > > --- a/drivers/dma/sun6i-dma.c
> > > > +++ b/drivers/dma/sun6i-dma.c
> > > > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
> > > >  	switch (maxburst) {
> > > >  	case 1:
> > > >  		return 0;
> > > > +	case 4:
> > > > +		return 1;
> > > >  	case 8:
> > > >  		return 2;
> > > >  	default:
> > > > -- 
> > > > 2.9.3  
> > > 
> > > This patch has already been rejected by Maxime in the threads
> > > 	http://www.spinics.net/lists/dmaengine/msg08610.html
> > > and
> > > 	http://www.spinics.net/lists/dmaengine/msg08719.html
> > > 
> > > I hope you will find the way he wants for this maxburst to be added.
> > 
> > I was about to reply to Mylene's e-mail, suggesting that she should add
> > a comment in the code (and maybe in the commit log) to explain why this
> > addition is needed, and also that even though the schematics say that
> > value "1" (max burst size of 4 bytes) is reserved, it is in fact
> > incorrect. The Allwinner BSP code is really using this value, and it's
> > the value that makes audio work, so we believe the datasheet is simply
> > incorrect.
> > 
> > We already discussed it with Maxime, so I believe he should agree this
> > time. But I would suggest to have such details explained in the commit
> > log and in a comment in the code.
> 
> Strange. Looking at the datasheets of the A23, A31, A33, A83T and H3
> (these are the SoCs using the DMA sun6i), only the H3 can have 4 as the
> burst size (the doc is unclear for the A31).
> 
> Well, I was submitting for the H3, Mylène is submitting for the A33.
> So, what about the A23, A31 and A83T?

Since these are device properties, I feel we should move this to DT. That
way any new controller can have any variation based on the mood of hw
designer that day and we can hopefully cope with it :-)

But yes we would need to set the bursts supported in driver and allow above
for supported bursts only.

-- 
~Vinod

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

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-10-04 15:40             ` Vinod Koul
  0 siblings, 0 replies; 170+ messages in thread
From: Vinod Koul @ 2016-10-04 15:40 UTC (permalink / raw)
  To: Jean-Francois Moine
  Cc: Thomas Petazzoni, Mylène Josserand,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8, wens-jdAy2FN1RRM,
	mturquette-rdvid1DuHRBWk0Htik3J/w, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A,
	perex-/Fr2/VpizcU, tiwai-IBi9RG/b67k,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Tue, Oct 04, 2016 at 03:46:51PM +0200, Jean-Francois Moine wrote:
> On Tue, 4 Oct 2016 14:12:21 +0200
> Thomas Petazzoni <thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> 
> > > > Add the case of a burst of 4 which is handled by the SoC.
> > > > 
> > > > Signed-off-by: Mylčne Josserand <mylene.josserand@free-electrons.com>
> > > > ---
> > > >  drivers/dma/sun6i-dma.c | 2 ++
> > > >  1 file changed, 2 insertions(+)
> > > > 
> > > > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> > > > index 8346199..0485204 100644
> > > > --- a/drivers/dma/sun6i-dma.c
> > > > +++ b/drivers/dma/sun6i-dma.c
> > > > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
> > > >  	switch (maxburst) {
> > > >  	case 1:
> > > >  		return 0;
> > > > +	case 4:
> > > > +		return 1;
> > > >  	case 8:
> > > >  		return 2;
> > > >  	default:
> > > > -- 
> > > > 2.9.3  
> > > 
> > > This patch has already been rejected by Maxime in the threads
> > > 	http://www.spinics.net/lists/dmaengine/msg08610.html
> > > and
> > > 	http://www.spinics.net/lists/dmaengine/msg08719.html
> > > 
> > > I hope you will find the way he wants for this maxburst to be added.
> > 
> > I was about to reply to Mylene's e-mail, suggesting that she should add
> > a comment in the code (and maybe in the commit log) to explain why this
> > addition is needed, and also that even though the schematics say that
> > value "1" (max burst size of 4 bytes) is reserved, it is in fact
> > incorrect. The Allwinner BSP code is really using this value, and it's
> > the value that makes audio work, so we believe the datasheet is simply
> > incorrect.
> > 
> > We already discussed it with Maxime, so I believe he should agree this
> > time. But I would suggest to have such details explained in the commit
> > log and in a comment in the code.
> 
> Strange. Looking at the datasheets of the A23, A31, A33, A83T and H3
> (these are the SoCs using the DMA sun6i), only the H3 can have 4 as the
> burst size (the doc is unclear for the A31).
> 
> Well, I was submitting for the H3, Mylčne is submitting for the A33.
> So, what about the A23, A31 and A83T?

Since these are device properties, I feel we should move this to DT. That
way any new controller can have any variation based on the mood of hw
designer that day and we can hopefully cope with it :-)

But yes we would need to set the bursts supported in driver and allow above
for supported bursts only.

-- 
~Vinod

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

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

* [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-10-04 15:40             ` Vinod Koul
  0 siblings, 0 replies; 170+ messages in thread
From: Vinod Koul @ 2016-10-04 15:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 04, 2016 at 03:46:51PM +0200, Jean-Francois Moine wrote:
> On Tue, 4 Oct 2016 14:12:21 +0200
> Thomas Petazzoni <thomas.petazzoni@free-electrons.com> wrote:
> 
> > > > Add the case of a burst of 4 which is handled by the SoC.
> > > > 
> > > > Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
> > > > ---
> > > >  drivers/dma/sun6i-dma.c | 2 ++
> > > >  1 file changed, 2 insertions(+)
> > > > 
> > > > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> > > > index 8346199..0485204 100644
> > > > --- a/drivers/dma/sun6i-dma.c
> > > > +++ b/drivers/dma/sun6i-dma.c
> > > > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
> > > >  	switch (maxburst) {
> > > >  	case 1:
> > > >  		return 0;
> > > > +	case 4:
> > > > +		return 1;
> > > >  	case 8:
> > > >  		return 2;
> > > >  	default:
> > > > -- 
> > > > 2.9.3  
> > > 
> > > This patch has already been rejected by Maxime in the threads
> > > 	http://www.spinics.net/lists/dmaengine/msg08610.html
> > > and
> > > 	http://www.spinics.net/lists/dmaengine/msg08719.html
> > > 
> > > I hope you will find the way he wants for this maxburst to be added.
> > 
> > I was about to reply to Mylene's e-mail, suggesting that she should add
> > a comment in the code (and maybe in the commit log) to explain why this
> > addition is needed, and also that even though the schematics say that
> > value "1" (max burst size of 4 bytes) is reserved, it is in fact
> > incorrect. The Allwinner BSP code is really using this value, and it's
> > the value that makes audio work, so we believe the datasheet is simply
> > incorrect.
> > 
> > We already discussed it with Maxime, so I believe he should agree this
> > time. But I would suggest to have such details explained in the commit
> > log and in a comment in the code.
> 
> Strange. Looking at the datasheets of the A23, A31, A33, A83T and H3
> (these are the SoCs using the DMA sun6i), only the H3 can have 4 as the
> burst size (the doc is unclear for the A31).
> 
> Well, I was submitting for the H3, Myl?ne is submitting for the A33.
> So, what about the A23, A31 and A83T?

Since these are device properties, I feel we should move this to DT. That
way any new controller can have any variation based on the mood of hw
designer that day and we can hopefully cope with it :-)

But yes we would need to set the bursts supported in driver and allow above
for supported bursts only.

-- 
~Vinod

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

* Re: [PATCH 03/14] ASoC: sun4i-i2s: Add apb reset
  2016-10-04 12:15       ` Thomas Petazzoni
@ 2016-10-04 15:42         ` Maxime Ripard
  -1 siblings, 0 replies; 170+ messages in thread
From: Maxime Ripard @ 2016-10-04 15:42 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Mylène Josserand, mark.rutland, devicetree, alsa-devel,
	linux-sunxi, vinod.koul, linux-kernel, mturquette, tiwai, sboyd,
	lgirdwood, robh+dt, perex, wens, broonie, alexandre.belloni,
	dmaengine, lee.jones, linux-clk, linux-arm-kernel

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

Hi,

On Tue, Oct 04, 2016 at 02:15:16PM +0200, Thomas Petazzoni wrote:
> Hello,
> 
> On Tue,  4 Oct 2016 11:46:16 +0200, Mylène Josserand wrote:
> 
> >  #include <sound/dmaengine_pcm.h>
> >  #include <sound/pcm_params.h>
> > @@ -589,6 +590,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
> >  {
> >  	struct sun4i_i2s *i2s;
> >  	struct resource *res;
> > +	struct reset_control *reset_apb;
> >  	void __iomem *regs;
> >  	int irq, ret;
> >  
> > @@ -626,7 +628,19 @@ 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);
> >  	}
> > -	
> > +
> > +	reset_apb = devm_reset_control_get(&pdev->dev, "apb_reset");
> 
> I believe this is a change in the Device Tree binding, since you're
> adding support for a new resource. Perhaps the Device Tree binding
> documentation should be updated accordingly?

Indeed.

You have two solutions to do that:
  - Either mark it as optional and use reset_control_get_optional
    (because here, you broke the other SoCs that have that controller
    but no reset line)
  - Or introduce a new compatible, and make the reset property
    mandatory for that new compatible.

I prefer the latter, since you get a stricter error check, and you
cannot end up in a situation where your driver probes but is
useless. But you'll find both in our drivers.

> > +	}
> > +
> > +	ret = reset_control_deassert(reset_apb);
> > +	if (ret < 0) {
> > +		dev_err(&pdev->dev, "Can't deassert apb reset (%d)\n", ret);
> > +		return ret;
> > +	}
> 
> Do you need to re-assert the reset line in the ->remove() hook?

Even better, you can add it to the runtime_pm hooks! :)

Maxime

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

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

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

* [PATCH 03/14] ASoC: sun4i-i2s: Add apb reset
@ 2016-10-04 15:42         ` Maxime Ripard
  0 siblings, 0 replies; 170+ messages in thread
From: Maxime Ripard @ 2016-10-04 15:42 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Tue, Oct 04, 2016 at 02:15:16PM +0200, Thomas Petazzoni wrote:
> Hello,
> 
> On Tue,  4 Oct 2016 11:46:16 +0200, Myl?ne Josserand wrote:
> 
> >  #include <sound/dmaengine_pcm.h>
> >  #include <sound/pcm_params.h>
> > @@ -589,6 +590,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
> >  {
> >  	struct sun4i_i2s *i2s;
> >  	struct resource *res;
> > +	struct reset_control *reset_apb;
> >  	void __iomem *regs;
> >  	int irq, ret;
> >  
> > @@ -626,7 +628,19 @@ 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);
> >  	}
> > -	
> > +
> > +	reset_apb = devm_reset_control_get(&pdev->dev, "apb_reset");
> 
> I believe this is a change in the Device Tree binding, since you're
> adding support for a new resource. Perhaps the Device Tree binding
> documentation should be updated accordingly?

Indeed.

You have two solutions to do that:
  - Either mark it as optional and use reset_control_get_optional
    (because here, you broke the other SoCs that have that controller
    but no reset line)
  - Or introduce a new compatible, and make the reset property
    mandatory for that new compatible.

I prefer the latter, since you get a stricter error check, and you
cannot end up in a situation where your driver probes but is
useless. But you'll find both in our drivers.

> > +	}
> > +
> > +	ret = reset_control_deassert(reset_apb);
> > +	if (ret < 0) {
> > +		dev_err(&pdev->dev, "Can't deassert apb reset (%d)\n", ret);
> > +		return ret;
> > +	}
> 
> Do you need to re-assert the reset line in the ->remove() hook?

Even better, you can add it to the runtime_pm hooks! :)

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: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161004/193777b3/attachment.sig>

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

* Re: [PATCH 06/14] ASoC: Add sun8i digital audio codec
@ 2016-10-04 16:09         ` Maxime Ripard
  0 siblings, 0 replies; 170+ messages in thread
From: Maxime Ripard @ 2016-10-04 16:09 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Mylène Josserand, vinod.koul, wens, mturquette, sboyd,
	lgirdwood, broonie, perex, tiwai, lee.jones, mark.rutland,
	robh+dt, linux-kernel, dmaengine, linux-arm-kernel, linux-clk,
	alsa-devel, devicetree, linux-sunxi, alexandre.belloni

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

Hi,

On Tue, Oct 04, 2016 at 02:40:08PM +0200, Thomas Petazzoni wrote:
> > +	scodec->clk_apb = devm_clk_get(&pdev->dev, "apb");
> > +	if (IS_ERR(scodec->clk_apb)) {
> > +		dev_err(&pdev->dev, "Failed to get the apb clock\n");
> > +		return PTR_ERR(scodec->clk_apb);
> > +	}
> > +	if (clk_prepare_enable(scodec->clk_apb))
> > +		pr_err("err:open failed;\n");
> 
> Ditto. + unprepare/disable the previous clock.

Ideally, that would be even not be part of the runtime_pm
hooks. Ideally, that would be great if that driver supports it.

We'll have to go through all the drivers to support it, that would be
one less to do (and ASoC makes it very easy, you can have a look at
the sun4i-i2s driver).

Thanks!
Maxime

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

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

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

* Re: [PATCH 06/14] ASoC: Add sun8i digital audio codec
@ 2016-10-04 16:09         ` Maxime Ripard
  0 siblings, 0 replies; 170+ messages in thread
From: Maxime Ripard @ 2016-10-04 16:09 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: Mylène Josserand, vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
	wens-jdAy2FN1RRM, mturquette-rdvid1DuHRBWk0Htik3J/w,
	sboyd-sgV2jX0FEOL9JmXXK+q4OQ, lgirdwood-Re5JQEeQqe8AvxtiuMwx3w,
	broonie-DgEjT+Ai2ygdnm+yROfE0A, perex-/Fr2/VpizcU,
	tiwai-IBi9RG/b67k, lee.jones-QSEj5FYQhm4dnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8

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

Hi,

On Tue, Oct 04, 2016 at 02:40:08PM +0200, Thomas Petazzoni wrote:
> > +	scodec->clk_apb = devm_clk_get(&pdev->dev, "apb");
> > +	if (IS_ERR(scodec->clk_apb)) {
> > +		dev_err(&pdev->dev, "Failed to get the apb clock\n");
> > +		return PTR_ERR(scodec->clk_apb);
> > +	}
> > +	if (clk_prepare_enable(scodec->clk_apb))
> > +		pr_err("err:open failed;\n");
> 
> Ditto. + unprepare/disable the previous clock.

Ideally, that would be even not be part of the runtime_pm
hooks. Ideally, that would be great if that driver supports it.

We'll have to go through all the drivers to support it, that would be
one less to do (and ASoC makes it very easy, you can have a look at
the sun4i-i2s driver).

Thanks!
Maxime

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

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

* [PATCH 06/14] ASoC: Add sun8i digital audio codec
@ 2016-10-04 16:09         ` Maxime Ripard
  0 siblings, 0 replies; 170+ messages in thread
From: Maxime Ripard @ 2016-10-04 16:09 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Tue, Oct 04, 2016 at 02:40:08PM +0200, Thomas Petazzoni wrote:
> > +	scodec->clk_apb = devm_clk_get(&pdev->dev, "apb");
> > +	if (IS_ERR(scodec->clk_apb)) {
> > +		dev_err(&pdev->dev, "Failed to get the apb clock\n");
> > +		return PTR_ERR(scodec->clk_apb);
> > +	}
> > +	if (clk_prepare_enable(scodec->clk_apb))
> > +		pr_err("err:open failed;\n");
> 
> Ditto. + unprepare/disable the previous clock.

Ideally, that would be even not be part of the runtime_pm
hooks. Ideally, that would be great if that driver supports it.

We'll have to go through all the drivers to support it, that would be
one less to do (and ASoC makes it very easy, you can have a look at
the sun4i-i2s driver).

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: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161004/3a347edd/attachment.sig>

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

* Re: [PATCH 06/14] ASoC: Add sun8i digital audio codec
  2016-10-04  9:46     ` Mylène Josserand
@ 2016-10-04 16:15       ` Maxime Ripard
  -1 siblings, 0 replies; 170+ messages in thread
From: Maxime Ripard @ 2016-10-04 16:15 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul, wens, mturquette, sboyd, lgirdwood, broonie, perex,
	tiwai, lee.jones, mark.rutland, robh+dt, linux-kernel, dmaengine,
	linux-arm-kernel, linux-clk, alsa-devel, devicetree, linux-sunxi,
	thomas.petazzoni, alexandre.belloni

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

Hi,

> +static const struct of_device_id sun8i_codec_of_match[] = {
> +	{ .compatible = "allwinner,sun8i-a33-codec" },
> +	{ .compatible = "allwinner,sun8i-a23-codec" },

I thought that the A23 and A33 had different codecs? In that case, it
wouldn't be a good assumption to make


> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, sun8i_codec_of_match);
> +
> +static struct platform_driver sun8i_codec_driver = {
> +	.driver = {
> +		.name = "sun8i-codec",
> +		.owner = THIS_MODULE,
> +		.of_match_table = sun8i_codec_of_match,
> +	},
> +	.probe = sun8i_codec_probe,
> +	.remove = sun8i_codec_remove,
> +};
> +module_platform_driver(sun8i_codec_driver);
> +
> +MODULE_DESCRIPTION("Allwinner A33 (sun8i) codec driver");
> +MODULE_AUTHOR("huanxin<huanxin@reuuimllatech.com>");

Those obfuscated email adresses are not really helpful :)

Thanks,
Maxime

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

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

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

* [PATCH 06/14] ASoC: Add sun8i digital audio codec
@ 2016-10-04 16:15       ` Maxime Ripard
  0 siblings, 0 replies; 170+ messages in thread
From: Maxime Ripard @ 2016-10-04 16:15 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

> +static const struct of_device_id sun8i_codec_of_match[] = {
> +	{ .compatible = "allwinner,sun8i-a33-codec" },
> +	{ .compatible = "allwinner,sun8i-a23-codec" },

I thought that the A23 and A33 had different codecs? In that case, it
wouldn't be a good assumption to make


> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, sun8i_codec_of_match);
> +
> +static struct platform_driver sun8i_codec_driver = {
> +	.driver = {
> +		.name = "sun8i-codec",
> +		.owner = THIS_MODULE,
> +		.of_match_table = sun8i_codec_of_match,
> +	},
> +	.probe = sun8i_codec_probe,
> +	.remove = sun8i_codec_remove,
> +};
> +module_platform_driver(sun8i_codec_driver);
> +
> +MODULE_DESCRIPTION("Allwinner A33 (sun8i) codec driver");
> +MODULE_AUTHOR("huanxin<huanxin@reuuimllatech.com>");

Those obfuscated email adresses are not really helpful :)

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: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161004/b93afd78/attachment.sig>

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

* Re: [PATCH 09/14] dt-bindings: sound: Add sun8i codec documentation
  2016-10-04  9:46     ` Mylène Josserand
@ 2016-10-04 16:19       ` Maxime Ripard
  -1 siblings, 0 replies; 170+ messages in thread
From: Maxime Ripard @ 2016-10-04 16:19 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul, wens, mturquette, sboyd, lgirdwood, broonie, perex,
	tiwai, lee.jones, mark.rutland, robh+dt, linux-kernel, dmaengine,
	linux-arm-kernel, linux-clk, alsa-devel, devicetree, linux-sunxi,
	thomas.petazzoni, alexandre.belloni

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

On Tue, Oct 04, 2016 at 11:46:22AM +0200, Mylène Josserand wrote:
> Add the documentation for dt-binding of the digital audio codec driver
> for sun8i SoC.
> 
> Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
> ---
>  .../devicetree/bindings/sound/sun8i-codec.txt      | 24 ++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/sound/sun8i-codec.txt
> 
> diff --git a/Documentation/devicetree/bindings/sound/sun8i-codec.txt b/Documentation/devicetree/bindings/sound/sun8i-codec.txt
> new file mode 100644
> index 0000000..1808869
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/sun8i-codec.txt
> @@ -0,0 +1,24 @@
> +* Allwinner A23/A33 Codec
> +
> +Required properties:
> +- compatible: must be either "allwinner,sun4i-a23-codec" or
> +  "allwinner,sun7i-a33-codec"

Copy and paste issue ? :)

One compatible by line is usually favored, since when you'll add new
compatibles, you don't have to modify the context.xs

> +- reg: must contain the registers location and length
> +- interrupts: must contain the codec interrupt
> +- clocks: a list of phandle + clock-specifer pairs, one for each entry
> +  in clock-names.
> +- clock-names: should contain followings:
> +   - "apb": the parent APB clock for this controller
> +   - "codec": the parent module clock

We're usually calling them "bus" and "mod".

> +
> +Example:
> +codec: codec@01c22e00 {
> +	#sound-dai-cells = <0>;
> +	compatible = "allwinner,sun8i-a33-codec";
> +	reg = <0x01c22e00 0x400>; /* SUNXI_AUDIO_PBASE + 0x200 */
> +	reg-names = "audio";

You don't define reg-names in your bindings, while your code relies on
it. It isn't really needed, since you have only one couple of base +
size, so it should just go away.

Thanks!
Maxime

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

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

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

* [PATCH 09/14] dt-bindings: sound: Add sun8i codec documentation
@ 2016-10-04 16:19       ` Maxime Ripard
  0 siblings, 0 replies; 170+ messages in thread
From: Maxime Ripard @ 2016-10-04 16:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 04, 2016 at 11:46:22AM +0200, Myl?ne Josserand wrote:
> Add the documentation for dt-binding of the digital audio codec driver
> for sun8i SoC.
> 
> Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
> ---
>  .../devicetree/bindings/sound/sun8i-codec.txt      | 24 ++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/sound/sun8i-codec.txt
> 
> diff --git a/Documentation/devicetree/bindings/sound/sun8i-codec.txt b/Documentation/devicetree/bindings/sound/sun8i-codec.txt
> new file mode 100644
> index 0000000..1808869
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/sun8i-codec.txt
> @@ -0,0 +1,24 @@
> +* Allwinner A23/A33 Codec
> +
> +Required properties:
> +- compatible: must be either "allwinner,sun4i-a23-codec" or
> +  "allwinner,sun7i-a33-codec"

Copy and paste issue ? :)

One compatible by line is usually favored, since when you'll add new
compatibles, you don't have to modify the context.xs

> +- reg: must contain the registers location and length
> +- interrupts: must contain the codec interrupt
> +- clocks: a list of phandle + clock-specifer pairs, one for each entry
> +  in clock-names.
> +- clock-names: should contain followings:
> +   - "apb": the parent APB clock for this controller
> +   - "codec": the parent module clock

We're usually calling them "bus" and "mod".

> +
> +Example:
> +codec: codec at 01c22e00 {
> +	#sound-dai-cells = <0>;
> +	compatible = "allwinner,sun8i-a33-codec";
> +	reg = <0x01c22e00 0x400>; /* SUNXI_AUDIO_PBASE + 0x200 */
> +	reg-names = "audio";

You don't define reg-names in your bindings, while your code relies on
it. It isn't really needed, since you have only one couple of base +
size, so it should just go away.

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: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161004/dc85a491/attachment.sig>

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

* Re: [PATCH 08/14] dt-bindings: sound: Add sun8i analog codec documentation
@ 2016-10-04 16:24       ` Maxime Ripard
  0 siblings, 0 replies; 170+ messages in thread
From: Maxime Ripard @ 2016-10-04 16:24 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul, wens, mturquette, sboyd, lgirdwood, broonie, perex,
	tiwai, lee.jones, mark.rutland, robh+dt, linux-kernel, dmaengine,
	linux-arm-kernel, linux-clk, alsa-devel, devicetree, linux-sunxi,
	thomas.petazzoni, alexandre.belloni

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

Hi,

On Tue, Oct 04, 2016 at 11:46:21AM +0200, Mylène Josserand wrote:
> Add the documentation for dt-binding of the analog audiocodec
> driver for SUN8I SoC.
> 
> Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
> ---
>  .../devicetree/bindings/sound/sun8i-codec-analog.txt | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
> 
> diff --git a/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
> new file mode 100644
> index 0000000..a03ec20
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
> @@ -0,0 +1,20 @@
> +* Allwinner A23/A33 Analog Codec
> +
> +This codec must be handled as a PRCM subnode.

Like Mark was saying, you should probably reference the sun6i-prcm.txt
binding here

> +Required properties:
> +- compatible: must be either "allwinner,sun8i-codec-analog"

Our compatible prefix is <family>-<soc>, and using the older SoC that
introduced that block.

In this case, that would be sun6i-a31, I think?

Thanks,
Maxime

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

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

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

* Re: [PATCH 08/14] dt-bindings: sound: Add sun8i analog codec documentation
@ 2016-10-04 16:24       ` Maxime Ripard
  0 siblings, 0 replies; 170+ messages in thread
From: Maxime Ripard @ 2016-10-04 16:24 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul-ral2JQCrhuEAvxtiuMwx3w, wens-jdAy2FN1RRM,
	mturquette-rdvid1DuHRBWk0Htik3J/w, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A,
	perex-/Fr2/VpizcU, tiwai-IBi9RG/b67k,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8

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

Hi,

On Tue, Oct 04, 2016 at 11:46:21AM +0200, Mylène Josserand wrote:
> Add the documentation for dt-binding of the analog audiocodec
> driver for SUN8I SoC.
> 
> Signed-off-by: Mylène Josserand <mylene.josserand-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> ---
>  .../devicetree/bindings/sound/sun8i-codec-analog.txt | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
> 
> diff --git a/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
> new file mode 100644
> index 0000000..a03ec20
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
> @@ -0,0 +1,20 @@
> +* Allwinner A23/A33 Analog Codec
> +
> +This codec must be handled as a PRCM subnode.

Like Mark was saying, you should probably reference the sun6i-prcm.txt
binding here

> +Required properties:
> +- compatible: must be either "allwinner,sun8i-codec-analog"

Our compatible prefix is <family>-<soc>, and using the older SoC that
introduced that block.

In this case, that would be sun6i-a31, I think?

Thanks,
Maxime

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

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

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

* [PATCH 08/14] dt-bindings: sound: Add sun8i analog codec documentation
@ 2016-10-04 16:24       ` Maxime Ripard
  0 siblings, 0 replies; 170+ messages in thread
From: Maxime Ripard @ 2016-10-04 16:24 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Tue, Oct 04, 2016 at 11:46:21AM +0200, Myl?ne Josserand wrote:
> Add the documentation for dt-binding of the analog audiocodec
> driver for SUN8I SoC.
> 
> Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
> ---
>  .../devicetree/bindings/sound/sun8i-codec-analog.txt | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
> 
> diff --git a/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
> new file mode 100644
> index 0000000..a03ec20
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
> @@ -0,0 +1,20 @@
> +* Allwinner A23/A33 Analog Codec
> +
> +This codec must be handled as a PRCM subnode.

Like Mark was saying, you should probably reference the sun6i-prcm.txt
binding here

> +Required properties:
> +- compatible: must be either "allwinner,sun8i-codec-analog"

Our compatible prefix is <family>-<soc>, and using the older SoC that
introduced that block.

In this case, that would be sun6i-a31, I think?

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: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161004/efe56436/attachment.sig>

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

* Re: [PATCH 10/14] dt-bindings: sound: Add sun8i audio card documentation
@ 2016-10-04 16:32       ` Maxime Ripard
  0 siblings, 0 replies; 170+ messages in thread
From: Maxime Ripard @ 2016-10-04 16:32 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul, wens, mturquette, sboyd, lgirdwood, broonie, perex,
	tiwai, lee.jones, mark.rutland, robh+dt, linux-kernel, dmaengine,
	linux-arm-kernel, linux-clk, alsa-devel, devicetree, linux-sunxi,
	thomas.petazzoni, alexandre.belloni

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

On Tue, Oct 04, 2016 at 11:46:23AM +0200, Mylène Josserand wrote:
> Add the documentation for dt-binding of the audio card driver
> for sun8i SoC.
> 
> Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
> ---
>  Documentation/devicetree/bindings/sound/sun8i-audio.txt | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/sound/sun8i-audio.txt
> 
> diff --git a/Documentation/devicetree/bindings/sound/sun8i-audio.txt b/Documentation/devicetree/bindings/sound/sun8i-audio.txt
> new file mode 100644
> index 0000000..2403983
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/sun8i-audio.txt
> @@ -0,0 +1,17 @@
> +* Allwinner A23/A33 audio card
> +
> +This binding implements the A33 audio card.
> +
> +Required properties:
> +- compatible: must be "allwinner,sun8i-audio"
> +- allwinner,audio-codec: must have the phandle of the audio codec
> +  ("sun8i-a33-codec", for example).
> +- allwinner,i2s-controller: must have the phandle of the DAI
> +  ("allwinner,sun4i-a10-i2s", for example)

You should probably have a link to the PRCM too, instead of relying on
the name of the device in your card, which is quite fragile.

Also, I'm wondering, shouldn't all these nodes be part of a single
MFD? They share the same address space (even though it's split
nicely), the same clocks, and really are just one big device. Chen-Yu,
Mark, any opinion?

Thanks,
Maxime

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

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

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

* Re: [PATCH 10/14] dt-bindings: sound: Add sun8i audio card documentation
@ 2016-10-04 16:32       ` Maxime Ripard
  0 siblings, 0 replies; 170+ messages in thread
From: Maxime Ripard @ 2016-10-04 16:32 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul-ral2JQCrhuEAvxtiuMwx3w, wens-jdAy2FN1RRM,
	mturquette-rdvid1DuHRBWk0Htik3J/w, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A,
	perex-/Fr2/VpizcU, tiwai-IBi9RG/b67k,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8

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

On Tue, Oct 04, 2016 at 11:46:23AM +0200, Mylène Josserand wrote:
> Add the documentation for dt-binding of the audio card driver
> for sun8i SoC.
> 
> Signed-off-by: Mylène Josserand <mylene.josserand-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> ---
>  Documentation/devicetree/bindings/sound/sun8i-audio.txt | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/sound/sun8i-audio.txt
> 
> diff --git a/Documentation/devicetree/bindings/sound/sun8i-audio.txt b/Documentation/devicetree/bindings/sound/sun8i-audio.txt
> new file mode 100644
> index 0000000..2403983
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/sun8i-audio.txt
> @@ -0,0 +1,17 @@
> +* Allwinner A23/A33 audio card
> +
> +This binding implements the A33 audio card.
> +
> +Required properties:
> +- compatible: must be "allwinner,sun8i-audio"
> +- allwinner,audio-codec: must have the phandle of the audio codec
> +  ("sun8i-a33-codec", for example).
> +- allwinner,i2s-controller: must have the phandle of the DAI
> +  ("allwinner,sun4i-a10-i2s", for example)

You should probably have a link to the PRCM too, instead of relying on
the name of the device in your card, which is quite fragile.

Also, I'm wondering, shouldn't all these nodes be part of a single
MFD? They share the same address space (even though it's split
nicely), the same clocks, and really are just one big device. Chen-Yu,
Mark, any opinion?

Thanks,
Maxime

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

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

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

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

* [PATCH 10/14] dt-bindings: sound: Add sun8i audio card documentation
@ 2016-10-04 16:32       ` Maxime Ripard
  0 siblings, 0 replies; 170+ messages in thread
From: Maxime Ripard @ 2016-10-04 16:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 04, 2016 at 11:46:23AM +0200, Myl?ne Josserand wrote:
> Add the documentation for dt-binding of the audio card driver
> for sun8i SoC.
> 
> Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
> ---
>  Documentation/devicetree/bindings/sound/sun8i-audio.txt | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/sound/sun8i-audio.txt
> 
> diff --git a/Documentation/devicetree/bindings/sound/sun8i-audio.txt b/Documentation/devicetree/bindings/sound/sun8i-audio.txt
> new file mode 100644
> index 0000000..2403983
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/sun8i-audio.txt
> @@ -0,0 +1,17 @@
> +* Allwinner A23/A33 audio card
> +
> +This binding implements the A33 audio card.
> +
> +Required properties:
> +- compatible: must be "allwinner,sun8i-audio"
> +- allwinner,audio-codec: must have the phandle of the audio codec
> +  ("sun8i-a33-codec", for example).
> +- allwinner,i2s-controller: must have the phandle of the DAI
> +  ("allwinner,sun4i-a10-i2s", for example)

You should probably have a link to the PRCM too, instead of relying on
the name of the device in your card, which is quite fragile.

Also, I'm wondering, shouldn't all these nodes be part of a single
MFD? They share the same address space (even though it's split
nicely), the same clocks, and really are just one big device. Chen-Yu,
Mark, any opinion?

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: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161004/998b2002/attachment.sig>

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

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
  2016-10-04 10:40       ` Jean-Francois Moine
@ 2016-10-04 16:55         ` Maxime Ripard
  -1 siblings, 0 replies; 170+ messages in thread
From: Maxime Ripard @ 2016-10-04 16:55 UTC (permalink / raw)
  To: Jean-Francois Moine
  Cc: Mylène Josserand, vinod.koul, wens, mturquette, sboyd,
	lgirdwood, broonie, perex, tiwai, lee.jones, mark.rutland,
	robh+dt, thomas.petazzoni, devicetree, alsa-devel, linux-kernel,
	linux-sunxi, alexandre.belloni, dmaengine, linux-clk,
	linux-arm-kernel

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

On Tue, Oct 04, 2016 at 12:40:11PM +0200, Jean-Francois Moine wrote:
> On Tue,  4 Oct 2016 11:46:14 +0200
> Mylène Josserand <mylene.josserand@free-electrons.com> wrote:
> 
> > Add the case of a burst of 4 which is handled by the SoC.
> > 
> > Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
> > ---
> >  drivers/dma/sun6i-dma.c | 2 ++
> >  1 file changed, 2 insertions(+)
> > 
> > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> > index 8346199..0485204 100644
> > --- a/drivers/dma/sun6i-dma.c
> > +++ b/drivers/dma/sun6i-dma.c
> > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
> >  	switch (maxburst) {
> >  	case 1:
> >  		return 0;
> > +	case 4:
> > +		return 1;
> >  	case 8:
> >  		return 2;
> >  	default:
> > -- 
> > 2.9.3
> 
> This patch has already been rejected by Maxime in the threads
> 	http://www.spinics.net/lists/dmaengine/msg08610.html
> and
> 	http://www.spinics.net/lists/dmaengine/msg08719.html
> 
> I hope you will find the way he wants for this maxburst to be added.

I was talking about something along these lines (not tested):

-------8<---------
diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
index 83461994e418..573ac4608293 100644
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
 	switch (maxburst) {
 	case 1:
 		return 0;
+	case 4:
+		return 1;
 	case 8:
 		return 2;
 	default:
@@ -1110,11 +1112,19 @@ static int sun6i_dma_probe(struct platform_device *pdev)
 	sdc->slave.dst_addr_widths		= BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
 						  BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
 						  BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
+	sdc->slave.dst_bursts			= BIT(1) | BIT(8);
+	sdc->slave.src_bursts			= BIT(1) | BIT(8);
 	sdc->slave.directions			= BIT(DMA_DEV_TO_MEM) |
 						  BIT(DMA_MEM_TO_DEV);
 	sdc->slave.residue_granularity		= DMA_RESIDUE_GRANULARITY_BURST;
 	sdc->slave.dev = &pdev->dev;
 
+	if (of_device_is_compatible(pdev->dev.of_node,
+				    "allwinner,sun8i-h3-dma")) {
+		sdc->slave.dst_bursts |= BIT(4);
+		sdc->slave.src_bursts |= BIT(4);
+	}
+
 	sdc->pchans = devm_kcalloc(&pdev->dev, sdc->cfg->nr_max_channels,
 				   sizeof(struct sun6i_pchan), GFP_KERNEL);
 	if (!sdc->pchans)
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index cc535a478bae..f7bbec24bb58 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -673,6 +673,8 @@ struct dma_filter {
  * 	each type of direction, the dma controller should fill (1 <<
  * 	<TYPE>) and same should be checked by controller as well
  * @max_burst: max burst capability per-transfer
+ * @dst_bursts: bitfield of the available burst sizes for the destination
+ * @src_bursts: bitfield of the available burst sizes for the source
  * @residue_granularity: granularity of the transfer residue reported
  *	by tx_status
  * @device_alloc_chan_resources: allocate resources and return the
@@ -800,6 +802,14 @@ struct dma_device {
 static inline int dmaengine_slave_config(struct dma_chan *chan,
 					  struct dma_slave_config *config)
 {
+	if (config->src_maxburst && config->device->src_bursts &&
+	    !(BIT(config->src_maxburst) & config->device->src_bursts))
+		return -EINVAL;
+
+	if (config->dst_maxburst && config->device->dst_bursts &&
+	    !(BIT(config->dst_maxburst) & config->device->dst_bursts))
+		return -EINVAL;
+
 	if (chan->device->device_config)
 		return chan->device->device_config(chan, config);
-------8<------------ 

Maxime

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

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

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

* [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-10-04 16:55         ` Maxime Ripard
  0 siblings, 0 replies; 170+ messages in thread
From: Maxime Ripard @ 2016-10-04 16:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Oct 04, 2016 at 12:40:11PM +0200, Jean-Francois Moine wrote:
> On Tue,  4 Oct 2016 11:46:14 +0200
> Myl?ne Josserand <mylene.josserand@free-electrons.com> wrote:
> 
> > Add the case of a burst of 4 which is handled by the SoC.
> > 
> > Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
> > ---
> >  drivers/dma/sun6i-dma.c | 2 ++
> >  1 file changed, 2 insertions(+)
> > 
> > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> > index 8346199..0485204 100644
> > --- a/drivers/dma/sun6i-dma.c
> > +++ b/drivers/dma/sun6i-dma.c
> > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
> >  	switch (maxburst) {
> >  	case 1:
> >  		return 0;
> > +	case 4:
> > +		return 1;
> >  	case 8:
> >  		return 2;
> >  	default:
> > -- 
> > 2.9.3
> 
> This patch has already been rejected by Maxime in the threads
> 	http://www.spinics.net/lists/dmaengine/msg08610.html
> and
> 	http://www.spinics.net/lists/dmaengine/msg08719.html
> 
> I hope you will find the way he wants for this maxburst to be added.

I was talking about something along these lines (not tested):

-------8<---------
diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
index 83461994e418..573ac4608293 100644
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
 	switch (maxburst) {
 	case 1:
 		return 0;
+	case 4:
+		return 1;
 	case 8:
 		return 2;
 	default:
@@ -1110,11 +1112,19 @@ static int sun6i_dma_probe(struct platform_device *pdev)
 	sdc->slave.dst_addr_widths		= BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
 						  BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
 						  BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
+	sdc->slave.dst_bursts			= BIT(1) | BIT(8);
+	sdc->slave.src_bursts			= BIT(1) | BIT(8);
 	sdc->slave.directions			= BIT(DMA_DEV_TO_MEM) |
 						  BIT(DMA_MEM_TO_DEV);
 	sdc->slave.residue_granularity		= DMA_RESIDUE_GRANULARITY_BURST;
 	sdc->slave.dev = &pdev->dev;
 
+	if (of_device_is_compatible(pdev->dev.of_node,
+				    "allwinner,sun8i-h3-dma")) {
+		sdc->slave.dst_bursts |= BIT(4);
+		sdc->slave.src_bursts |= BIT(4);
+	}
+
 	sdc->pchans = devm_kcalloc(&pdev->dev, sdc->cfg->nr_max_channels,
 				   sizeof(struct sun6i_pchan), GFP_KERNEL);
 	if (!sdc->pchans)
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index cc535a478bae..f7bbec24bb58 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -673,6 +673,8 @@ struct dma_filter {
  * 	each type of direction, the dma controller should fill (1 <<
  * 	<TYPE>) and same should be checked by controller as well
  * @max_burst: max burst capability per-transfer
+ * @dst_bursts: bitfield of the available burst sizes for the destination
+ * @src_bursts: bitfield of the available burst sizes for the source
  * @residue_granularity: granularity of the transfer residue reported
  *	by tx_status
  * @device_alloc_chan_resources: allocate resources and return the
@@ -800,6 +802,14 @@ struct dma_device {
 static inline int dmaengine_slave_config(struct dma_chan *chan,
 					  struct dma_slave_config *config)
 {
+	if (config->src_maxburst && config->device->src_bursts &&
+	    !(BIT(config->src_maxburst) & config->device->src_bursts))
+		return -EINVAL;
+
+	if (config->dst_maxburst && config->device->dst_bursts &&
+	    !(BIT(config->dst_maxburst) & config->device->dst_bursts))
+		return -EINVAL;
+
 	if (chan->device->device_config)
 		return chan->device->device_config(chan, config);
-------8<------------ 

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: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161004/925068da/attachment.sig>

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

* Re: [PATCH 08/14] dt-bindings: sound: Add sun8i analog codec documentation
  2016-10-04 16:24       ` Maxime Ripard
  (?)
  (?)
@ 2016-10-05  2:59         ` Chen-Yu Tsai
  -1 siblings, 0 replies; 170+ messages in thread
From: Chen-Yu Tsai @ 2016-10-05  2:59 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Mylène Josserand, Vinod Koul, Chen-Yu Tsai,
	Michael Turquette, Stephen Boyd, Liam Girdwood, Mark Brown,
	Jaroslav Kysela, Takashi Iwai, Lee Jones, Mark Rutland,
	Rob Herring, linux-kernel, dmaengine, linux-arm-kernel,
	linux-clk, Linux-ALSA, devicetree, linux-sunxi, Thomas Petazzoni,
	Alexandre Belloni

On Wed, Oct 5, 2016 at 12:24 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Hi,
>
> On Tue, Oct 04, 2016 at 11:46:21AM +0200, Mylène Josserand wrote:
>> Add the documentation for dt-binding of the analog audiocodec
>> driver for SUN8I SoC.
>>
>> Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
>> ---
>>  .../devicetree/bindings/sound/sun8i-codec-analog.txt | 20 ++++++++++++++++++++
>>  1 file changed, 20 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
>>
>> diff --git a/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
>> new file mode 100644
>> index 0000000..a03ec20
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
>> @@ -0,0 +1,20 @@
>> +* Allwinner A23/A33 Analog Codec
>> +
>> +This codec must be handled as a PRCM subnode.
>
> Like Mark was saying, you should probably reference the sun6i-prcm.txt
> binding here
>
>> +Required properties:
>> +- compatible: must be either "allwinner,sun8i-codec-analog"
>
> Our compatible prefix is <family>-<soc>, and using the older SoC that
> introduced that block.
>
> In this case, that would be sun6i-a31, I think?

sun6i-a31s actually, but a31s has extra line out controls,
so the right one would be sun8i-a23. Both are listed in my
original driver.

ChenYu

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

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

* Re: [PATCH 08/14] dt-bindings: sound: Add sun8i analog codec documentation
@ 2016-10-05  2:59         ` Chen-Yu Tsai
  0 siblings, 0 replies; 170+ messages in thread
From: Chen-Yu Tsai @ 2016-10-05  2:59 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Mylène Josserand, Vinod Koul, Chen-Yu Tsai,
	Michael Turquette, Stephen Boyd, Liam Girdwood, Mark Brown,
	Jaroslav Kysela, Takashi Iwai, Lee Jones, Mark Rutland,
	Rob Herring, linux-kernel, dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel, linux-clk, Linux-ALSA, devicetree, linux-sunxi,
	Thomas Petazzoni, Alexandre Belloni

On Wed, Oct 5, 2016 at 12:24 AM, Maxime Ripard
<maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> Hi,
>
> On Tue, Oct 04, 2016 at 11:46:21AM +0200, Mylène Josserand wrote:
>> Add the documentation for dt-binding of the analog audiocodec
>> driver for SUN8I SoC.
>>
>> Signed-off-by: Mylène Josserand <mylene.josserand-wi1+55ScJUtKEb57/3fJTGGXanvQGlWp@public.gmane.orgm>
>> ---
>>  .../devicetree/bindings/sound/sun8i-codec-analog.txt | 20 ++++++++++++++++++++
>>  1 file changed, 20 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
>>
>> diff --git a/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
>> new file mode 100644
>> index 0000000..a03ec20
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
>> @@ -0,0 +1,20 @@
>> +* Allwinner A23/A33 Analog Codec
>> +
>> +This codec must be handled as a PRCM subnode.
>
> Like Mark was saying, you should probably reference the sun6i-prcm.txt
> binding here
>
>> +Required properties:
>> +- compatible: must be either "allwinner,sun8i-codec-analog"
>
> Our compatible prefix is <family>-<soc>, and using the older SoC that
> introduced that block.
>
> In this case, that would be sun6i-a31, I think?

sun6i-a31s actually, but a31s has extra line out controls,
so the right one would be sun8i-a23. Both are listed in my
original driver.

ChenYu

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

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

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

* Re: [PATCH 08/14] dt-bindings: sound: Add sun8i analog codec documentation
@ 2016-10-05  2:59         ` Chen-Yu Tsai
  0 siblings, 0 replies; 170+ messages in thread
From: Chen-Yu Tsai @ 2016-10-05  2:59 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Mylène Josserand, Vinod Koul, Chen-Yu Tsai,
	Michael Turquette, Stephen Boyd, Liam Girdwood, Mark Brown,
	Jaroslav Kysela, Takashi Iwai, Lee Jones, Mark Rutland,
	Rob Herring, linux-kernel, dmaengine, linux-arm-kernel,
	linux-clk, Linux-ALSA, devicetree, linux-sunxi, Thomas Petazzoni,
	Alexandre Belloni

On Wed, Oct 5, 2016 at 12:24 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Hi,
>
> On Tue, Oct 04, 2016 at 11:46:21AM +0200, Myl=C3=A8ne Josserand wrote:
>> Add the documentation for dt-binding of the analog audiocodec
>> driver for SUN8I SoC.
>>
>> Signed-off-by: Myl=C3=A8ne Josserand <mylene.josserand@free-electrons.co=
m>
>> ---
>>  .../devicetree/bindings/sound/sun8i-codec-analog.txt | 20 +++++++++++++=
+++++++
>>  1 file changed, 20 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/sound/sun8i-codec-=
analog.txt
>>
>> diff --git a/Documentation/devicetree/bindings/sound/sun8i-codec-analog.=
txt b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
>> new file mode 100644
>> index 0000000..a03ec20
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
>> @@ -0,0 +1,20 @@
>> +* Allwinner A23/A33 Analog Codec
>> +
>> +This codec must be handled as a PRCM subnode.
>
> Like Mark was saying, you should probably reference the sun6i-prcm.txt
> binding here
>
>> +Required properties:
>> +- compatible: must be either "allwinner,sun8i-codec-analog"
>
> Our compatible prefix is <family>-<soc>, and using the older SoC that
> introduced that block.
>
> In this case, that would be sun6i-a31, I think?

sun6i-a31s actually, but a31s has extra line out controls,
so the right one would be sun8i-a23. Both are listed in my
original driver.

ChenYu

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

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

* [PATCH 08/14] dt-bindings: sound: Add sun8i analog codec documentation
@ 2016-10-05  2:59         ` Chen-Yu Tsai
  0 siblings, 0 replies; 170+ messages in thread
From: Chen-Yu Tsai @ 2016-10-05  2:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Oct 5, 2016 at 12:24 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Hi,
>
> On Tue, Oct 04, 2016 at 11:46:21AM +0200, Myl?ne Josserand wrote:
>> Add the documentation for dt-binding of the analog audiocodec
>> driver for SUN8I SoC.
>>
>> Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
>> ---
>>  .../devicetree/bindings/sound/sun8i-codec-analog.txt | 20 ++++++++++++++++++++
>>  1 file changed, 20 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
>>
>> diff --git a/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
>> new file mode 100644
>> index 0000000..a03ec20
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
>> @@ -0,0 +1,20 @@
>> +* Allwinner A23/A33 Analog Codec
>> +
>> +This codec must be handled as a PRCM subnode.
>
> Like Mark was saying, you should probably reference the sun6i-prcm.txt
> binding here
>
>> +Required properties:
>> +- compatible: must be either "allwinner,sun8i-codec-analog"
>
> Our compatible prefix is <family>-<soc>, and using the older SoC that
> introduced that block.
>
> In this case, that would be sun6i-a31, I think?

sun6i-a31s actually, but a31s has extra line out controls,
so the right one would be sun8i-a23. Both are listed in my
original driver.

ChenYu

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

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

* Re: [PATCH 07/14] ASoC: Add sun8i audio card
@ 2016-10-05  6:04       ` Code Kipper
  0 siblings, 0 replies; 170+ messages in thread
From: Code Kipper @ 2016-10-05  6:04 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul, Maxime Ripard, Chen-Yu Tsai, Michael Turquette,
	sboyd, Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai,
	Lee Jones, mark.rutland, Rob Herring, linux-kernel, dmaengine,
	linux-arm-kernel, linux-clk, alsa-devel, devicetree, linux-sunxi,
	thomas.petazzoni, alexandre.belloni

On 4 October 2016 at 11:46, Mylène Josserand
<mylene.josserand@free-electrons.com> wrote:
> Add the audio card for sun8i SoC. This card links the codec driver
> (digital part) with the DAI driver. The analog codec driver is
> added as an aux_device.
>
> Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
> ---
>  sound/soc/sunxi/Kconfig  |  14 +++++++
>  sound/soc/sunxi/Makefile |   1 +
>  sound/soc/sunxi/sun8i.c  | 101 +++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 116 insertions(+)
>  create mode 100644 sound/soc/sunxi/sun8i.c
>
> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
> index 9e287b0..7b97395 100644
> --- a/sound/soc/sunxi/Kconfig
> +++ b/sound/soc/sunxi/Kconfig
> @@ -27,6 +27,20 @@ config SND_SUN4I_SPDIF
>           Say Y or M to add support for the S/PDIF audio block in the Allwinner
>           A10 and affiliated SoCs.
>
> +config SND_SUN8I
> +       tristate "Allwinner SUN6I/SUN8I audio card support"
> +       select SND_SUN8I_CODEC
> +       select SND_SUN4I_I2S
> +       select SND_SUN8I_CODEC_ANALOG
> +       select REGMAP_MMIO
> +       help
> +         This option enables the audio card for Allwinner A33 (sun8i) SoC.
> +         It enables the DAI driver (SND_SUN4I_I2S), the digital audio
> +         codec driver (SND_SUN8I_CODEC) and the analog codec driver
> +         (SND_SUN8I_CODEC_ANALOG).
> +
> +         Say Y or M if you want to add sun8i/6i card support
> +
>  config SND_SUN8I_CODEC
>         tristate "Allwinner SUN8I audio codec"
>         select REGMAP_MMIO
> diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
> index 1da63d3..7f1bab9 100644
> --- a/sound/soc/sunxi/Makefile
> +++ b/sound/soc/sunxi/Makefile
> @@ -1,5 +1,6 @@
>  obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
>  obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
>  obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
> +obj-$(CONFIG_SND_SUN8I) += sun8i.o
>  obj-$(CONFIG_SND_SUN8I_CODEC) += sun8i-codec.o
>  obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
> diff --git a/sound/soc/sunxi/sun8i.c b/sound/soc/sunxi/sun8i.c
> new file mode 100644
> index 0000000..565cd88
> --- /dev/null
> +++ b/sound/soc/sunxi/sun8i.c
> @@ -0,0 +1,101 @@
> +/*
> + * ALSA SoC driver for Allwinner sun8i SoC
> + *
> + * Copyright (C) 2016 Mylène Josserand <mylene.josserand@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/firmware.h>
> +#include <linux/module.h>
> +
> +#include <sound/soc.h>
> +
> +static struct snd_soc_aux_dev sun8i_audio_prcm_aux_devs[] = {
> +       {
> +               .name = "sun8i-codec-analog",
> +               .codec_name = "sun8i-codec-analog.0",
> +       },
> +};
> +
> +static struct snd_soc_dai_link sun8i_dai_link = {
> +       .name           = "sun4i-i2s",
> +       .stream_name    = "Playback",
> +       .codec_dai_name = "sun8i",
> +       .dai_fmt        = SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S |
> +                       SND_SOC_DAIFMT_CBM_CFM,
> +};
> +
> +static struct snd_soc_card sun8i_card = {
> +       .name           = "sun8i-card",
> +       .owner          = THIS_MODULE,
> +       .dai_link       = &sun8i_dai_link,
> +       .num_links      = 1,
> +       .aux_dev        = sun8i_audio_prcm_aux_devs,
> +       .num_aux_devs   = ARRAY_SIZE(sun8i_audio_prcm_aux_devs),
> +};
> +
> +static int sun8i_probe(struct platform_device *pdev)
> +{
> +       struct snd_soc_dai_link *link = &sun8i_dai_link;
> +       struct device_node *np = pdev->dev.of_node;
> +       int ret;
> +
> +       /* register the soc card */
> +       sun8i_card.dev = &pdev->dev;
> +
> +       /* Retrieve the audio-codec from DT */
> +       link->codec_of_node = of_parse_phandle(np, "allwinner,audio-codec", 0);
> +       if (!link->codec_of_node) {
> +               dev_err(&pdev->dev, "Missing audio codec\n");
> +               return -EINVAL;
> +       }
> +
> +       /* Retrieve DAI from DT */
> +       link->cpu_of_node = of_parse_phandle(np, "allwinner,i2s-controller", 0);
Now that I've spent some time trying to add my changes for the H3
ontop of your code,  I think this file should be more generic and rely
on the dtsi more. It's pretty A33 specific but with little effort it
can be worked to cover all of the sun8i type drivers. I would change
"allwinner,i2s-controller" to "allwinner,audio-dai" for starters and
then maybe pull in some info for the dai-link from the dtsi.
CK
> +       if (!link->cpu_of_node) {
> +               dev_err(&pdev->dev, "Missing I2S controller\n");
> +               return -EINVAL;
> +       }
> +
> +       link->platform_of_node = link->cpu_of_node;
> +
> +       /* Register the sound card */
> +       ret = devm_snd_soc_register_card(&pdev->dev, &sun8i_card);
> +       if (ret) {
> +               dev_err(&pdev->dev,
> +                       "Soc register card failed %d\n", ret);
> +               return ret;
> +       }
> +
> +       return ret;
> +}
> +
> +static const struct of_device_id sun8i_of_match[] = {
> +       { .compatible = "allwinner,sun8i-audio", },
> +       {},
> +};
> +
> +MODULE_DEVICE_TABLE(of, sun8i_of_match);
> +
> +static struct platform_driver sun8i_card_driver = {
> +       .probe = sun8i_probe,
> +       .driver = {
> +               .name   = "sun8i-audio",
> +               .of_match_table = sun8i_of_match,
> +       },
> +};
> +
> +module_platform_driver(sun8i_card_driver);
> +
> +MODULE_AUTHOR("Mylène Josserand <mylene.josserand@free-electrons.com>");
> +MODULE_DESCRIPTION("Allwinner sun8i machine ASoC driver");
> +MODULE_LICENSE("GPL v2");
> --
> 2.9.3
>

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

* Re: [PATCH 07/14] ASoC: Add sun8i audio card
@ 2016-10-05  6:04       ` Code Kipper
  0 siblings, 0 replies; 170+ messages in thread
From: Code Kipper @ 2016-10-05  6:04 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul-ral2JQCrhuEAvxtiuMwx3w, Maxime Ripard, Chen-Yu Tsai,
	Michael Turquette, sboyd-sgV2jX0FEOL9JmXXK+q4OQ, Liam Girdwood,
	Mark Brown, Jaroslav Kysela, Takashi Iwai, Lee Jones,
	mark.rutland-5wv7dgnIgG8, Rob Herring,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	dmaengine-u79uwXL29TY76Z2rM5mHXA, linux-arm-kernel,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw, devicetree, linux-sunxi,
	thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8

On 4 October 2016 at 11:46, Mylène Josserand
<mylene.josserand-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> Add the audio card for sun8i SoC. This card links the codec driver
> (digital part) with the DAI driver. The analog codec driver is
> added as an aux_device.
>
> Signed-off-by: Mylène Josserand <mylene.josserand-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> ---
>  sound/soc/sunxi/Kconfig  |  14 +++++++
>  sound/soc/sunxi/Makefile |   1 +
>  sound/soc/sunxi/sun8i.c  | 101 +++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 116 insertions(+)
>  create mode 100644 sound/soc/sunxi/sun8i.c
>
> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
> index 9e287b0..7b97395 100644
> --- a/sound/soc/sunxi/Kconfig
> +++ b/sound/soc/sunxi/Kconfig
> @@ -27,6 +27,20 @@ config SND_SUN4I_SPDIF
>           Say Y or M to add support for the S/PDIF audio block in the Allwinner
>           A10 and affiliated SoCs.
>
> +config SND_SUN8I
> +       tristate "Allwinner SUN6I/SUN8I audio card support"
> +       select SND_SUN8I_CODEC
> +       select SND_SUN4I_I2S
> +       select SND_SUN8I_CODEC_ANALOG
> +       select REGMAP_MMIO
> +       help
> +         This option enables the audio card for Allwinner A33 (sun8i) SoC.
> +         It enables the DAI driver (SND_SUN4I_I2S), the digital audio
> +         codec driver (SND_SUN8I_CODEC) and the analog codec driver
> +         (SND_SUN8I_CODEC_ANALOG).
> +
> +         Say Y or M if you want to add sun8i/6i card support
> +
>  config SND_SUN8I_CODEC
>         tristate "Allwinner SUN8I audio codec"
>         select REGMAP_MMIO
> diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
> index 1da63d3..7f1bab9 100644
> --- a/sound/soc/sunxi/Makefile
> +++ b/sound/soc/sunxi/Makefile
> @@ -1,5 +1,6 @@
>  obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
>  obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
>  obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
> +obj-$(CONFIG_SND_SUN8I) += sun8i.o
>  obj-$(CONFIG_SND_SUN8I_CODEC) += sun8i-codec.o
>  obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
> diff --git a/sound/soc/sunxi/sun8i.c b/sound/soc/sunxi/sun8i.c
> new file mode 100644
> index 0000000..565cd88
> --- /dev/null
> +++ b/sound/soc/sunxi/sun8i.c
> @@ -0,0 +1,101 @@
> +/*
> + * ALSA SoC driver for Allwinner sun8i SoC
> + *
> + * Copyright (C) 2016 Mylène Josserand <mylene.josserand@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/firmware.h>
> +#include <linux/module.h>
> +
> +#include <sound/soc.h>
> +
> +static struct snd_soc_aux_dev sun8i_audio_prcm_aux_devs[] = {
> +       {
> +               .name = "sun8i-codec-analog",
> +               .codec_name = "sun8i-codec-analog.0",
> +       },
> +};
> +
> +static struct snd_soc_dai_link sun8i_dai_link = {
> +       .name           = "sun4i-i2s",
> +       .stream_name    = "Playback",
> +       .codec_dai_name = "sun8i",
> +       .dai_fmt        = SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S |
> +                       SND_SOC_DAIFMT_CBM_CFM,
> +};
> +
> +static struct snd_soc_card sun8i_card = {
> +       .name           = "sun8i-card",
> +       .owner          = THIS_MODULE,
> +       .dai_link       = &sun8i_dai_link,
> +       .num_links      = 1,
> +       .aux_dev        = sun8i_audio_prcm_aux_devs,
> +       .num_aux_devs   = ARRAY_SIZE(sun8i_audio_prcm_aux_devs),
> +};
> +
> +static int sun8i_probe(struct platform_device *pdev)
> +{
> +       struct snd_soc_dai_link *link = &sun8i_dai_link;
> +       struct device_node *np = pdev->dev.of_node;
> +       int ret;
> +
> +       /* register the soc card */
> +       sun8i_card.dev = &pdev->dev;
> +
> +       /* Retrieve the audio-codec from DT */
> +       link->codec_of_node = of_parse_phandle(np, "allwinner,audio-codec", 0);
> +       if (!link->codec_of_node) {
> +               dev_err(&pdev->dev, "Missing audio codec\n");
> +               return -EINVAL;
> +       }
> +
> +       /* Retrieve DAI from DT */
> +       link->cpu_of_node = of_parse_phandle(np, "allwinner,i2s-controller", 0);
Now that I've spent some time trying to add my changes for the H3
ontop of your code,  I think this file should be more generic and rely
on the dtsi more. It's pretty A33 specific but with little effort it
can be worked to cover all of the sun8i type drivers. I would change
"allwinner,i2s-controller" to "allwinner,audio-dai" for starters and
then maybe pull in some info for the dai-link from the dtsi.
CK
> +       if (!link->cpu_of_node) {
> +               dev_err(&pdev->dev, "Missing I2S controller\n");
> +               return -EINVAL;
> +       }
> +
> +       link->platform_of_node = link->cpu_of_node;
> +
> +       /* Register the sound card */
> +       ret = devm_snd_soc_register_card(&pdev->dev, &sun8i_card);
> +       if (ret) {
> +               dev_err(&pdev->dev,
> +                       "Soc register card failed %d\n", ret);
> +               return ret;
> +       }
> +
> +       return ret;
> +}
> +
> +static const struct of_device_id sun8i_of_match[] = {
> +       { .compatible = "allwinner,sun8i-audio", },
> +       {},
> +};
> +
> +MODULE_DEVICE_TABLE(of, sun8i_of_match);
> +
> +static struct platform_driver sun8i_card_driver = {
> +       .probe = sun8i_probe,
> +       .driver = {
> +               .name   = "sun8i-audio",
> +               .of_match_table = sun8i_of_match,
> +       },
> +};
> +
> +module_platform_driver(sun8i_card_driver);
> +
> +MODULE_AUTHOR("Mylène Josserand <mylene.josserand-wi1+55ScJUtKEb57/3fJTGGXanvQGlWp@public.gmane.orgm>");
> +MODULE_DESCRIPTION("Allwinner sun8i machine ASoC driver");
> +MODULE_LICENSE("GPL v2");
> --
> 2.9.3
>

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

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

* Re: [PATCH 07/14] ASoC: Add sun8i audio card
@ 2016-10-05  6:04       ` Code Kipper
  0 siblings, 0 replies; 170+ messages in thread
From: Code Kipper @ 2016-10-05  6:04 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul, Maxime Ripard, Chen-Yu Tsai, Michael Turquette,
	sboyd, Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai,
	Lee Jones, mark.rutland, Rob Herring, linux-kernel, dmaengine,
	linux-arm-kernel, linux-clk, alsa-devel, devicetree, linux-sunxi,
	thomas.petazzoni, alexandre.belloni

On 4 October 2016 at 11:46, Myl=C3=A8ne Josserand
<mylene.josserand@free-electrons.com> wrote:
> Add the audio card for sun8i SoC. This card links the codec driver
> (digital part) with the DAI driver. The analog codec driver is
> added as an aux_device.
>
> Signed-off-by: Myl=C3=A8ne Josserand <mylene.josserand@free-electrons.com=
>
> ---
>  sound/soc/sunxi/Kconfig  |  14 +++++++
>  sound/soc/sunxi/Makefile |   1 +
>  sound/soc/sunxi/sun8i.c  | 101 +++++++++++++++++++++++++++++++++++++++++=
++++++
>  3 files changed, 116 insertions(+)
>  create mode 100644 sound/soc/sunxi/sun8i.c
>
> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
> index 9e287b0..7b97395 100644
> --- a/sound/soc/sunxi/Kconfig
> +++ b/sound/soc/sunxi/Kconfig
> @@ -27,6 +27,20 @@ config SND_SUN4I_SPDIF
>           Say Y or M to add support for the S/PDIF audio block in the All=
winner
>           A10 and affiliated SoCs.
>
> +config SND_SUN8I
> +       tristate "Allwinner SUN6I/SUN8I audio card support"
> +       select SND_SUN8I_CODEC
> +       select SND_SUN4I_I2S
> +       select SND_SUN8I_CODEC_ANALOG
> +       select REGMAP_MMIO
> +       help
> +         This option enables the audio card for Allwinner A33 (sun8i) So=
C.
> +         It enables the DAI driver (SND_SUN4I_I2S), the digital audio
> +         codec driver (SND_SUN8I_CODEC) and the analog codec driver
> +         (SND_SUN8I_CODEC_ANALOG).
> +
> +         Say Y or M if you want to add sun8i/6i card support
> +
>  config SND_SUN8I_CODEC
>         tristate "Allwinner SUN8I audio codec"
>         select REGMAP_MMIO
> diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
> index 1da63d3..7f1bab9 100644
> --- a/sound/soc/sunxi/Makefile
> +++ b/sound/soc/sunxi/Makefile
> @@ -1,5 +1,6 @@
>  obj-$(CONFIG_SND_SUN4I_CODEC) +=3D sun4i-codec.o
>  obj-$(CONFIG_SND_SUN4I_I2S) +=3D sun4i-i2s.o
>  obj-$(CONFIG_SND_SUN4I_SPDIF) +=3D sun4i-spdif.o
> +obj-$(CONFIG_SND_SUN8I) +=3D sun8i.o
>  obj-$(CONFIG_SND_SUN8I_CODEC) +=3D sun8i-codec.o
>  obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) +=3D sun8i-codec-analog.o
> diff --git a/sound/soc/sunxi/sun8i.c b/sound/soc/sunxi/sun8i.c
> new file mode 100644
> index 0000000..565cd88
> --- /dev/null
> +++ b/sound/soc/sunxi/sun8i.c
> @@ -0,0 +1,101 @@
> +/*
> + * ALSA SoC driver for Allwinner sun8i SoC
> + *
> + * Copyright (C) 2016 Myl=C3=A8ne Josserand <mylene.josserand@free-elect=
rons.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/firmware.h>
> +#include <linux/module.h>
> +
> +#include <sound/soc.h>
> +
> +static struct snd_soc_aux_dev sun8i_audio_prcm_aux_devs[] =3D {
> +       {
> +               .name =3D "sun8i-codec-analog",
> +               .codec_name =3D "sun8i-codec-analog.0",
> +       },
> +};
> +
> +static struct snd_soc_dai_link sun8i_dai_link =3D {
> +       .name           =3D "sun4i-i2s",
> +       .stream_name    =3D "Playback",
> +       .codec_dai_name =3D "sun8i",
> +       .dai_fmt        =3D SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S |
> +                       SND_SOC_DAIFMT_CBM_CFM,
> +};
> +
> +static struct snd_soc_card sun8i_card =3D {
> +       .name           =3D "sun8i-card",
> +       .owner          =3D THIS_MODULE,
> +       .dai_link       =3D &sun8i_dai_link,
> +       .num_links      =3D 1,
> +       .aux_dev        =3D sun8i_audio_prcm_aux_devs,
> +       .num_aux_devs   =3D ARRAY_SIZE(sun8i_audio_prcm_aux_devs),
> +};
> +
> +static int sun8i_probe(struct platform_device *pdev)
> +{
> +       struct snd_soc_dai_link *link =3D &sun8i_dai_link;
> +       struct device_node *np =3D pdev->dev.of_node;
> +       int ret;
> +
> +       /* register the soc card */
> +       sun8i_card.dev =3D &pdev->dev;
> +
> +       /* Retrieve the audio-codec from DT */
> +       link->codec_of_node =3D of_parse_phandle(np, "allwinner,audio-cod=
ec", 0);
> +       if (!link->codec_of_node) {
> +               dev_err(&pdev->dev, "Missing audio codec\n");
> +               return -EINVAL;
> +       }
> +
> +       /* Retrieve DAI from DT */
> +       link->cpu_of_node =3D of_parse_phandle(np, "allwinner,i2s-control=
ler", 0);
Now that I've spent some time trying to add my changes for the H3
ontop of your code,  I think this file should be more generic and rely
on the dtsi more. It's pretty A33 specific but with little effort it
can be worked to cover all of the sun8i type drivers. I would change
"allwinner,i2s-controller" to "allwinner,audio-dai" for starters and
then maybe pull in some info for the dai-link from the dtsi.
CK
> +       if (!link->cpu_of_node) {
> +               dev_err(&pdev->dev, "Missing I2S controller\n");
> +               return -EINVAL;
> +       }
> +
> +       link->platform_of_node =3D link->cpu_of_node;
> +
> +       /* Register the sound card */
> +       ret =3D devm_snd_soc_register_card(&pdev->dev, &sun8i_card);
> +       if (ret) {
> +               dev_err(&pdev->dev,
> +                       "Soc register card failed %d\n", ret);
> +               return ret;
> +       }
> +
> +       return ret;
> +}
> +
> +static const struct of_device_id sun8i_of_match[] =3D {
> +       { .compatible =3D "allwinner,sun8i-audio", },
> +       {},
> +};
> +
> +MODULE_DEVICE_TABLE(of, sun8i_of_match);
> +
> +static struct platform_driver sun8i_card_driver =3D {
> +       .probe =3D sun8i_probe,
> +       .driver =3D {
> +               .name   =3D "sun8i-audio",
> +               .of_match_table =3D sun8i_of_match,
> +       },
> +};
> +
> +module_platform_driver(sun8i_card_driver);
> +
> +MODULE_AUTHOR("Myl=C3=A8ne Josserand <mylene.josserand@free-electrons.co=
m>");
> +MODULE_DESCRIPTION("Allwinner sun8i machine ASoC driver");
> +MODULE_LICENSE("GPL v2");
> --
> 2.9.3
>

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

* [PATCH 07/14] ASoC: Add sun8i audio card
@ 2016-10-05  6:04       ` Code Kipper
  0 siblings, 0 replies; 170+ messages in thread
From: Code Kipper @ 2016-10-05  6:04 UTC (permalink / raw)
  To: linux-arm-kernel

On 4 October 2016 at 11:46, Myl?ne Josserand
<mylene.josserand@free-electrons.com> wrote:
> Add the audio card for sun8i SoC. This card links the codec driver
> (digital part) with the DAI driver. The analog codec driver is
> added as an aux_device.
>
> Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
> ---
>  sound/soc/sunxi/Kconfig  |  14 +++++++
>  sound/soc/sunxi/Makefile |   1 +
>  sound/soc/sunxi/sun8i.c  | 101 +++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 116 insertions(+)
>  create mode 100644 sound/soc/sunxi/sun8i.c
>
> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
> index 9e287b0..7b97395 100644
> --- a/sound/soc/sunxi/Kconfig
> +++ b/sound/soc/sunxi/Kconfig
> @@ -27,6 +27,20 @@ config SND_SUN4I_SPDIF
>           Say Y or M to add support for the S/PDIF audio block in the Allwinner
>           A10 and affiliated SoCs.
>
> +config SND_SUN8I
> +       tristate "Allwinner SUN6I/SUN8I audio card support"
> +       select SND_SUN8I_CODEC
> +       select SND_SUN4I_I2S
> +       select SND_SUN8I_CODEC_ANALOG
> +       select REGMAP_MMIO
> +       help
> +         This option enables the audio card for Allwinner A33 (sun8i) SoC.
> +         It enables the DAI driver (SND_SUN4I_I2S), the digital audio
> +         codec driver (SND_SUN8I_CODEC) and the analog codec driver
> +         (SND_SUN8I_CODEC_ANALOG).
> +
> +         Say Y or M if you want to add sun8i/6i card support
> +
>  config SND_SUN8I_CODEC
>         tristate "Allwinner SUN8I audio codec"
>         select REGMAP_MMIO
> diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
> index 1da63d3..7f1bab9 100644
> --- a/sound/soc/sunxi/Makefile
> +++ b/sound/soc/sunxi/Makefile
> @@ -1,5 +1,6 @@
>  obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
>  obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
>  obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
> +obj-$(CONFIG_SND_SUN8I) += sun8i.o
>  obj-$(CONFIG_SND_SUN8I_CODEC) += sun8i-codec.o
>  obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
> diff --git a/sound/soc/sunxi/sun8i.c b/sound/soc/sunxi/sun8i.c
> new file mode 100644
> index 0000000..565cd88
> --- /dev/null
> +++ b/sound/soc/sunxi/sun8i.c
> @@ -0,0 +1,101 @@
> +/*
> + * ALSA SoC driver for Allwinner sun8i SoC
> + *
> + * Copyright (C) 2016 Myl?ne Josserand <mylene.josserand@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/firmware.h>
> +#include <linux/module.h>
> +
> +#include <sound/soc.h>
> +
> +static struct snd_soc_aux_dev sun8i_audio_prcm_aux_devs[] = {
> +       {
> +               .name = "sun8i-codec-analog",
> +               .codec_name = "sun8i-codec-analog.0",
> +       },
> +};
> +
> +static struct snd_soc_dai_link sun8i_dai_link = {
> +       .name           = "sun4i-i2s",
> +       .stream_name    = "Playback",
> +       .codec_dai_name = "sun8i",
> +       .dai_fmt        = SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S |
> +                       SND_SOC_DAIFMT_CBM_CFM,
> +};
> +
> +static struct snd_soc_card sun8i_card = {
> +       .name           = "sun8i-card",
> +       .owner          = THIS_MODULE,
> +       .dai_link       = &sun8i_dai_link,
> +       .num_links      = 1,
> +       .aux_dev        = sun8i_audio_prcm_aux_devs,
> +       .num_aux_devs   = ARRAY_SIZE(sun8i_audio_prcm_aux_devs),
> +};
> +
> +static int sun8i_probe(struct platform_device *pdev)
> +{
> +       struct snd_soc_dai_link *link = &sun8i_dai_link;
> +       struct device_node *np = pdev->dev.of_node;
> +       int ret;
> +
> +       /* register the soc card */
> +       sun8i_card.dev = &pdev->dev;
> +
> +       /* Retrieve the audio-codec from DT */
> +       link->codec_of_node = of_parse_phandle(np, "allwinner,audio-codec", 0);
> +       if (!link->codec_of_node) {
> +               dev_err(&pdev->dev, "Missing audio codec\n");
> +               return -EINVAL;
> +       }
> +
> +       /* Retrieve DAI from DT */
> +       link->cpu_of_node = of_parse_phandle(np, "allwinner,i2s-controller", 0);
Now that I've spent some time trying to add my changes for the H3
ontop of your code,  I think this file should be more generic and rely
on the dtsi more. It's pretty A33 specific but with little effort it
can be worked to cover all of the sun8i type drivers. I would change
"allwinner,i2s-controller" to "allwinner,audio-dai" for starters and
then maybe pull in some info for the dai-link from the dtsi.
CK
> +       if (!link->cpu_of_node) {
> +               dev_err(&pdev->dev, "Missing I2S controller\n");
> +               return -EINVAL;
> +       }
> +
> +       link->platform_of_node = link->cpu_of_node;
> +
> +       /* Register the sound card */
> +       ret = devm_snd_soc_register_card(&pdev->dev, &sun8i_card);
> +       if (ret) {
> +               dev_err(&pdev->dev,
> +                       "Soc register card failed %d\n", ret);
> +               return ret;
> +       }
> +
> +       return ret;
> +}
> +
> +static const struct of_device_id sun8i_of_match[] = {
> +       { .compatible = "allwinner,sun8i-audio", },
> +       {},
> +};
> +
> +MODULE_DEVICE_TABLE(of, sun8i_of_match);
> +
> +static struct platform_driver sun8i_card_driver = {
> +       .probe = sun8i_probe,
> +       .driver = {
> +               .name   = "sun8i-audio",
> +               .of_match_table = sun8i_of_match,
> +       },
> +};
> +
> +module_platform_driver(sun8i_card_driver);
> +
> +MODULE_AUTHOR("Myl?ne Josserand <mylene.josserand@free-electrons.com>");
> +MODULE_DESCRIPTION("Allwinner sun8i machine ASoC driver");
> +MODULE_LICENSE("GPL v2");
> --
> 2.9.3
>

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

* Re: [PATCH 02/14] clk: ccu-sun8i-a33: Add CLK_SET_RATE_PARENT to ac-dig
  2016-10-04 12:12       ` Thomas Petazzoni
@ 2016-10-05  9:37         ` Mylene Josserand
  -1 siblings, 0 replies; 170+ messages in thread
From: Mylene Josserand @ 2016-10-05  9:37 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt,
	linux-kernel, dmaengine, linux-arm-kernel, linux-clk, alsa-devel,
	devicetree, linux-sunxi, alexandre.belloni

Hello Thomas,


On 04/10/2016 14:12, Thomas Petazzoni wrote:
> Hello,
>
> On Tue,  4 Oct 2016 11:46:15 +0200, Mylène Josserand wrote:
>> Add the flag CLK_SET_RATE_PARENT to 'ac-dig' clock.
>
> There is no need to repeat the commit title inside the commit log
> itself. What would be more useful is to explain *why* this is needed.


Agreed, I will update it for a V2.

Thanks !

-- 
Mylène Josserand, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* [PATCH 02/14] clk: ccu-sun8i-a33: Add CLK_SET_RATE_PARENT to ac-dig
@ 2016-10-05  9:37         ` Mylene Josserand
  0 siblings, 0 replies; 170+ messages in thread
From: Mylene Josserand @ 2016-10-05  9:37 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Thomas,


On 04/10/2016 14:12, Thomas Petazzoni wrote:
> Hello,
>
> On Tue,  4 Oct 2016 11:46:15 +0200, Myl?ne Josserand wrote:
>> Add the flag CLK_SET_RATE_PARENT to 'ac-dig' clock.
>
> There is no need to repeat the commit title inside the commit log
> itself. What would be more useful is to explain *why* this is needed.


Agreed, I will update it for a V2.

Thanks !

-- 
Myl?ne Josserand, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* Re: [PATCH 03/14] ASoC: sun4i-i2s: Add apb reset
  2016-10-04 15:42         ` Maxime Ripard
@ 2016-10-05  9:43           ` Mylene Josserand
  -1 siblings, 0 replies; 170+ messages in thread
From: Mylene Josserand @ 2016-10-05  9:43 UTC (permalink / raw)
  To: Maxime Ripard, Thomas Petazzoni
  Cc: mark.rutland, devicetree, alsa-devel, vinod.koul, linux-kernel,
	mturquette, tiwai, sboyd, lgirdwood, robh+dt, perex, wens,
	broonie, alexandre.belloni, dmaengine, lee.jones, linux-clk,
	linux-arm-kernel

Hello,


On 04/10/2016 17:42, Maxime Ripard wrote:
> Hi,
>
> On Tue, Oct 04, 2016 at 02:15:16PM +0200, Thomas Petazzoni wrote:
>> Hello,
>>
>> On Tue,  4 Oct 2016 11:46:16 +0200, Mylène Josserand wrote:
>>
>>>  #include <sound/dmaengine_pcm.h>
>>>  #include <sound/pcm_params.h>
>>> @@ -589,6 +590,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>>>  {
>>>  	struct sun4i_i2s *i2s;
>>>  	struct resource *res;
>>> +	struct reset_control *reset_apb;
>>>  	void __iomem *regs;
>>>  	int irq, ret;
>>>
>>> @@ -626,7 +628,19 @@ 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);
>>>  	}
>>> -	
>>> +
>>> +	reset_apb = devm_reset_control_get(&pdev->dev, "apb_reset");
>>
>> I believe this is a change in the Device Tree binding, since you're
>> adding support for a new resource. Perhaps the Device Tree binding
>> documentation should be updated accordingly?
>
> Indeed.
>
> You have two solutions to do that:
>   - Either mark it as optional and use reset_control_get_optional
>     (because here, you broke the other SoCs that have that controller
>     but no reset line)
>   - Or introduce a new compatible, and make the reset property
>     mandatory for that new compatible.
>
> I prefer the latter, since you get a stricter error check, and you
> cannot end up in a situation where your driver probes but is
> useless. But you'll find both in our drivers.
>


Okay, thank you for the hints!


>>> +	}
>>> +
>>> +	ret = reset_control_deassert(reset_apb);
>>> +	if (ret < 0) {
>>> +		dev_err(&pdev->dev, "Can't deassert apb reset (%d)\n", ret);
>>> +		return ret;
>>> +	}
>>
>> Do you need to re-assert the reset line in the ->remove() hook?
>
> Even better, you can add it to the runtime_pm hooks! :)


I will have a look to runtime_pm and update it for a V2.


-- 
Mylène Josserand, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* [PATCH 03/14] ASoC: sun4i-i2s: Add apb reset
@ 2016-10-05  9:43           ` Mylene Josserand
  0 siblings, 0 replies; 170+ messages in thread
From: Mylene Josserand @ 2016-10-05  9:43 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,


On 04/10/2016 17:42, Maxime Ripard wrote:
> Hi,
>
> On Tue, Oct 04, 2016 at 02:15:16PM +0200, Thomas Petazzoni wrote:
>> Hello,
>>
>> On Tue,  4 Oct 2016 11:46:16 +0200, Myl?ne Josserand wrote:
>>
>>>  #include <sound/dmaengine_pcm.h>
>>>  #include <sound/pcm_params.h>
>>> @@ -589,6 +590,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
>>>  {
>>>  	struct sun4i_i2s *i2s;
>>>  	struct resource *res;
>>> +	struct reset_control *reset_apb;
>>>  	void __iomem *regs;
>>>  	int irq, ret;
>>>
>>> @@ -626,7 +628,19 @@ 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);
>>>  	}
>>> -	
>>> +
>>> +	reset_apb = devm_reset_control_get(&pdev->dev, "apb_reset");
>>
>> I believe this is a change in the Device Tree binding, since you're
>> adding support for a new resource. Perhaps the Device Tree binding
>> documentation should be updated accordingly?
>
> Indeed.
>
> You have two solutions to do that:
>   - Either mark it as optional and use reset_control_get_optional
>     (because here, you broke the other SoCs that have that controller
>     but no reset line)
>   - Or introduce a new compatible, and make the reset property
>     mandatory for that new compatible.
>
> I prefer the latter, since you get a stricter error check, and you
> cannot end up in a situation where your driver probes but is
> useless. But you'll find both in our drivers.
>


Okay, thank you for the hints!


>>> +	}
>>> +
>>> +	ret = reset_control_deassert(reset_apb);
>>> +	if (ret < 0) {
>>> +		dev_err(&pdev->dev, "Can't deassert apb reset (%d)\n", ret);
>>> +		return ret;
>>> +	}
>>
>> Do you need to re-assert the reset line in the ->remove() hook?
>
> Even better, you can add it to the runtime_pm hooks! :)


I will have a look to runtime_pm and update it for a V2.


-- 
Myl?ne Josserand, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* Re: [PATCH 07/14] ASoC: Add sun8i audio card
@ 2016-10-05 10:03         ` Jean-Francois Moine
  0 siblings, 0 replies; 170+ messages in thread
From: Jean-Francois Moine @ 2016-10-05 10:03 UTC (permalink / raw)
  To: Code Kipper
  Cc: Mylène Josserand, mark.rutland, devicetree, alsa-devel,
	linux-sunxi, thomas.petazzoni, vinod.koul, linux-kernel,
	Michael Turquette, Takashi Iwai, sboyd, Liam Girdwood,
	Rob Herring, Jaroslav Kysela, Chen-Yu Tsai, Mark Brown,
	alexandre.belloni, dmaengine, Maxime Ripard, Lee Jones,
	linux-clk, linux-arm-kernel

On Wed, 5 Oct 2016 08:04:26 +0200
Code Kipper <codekipper@gmail.com> wrote:

> > +static int sun8i_probe(struct platform_device *pdev)
> > +{
> > +       struct snd_soc_dai_link *link = &sun8i_dai_link;
> > +       struct device_node *np = pdev->dev.of_node;
> > +       int ret;
> > +
> > +       /* register the soc card */
> > +       sun8i_card.dev = &pdev->dev;
> > +
> > +       /* Retrieve the audio-codec from DT */
> > +       link->codec_of_node = of_parse_phandle(np, "allwinner,audio-codec", 0);
> > +       if (!link->codec_of_node) {
> > +               dev_err(&pdev->dev, "Missing audio codec\n");
> > +               return -EINVAL;
> > +       }
> > +
> > +       /* Retrieve DAI from DT */
> > +       link->cpu_of_node = of_parse_phandle(np, "allwinner,i2s-controller", 0);
> Now that I've spent some time trying to add my changes for the H3
> ontop of your code,  I think this file should be more generic and rely
> on the dtsi more. It's pretty A33 specific but with little effort it
> can be worked to cover all of the sun8i type drivers. I would change
> "allwinner,i2s-controller" to "allwinner,audio-dai" for starters and
> then maybe pull in some info for the dai-link from the dtsi.
> CK
	[snip]

In fact, there should be no audio card driver as proposed here:
with such a simple layout
	CPU DAI (sun4i-a10-i2s) -> CODEC DAI (sun8i-a33-codec)
the 'simple-card' does the job.

BTW, I have a I2S/PCM/TDM driver for the H3 and A83T.
But, as it works with HDMI and contains echanges with the DRM driver,
it cannot go yet to the mainline...

-- 
Ken ar c'hentañ	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

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

* Re: [PATCH 07/14] ASoC: Add sun8i audio card
@ 2016-10-05 10:03         ` Jean-Francois Moine
  0 siblings, 0 replies; 170+ messages in thread
From: Jean-Francois Moine @ 2016-10-05 10:03 UTC (permalink / raw)
  To: Code Kipper
  Cc: Mylène Josserand, mark.rutland-5wv7dgnIgG8, devicetree,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw, linux-sunxi,
	thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Michael Turquette,
	Takashi Iwai, sboyd-sgV2jX0FEOL9JmXXK+q4OQ, Liam Girdwood,
	Rob Herring, Jaroslav Kysela, Chen-Yu Tsai, Mark Brown,
	alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	dmaengine-u79uwXL29TY76Z2rM5mHXA, Maxime Ripard, Lee Jones,
	linux-clk-u79uwXL29TY76Z2rM5mHXA, linux-arm-kernel

On Wed, 5 Oct 2016 08:04:26 +0200
Code Kipper <codekipper-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:

> > +static int sun8i_probe(struct platform_device *pdev)
> > +{
> > +       struct snd_soc_dai_link *link = &sun8i_dai_link;
> > +       struct device_node *np = pdev->dev.of_node;
> > +       int ret;
> > +
> > +       /* register the soc card */
> > +       sun8i_card.dev = &pdev->dev;
> > +
> > +       /* Retrieve the audio-codec from DT */
> > +       link->codec_of_node = of_parse_phandle(np, "allwinner,audio-codec", 0);
> > +       if (!link->codec_of_node) {
> > +               dev_err(&pdev->dev, "Missing audio codec\n");
> > +               return -EINVAL;
> > +       }
> > +
> > +       /* Retrieve DAI from DT */
> > +       link->cpu_of_node = of_parse_phandle(np, "allwinner,i2s-controller", 0);
> Now that I've spent some time trying to add my changes for the H3
> ontop of your code,  I think this file should be more generic and rely
> on the dtsi more. It's pretty A33 specific but with little effort it
> can be worked to cover all of the sun8i type drivers. I would change
> "allwinner,i2s-controller" to "allwinner,audio-dai" for starters and
> then maybe pull in some info for the dai-link from the dtsi.
> CK
	[snip]

In fact, there should be no audio card driver as proposed here:
with such a simple layout
	CPU DAI (sun4i-a10-i2s) -> CODEC DAI (sun8i-a33-codec)
the 'simple-card' does the job.

BTW, I have a I2S/PCM/TDM driver for the H3 and A83T.
But, as it works with HDMI and contains echanges with the DRM driver,
it cannot go yet to the mainline...

-- 
Ken ar c'hentañ	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

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

* Re: [PATCH 07/14] ASoC: Add sun8i audio card
@ 2016-10-05 10:03         ` Jean-Francois Moine
  0 siblings, 0 replies; 170+ messages in thread
From: Jean-Francois Moine @ 2016-10-05 10:03 UTC (permalink / raw)
  To: Code Kipper
  Cc: Mylène Josserand, mark.rutland, devicetree, alsa-devel,
	linux-sunxi, thomas.petazzoni, vinod.koul, linux-kernel,
	Michael Turquette, Takashi Iwai, sboyd, Liam Girdwood,
	Rob Herring, Jaroslav Kysela, Chen-Yu Tsai, Mark Brown,
	alexandre.belloni, dmaengine, Maxime Ripard, Lee Jones,
	linux-clk, linux-arm-kernel

On Wed, 5 Oct 2016 08:04:26 +0200
Code Kipper <codekipper@gmail.com> wrote:

> > +static int sun8i_probe(struct platform_device *pdev)
> > +{
> > +       struct snd_soc_dai_link *link =3D &sun8i_dai_link;
> > +       struct device_node *np =3D pdev->dev.of_node;
> > +       int ret;
> > +
> > +       /* register the soc card */
> > +       sun8i_card.dev =3D &pdev->dev;
> > +
> > +       /* Retrieve the audio-codec from DT */
> > +       link->codec_of_node =3D of_parse_phandle(np, "allwinner,audio-c=
odec", 0);
> > +       if (!link->codec_of_node) {
> > +               dev_err(&pdev->dev, "Missing audio codec\n");
> > +               return -EINVAL;
> > +       }
> > +
> > +       /* Retrieve DAI from DT */
> > +       link->cpu_of_node =3D of_parse_phandle(np, "allwinner,i2s-contr=
oller", 0);
> Now that I've spent some time trying to add my changes for the H3
> ontop of your code,  I think this file should be more generic and rely
> on the dtsi more. It's pretty A33 specific but with little effort it
> can be worked to cover all of the sun8i type drivers. I would change
> "allwinner,i2s-controller" to "allwinner,audio-dai" for starters and
> then maybe pull in some info for the dai-link from the dtsi.
> CK
	[snip]

In fact, there should be no audio card driver as proposed here:
with such a simple layout
	CPU DAI (sun4i-a10-i2s) -> CODEC DAI (sun8i-a33-codec)
the 'simple-card' does the job.

BTW, I have a I2S/PCM/TDM driver for the H3 and A83T.
But, as it works with HDMI and contains echanges with the DRM driver,
it cannot go yet to the mainline...

--=20
Ken ar c'henta=F1	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

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

* [PATCH 07/14] ASoC: Add sun8i audio card
@ 2016-10-05 10:03         ` Jean-Francois Moine
  0 siblings, 0 replies; 170+ messages in thread
From: Jean-Francois Moine @ 2016-10-05 10:03 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 5 Oct 2016 08:04:26 +0200
Code Kipper <codekipper@gmail.com> wrote:

> > +static int sun8i_probe(struct platform_device *pdev)
> > +{
> > +       struct snd_soc_dai_link *link = &sun8i_dai_link;
> > +       struct device_node *np = pdev->dev.of_node;
> > +       int ret;
> > +
> > +       /* register the soc card */
> > +       sun8i_card.dev = &pdev->dev;
> > +
> > +       /* Retrieve the audio-codec from DT */
> > +       link->codec_of_node = of_parse_phandle(np, "allwinner,audio-codec", 0);
> > +       if (!link->codec_of_node) {
> > +               dev_err(&pdev->dev, "Missing audio codec\n");
> > +               return -EINVAL;
> > +       }
> > +
> > +       /* Retrieve DAI from DT */
> > +       link->cpu_of_node = of_parse_phandle(np, "allwinner,i2s-controller", 0);
> Now that I've spent some time trying to add my changes for the H3
> ontop of your code,  I think this file should be more generic and rely
> on the dtsi more. It's pretty A33 specific but with little effort it
> can be worked to cover all of the sun8i type drivers. I would change
> "allwinner,i2s-controller" to "allwinner,audio-dai" for starters and
> then maybe pull in some info for the dai-link from the dtsi.
> CK
	[snip]

In fact, there should be no audio card driver as proposed here:
with such a simple layout
	CPU DAI (sun4i-a10-i2s) -> CODEC DAI (sun8i-a33-codec)
the 'simple-card' does the job.

BTW, I have a I2S/PCM/TDM driver for the H3 and A83T.
But, as it works with HDMI and contains echanges with the DRM driver,
it cannot go yet to the mainline...

-- 
Ken ar c'henta?	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

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

* Re: [PATCH 06/14] ASoC: Add sun8i digital audio codec
  2016-10-04  9:46     ` Mylène Josserand
  (?)
@ 2016-10-05 10:19         ` Icenowy Zheng
  -1 siblings, 0 replies; 170+ messages in thread
From: Icenowy Zheng @ 2016-10-05 10:19 UTC (permalink / raw)
  To: Mylène Josserand, vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8, wens-jdAy2FN1RRM,
	mturquette-rdvid1DuHRBWk0Htik3J/w, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A,
	perex-/Fr2/VpizcU, tiwai-IBi9RG/b67k,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A
  Cc: thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r



04.10.2016, 17:54, "Mylène Josserand" <mylene.josserand@free-electrons.com>:
> Add the digital sun8i audio codec which handles the base register
> (without DAI).
> The driver handles only the basic playback of the A33 codec, from
> the DAC to the headphones. All other features (microphone, capture,
> etc) will be added later.
>
> Signed-off-by: Mylène Josserand <mylene.josserand-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> ---
>  sound/soc/sunxi/Kconfig | 9 +
>  sound/soc/sunxi/Makefile | 1 +
>  sound/soc/sunxi/sun8i-codec.c | 492 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 502 insertions(+)
>  create mode 100644 sound/soc/sunxi/sun8i-codec.c
>
> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
> index 7aee95a..9e287b0 100644
> --- a/sound/soc/sunxi/Kconfig
> +++ b/sound/soc/sunxi/Kconfig
> @@ -27,6 +27,15 @@ config SND_SUN4I_SPDIF
>            Say Y or M to add support for the S/PDIF audio block in the Allwinner
>            A10 and affiliated SoCs.
>
> +config SND_SUN8I_CODEC
> + tristate "Allwinner SUN8I audio codec"
> + select REGMAP_MMIO
> + help
> + This option enables the digital part of the internal audio codec for
> + Allwinner sun8i SoC.
> +
> + Say Y or M if you want to add sun8i digital audio codec support.
> +
>  config SND_SUN8I_CODEC_ANALOG
>          tristate "Allwinner SUN8I analog codec"
>          select REGMAP_MMIO
> diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
> index 241c0df..1da63d3 100644
> --- a/sound/soc/sunxi/Makefile
> +++ b/sound/soc/sunxi/Makefile
> @@ -1,4 +1,5 @@
>  obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
>  obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
>  obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
> +obj-$(CONFIG_SND_SUN8I_CODEC) += sun8i-codec.o
>  obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
> diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c
> new file mode 100644
> index 0000000..e157f89
> --- /dev/null
> +++ b/sound/soc/sunxi/sun8i-codec.c
> @@ -0,0 +1,492 @@
> +/*
> + * This driver supports the digital controls for the internal codec
> + * found in Allwinner's A33 and A23 SoCs.
> + *
> + * (C) Copyright 2010-2016
> + * Reuuimlla Technology Co., Ltd. <www.reuuimllatech.com>
> + * huangxin <huangxin-VvRAZUq9tDuYHARAtoI1EgC/G2K4zDHf@public.gmane.org>
> + * Mylène Josserand <mylene.josserand-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/delay.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/regmap.h>
> +
> +#include <sound/pcm_params.h>
> +#include <sound/soc.h>
> +#include <sound/soc-dapm.h>
> +
> +/* CODEC_OFFSET represents the offset of the codec registers
> + * and not all the DAI registers
> + */
> +#define CODEC_OFFSET 0x200
> +#define CODEC_BASSADDRESS 0x01c22c00

I don't think this kind of absolute address should exist here...
It should exist in device tree...

> +#define SUN8I_SYSCLK_CTL (0x20c - CODEC_OFFSET)
> +#define SUN8I_SYSCLK_CTL_AIF1CLK_ENA (11)
> +#define SUN8I_SYSCLK_CTL_SYSCLK_ENA (3)
> +#define SUN8I_SYSCLK_CTL_SYSCLK_SRC (0)
> +#define SUN8I_MOD_CLK_ENA (0x210 - CODEC_OFFSET)
> +#define SUN8I_MOD_CLK_ENA_AIF1 (15)
> +#define SUN8I_MOD_CLK_ENA_DAC (2)
> +#define SUN8I_MOD_RST_CTL (0x214 - CODEC_OFFSET)
> +#define SUN8I_MOD_RST_CTL_AIF1 (15)
> +#define SUN8I_MOD_RST_CTL_DAC (2)
> +#define SUN8I_SYS_SR_CTRL (0x218 - CODEC_OFFSET)
> +#define SUN8I_SYS_SR_CTRL_AIF1_FS (12)
> +#define SUN8I_SYS_SR_CTRL_AIF2_FS (8)
> +#define SUN8I_AIF1CLK_CTRL (0x240 - CODEC_OFFSET)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_MSTR_MOD (15)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_INV (14)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV (13)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV (9)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV (6)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ (4)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT (2)
> +#define SUN8I_AIF1_DACDAT_CTRL (0x248 - CODEC_OFFSET)
> +#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA (15)
> +#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA (14)
> +#define SUN8I_DAC_DIG_CTRL (0x320 - CODEC_OFFSET)
> +#define SUN8I_DAC_DIG_CTRL_ENDA (15)
> +#define SUN8I_DAC_MXR_SRC (0x330 - CODEC_OFFSET)
> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA0L (15)
> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA1L (14)
> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF2DACL (13)
> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_ADCL (12)
> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA0R (11)
> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA1R (10)
> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF2DACR (9)
> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR (8)
> +
> +struct sun8i_codec {
> + struct device *dev;
> + struct regmap *regmap;
> + struct clk *clk_module;
> + struct clk *clk_apb;
> +};
> +
> +static int sun8i_codec_get_hw_rate(struct snd_pcm_hw_params *params)
> +{
> + unsigned int rate = params_rate(params);
> +
> + switch (rate) {
> + case 8000:
> + case 7350:
> + return 0x0;
> + case 11025:
> + return 0x1;
> + case 12000:
> + return 0x2;
> + case 16000:
> + return 0x3;
> + case 22050:
> + return 0x4;
> + case 24000:
> + return 0x5;
> + case 32000:
> + return 0x6;
> + case 44100:
> + return 0x7;
> + case 48000:
> + return 0x8;
> + case 96000:
> + return 0x9;
> + case 192000:
> + return 0xa;
> + default:
> + return -EINVAL;
> + }
> +}
> +
> +static int sun8i_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
> +{
> + struct sun8i_codec *scodec = snd_soc_codec_get_drvdata(dai->codec);
> + unsigned long value;
> +
> + /* clock masters */
> + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
> + case SND_SOC_DAIFMT_CBS_CFS: /* DAI Slave */
> + value = 0x0; /* Codec Master */
> + break;
> + case SND_SOC_DAIFMT_CBM_CFM: /* DAI Master */
> + value = 0x1; /* Codec Slave */
> + break;
> + default:
> + return -EINVAL;
> + }
> + regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
> + BIT(SUN8I_AIF1CLK_CTRL_AIF1_MSTR_MOD),
> + value << SUN8I_AIF1CLK_CTRL_AIF1_MSTR_MOD);
> +
> + /* clock inversion */
> + switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
> + case SND_SOC_DAIFMT_NB_NF: /* Normal */
> + value = 0x0;
> + break;
> + case SND_SOC_DAIFMT_IB_IF: /* Inversion */
> + value = 0x1;
> + break;
> + default:
> + return -EINVAL;
> + }
> + regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
> + BIT(SUN8I_AIF1CLK_CTRL_AIF1_BCLK_INV),
> + value << SUN8I_AIF1CLK_CTRL_AIF1_BCLK_INV);
> + regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
> + BIT(SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV),
> + value << SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV);
> +
> + /* DAI format */
> + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
> + case SND_SOC_DAIFMT_I2S:
> + value = 0x0;
> + break;
> + case SND_SOC_DAIFMT_LEFT_J:
> + value = 0x1;
> + break;
> + case SND_SOC_DAIFMT_RIGHT_J:
> + value = 0x2;
> + break;
> + case SND_SOC_DAIFMT_DSP_A:
> + case SND_SOC_DAIFMT_DSP_B:
> + value = 0x3;
> + break;
> + default:
> + return -EINVAL;
> + }
> + regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
> + BIT(SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT),
> + value << SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT);
> +
> + return 0;
> +}
> +
> +static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,
> + struct snd_pcm_hw_params *params,
> + struct snd_soc_dai *dai)
> +{
> + int rs_value = 0;
> + u32 bclk_lrck_div = 0, sample_resolution;
> + int sample_rate = 0;
> + struct sun8i_codec *scodec = snd_soc_codec_get_drvdata(dai->codec);
> +
> + switch (params_format(params)) {
> + case SNDRV_PCM_FORMAT_S16_LE:
> + sample_resolution = 16;
> + break;
> + case SNDRV_PCM_FORMAT_S20_3LE:
> + case SNDRV_PCM_FORMAT_S24_LE:
> + case SNDRV_PCM_FORMAT_S32_LE:
> + sample_resolution = 24;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + /*calculate word select bit*/
> + switch (sample_resolution) {
> + case 8:
> + rs_value = 0x0;
> + break;
> + case 16:
> + rs_value = 0x1;
> + break;
> + case 20:
> + rs_value = 0x2;
> + break;
> + case 24:
> + rs_value = 0x3;
> + break;
> + default:
> + break;
> + }
> + regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
> + 0x3 << SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ,
> + rs_value << SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ);
> +
> + /* calculate bclk_lrck_div Ratio */
> + bclk_lrck_div = sample_resolution * 2;
> + switch (bclk_lrck_div) {
> + case 16:
> + bclk_lrck_div = 0;
> + break;
> + case 32:
> + bclk_lrck_div = 1;
> + break;
> + case 64:
> + bclk_lrck_div = 2;
> + break;
> + case 128:
> + bclk_lrck_div = 3;
> + break;
> + case 256:
> + bclk_lrck_div = 4;
> + break;
> + default:
> + break;
> + }
> + regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
> + 0x7 << SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV,
> + bclk_lrck_div << SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV);
> +
> + sample_rate = sun8i_codec_get_hw_rate(params);
> + if (sample_rate < 0)
> + return sample_rate;
> +
> + regmap_update_bits(scodec->regmap, SUN8I_SYS_SR_CTRL,
> + 0xf << SUN8I_SYS_SR_CTRL_AIF1_FS,
> + sample_rate << SUN8I_SYS_SR_CTRL_AIF1_FS);
> + regmap_update_bits(scodec->regmap, SUN8I_SYS_SR_CTRL,
> + 0xf << SUN8I_SYS_SR_CTRL_AIF2_FS,
> + sample_rate << SUN8I_SYS_SR_CTRL_AIF2_FS);
> +
> + return 0;
> +}
> +
> +static const struct snd_kcontrol_new sun8i_output_left_mixer_controls[] = {
> + SOC_DAPM_SINGLE("LSlot 0", SUN8I_DAC_MXR_SRC,
> + SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA0L, 1, 0),
> + SOC_DAPM_SINGLE("LSlot 1", SUN8I_DAC_MXR_SRC,
> + SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA1L, 1, 0),
> + SOC_DAPM_SINGLE("DACL", SUN8I_DAC_MXR_SRC,
> + SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF2DACL, 1, 0),
> + SOC_DAPM_SINGLE("ADCL", SUN8I_DAC_MXR_SRC,
> + SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_ADCL, 1, 0),
> +};
> +
> +static const struct snd_kcontrol_new sun8i_output_right_mixer_controls[] = {
> + SOC_DAPM_SINGLE("RSlot 0", SUN8I_DAC_MXR_SRC,
> + SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA0R, 1, 0),
> + SOC_DAPM_SINGLE("RSlot 1", SUN8I_DAC_MXR_SRC,
> + SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA1R, 1, 0),
> + SOC_DAPM_SINGLE("DACR", SUN8I_DAC_MXR_SRC,
> + SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF2DACR, 1, 0),
> + SOC_DAPM_SINGLE("ADCR", SUN8I_DAC_MXR_SRC,
> + SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR, 1, 0),
> +};
> +
> +static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = {
> + /* Digital parts of the DACs */
> + SND_SOC_DAPM_SUPPLY("DAC", SUN8I_DAC_DIG_CTRL, SUN8I_DAC_DIG_CTRL_ENDA,
> + 0, NULL, 0),
> +
> + /* Analog DAC */
> + SND_SOC_DAPM_DAC("Left DAC", "Playback", SUN8I_AIF1_DACDAT_CTRL,
> + SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA, 0),
> + SND_SOC_DAPM_DAC("Right DAC", "Playback", SUN8I_AIF1_DACDAT_CTRL,
> + SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA, 0),
> +
> + /* DAC Mixers */
> + SND_SOC_DAPM_MIXER("Left DAC Mixer", SND_SOC_NOPM, 0, 0,
> + sun8i_output_left_mixer_controls,
> + ARRAY_SIZE(sun8i_output_left_mixer_controls)),
> + SND_SOC_DAPM_MIXER("Right DAC Mixer", SND_SOC_NOPM, 0, 0,
> + sun8i_output_right_mixer_controls,
> + ARRAY_SIZE(sun8i_output_right_mixer_controls)),
> +
> + /* Clocks */
> + SND_SOC_DAPM_SUPPLY("MODCLK AFI1", SUN8I_MOD_CLK_ENA,
> + SUN8I_MOD_CLK_ENA_AIF1, 0, NULL, 0),
> + SND_SOC_DAPM_SUPPLY("MODCLK DAC", SUN8I_MOD_CLK_ENA,
> + SUN8I_MOD_CLK_ENA_DAC, 0, NULL, 0),
> + SND_SOC_DAPM_SUPPLY("AIF1", SUN8I_SYSCLK_CTL,
> + SUN8I_SYSCLK_CTL_AIF1CLK_ENA, 0, NULL, 0),
> + SND_SOC_DAPM_SUPPLY("SYSCLK", SUN8I_SYSCLK_CTL,
> + SUN8I_SYSCLK_CTL_SYSCLK_ENA, 0, NULL, 0),
> +
> + SND_SOC_DAPM_SUPPLY("AIF1 PLL", SUN8I_SYSCLK_CTL, 0x9, 0, NULL, 0),
> + /* Inversion as 0=AIF1, 1=AIF2 */
> + SND_SOC_DAPM_SUPPLY("SYSCLK AIF1", SUN8I_SYSCLK_CTL,
> + SUN8I_SYSCLK_CTL_SYSCLK_SRC, 1, NULL, 0),
> +
> + /* Module reset */
> + SND_SOC_DAPM_SUPPLY("RST AIF1", SUN8I_MOD_RST_CTL,
> + SUN8I_MOD_RST_CTL_AIF1, 0, NULL, 0),
> + SND_SOC_DAPM_SUPPLY("RST DAC", SUN8I_MOD_RST_CTL,
> + SUN8I_MOD_RST_CTL_DAC, 0, NULL, 0),
> +
> + /* Headphone outputs */
> + SND_SOC_DAPM_OUTPUT("HPOUTL"),
> + SND_SOC_DAPM_OUTPUT("HPOUTR"),
> +
> +};
> +
> +static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = {
> + /* Clock Routes */
> + { "AIF1", NULL, "SYSCLK AIF1" },
> + { "AIF1 PLL", NULL, "AIF1" },
> + { "RST AIF1", NULL, "AIF1 PLL" },
> + { "MODCLK AFI1", NULL, "RST AIF1" },
> + { "DAC", NULL, "MODCLK AFI1" },
> +
> + { "RST DAC", NULL, "SYSCLK" },
> + { "MODCLK DAC", NULL, "RST DAC" },
> + { "DAC", NULL, "MODCLK DAC" },
> +
> + /* DAC Routes */
> + { "Left DAC", NULL, "DAC" },
> + { "Right DAC", NULL, "DAC" },
> +
> + /* DAC Mixer Routes */
> + { "Left DAC Mixer", "LSlot 0", "Left DAC"},
> + { "Right DAC Mixer", "RSlot 0", "Right DAC"},
> +
> + /* End of route : HP out */
> + { "HPOUTL", NULL, "Left DAC Mixer" },
> + { "HPOUTR", NULL, "Right DAC Mixer" },
> +};
> +
> +static struct snd_soc_dai_ops sun8i_codec_dai_ops = {
> + .hw_params = sun8i_codec_hw_params,
> + .set_fmt = sun8i_set_fmt,
> +};
> +
> +static struct snd_soc_dai_driver sun8i_codec_dai = {
> + .name = "sun8i",
> + /* playback capabilities */
> + .playback = {
> + .stream_name = "Playback",
> + .channels_min = 1,
> + .channels_max = 2,
> + .rates = SNDRV_PCM_RATE_8000_192000 |
> + SNDRV_PCM_RATE_KNOT,
> + .formats = SNDRV_PCM_FMTBIT_S8 |
> + SNDRV_PCM_FMTBIT_S16_LE |
> + SNDRV_PCM_FMTBIT_S18_3LE |
> + SNDRV_PCM_FMTBIT_S20_3LE |
> + SNDRV_PCM_FMTBIT_S24_LE |
> + SNDRV_PCM_FMTBIT_S32_LE,
> + },
> + /* pcm operations */
> + .ops = &sun8i_codec_dai_ops,
> +};
> +EXPORT_SYMBOL(sun8i_codec_dai);
> +
> +static int sun8i_soc_probe(struct snd_soc_codec *codec)
> +{
> + return 0;
> +}
> +
> +/* power down chip */
> +static int sun8i_soc_remove(struct snd_soc_codec *codec)
> +{
> + return 0;
> +}
> +
> +static struct snd_soc_codec_driver sun8i_soc_codec = {
> + .probe = sun8i_soc_probe,
> + .remove = sun8i_soc_remove,
> + .component_driver = {
> + .dapm_widgets = sun8i_codec_dapm_widgets,
> + .num_dapm_widgets = ARRAY_SIZE(sun8i_codec_dapm_widgets),
> + .dapm_routes = sun8i_codec_dapm_routes,
> + .num_dapm_routes = ARRAY_SIZE(sun8i_codec_dapm_routes),
> + },
> +};
> +
> +static const struct regmap_config sun8i_codec_regmap_config = {
> + .reg_bits = 32,
> + .reg_stride = 4,
> + .val_bits = 32,
> + .max_register = SUN8I_DAC_MXR_SRC,
> +};
> +
> +static int sun8i_codec_probe(struct platform_device *pdev)
> +{
> + struct resource *res_base;
> + struct sun8i_codec *scodec;
> + void __iomem *base;
> +
> + scodec = devm_kzalloc(&pdev->dev, sizeof(*scodec), GFP_KERNEL);
> + if (!scodec)
> + return -ENOMEM;
> +
> + scodec->dev = &pdev->dev;
> +
> + /* Get the clocks from the DT */
> + scodec->clk_module = devm_clk_get(&pdev->dev, "codec");
> + if (IS_ERR(scodec->clk_module)) {
> + dev_err(&pdev->dev, "Failed to get the module clock\n");
> + return PTR_ERR(scodec->clk_module);
> + }
> + if (clk_prepare_enable(scodec->clk_module))
> + pr_err("err:open failed;\n");
> +
> + scodec->clk_apb = devm_clk_get(&pdev->dev, "apb");
> + if (IS_ERR(scodec->clk_apb)) {
> + dev_err(&pdev->dev, "Failed to get the apb clock\n");
> + return PTR_ERR(scodec->clk_apb);
> + }
> + if (clk_prepare_enable(scodec->clk_apb))
> + pr_err("err:open failed;\n");
> +
> + /* Get base resources, registers and regmap */
> + res_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audio");
> + base = devm_ioremap_resource(&pdev->dev, res_base);
> + if (IS_ERR(base)) {
> + dev_err(&pdev->dev, "Failed to map the registers\n");
> + return PTR_ERR(base);
> + }
> +
> + scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
> + &sun8i_codec_regmap_config);
> + if (IS_ERR(scodec->regmap)) {
> + dev_err(&pdev->dev, "Failed to create our regmap\n");
> + return PTR_ERR(scodec->regmap);
> + }
> +
> + /* Set the codec data as driver data */
> + dev_set_drvdata(&pdev->dev, scodec);
> +
> + snd_soc_register_codec(&pdev->dev, &sun8i_soc_codec, &sun8i_codec_dai,
> + 1);
> +
> + return 0;
> +}
> +
> +static int sun8i_codec_remove(struct platform_device *pdev)
> +{
> + struct snd_soc_card *card = platform_get_drvdata(pdev);
> + struct sun8i_codec *scodec = snd_soc_card_get_drvdata(card);
> +
> + snd_soc_unregister_codec(&pdev->dev);
> + clk_disable_unprepare(scodec->clk_module);
> + clk_disable_unprepare(scodec->clk_apb);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id sun8i_codec_of_match[] = {
> + { .compatible = "allwinner,sun8i-a33-codec" },
> + { .compatible = "allwinner,sun8i-a23-codec" },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, sun8i_codec_of_match);
> +
> +static struct platform_driver sun8i_codec_driver = {
> + .driver = {
> + .name = "sun8i-codec",
> + .owner = THIS_MODULE,
> + .of_match_table = sun8i_codec_of_match,
> + },
> + .probe = sun8i_codec_probe,
> + .remove = sun8i_codec_remove,
> +};
> +module_platform_driver(sun8i_codec_driver);
> +
> +MODULE_DESCRIPTION("Allwinner A33 (sun8i) codec driver");
> +MODULE_AUTHOR("huanxin<huanxin-jFKXxz0WcGyYHARAtoI1EgC/G2K4zDHf@public.gmane.org>");
> +MODULE_AUTHOR("Mylène Josserand <mylene.josserand-wi1+55ScJUtKEb57/3fJTGGXanvQGlWp@public.gmane.orgm>");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:sun8i-codec");
> --
> 2.9.3
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

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

* Re: [PATCH 06/14] ASoC: Add sun8i digital audio codec
@ 2016-10-05 10:19         ` Icenowy Zheng
  0 siblings, 0 replies; 170+ messages in thread
From: Icenowy Zheng @ 2016-10-05 10:19 UTC (permalink / raw)
  To: Mylène Josserand, vinod.koul, maxime.ripard, wens,
	mturquette, sboyd, lgirdwood, broonie, perex, tiwai, lee.jones,
	mark.rutland, robh+dt
  Cc: thomas.petazzoni, devicetree, alsa-devel, linux-kernel,
	linux-sunxi, alexandre.belloni, dmaengine, linux-clk,
	linux-arm-kernel



04.10.2016, 17:54, "Mylène Josserand" <mylene.josserand@free-electrons.com>:
> Add the digital sun8i audio codec which handles the base register
> (without DAI).
> The driver handles only the basic playback of the A33 codec, from
> the DAC to the headphones. All other features (microphone, capture,
> etc) will be added later.
>
> Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
> ---
>  sound/soc/sunxi/Kconfig | 9 +
>  sound/soc/sunxi/Makefile | 1 +
>  sound/soc/sunxi/sun8i-codec.c | 492 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 502 insertions(+)
>  create mode 100644 sound/soc/sunxi/sun8i-codec.c
>
> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
> index 7aee95a..9e287b0 100644
> --- a/sound/soc/sunxi/Kconfig
> +++ b/sound/soc/sunxi/Kconfig
> @@ -27,6 +27,15 @@ config SND_SUN4I_SPDIF
>            Say Y or M to add support for the S/PDIF audio block in the Allwinner
>            A10 and affiliated SoCs.
>
> +config SND_SUN8I_CODEC
> + tristate "Allwinner SUN8I audio codec"
> + select REGMAP_MMIO
> + help
> + This option enables the digital part of the internal audio codec for
> + Allwinner sun8i SoC.
> +
> + Say Y or M if you want to add sun8i digital audio codec support.
> +
>  config SND_SUN8I_CODEC_ANALOG
>          tristate "Allwinner SUN8I analog codec"
>          select REGMAP_MMIO
> diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
> index 241c0df..1da63d3 100644
> --- a/sound/soc/sunxi/Makefile
> +++ b/sound/soc/sunxi/Makefile
> @@ -1,4 +1,5 @@
>  obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
>  obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
>  obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
> +obj-$(CONFIG_SND_SUN8I_CODEC) += sun8i-codec.o
>  obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
> diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c
> new file mode 100644
> index 0000000..e157f89
> --- /dev/null
> +++ b/sound/soc/sunxi/sun8i-codec.c
> @@ -0,0 +1,492 @@
> +/*
> + * This driver supports the digital controls for the internal codec
> + * found in Allwinner's A33 and A23 SoCs.
> + *
> + * (C) Copyright 2010-2016
> + * Reuuimlla Technology Co., Ltd. <www.reuuimllatech.com>
> + * huangxin <huangxin@Reuuimllatech.com>
> + * Mylène Josserand <mylene.josserand@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/delay.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/regmap.h>
> +
> +#include <sound/pcm_params.h>
> +#include <sound/soc.h>
> +#include <sound/soc-dapm.h>
> +
> +/* CODEC_OFFSET represents the offset of the codec registers
> + * and not all the DAI registers
> + */
> +#define CODEC_OFFSET 0x200
> +#define CODEC_BASSADDRESS 0x01c22c00

I don't think this kind of absolute address should exist here...
It should exist in device tree...

> +#define SUN8I_SYSCLK_CTL (0x20c - CODEC_OFFSET)
> +#define SUN8I_SYSCLK_CTL_AIF1CLK_ENA (11)
> +#define SUN8I_SYSCLK_CTL_SYSCLK_ENA (3)
> +#define SUN8I_SYSCLK_CTL_SYSCLK_SRC (0)
> +#define SUN8I_MOD_CLK_ENA (0x210 - CODEC_OFFSET)
> +#define SUN8I_MOD_CLK_ENA_AIF1 (15)
> +#define SUN8I_MOD_CLK_ENA_DAC (2)
> +#define SUN8I_MOD_RST_CTL (0x214 - CODEC_OFFSET)
> +#define SUN8I_MOD_RST_CTL_AIF1 (15)
> +#define SUN8I_MOD_RST_CTL_DAC (2)
> +#define SUN8I_SYS_SR_CTRL (0x218 - CODEC_OFFSET)
> +#define SUN8I_SYS_SR_CTRL_AIF1_FS (12)
> +#define SUN8I_SYS_SR_CTRL_AIF2_FS (8)
> +#define SUN8I_AIF1CLK_CTRL (0x240 - CODEC_OFFSET)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_MSTR_MOD (15)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_INV (14)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV (13)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV (9)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV (6)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ (4)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT (2)
> +#define SUN8I_AIF1_DACDAT_CTRL (0x248 - CODEC_OFFSET)
> +#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA (15)
> +#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA (14)
> +#define SUN8I_DAC_DIG_CTRL (0x320 - CODEC_OFFSET)
> +#define SUN8I_DAC_DIG_CTRL_ENDA (15)
> +#define SUN8I_DAC_MXR_SRC (0x330 - CODEC_OFFSET)
> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA0L (15)
> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA1L (14)
> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF2DACL (13)
> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_ADCL (12)
> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA0R (11)
> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA1R (10)
> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF2DACR (9)
> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR (8)
> +
> +struct sun8i_codec {
> + struct device *dev;
> + struct regmap *regmap;
> + struct clk *clk_module;
> + struct clk *clk_apb;
> +};
> +
> +static int sun8i_codec_get_hw_rate(struct snd_pcm_hw_params *params)
> +{
> + unsigned int rate = params_rate(params);
> +
> + switch (rate) {
> + case 8000:
> + case 7350:
> + return 0x0;
> + case 11025:
> + return 0x1;
> + case 12000:
> + return 0x2;
> + case 16000:
> + return 0x3;
> + case 22050:
> + return 0x4;
> + case 24000:
> + return 0x5;
> + case 32000:
> + return 0x6;
> + case 44100:
> + return 0x7;
> + case 48000:
> + return 0x8;
> + case 96000:
> + return 0x9;
> + case 192000:
> + return 0xa;
> + default:
> + return -EINVAL;
> + }
> +}
> +
> +static int sun8i_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
> +{
> + struct sun8i_codec *scodec = snd_soc_codec_get_drvdata(dai->codec);
> + unsigned long value;
> +
> + /* clock masters */
> + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
> + case SND_SOC_DAIFMT_CBS_CFS: /* DAI Slave */
> + value = 0x0; /* Codec Master */
> + break;
> + case SND_SOC_DAIFMT_CBM_CFM: /* DAI Master */
> + value = 0x1; /* Codec Slave */
> + break;
> + default:
> + return -EINVAL;
> + }
> + regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
> + BIT(SUN8I_AIF1CLK_CTRL_AIF1_MSTR_MOD),
> + value << SUN8I_AIF1CLK_CTRL_AIF1_MSTR_MOD);
> +
> + /* clock inversion */
> + switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
> + case SND_SOC_DAIFMT_NB_NF: /* Normal */
> + value = 0x0;
> + break;
> + case SND_SOC_DAIFMT_IB_IF: /* Inversion */
> + value = 0x1;
> + break;
> + default:
> + return -EINVAL;
> + }
> + regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
> + BIT(SUN8I_AIF1CLK_CTRL_AIF1_BCLK_INV),
> + value << SUN8I_AIF1CLK_CTRL_AIF1_BCLK_INV);
> + regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
> + BIT(SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV),
> + value << SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV);
> +
> + /* DAI format */
> + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
> + case SND_SOC_DAIFMT_I2S:
> + value = 0x0;
> + break;
> + case SND_SOC_DAIFMT_LEFT_J:
> + value = 0x1;
> + break;
> + case SND_SOC_DAIFMT_RIGHT_J:
> + value = 0x2;
> + break;
> + case SND_SOC_DAIFMT_DSP_A:
> + case SND_SOC_DAIFMT_DSP_B:
> + value = 0x3;
> + break;
> + default:
> + return -EINVAL;
> + }
> + regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
> + BIT(SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT),
> + value << SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT);
> +
> + return 0;
> +}
> +
> +static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,
> + struct snd_pcm_hw_params *params,
> + struct snd_soc_dai *dai)
> +{
> + int rs_value = 0;
> + u32 bclk_lrck_div = 0, sample_resolution;
> + int sample_rate = 0;
> + struct sun8i_codec *scodec = snd_soc_codec_get_drvdata(dai->codec);
> +
> + switch (params_format(params)) {
> + case SNDRV_PCM_FORMAT_S16_LE:
> + sample_resolution = 16;
> + break;
> + case SNDRV_PCM_FORMAT_S20_3LE:
> + case SNDRV_PCM_FORMAT_S24_LE:
> + case SNDRV_PCM_FORMAT_S32_LE:
> + sample_resolution = 24;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + /*calculate word select bit*/
> + switch (sample_resolution) {
> + case 8:
> + rs_value = 0x0;
> + break;
> + case 16:
> + rs_value = 0x1;
> + break;
> + case 20:
> + rs_value = 0x2;
> + break;
> + case 24:
> + rs_value = 0x3;
> + break;
> + default:
> + break;
> + }
> + regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
> + 0x3 << SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ,
> + rs_value << SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ);
> +
> + /* calculate bclk_lrck_div Ratio */
> + bclk_lrck_div = sample_resolution * 2;
> + switch (bclk_lrck_div) {
> + case 16:
> + bclk_lrck_div = 0;
> + break;
> + case 32:
> + bclk_lrck_div = 1;
> + break;
> + case 64:
> + bclk_lrck_div = 2;
> + break;
> + case 128:
> + bclk_lrck_div = 3;
> + break;
> + case 256:
> + bclk_lrck_div = 4;
> + break;
> + default:
> + break;
> + }
> + regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
> + 0x7 << SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV,
> + bclk_lrck_div << SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV);
> +
> + sample_rate = sun8i_codec_get_hw_rate(params);
> + if (sample_rate < 0)
> + return sample_rate;
> +
> + regmap_update_bits(scodec->regmap, SUN8I_SYS_SR_CTRL,
> + 0xf << SUN8I_SYS_SR_CTRL_AIF1_FS,
> + sample_rate << SUN8I_SYS_SR_CTRL_AIF1_FS);
> + regmap_update_bits(scodec->regmap, SUN8I_SYS_SR_CTRL,
> + 0xf << SUN8I_SYS_SR_CTRL_AIF2_FS,
> + sample_rate << SUN8I_SYS_SR_CTRL_AIF2_FS);
> +
> + return 0;
> +}
> +
> +static const struct snd_kcontrol_new sun8i_output_left_mixer_controls[] = {
> + SOC_DAPM_SINGLE("LSlot 0", SUN8I_DAC_MXR_SRC,
> + SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA0L, 1, 0),
> + SOC_DAPM_SINGLE("LSlot 1", SUN8I_DAC_MXR_SRC,
> + SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA1L, 1, 0),
> + SOC_DAPM_SINGLE("DACL", SUN8I_DAC_MXR_SRC,
> + SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF2DACL, 1, 0),
> + SOC_DAPM_SINGLE("ADCL", SUN8I_DAC_MXR_SRC,
> + SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_ADCL, 1, 0),
> +};
> +
> +static const struct snd_kcontrol_new sun8i_output_right_mixer_controls[] = {
> + SOC_DAPM_SINGLE("RSlot 0", SUN8I_DAC_MXR_SRC,
> + SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA0R, 1, 0),
> + SOC_DAPM_SINGLE("RSlot 1", SUN8I_DAC_MXR_SRC,
> + SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA1R, 1, 0),
> + SOC_DAPM_SINGLE("DACR", SUN8I_DAC_MXR_SRC,
> + SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF2DACR, 1, 0),
> + SOC_DAPM_SINGLE("ADCR", SUN8I_DAC_MXR_SRC,
> + SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR, 1, 0),
> +};
> +
> +static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = {
> + /* Digital parts of the DACs */
> + SND_SOC_DAPM_SUPPLY("DAC", SUN8I_DAC_DIG_CTRL, SUN8I_DAC_DIG_CTRL_ENDA,
> + 0, NULL, 0),
> +
> + /* Analog DAC */
> + SND_SOC_DAPM_DAC("Left DAC", "Playback", SUN8I_AIF1_DACDAT_CTRL,
> + SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA, 0),
> + SND_SOC_DAPM_DAC("Right DAC", "Playback", SUN8I_AIF1_DACDAT_CTRL,
> + SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA, 0),
> +
> + /* DAC Mixers */
> + SND_SOC_DAPM_MIXER("Left DAC Mixer", SND_SOC_NOPM, 0, 0,
> + sun8i_output_left_mixer_controls,
> + ARRAY_SIZE(sun8i_output_left_mixer_controls)),
> + SND_SOC_DAPM_MIXER("Right DAC Mixer", SND_SOC_NOPM, 0, 0,
> + sun8i_output_right_mixer_controls,
> + ARRAY_SIZE(sun8i_output_right_mixer_controls)),
> +
> + /* Clocks */
> + SND_SOC_DAPM_SUPPLY("MODCLK AFI1", SUN8I_MOD_CLK_ENA,
> + SUN8I_MOD_CLK_ENA_AIF1, 0, NULL, 0),
> + SND_SOC_DAPM_SUPPLY("MODCLK DAC", SUN8I_MOD_CLK_ENA,
> + SUN8I_MOD_CLK_ENA_DAC, 0, NULL, 0),
> + SND_SOC_DAPM_SUPPLY("AIF1", SUN8I_SYSCLK_CTL,
> + SUN8I_SYSCLK_CTL_AIF1CLK_ENA, 0, NULL, 0),
> + SND_SOC_DAPM_SUPPLY("SYSCLK", SUN8I_SYSCLK_CTL,
> + SUN8I_SYSCLK_CTL_SYSCLK_ENA, 0, NULL, 0),
> +
> + SND_SOC_DAPM_SUPPLY("AIF1 PLL", SUN8I_SYSCLK_CTL, 0x9, 0, NULL, 0),
> + /* Inversion as 0=AIF1, 1=AIF2 */
> + SND_SOC_DAPM_SUPPLY("SYSCLK AIF1", SUN8I_SYSCLK_CTL,
> + SUN8I_SYSCLK_CTL_SYSCLK_SRC, 1, NULL, 0),
> +
> + /* Module reset */
> + SND_SOC_DAPM_SUPPLY("RST AIF1", SUN8I_MOD_RST_CTL,
> + SUN8I_MOD_RST_CTL_AIF1, 0, NULL, 0),
> + SND_SOC_DAPM_SUPPLY("RST DAC", SUN8I_MOD_RST_CTL,
> + SUN8I_MOD_RST_CTL_DAC, 0, NULL, 0),
> +
> + /* Headphone outputs */
> + SND_SOC_DAPM_OUTPUT("HPOUTL"),
> + SND_SOC_DAPM_OUTPUT("HPOUTR"),
> +
> +};
> +
> +static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = {
> + /* Clock Routes */
> + { "AIF1", NULL, "SYSCLK AIF1" },
> + { "AIF1 PLL", NULL, "AIF1" },
> + { "RST AIF1", NULL, "AIF1 PLL" },
> + { "MODCLK AFI1", NULL, "RST AIF1" },
> + { "DAC", NULL, "MODCLK AFI1" },
> +
> + { "RST DAC", NULL, "SYSCLK" },
> + { "MODCLK DAC", NULL, "RST DAC" },
> + { "DAC", NULL, "MODCLK DAC" },
> +
> + /* DAC Routes */
> + { "Left DAC", NULL, "DAC" },
> + { "Right DAC", NULL, "DAC" },
> +
> + /* DAC Mixer Routes */
> + { "Left DAC Mixer", "LSlot 0", "Left DAC"},
> + { "Right DAC Mixer", "RSlot 0", "Right DAC"},
> +
> + /* End of route : HP out */
> + { "HPOUTL", NULL, "Left DAC Mixer" },
> + { "HPOUTR", NULL, "Right DAC Mixer" },
> +};
> +
> +static struct snd_soc_dai_ops sun8i_codec_dai_ops = {
> + .hw_params = sun8i_codec_hw_params,
> + .set_fmt = sun8i_set_fmt,
> +};
> +
> +static struct snd_soc_dai_driver sun8i_codec_dai = {
> + .name = "sun8i",
> + /* playback capabilities */
> + .playback = {
> + .stream_name = "Playback",
> + .channels_min = 1,
> + .channels_max = 2,
> + .rates = SNDRV_PCM_RATE_8000_192000 |
> + SNDRV_PCM_RATE_KNOT,
> + .formats = SNDRV_PCM_FMTBIT_S8 |
> + SNDRV_PCM_FMTBIT_S16_LE |
> + SNDRV_PCM_FMTBIT_S18_3LE |
> + SNDRV_PCM_FMTBIT_S20_3LE |
> + SNDRV_PCM_FMTBIT_S24_LE |
> + SNDRV_PCM_FMTBIT_S32_LE,
> + },
> + /* pcm operations */
> + .ops = &sun8i_codec_dai_ops,
> +};
> +EXPORT_SYMBOL(sun8i_codec_dai);
> +
> +static int sun8i_soc_probe(struct snd_soc_codec *codec)
> +{
> + return 0;
> +}
> +
> +/* power down chip */
> +static int sun8i_soc_remove(struct snd_soc_codec *codec)
> +{
> + return 0;
> +}
> +
> +static struct snd_soc_codec_driver sun8i_soc_codec = {
> + .probe = sun8i_soc_probe,
> + .remove = sun8i_soc_remove,
> + .component_driver = {
> + .dapm_widgets = sun8i_codec_dapm_widgets,
> + .num_dapm_widgets = ARRAY_SIZE(sun8i_codec_dapm_widgets),
> + .dapm_routes = sun8i_codec_dapm_routes,
> + .num_dapm_routes = ARRAY_SIZE(sun8i_codec_dapm_routes),
> + },
> +};
> +
> +static const struct regmap_config sun8i_codec_regmap_config = {
> + .reg_bits = 32,
> + .reg_stride = 4,
> + .val_bits = 32,
> + .max_register = SUN8I_DAC_MXR_SRC,
> +};
> +
> +static int sun8i_codec_probe(struct platform_device *pdev)
> +{
> + struct resource *res_base;
> + struct sun8i_codec *scodec;
> + void __iomem *base;
> +
> + scodec = devm_kzalloc(&pdev->dev, sizeof(*scodec), GFP_KERNEL);
> + if (!scodec)
> + return -ENOMEM;
> +
> + scodec->dev = &pdev->dev;
> +
> + /* Get the clocks from the DT */
> + scodec->clk_module = devm_clk_get(&pdev->dev, "codec");
> + if (IS_ERR(scodec->clk_module)) {
> + dev_err(&pdev->dev, "Failed to get the module clock\n");
> + return PTR_ERR(scodec->clk_module);
> + }
> + if (clk_prepare_enable(scodec->clk_module))
> + pr_err("err:open failed;\n");
> +
> + scodec->clk_apb = devm_clk_get(&pdev->dev, "apb");
> + if (IS_ERR(scodec->clk_apb)) {
> + dev_err(&pdev->dev, "Failed to get the apb clock\n");
> + return PTR_ERR(scodec->clk_apb);
> + }
> + if (clk_prepare_enable(scodec->clk_apb))
> + pr_err("err:open failed;\n");
> +
> + /* Get base resources, registers and regmap */
> + res_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audio");
> + base = devm_ioremap_resource(&pdev->dev, res_base);
> + if (IS_ERR(base)) {
> + dev_err(&pdev->dev, "Failed to map the registers\n");
> + return PTR_ERR(base);
> + }
> +
> + scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
> + &sun8i_codec_regmap_config);
> + if (IS_ERR(scodec->regmap)) {
> + dev_err(&pdev->dev, "Failed to create our regmap\n");
> + return PTR_ERR(scodec->regmap);
> + }
> +
> + /* Set the codec data as driver data */
> + dev_set_drvdata(&pdev->dev, scodec);
> +
> + snd_soc_register_codec(&pdev->dev, &sun8i_soc_codec, &sun8i_codec_dai,
> + 1);
> +
> + return 0;
> +}
> +
> +static int sun8i_codec_remove(struct platform_device *pdev)
> +{
> + struct snd_soc_card *card = platform_get_drvdata(pdev);
> + struct sun8i_codec *scodec = snd_soc_card_get_drvdata(card);
> +
> + snd_soc_unregister_codec(&pdev->dev);
> + clk_disable_unprepare(scodec->clk_module);
> + clk_disable_unprepare(scodec->clk_apb);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id sun8i_codec_of_match[] = {
> + { .compatible = "allwinner,sun8i-a33-codec" },
> + { .compatible = "allwinner,sun8i-a23-codec" },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, sun8i_codec_of_match);
> +
> +static struct platform_driver sun8i_codec_driver = {
> + .driver = {
> + .name = "sun8i-codec",
> + .owner = THIS_MODULE,
> + .of_match_table = sun8i_codec_of_match,
> + },
> + .probe = sun8i_codec_probe,
> + .remove = sun8i_codec_remove,
> +};
> +module_platform_driver(sun8i_codec_driver);
> +
> +MODULE_DESCRIPTION("Allwinner A33 (sun8i) codec driver");
> +MODULE_AUTHOR("huanxin<huanxin@reuuimllatech.com>");
> +MODULE_AUTHOR("Mylène Josserand <mylene.josserand@free-electrons.com>");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:sun8i-codec");
> --
> 2.9.3
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 06/14] ASoC: Add sun8i digital audio codec
@ 2016-10-05 10:19         ` Icenowy Zheng
  0 siblings, 0 replies; 170+ messages in thread
From: Icenowy Zheng @ 2016-10-05 10:19 UTC (permalink / raw)
  To: linux-arm-kernel



04.10.2016, 17:54, "Myl?ne Josserand" <mylene.josserand@free-electrons.com>:
> Add the digital sun8i audio codec which handles the base register
> (without DAI).
> The driver handles only the basic playback of the A33 codec, from
> the DAC to the headphones. All other features (microphone, capture,
> etc) will be added later.
>
> Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
> ---
> ?sound/soc/sunxi/Kconfig | 9 +
> ?sound/soc/sunxi/Makefile | 1 +
> ?sound/soc/sunxi/sun8i-codec.c | 492 ++++++++++++++++++++++++++++++++++++++++++
> ?3 files changed, 502 insertions(+)
> ?create mode 100644 sound/soc/sunxi/sun8i-codec.c
>
> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
> index 7aee95a..9e287b0 100644
> --- a/sound/soc/sunxi/Kconfig
> +++ b/sound/soc/sunxi/Kconfig
> @@ -27,6 +27,15 @@ config SND_SUN4I_SPDIF
> ???????????Say Y or M to add support for the S/PDIF audio block in the Allwinner
> ???????????A10 and affiliated SoCs.
>
> +config SND_SUN8I_CODEC
> + tristate "Allwinner SUN8I audio codec"
> + select REGMAP_MMIO
> + help
> + This option enables the digital part of the internal audio codec for
> + Allwinner sun8i SoC.
> +
> + Say Y or M if you want to add sun8i digital audio codec support.
> +
> ?config SND_SUN8I_CODEC_ANALOG
> ?????????tristate "Allwinner SUN8I analog codec"
> ?????????select REGMAP_MMIO
> diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
> index 241c0df..1da63d3 100644
> --- a/sound/soc/sunxi/Makefile
> +++ b/sound/soc/sunxi/Makefile
> @@ -1,4 +1,5 @@
> ?obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o
> ?obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
> ?obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
> +obj-$(CONFIG_SND_SUN8I_CODEC) += sun8i-codec.o
> ?obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
> diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c
> new file mode 100644
> index 0000000..e157f89
> --- /dev/null
> +++ b/sound/soc/sunxi/sun8i-codec.c
> @@ -0,0 +1,492 @@
> +/*
> + * This driver supports the digital controls for the internal codec
> + * found in Allwinner's A33 and A23 SoCs.
> + *
> + * (C) Copyright 2010-2016
> + * Reuuimlla Technology Co., Ltd. <www.reuuimllatech.com>
> + * huangxin <huangxin@Reuuimllatech.com>
> + * Myl?ne Josserand <mylene.josserand@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/delay.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/regmap.h>
> +
> +#include <sound/pcm_params.h>
> +#include <sound/soc.h>
> +#include <sound/soc-dapm.h>
> +
> +/* CODEC_OFFSET represents the offset of the codec registers
> + * and not all the DAI registers
> + */
> +#define CODEC_OFFSET 0x200
> +#define CODEC_BASSADDRESS 0x01c22c00

I don't think this kind of absolute address should exist here...
It should exist in device tree...

> +#define SUN8I_SYSCLK_CTL (0x20c - CODEC_OFFSET)
> +#define SUN8I_SYSCLK_CTL_AIF1CLK_ENA (11)
> +#define SUN8I_SYSCLK_CTL_SYSCLK_ENA (3)
> +#define SUN8I_SYSCLK_CTL_SYSCLK_SRC (0)
> +#define SUN8I_MOD_CLK_ENA (0x210 - CODEC_OFFSET)
> +#define SUN8I_MOD_CLK_ENA_AIF1 (15)
> +#define SUN8I_MOD_CLK_ENA_DAC (2)
> +#define SUN8I_MOD_RST_CTL (0x214 - CODEC_OFFSET)
> +#define SUN8I_MOD_RST_CTL_AIF1 (15)
> +#define SUN8I_MOD_RST_CTL_DAC (2)
> +#define SUN8I_SYS_SR_CTRL (0x218 - CODEC_OFFSET)
> +#define SUN8I_SYS_SR_CTRL_AIF1_FS (12)
> +#define SUN8I_SYS_SR_CTRL_AIF2_FS (8)
> +#define SUN8I_AIF1CLK_CTRL (0x240 - CODEC_OFFSET)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_MSTR_MOD (15)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_INV (14)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV (13)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV (9)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV (6)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ (4)
> +#define SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT (2)
> +#define SUN8I_AIF1_DACDAT_CTRL (0x248 - CODEC_OFFSET)
> +#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA (15)
> +#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA (14)
> +#define SUN8I_DAC_DIG_CTRL (0x320 - CODEC_OFFSET)
> +#define SUN8I_DAC_DIG_CTRL_ENDA (15)
> +#define SUN8I_DAC_MXR_SRC (0x330 - CODEC_OFFSET)
> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA0L (15)
> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA1L (14)
> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF2DACL (13)
> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_ADCL (12)
> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA0R (11)
> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA1R (10)
> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF2DACR (9)
> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR (8)
> +
> +struct sun8i_codec {
> + struct device *dev;
> + struct regmap *regmap;
> + struct clk *clk_module;
> + struct clk *clk_apb;
> +};
> +
> +static int sun8i_codec_get_hw_rate(struct snd_pcm_hw_params *params)
> +{
> + unsigned int rate = params_rate(params);
> +
> + switch (rate) {
> + case 8000:
> + case 7350:
> + return 0x0;
> + case 11025:
> + return 0x1;
> + case 12000:
> + return 0x2;
> + case 16000:
> + return 0x3;
> + case 22050:
> + return 0x4;
> + case 24000:
> + return 0x5;
> + case 32000:
> + return 0x6;
> + case 44100:
> + return 0x7;
> + case 48000:
> + return 0x8;
> + case 96000:
> + return 0x9;
> + case 192000:
> + return 0xa;
> + default:
> + return -EINVAL;
> + }
> +}
> +
> +static int sun8i_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
> +{
> + struct sun8i_codec *scodec = snd_soc_codec_get_drvdata(dai->codec);
> + unsigned long value;
> +
> + /* clock masters */
> + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
> + case SND_SOC_DAIFMT_CBS_CFS: /* DAI Slave */
> + value = 0x0; /* Codec Master */
> + break;
> + case SND_SOC_DAIFMT_CBM_CFM: /* DAI Master */
> + value = 0x1; /* Codec Slave */
> + break;
> + default:
> + return -EINVAL;
> + }
> + regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
> + BIT(SUN8I_AIF1CLK_CTRL_AIF1_MSTR_MOD),
> + value << SUN8I_AIF1CLK_CTRL_AIF1_MSTR_MOD);
> +
> + /* clock inversion */
> + switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
> + case SND_SOC_DAIFMT_NB_NF: /* Normal */
> + value = 0x0;
> + break;
> + case SND_SOC_DAIFMT_IB_IF: /* Inversion */
> + value = 0x1;
> + break;
> + default:
> + return -EINVAL;
> + }
> + regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
> + BIT(SUN8I_AIF1CLK_CTRL_AIF1_BCLK_INV),
> + value << SUN8I_AIF1CLK_CTRL_AIF1_BCLK_INV);
> + regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
> + BIT(SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV),
> + value << SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV);
> +
> + /* DAI format */
> + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
> + case SND_SOC_DAIFMT_I2S:
> + value = 0x0;
> + break;
> + case SND_SOC_DAIFMT_LEFT_J:
> + value = 0x1;
> + break;
> + case SND_SOC_DAIFMT_RIGHT_J:
> + value = 0x2;
> + break;
> + case SND_SOC_DAIFMT_DSP_A:
> + case SND_SOC_DAIFMT_DSP_B:
> + value = 0x3;
> + break;
> + default:
> + return -EINVAL;
> + }
> + regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
> + BIT(SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT),
> + value << SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT);
> +
> + return 0;
> +}
> +
> +static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,
> + struct snd_pcm_hw_params *params,
> + struct snd_soc_dai *dai)
> +{
> + int rs_value = 0;
> + u32 bclk_lrck_div = 0, sample_resolution;
> + int sample_rate = 0;
> + struct sun8i_codec *scodec = snd_soc_codec_get_drvdata(dai->codec);
> +
> + switch (params_format(params)) {
> + case SNDRV_PCM_FORMAT_S16_LE:
> + sample_resolution = 16;
> + break;
> + case SNDRV_PCM_FORMAT_S20_3LE:
> + case SNDRV_PCM_FORMAT_S24_LE:
> + case SNDRV_PCM_FORMAT_S32_LE:
> + sample_resolution = 24;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + /*calculate word select bit*/
> + switch (sample_resolution) {
> + case 8:
> + rs_value = 0x0;
> + break;
> + case 16:
> + rs_value = 0x1;
> + break;
> + case 20:
> + rs_value = 0x2;
> + break;
> + case 24:
> + rs_value = 0x3;
> + break;
> + default:
> + break;
> + }
> + regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
> + 0x3 << SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ,
> + rs_value << SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ);
> +
> + /* calculate bclk_lrck_div Ratio */
> + bclk_lrck_div = sample_resolution * 2;
> + switch (bclk_lrck_div) {
> + case 16:
> + bclk_lrck_div = 0;
> + break;
> + case 32:
> + bclk_lrck_div = 1;
> + break;
> + case 64:
> + bclk_lrck_div = 2;
> + break;
> + case 128:
> + bclk_lrck_div = 3;
> + break;
> + case 256:
> + bclk_lrck_div = 4;
> + break;
> + default:
> + break;
> + }
> + regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
> + 0x7 << SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV,
> + bclk_lrck_div << SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV);
> +
> + sample_rate = sun8i_codec_get_hw_rate(params);
> + if (sample_rate < 0)
> + return sample_rate;
> +
> + regmap_update_bits(scodec->regmap, SUN8I_SYS_SR_CTRL,
> + 0xf << SUN8I_SYS_SR_CTRL_AIF1_FS,
> + sample_rate << SUN8I_SYS_SR_CTRL_AIF1_FS);
> + regmap_update_bits(scodec->regmap, SUN8I_SYS_SR_CTRL,
> + 0xf << SUN8I_SYS_SR_CTRL_AIF2_FS,
> + sample_rate << SUN8I_SYS_SR_CTRL_AIF2_FS);
> +
> + return 0;
> +}
> +
> +static const struct snd_kcontrol_new sun8i_output_left_mixer_controls[] = {
> + SOC_DAPM_SINGLE("LSlot 0", SUN8I_DAC_MXR_SRC,
> + SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA0L, 1, 0),
> + SOC_DAPM_SINGLE("LSlot 1", SUN8I_DAC_MXR_SRC,
> + SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA1L, 1, 0),
> + SOC_DAPM_SINGLE("DACL", SUN8I_DAC_MXR_SRC,
> + SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF2DACL, 1, 0),
> + SOC_DAPM_SINGLE("ADCL", SUN8I_DAC_MXR_SRC,
> + SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_ADCL, 1, 0),
> +};
> +
> +static const struct snd_kcontrol_new sun8i_output_right_mixer_controls[] = {
> + SOC_DAPM_SINGLE("RSlot 0", SUN8I_DAC_MXR_SRC,
> + SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA0R, 1, 0),
> + SOC_DAPM_SINGLE("RSlot 1", SUN8I_DAC_MXR_SRC,
> + SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA1R, 1, 0),
> + SOC_DAPM_SINGLE("DACR", SUN8I_DAC_MXR_SRC,
> + SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF2DACR, 1, 0),
> + SOC_DAPM_SINGLE("ADCR", SUN8I_DAC_MXR_SRC,
> + SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR, 1, 0),
> +};
> +
> +static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = {
> + /* Digital parts of the DACs */
> + SND_SOC_DAPM_SUPPLY("DAC", SUN8I_DAC_DIG_CTRL, SUN8I_DAC_DIG_CTRL_ENDA,
> + 0, NULL, 0),
> +
> + /* Analog DAC */
> + SND_SOC_DAPM_DAC("Left DAC", "Playback", SUN8I_AIF1_DACDAT_CTRL,
> + SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA, 0),
> + SND_SOC_DAPM_DAC("Right DAC", "Playback", SUN8I_AIF1_DACDAT_CTRL,
> + SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA, 0),
> +
> + /* DAC Mixers */
> + SND_SOC_DAPM_MIXER("Left DAC Mixer", SND_SOC_NOPM, 0, 0,
> + sun8i_output_left_mixer_controls,
> + ARRAY_SIZE(sun8i_output_left_mixer_controls)),
> + SND_SOC_DAPM_MIXER("Right DAC Mixer", SND_SOC_NOPM, 0, 0,
> + sun8i_output_right_mixer_controls,
> + ARRAY_SIZE(sun8i_output_right_mixer_controls)),
> +
> + /* Clocks */
> + SND_SOC_DAPM_SUPPLY("MODCLK AFI1", SUN8I_MOD_CLK_ENA,
> + SUN8I_MOD_CLK_ENA_AIF1, 0, NULL, 0),
> + SND_SOC_DAPM_SUPPLY("MODCLK DAC", SUN8I_MOD_CLK_ENA,
> + SUN8I_MOD_CLK_ENA_DAC, 0, NULL, 0),
> + SND_SOC_DAPM_SUPPLY("AIF1", SUN8I_SYSCLK_CTL,
> + SUN8I_SYSCLK_CTL_AIF1CLK_ENA, 0, NULL, 0),
> + SND_SOC_DAPM_SUPPLY("SYSCLK", SUN8I_SYSCLK_CTL,
> + SUN8I_SYSCLK_CTL_SYSCLK_ENA, 0, NULL, 0),
> +
> + SND_SOC_DAPM_SUPPLY("AIF1 PLL", SUN8I_SYSCLK_CTL, 0x9, 0, NULL, 0),
> + /* Inversion as 0=AIF1, 1=AIF2 */
> + SND_SOC_DAPM_SUPPLY("SYSCLK AIF1", SUN8I_SYSCLK_CTL,
> + SUN8I_SYSCLK_CTL_SYSCLK_SRC, 1, NULL, 0),
> +
> + /* Module reset */
> + SND_SOC_DAPM_SUPPLY("RST AIF1", SUN8I_MOD_RST_CTL,
> + SUN8I_MOD_RST_CTL_AIF1, 0, NULL, 0),
> + SND_SOC_DAPM_SUPPLY("RST DAC", SUN8I_MOD_RST_CTL,
> + SUN8I_MOD_RST_CTL_DAC, 0, NULL, 0),
> +
> + /* Headphone outputs */
> + SND_SOC_DAPM_OUTPUT("HPOUTL"),
> + SND_SOC_DAPM_OUTPUT("HPOUTR"),
> +
> +};
> +
> +static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = {
> + /* Clock Routes */
> + { "AIF1", NULL, "SYSCLK AIF1" },
> + { "AIF1 PLL", NULL, "AIF1" },
> + { "RST AIF1", NULL, "AIF1 PLL" },
> + { "MODCLK AFI1", NULL, "RST AIF1" },
> + { "DAC", NULL, "MODCLK AFI1" },
> +
> + { "RST DAC", NULL, "SYSCLK" },
> + { "MODCLK DAC", NULL, "RST DAC" },
> + { "DAC", NULL, "MODCLK DAC" },
> +
> + /* DAC Routes */
> + { "Left DAC", NULL, "DAC" },
> + { "Right DAC", NULL, "DAC" },
> +
> + /* DAC Mixer Routes */
> + { "Left DAC Mixer", "LSlot 0", "Left DAC"},
> + { "Right DAC Mixer", "RSlot 0", "Right DAC"},
> +
> + /* End of route : HP out */
> + { "HPOUTL", NULL, "Left DAC Mixer" },
> + { "HPOUTR", NULL, "Right DAC Mixer" },
> +};
> +
> +static struct snd_soc_dai_ops sun8i_codec_dai_ops = {
> + .hw_params = sun8i_codec_hw_params,
> + .set_fmt = sun8i_set_fmt,
> +};
> +
> +static struct snd_soc_dai_driver sun8i_codec_dai = {
> + .name = "sun8i",
> + /* playback capabilities */
> + .playback = {
> + .stream_name = "Playback",
> + .channels_min = 1,
> + .channels_max = 2,
> + .rates = SNDRV_PCM_RATE_8000_192000 |
> + SNDRV_PCM_RATE_KNOT,
> + .formats = SNDRV_PCM_FMTBIT_S8 |
> + SNDRV_PCM_FMTBIT_S16_LE |
> + SNDRV_PCM_FMTBIT_S18_3LE |
> + SNDRV_PCM_FMTBIT_S20_3LE |
> + SNDRV_PCM_FMTBIT_S24_LE |
> + SNDRV_PCM_FMTBIT_S32_LE,
> + },
> + /* pcm operations */
> + .ops = &sun8i_codec_dai_ops,
> +};
> +EXPORT_SYMBOL(sun8i_codec_dai);
> +
> +static int sun8i_soc_probe(struct snd_soc_codec *codec)
> +{
> + return 0;
> +}
> +
> +/* power down chip */
> +static int sun8i_soc_remove(struct snd_soc_codec *codec)
> +{
> + return 0;
> +}
> +
> +static struct snd_soc_codec_driver sun8i_soc_codec = {
> + .probe = sun8i_soc_probe,
> + .remove = sun8i_soc_remove,
> + .component_driver = {
> + .dapm_widgets = sun8i_codec_dapm_widgets,
> + .num_dapm_widgets = ARRAY_SIZE(sun8i_codec_dapm_widgets),
> + .dapm_routes = sun8i_codec_dapm_routes,
> + .num_dapm_routes = ARRAY_SIZE(sun8i_codec_dapm_routes),
> + },
> +};
> +
> +static const struct regmap_config sun8i_codec_regmap_config = {
> + .reg_bits = 32,
> + .reg_stride = 4,
> + .val_bits = 32,
> + .max_register = SUN8I_DAC_MXR_SRC,
> +};
> +
> +static int sun8i_codec_probe(struct platform_device *pdev)
> +{
> + struct resource *res_base;
> + struct sun8i_codec *scodec;
> + void __iomem *base;
> +
> + scodec = devm_kzalloc(&pdev->dev, sizeof(*scodec), GFP_KERNEL);
> + if (!scodec)
> + return -ENOMEM;
> +
> + scodec->dev = &pdev->dev;
> +
> + /* Get the clocks from the DT */
> + scodec->clk_module = devm_clk_get(&pdev->dev, "codec");
> + if (IS_ERR(scodec->clk_module)) {
> + dev_err(&pdev->dev, "Failed to get the module clock\n");
> + return PTR_ERR(scodec->clk_module);
> + }
> + if (clk_prepare_enable(scodec->clk_module))
> + pr_err("err:open failed;\n");
> +
> + scodec->clk_apb = devm_clk_get(&pdev->dev, "apb");
> + if (IS_ERR(scodec->clk_apb)) {
> + dev_err(&pdev->dev, "Failed to get the apb clock\n");
> + return PTR_ERR(scodec->clk_apb);
> + }
> + if (clk_prepare_enable(scodec->clk_apb))
> + pr_err("err:open failed;\n");
> +
> + /* Get base resources, registers and regmap */
> + res_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audio");
> + base = devm_ioremap_resource(&pdev->dev, res_base);
> + if (IS_ERR(base)) {
> + dev_err(&pdev->dev, "Failed to map the registers\n");
> + return PTR_ERR(base);
> + }
> +
> + scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
> + &sun8i_codec_regmap_config);
> + if (IS_ERR(scodec->regmap)) {
> + dev_err(&pdev->dev, "Failed to create our regmap\n");
> + return PTR_ERR(scodec->regmap);
> + }
> +
> + /* Set the codec data as driver data */
> + dev_set_drvdata(&pdev->dev, scodec);
> +
> + snd_soc_register_codec(&pdev->dev, &sun8i_soc_codec, &sun8i_codec_dai,
> + 1);
> +
> + return 0;
> +}
> +
> +static int sun8i_codec_remove(struct platform_device *pdev)
> +{
> + struct snd_soc_card *card = platform_get_drvdata(pdev);
> + struct sun8i_codec *scodec = snd_soc_card_get_drvdata(card);
> +
> + snd_soc_unregister_codec(&pdev->dev);
> + clk_disable_unprepare(scodec->clk_module);
> + clk_disable_unprepare(scodec->clk_apb);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id sun8i_codec_of_match[] = {
> + { .compatible = "allwinner,sun8i-a33-codec" },
> + { .compatible = "allwinner,sun8i-a23-codec" },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, sun8i_codec_of_match);
> +
> +static struct platform_driver sun8i_codec_driver = {
> + .driver = {
> + .name = "sun8i-codec",
> + .owner = THIS_MODULE,
> + .of_match_table = sun8i_codec_of_match,
> + },
> + .probe = sun8i_codec_probe,
> + .remove = sun8i_codec_remove,
> +};
> +module_platform_driver(sun8i_codec_driver);
> +
> +MODULE_DESCRIPTION("Allwinner A33 (sun8i) codec driver");
> +MODULE_AUTHOR("huanxin<huanxin@reuuimllatech.com>");
> +MODULE_AUTHOR("Myl?ne Josserand <mylene.josserand@free-electrons.com>");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:sun8i-codec");
> --
> 2.9.3
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 06/14] ASoC: Add sun8i digital audio codec
  2016-10-04 12:40       ` Thomas Petazzoni
@ 2016-10-05 11:54         ` Mylene Josserand
  -1 siblings, 0 replies; 170+ messages in thread
From: Mylene Josserand @ 2016-10-05 11:54 UTC (permalink / raw)
  To: Thomas Petazzoni
  Cc: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt,
	linux-kernel, dmaengine, linux-arm-kernel, linux-clk, alsa-devel,
	devicetree, linux-sunxi, alexandre.belloni

Hello,


On 04/10/2016 14:40, Thomas Petazzoni wrote:
> Hello,
>
> On Tue,  4 Oct 2016 11:46:19 +0200, Mylène Josserand wrote:
>> Add the digital sun8i audio codec which handles the base register
>> (without DAI).
>
> I'm not sure what you mean by "which handles the base register".

I wanted to explain that it is registers for audio codec and not PRCM 
ones. This is, maybe, unclear (and useless ?).

>
>> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
>> index 7aee95a..9e287b0 100644
>> --- a/sound/soc/sunxi/Kconfig
>> +++ b/sound/soc/sunxi/Kconfig
>> @@ -27,6 +27,15 @@ config SND_SUN4I_SPDIF
>>  	  Say Y or M to add support for the S/PDIF audio block in the Allwinner
>>  	  A10 and affiliated SoCs.
>>
>> +config SND_SUN8I_CODEC
>> +	tristate "Allwinner SUN8I audio codec"
>> +	select REGMAP_MMIO
>> +        help
>
> Indentation issue here, it should be intended with one tab, not spaces.
>
> You probably also want a "depends on OF" here.

Yes, thanks !

>
>> +/* CODEC_OFFSET represents the offset of the codec registers
>> + * and not all the DAI registers
>> + */
>
> This is not the proper comment style I believe for audio code, it
> should be:
>
> /*
>  * ...
>  */
>
>> +#define CODEC_OFFSET				0x200
>
> Do you really need this CODEC_OFFSET macro? Why not simply use directly
> the right offsets? I.e instead of:
>
>   #define SUN8I_SYSCLK_CTL			(0x20c - CODEC_OFFSET)
>
> use:
>
>   #define SUN8I_SYSCLK_CTL			0xc

I thought it could be easier to find registers using offset but I guess 
that register's names are enough.

>
>> +#define CODEC_BASSADDRESS			0x01c22c00
>
> This define is not used anywhere.

Yes, sorry, I forgot to remove it.

>
>> +#define SUN8I_SYSCLK_CTL			(0x20c - CODEC_OFFSET)
>> +#define SUN8I_SYSCLK_CTL_AIF1CLK_ENA		(11)
>> +#define SUN8I_SYSCLK_CTL_SYSCLK_ENA		(3)
>> +#define SUN8I_SYSCLK_CTL_SYSCLK_SRC		(0)
>
> Parenthesis around single values are not really useful.
>
>> +#define SUN8I_MOD_CLK_ENA			(0x210 - CODEC_OFFSET)
>> +#define SUN8I_MOD_CLK_ENA_AIF1			(15)
>> +#define SUN8I_MOD_CLK_ENA_DAC			(2)
>> +#define SUN8I_MOD_RST_CTL			(0x214 - CODEC_OFFSET)
>> +#define SUN8I_MOD_RST_CTL_AIF1			(15)
>> +#define SUN8I_MOD_RST_CTL_DAC			(2)
>> +#define SUN8I_SYS_SR_CTRL			(0x218 - CODEC_OFFSET)
>> +#define SUN8I_SYS_SR_CTRL_AIF1_FS		(12)
>> +#define SUN8I_SYS_SR_CTRL_AIF2_FS		(8)
>> +#define SUN8I_AIF1CLK_CTRL			(0x240 - CODEC_OFFSET)
>> +#define SUN8I_AIF1CLK_CTRL_AIF1_MSTR_MOD	(15)
>> +#define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_INV	(14)
>> +#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV	(13)
>> +#define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV	(9)
>> +#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV	(6)
>> +#define SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ	(4)
>> +#define SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT	(2)
>> +#define SUN8I_AIF1_DACDAT_CTRL			(0x248 - CODEC_OFFSET)
>> +#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA	(15)
>> +#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA	(14)
>> +#define SUN8I_DAC_DIG_CTRL			(0x320 - CODEC_OFFSET)
>> +#define SUN8I_DAC_DIG_CTRL_ENDA		(15)
>> +#define SUN8I_DAC_MXR_SRC			(0x330 - CODEC_OFFSET)
>> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA0L (15)
>> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA1L (14)
>> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF2DACL (13)
>> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_ADCL	(12)
>> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA0R (11)
>> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA1R (10)
>> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF2DACR (9)
>> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR	(8)
>
> Indentation of the value is not very clean for those last defines.
>
>> +static int sun8i_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
>> +{
>> +	struct sun8i_codec *scodec = snd_soc_codec_get_drvdata(dai->codec);
>> +	unsigned long value;
>
> I'm not sure "unsigned long" is a very good choice here, it's going to
> be a 64 bits integer on 64 bits platform. I'd suggest to use "u32",
> which also seems to be what's used in _set_fmt() function of the
> sun4i-i2s.c driver.

Agreed, thanks !

>
>
>> +static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,
>> +				 struct snd_pcm_hw_params *params,
>> +				 struct snd_soc_dai *dai)
>> +{
>> +	int rs_value  = 0;
>
> Two spaces before the = sign, not needed. Is the initialization to 0
> really needed? Also, this should be a u32.

ditto

>
>> +	regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
>> +			   0x3 << SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ,
>
> Maybe a #define value to replace the hardcoded 0x3 ?
>
>> +			   rs_value << SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ);
>> +
>> +	/* calculate bclk_lrck_div Ratio */
>> +	bclk_lrck_div = sample_resolution * 2;
>> +	switch (bclk_lrck_div) {
>> +	case 16:
>> +		bclk_lrck_div = 0;
>> +		break;
>> +	case 32:
>> +		bclk_lrck_div = 1;
>> +		break;
>> +	case 64:
>> +		bclk_lrck_div = 2;
>> +		break;
>> +	case 128:
>> +		bclk_lrck_div = 3;
>> +		break;
>> +	case 256:
>> +		bclk_lrck_div = 4;
>> +		break;
>
> This could quite easily be replaced by a formula, if you don't care
> about error checking:
>
> 	bclk_lrck_div = log2(bclk_lrck_div) - 4;
>
> Of course, if you care about error checking, this switch is nicer.
>
>> +	default:
>
> So there's no error checking if the value is not supported?

You are right. I guess it should return -EINVAL.

[snip]

>
>
>> +static struct snd_soc_dai_driver sun8i_codec_dai = {
>> +	.name = "sun8i",
>> +	/* playback capabilities */
>> +	.playback = {
>> +		.stream_name = "Playback",
>> +		.channels_min = 1,
>> +		.channels_max = 2,
>> +		.rates = SNDRV_PCM_RATE_8000_192000 |
>> +			SNDRV_PCM_RATE_KNOT,
>> +		.formats = SNDRV_PCM_FMTBIT_S8 |
>> +			SNDRV_PCM_FMTBIT_S16_LE |
>> +			SNDRV_PCM_FMTBIT_S18_3LE |
>> +			SNDRV_PCM_FMTBIT_S20_3LE |
>> +			SNDRV_PCM_FMTBIT_S24_LE |
>> +			SNDRV_PCM_FMTBIT_S32_LE,
>> +	},
>> +	/* pcm operations */
>> +	.ops = &sun8i_codec_dai_ops,
>> +};
>> +EXPORT_SYMBOL(sun8i_codec_dai);
>
> This EXPORT_SYMBOL looks wrong. First because it doesn't seem to be
> used outside of this module. And second because using EXPORT_SYMBOL on
> a function defined as static doesn't make much sense, as the "static"
> qualifier limits the visibility of the symbol to the current
> compilation unit.
>

Yes, sorry, I missed it from the clean-up of the original driver.

[snip]

>> +static int sun8i_codec_probe(struct platform_device *pdev)
>> +{
>> +	struct resource *res_base;
>> +	struct sun8i_codec *scodec;
>> +	void __iomem *base;
>> +
>> +	scodec = devm_kzalloc(&pdev->dev, sizeof(*scodec), GFP_KERNEL);
>> +	if (!scodec)
>> +		return -ENOMEM;
>> +
>> +	scodec->dev = &pdev->dev;
>> +
>> +	/* Get the clocks from the DT */
>> +	scodec->clk_module = devm_clk_get(&pdev->dev, "codec");
>> +	if (IS_ERR(scodec->clk_module)) {
>> +		dev_err(&pdev->dev, "Failed to get the module clock\n");
>> +		return PTR_ERR(scodec->clk_module);
>> +	}
>> +	if (clk_prepare_enable(scodec->clk_module))
>> +		pr_err("err:open failed;\n");
>
> Grr, pr_err, not good. Plus you want to return with an error from the
> probe() function.

Oh, sorry for that ugly use :(

>
>> +
>> +	scodec->clk_apb = devm_clk_get(&pdev->dev, "apb");
>> +	if (IS_ERR(scodec->clk_apb)) {
>> +		dev_err(&pdev->dev, "Failed to get the apb clock\n");
>> +		return PTR_ERR(scodec->clk_apb);
>> +	}
>> +	if (clk_prepare_enable(scodec->clk_apb))
>> +		pr_err("err:open failed;\n");
>
> Ditto. + unprepare/disable the previous clock.

[snip]

ack, thank you for the review!


-- 
Mylène Josserand, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* [PATCH 06/14] ASoC: Add sun8i digital audio codec
@ 2016-10-05 11:54         ` Mylene Josserand
  0 siblings, 0 replies; 170+ messages in thread
From: Mylene Josserand @ 2016-10-05 11:54 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,


On 04/10/2016 14:40, Thomas Petazzoni wrote:
> Hello,
>
> On Tue,  4 Oct 2016 11:46:19 +0200, Myl?ne Josserand wrote:
>> Add the digital sun8i audio codec which handles the base register
>> (without DAI).
>
> I'm not sure what you mean by "which handles the base register".

I wanted to explain that it is registers for audio codec and not PRCM 
ones. This is, maybe, unclear (and useless ?).

>
>> diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
>> index 7aee95a..9e287b0 100644
>> --- a/sound/soc/sunxi/Kconfig
>> +++ b/sound/soc/sunxi/Kconfig
>> @@ -27,6 +27,15 @@ config SND_SUN4I_SPDIF
>>  	  Say Y or M to add support for the S/PDIF audio block in the Allwinner
>>  	  A10 and affiliated SoCs.
>>
>> +config SND_SUN8I_CODEC
>> +	tristate "Allwinner SUN8I audio codec"
>> +	select REGMAP_MMIO
>> +        help
>
> Indentation issue here, it should be intended with one tab, not spaces.
>
> You probably also want a "depends on OF" here.

Yes, thanks !

>
>> +/* CODEC_OFFSET represents the offset of the codec registers
>> + * and not all the DAI registers
>> + */
>
> This is not the proper comment style I believe for audio code, it
> should be:
>
> /*
>  * ...
>  */
>
>> +#define CODEC_OFFSET				0x200
>
> Do you really need this CODEC_OFFSET macro? Why not simply use directly
> the right offsets? I.e instead of:
>
>   #define SUN8I_SYSCLK_CTL			(0x20c - CODEC_OFFSET)
>
> use:
>
>   #define SUN8I_SYSCLK_CTL			0xc

I thought it could be easier to find registers using offset but I guess 
that register's names are enough.

>
>> +#define CODEC_BASSADDRESS			0x01c22c00
>
> This define is not used anywhere.

Yes, sorry, I forgot to remove it.

>
>> +#define SUN8I_SYSCLK_CTL			(0x20c - CODEC_OFFSET)
>> +#define SUN8I_SYSCLK_CTL_AIF1CLK_ENA		(11)
>> +#define SUN8I_SYSCLK_CTL_SYSCLK_ENA		(3)
>> +#define SUN8I_SYSCLK_CTL_SYSCLK_SRC		(0)
>
> Parenthesis around single values are not really useful.
>
>> +#define SUN8I_MOD_CLK_ENA			(0x210 - CODEC_OFFSET)
>> +#define SUN8I_MOD_CLK_ENA_AIF1			(15)
>> +#define SUN8I_MOD_CLK_ENA_DAC			(2)
>> +#define SUN8I_MOD_RST_CTL			(0x214 - CODEC_OFFSET)
>> +#define SUN8I_MOD_RST_CTL_AIF1			(15)
>> +#define SUN8I_MOD_RST_CTL_DAC			(2)
>> +#define SUN8I_SYS_SR_CTRL			(0x218 - CODEC_OFFSET)
>> +#define SUN8I_SYS_SR_CTRL_AIF1_FS		(12)
>> +#define SUN8I_SYS_SR_CTRL_AIF2_FS		(8)
>> +#define SUN8I_AIF1CLK_CTRL			(0x240 - CODEC_OFFSET)
>> +#define SUN8I_AIF1CLK_CTRL_AIF1_MSTR_MOD	(15)
>> +#define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_INV	(14)
>> +#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV	(13)
>> +#define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV	(9)
>> +#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV	(6)
>> +#define SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ	(4)
>> +#define SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT	(2)
>> +#define SUN8I_AIF1_DACDAT_CTRL			(0x248 - CODEC_OFFSET)
>> +#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA	(15)
>> +#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA	(14)
>> +#define SUN8I_DAC_DIG_CTRL			(0x320 - CODEC_OFFSET)
>> +#define SUN8I_DAC_DIG_CTRL_ENDA		(15)
>> +#define SUN8I_DAC_MXR_SRC			(0x330 - CODEC_OFFSET)
>> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA0L (15)
>> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF1DA1L (14)
>> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_AIF2DACL (13)
>> +#define SUN8I_DAC_MXR_SRC_DACL_MXR_SRC_ADCL	(12)
>> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA0R (11)
>> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF1DA1R (10)
>> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_AIF2DACR (9)
>> +#define SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR	(8)
>
> Indentation of the value is not very clean for those last defines.
>
>> +static int sun8i_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
>> +{
>> +	struct sun8i_codec *scodec = snd_soc_codec_get_drvdata(dai->codec);
>> +	unsigned long value;
>
> I'm not sure "unsigned long" is a very good choice here, it's going to
> be a 64 bits integer on 64 bits platform. I'd suggest to use "u32",
> which also seems to be what's used in _set_fmt() function of the
> sun4i-i2s.c driver.

Agreed, thanks !

>
>
>> +static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,
>> +				 struct snd_pcm_hw_params *params,
>> +				 struct snd_soc_dai *dai)
>> +{
>> +	int rs_value  = 0;
>
> Two spaces before the = sign, not needed. Is the initialization to 0
> really needed? Also, this should be a u32.

ditto

>
>> +	regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
>> +			   0x3 << SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ,
>
> Maybe a #define value to replace the hardcoded 0x3 ?
>
>> +			   rs_value << SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ);
>> +
>> +	/* calculate bclk_lrck_div Ratio */
>> +	bclk_lrck_div = sample_resolution * 2;
>> +	switch (bclk_lrck_div) {
>> +	case 16:
>> +		bclk_lrck_div = 0;
>> +		break;
>> +	case 32:
>> +		bclk_lrck_div = 1;
>> +		break;
>> +	case 64:
>> +		bclk_lrck_div = 2;
>> +		break;
>> +	case 128:
>> +		bclk_lrck_div = 3;
>> +		break;
>> +	case 256:
>> +		bclk_lrck_div = 4;
>> +		break;
>
> This could quite easily be replaced by a formula, if you don't care
> about error checking:
>
> 	bclk_lrck_div = log2(bclk_lrck_div) - 4;
>
> Of course, if you care about error checking, this switch is nicer.
>
>> +	default:
>
> So there's no error checking if the value is not supported?

You are right. I guess it should return -EINVAL.

[snip]

>
>
>> +static struct snd_soc_dai_driver sun8i_codec_dai = {
>> +	.name = "sun8i",
>> +	/* playback capabilities */
>> +	.playback = {
>> +		.stream_name = "Playback",
>> +		.channels_min = 1,
>> +		.channels_max = 2,
>> +		.rates = SNDRV_PCM_RATE_8000_192000 |
>> +			SNDRV_PCM_RATE_KNOT,
>> +		.formats = SNDRV_PCM_FMTBIT_S8 |
>> +			SNDRV_PCM_FMTBIT_S16_LE |
>> +			SNDRV_PCM_FMTBIT_S18_3LE |
>> +			SNDRV_PCM_FMTBIT_S20_3LE |
>> +			SNDRV_PCM_FMTBIT_S24_LE |
>> +			SNDRV_PCM_FMTBIT_S32_LE,
>> +	},
>> +	/* pcm operations */
>> +	.ops = &sun8i_codec_dai_ops,
>> +};
>> +EXPORT_SYMBOL(sun8i_codec_dai);
>
> This EXPORT_SYMBOL looks wrong. First because it doesn't seem to be
> used outside of this module. And second because using EXPORT_SYMBOL on
> a function defined as static doesn't make much sense, as the "static"
> qualifier limits the visibility of the symbol to the current
> compilation unit.
>

Yes, sorry, I missed it from the clean-up of the original driver.

[snip]

>> +static int sun8i_codec_probe(struct platform_device *pdev)
>> +{
>> +	struct resource *res_base;
>> +	struct sun8i_codec *scodec;
>> +	void __iomem *base;
>> +
>> +	scodec = devm_kzalloc(&pdev->dev, sizeof(*scodec), GFP_KERNEL);
>> +	if (!scodec)
>> +		return -ENOMEM;
>> +
>> +	scodec->dev = &pdev->dev;
>> +
>> +	/* Get the clocks from the DT */
>> +	scodec->clk_module = devm_clk_get(&pdev->dev, "codec");
>> +	if (IS_ERR(scodec->clk_module)) {
>> +		dev_err(&pdev->dev, "Failed to get the module clock\n");
>> +		return PTR_ERR(scodec->clk_module);
>> +	}
>> +	if (clk_prepare_enable(scodec->clk_module))
>> +		pr_err("err:open failed;\n");
>
> Grr, pr_err, not good. Plus you want to return with an error from the
> probe() function.

Oh, sorry for that ugly use :(

>
>> +
>> +	scodec->clk_apb = devm_clk_get(&pdev->dev, "apb");
>> +	if (IS_ERR(scodec->clk_apb)) {
>> +		dev_err(&pdev->dev, "Failed to get the apb clock\n");
>> +		return PTR_ERR(scodec->clk_apb);
>> +	}
>> +	if (clk_prepare_enable(scodec->clk_apb))
>> +		pr_err("err:open failed;\n");
>
> Ditto. + unprepare/disable the previous clock.

[snip]

ack, thank you for the review!


-- 
Myl?ne Josserand, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* Re: [PATCH 08/14] dt-bindings: sound: Add sun8i analog codec documentation
  2016-10-05  2:59         ` Chen-Yu Tsai
  (?)
@ 2016-10-05 12:08           ` Mylene Josserand
  -1 siblings, 0 replies; 170+ messages in thread
From: Mylene Josserand @ 2016-10-05 12:08 UTC (permalink / raw)
  To: Chen-Yu Tsai, Maxime Ripard
  Cc: Vinod Koul, Michael Turquette, Stephen Boyd, Liam Girdwood,
	Mark Brown, Jaroslav Kysela, Takashi Iwai, Lee Jones,
	Mark Rutland, Rob Herring, linux-kernel, dmaengine,
	linux-arm-kernel, linux-clk, Linux-ALSA, devicetree, linux-sunxi,
	Thomas Petazzoni, Alexandre Belloni

Hello,


On 05/10/2016 04:59, Chen-Yu Tsai wrote:
> On Wed, Oct 5, 2016 at 12:24 AM, Maxime Ripard
> <maxime.ripard@free-electrons.com> wrote:
>> Hi,
>>
>> On Tue, Oct 04, 2016 at 11:46:21AM +0200, Mylène Josserand wrote:
>>> Add the documentation for dt-binding of the analog audiocodec
>>> driver for SUN8I SoC.
>>>
>>> Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
>>> ---
>>>  .../devicetree/bindings/sound/sun8i-codec-analog.txt | 20 ++++++++++++++++++++
>>>  1 file changed, 20 insertions(+)
>>>  create mode 100644 Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
>>>
>>> diff --git a/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
>>> new file mode 100644
>>> index 0000000..a03ec20
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
>>> @@ -0,0 +1,20 @@
>>> +* Allwinner A23/A33 Analog Codec
>>> +
>>> +This codec must be handled as a PRCM subnode.
>>
>> Like Mark was saying, you should probably reference the sun6i-prcm.txt
>> binding here


Okay, I will explain more how it works.


>>
>>> +Required properties:
>>> +- compatible: must be either "allwinner,sun8i-codec-analog"
>>
>> Our compatible prefix is <family>-<soc>, and using the older SoC that
>> introduced that block.
>>
>> In this case, that would be sun6i-a31, I think?
>
> sun6i-a31s actually, but a31s has extra line out controls,
> so the right one would be sun8i-a23. Both are listed in my
> original driver.


It is noted.

Thanks!


-- 
Mylène Josserand, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* Re: [PATCH 08/14] dt-bindings: sound: Add sun8i analog codec documentation
@ 2016-10-05 12:08           ` Mylene Josserand
  0 siblings, 0 replies; 170+ messages in thread
From: Mylene Josserand @ 2016-10-05 12:08 UTC (permalink / raw)
  To: Chen-Yu Tsai, Maxime Ripard
  Cc: Vinod Koul, Michael Turquette, Stephen Boyd, Liam Girdwood,
	Mark Brown, Jaroslav Kysela, Takashi Iwai, Lee Jones,
	Mark Rutland, Rob Herring, linux-kernel, dmaengine,
	linux-arm-kernel, linux-clk, Linux-ALSA, devicetree, linux-sunxi,
	Thomas Petazzoni, Alexandre Belloni

Hello,


On 05/10/2016 04:59, Chen-Yu Tsai wrote:
> On Wed, Oct 5, 2016 at 12:24 AM, Maxime Ripard
> <maxime.ripard@free-electrons.com> wrote:
>> Hi,
>>
>> On Tue, Oct 04, 2016 at 11:46:21AM +0200, Mylène Josserand wrote:
>>> Add the documentation for dt-binding of the analog audiocodec
>>> driver for SUN8I SoC.
>>>
>>> Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
>>> ---
>>>  .../devicetree/bindings/sound/sun8i-codec-analog.txt | 20 ++++++++++++++++++++
>>>  1 file changed, 20 insertions(+)
>>>  create mode 100644 Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
>>>
>>> diff --git a/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
>>> new file mode 100644
>>> index 0000000..a03ec20
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
>>> @@ -0,0 +1,20 @@
>>> +* Allwinner A23/A33 Analog Codec
>>> +
>>> +This codec must be handled as a PRCM subnode.
>>
>> Like Mark was saying, you should probably reference the sun6i-prcm.txt
>> binding here


Okay, I will explain more how it works.


>>
>>> +Required properties:
>>> +- compatible: must be either "allwinner,sun8i-codec-analog"
>>
>> Our compatible prefix is <family>-<soc>, and using the older SoC that
>> introduced that block.
>>
>> In this case, that would be sun6i-a31, I think?
>
> sun6i-a31s actually, but a31s has extra line out controls,
> so the right one would be sun8i-a23. Both are listed in my
> original driver.


It is noted.

Thanks!


-- 
Mylène Josserand, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* [PATCH 08/14] dt-bindings: sound: Add sun8i analog codec documentation
@ 2016-10-05 12:08           ` Mylene Josserand
  0 siblings, 0 replies; 170+ messages in thread
From: Mylene Josserand @ 2016-10-05 12:08 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,


On 05/10/2016 04:59, Chen-Yu Tsai wrote:
> On Wed, Oct 5, 2016 at 12:24 AM, Maxime Ripard
> <maxime.ripard@free-electrons.com> wrote:
>> Hi,
>>
>> On Tue, Oct 04, 2016 at 11:46:21AM +0200, Myl?ne Josserand wrote:
>>> Add the documentation for dt-binding of the analog audiocodec
>>> driver for SUN8I SoC.
>>>
>>> Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
>>> ---
>>>  .../devicetree/bindings/sound/sun8i-codec-analog.txt | 20 ++++++++++++++++++++
>>>  1 file changed, 20 insertions(+)
>>>  create mode 100644 Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
>>>
>>> diff --git a/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
>>> new file mode 100644
>>> index 0000000..a03ec20
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
>>> @@ -0,0 +1,20 @@
>>> +* Allwinner A23/A33 Analog Codec
>>> +
>>> +This codec must be handled as a PRCM subnode.
>>
>> Like Mark was saying, you should probably reference the sun6i-prcm.txt
>> binding here


Okay, I will explain more how it works.


>>
>>> +Required properties:
>>> +- compatible: must be either "allwinner,sun8i-codec-analog"
>>
>> Our compatible prefix is <family>-<soc>, and using the older SoC that
>> introduced that block.
>>
>> In this case, that would be sun6i-a31, I think?
>
> sun6i-a31s actually, but a31s has extra line out controls,
> so the right one would be sun8i-a23. Both are listed in my
> original driver.


It is noted.

Thanks!


-- 
Myl?ne Josserand, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

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

* Re: [PATCH 06/14] ASoC: Add sun8i digital audio codec
  2016-10-04 16:15       ` Maxime Ripard
  (?)
@ 2016-10-06 16:06         ` Icenowy Zheng
  -1 siblings, 0 replies; 170+ messages in thread
From: Icenowy Zheng @ 2016-10-06 16:06 UTC (permalink / raw)
  To: Maxime Ripard, Mylène Josserand
  Cc: mark.rutland-5wv7dgnIgG8, devicetree-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	mturquette-rdvid1DuHRBWk0Htik3J/w, tiwai-IBi9RG/b67k,
	sboyd-sgV2jX0FEOL9JmXXK+q4OQ, lgirdwood-Re5JQEeQqe8AvxtiuMwx3w,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, perex-/Fr2/VpizcU,
	wens-jdAy2FN1RRM, broonie-DgEjT+Ai2ygdnm+yROfE0A,
	alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	dmaengine-u79uwXL29TY76Z2rM5mHXA@public.gmane.org



05.10.2016, 00:20, "Maxime Ripard" <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>:
> Hi,
>
>>  +static const struct of_device_id sun8i_codec_of_match[] = {
>>  + { .compatible = "allwinner,sun8i-a33-codec" },
>>  + { .compatible = "allwinner,sun8i-a23-codec" },
>
> I thought that the A23 and A33 had different codecs? In that case, it
> wouldn't be a good assumption to make

Yes.

>
>>  + {}
>>  +};
>>  +MODULE_DEVICE_TABLE(of, sun8i_codec_of_match);
>>  +
>>  +static struct platform_driver sun8i_codec_driver = {
>>  + .driver = {
>>  + .name = "sun8i-codec",
>>  + .owner = THIS_MODULE,
>>  + .of_match_table = sun8i_codec_of_match,
>>  + },
>>  + .probe = sun8i_codec_probe,
>>  + .remove = sun8i_codec_remove,
>>  +};
>>  +module_platform_driver(sun8i_codec_driver);
>>  +
>>  +MODULE_DESCRIPTION("Allwinner A33 (sun8i) codec driver");
>>  +MODULE_AUTHOR("huanxin<huanxin-jFKXxz0WcGyYHARAtoI1EgC/G2K4zDHf@public.gmane.org>");
>
> Those obfuscated email adresses are not really helpful :)

This kind of email addresses  are kept in many places in mainline kernel.

e.g. drivers/mmc/host/sunxi-mmc.c have 'Aaron Maoye <leafy.myeh@reuuimllatech.com>'

>
> Thanks,
> Maxime
>
> --
> Maxime Ripard, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com
> ,
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

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

* Re: [PATCH 06/14] ASoC: Add sun8i digital audio codec
@ 2016-10-06 16:06         ` Icenowy Zheng
  0 siblings, 0 replies; 170+ messages in thread
From: Icenowy Zheng @ 2016-10-06 16:06 UTC (permalink / raw)
  To: Maxime Ripard, Mylène Josserand
  Cc: mark.rutland, devicetree, alsa-devel, linux-sunxi,
	thomas.petazzoni, vinod.koul, linux-kernel, mturquette, tiwai,
	sboyd, lgirdwood, robh+dt, perex, wens, broonie,
	alexandre.belloni, dmaengine, lee.jones, linux-clk,
	linux-arm-kernel



05.10.2016, 00:20, "Maxime Ripard" <maxime.ripard@free-electrons.com>:
> Hi,
>
>>  +static const struct of_device_id sun8i_codec_of_match[] = {
>>  + { .compatible = "allwinner,sun8i-a33-codec" },
>>  + { .compatible = "allwinner,sun8i-a23-codec" },
>
> I thought that the A23 and A33 had different codecs? In that case, it
> wouldn't be a good assumption to make

Yes.

>
>>  + {}
>>  +};
>>  +MODULE_DEVICE_TABLE(of, sun8i_codec_of_match);
>>  +
>>  +static struct platform_driver sun8i_codec_driver = {
>>  + .driver = {
>>  + .name = "sun8i-codec",
>>  + .owner = THIS_MODULE,
>>  + .of_match_table = sun8i_codec_of_match,
>>  + },
>>  + .probe = sun8i_codec_probe,
>>  + .remove = sun8i_codec_remove,
>>  +};
>>  +module_platform_driver(sun8i_codec_driver);
>>  +
>>  +MODULE_DESCRIPTION("Allwinner A33 (sun8i) codec driver");
>>  +MODULE_AUTHOR("huanxin<huanxin@reuuimllatech.com>");
>
> Those obfuscated email adresses are not really helpful :)

This kind of email addresses  are kept in many places in mainline kernel.

e.g. drivers/mmc/host/sunxi-mmc.c have 'Aaron Maoye <leafy.myeh@reuuimllatech.com>'

>
> Thanks,
> Maxime
>
> --
> Maxime Ripard, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com
> ,
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 06/14] ASoC: Add sun8i digital audio codec
@ 2016-10-06 16:06         ` Icenowy Zheng
  0 siblings, 0 replies; 170+ messages in thread
From: Icenowy Zheng @ 2016-10-06 16:06 UTC (permalink / raw)
  To: linux-arm-kernel



05.10.2016, 00:20, "Maxime Ripard" <maxime.ripard@free-electrons.com>:
> Hi,
>
>> ?+static const struct of_device_id sun8i_codec_of_match[] = {
>> ?+ { .compatible = "allwinner,sun8i-a33-codec" },
>> ?+ { .compatible = "allwinner,sun8i-a23-codec" },
>
> I thought that the A23 and A33 had different codecs? In that case, it
> wouldn't be a good assumption to make

Yes.

>
>> ?+ {}
>> ?+};
>> ?+MODULE_DEVICE_TABLE(of, sun8i_codec_of_match);
>> ?+
>> ?+static struct platform_driver sun8i_codec_driver = {
>> ?+ .driver = {
>> ?+ .name = "sun8i-codec",
>> ?+ .owner = THIS_MODULE,
>> ?+ .of_match_table = sun8i_codec_of_match,
>> ?+ },
>> ?+ .probe = sun8i_codec_probe,
>> ?+ .remove = sun8i_codec_remove,
>> ?+};
>> ?+module_platform_driver(sun8i_codec_driver);
>> ?+
>> ?+MODULE_DESCRIPTION("Allwinner A33 (sun8i) codec driver");
>> ?+MODULE_AUTHOR("huanxin<huanxin@reuuimllatech.com>");
>
> Those obfuscated email adresses are not really helpful :)

This kind of email addresses  are kept in many places in mainline kernel.

e.g. drivers/mmc/host/sunxi-mmc.c have 'Aaron Maoye <leafy.myeh@reuuimllatech.com>'

>
> Thanks,
> Maxime
>
> --
> Maxime Ripard, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com
> ,
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 06/14] ASoC: Add sun8i digital audio codec
@ 2016-10-06 18:23           ` Alexandre Belloni
  0 siblings, 0 replies; 170+ messages in thread
From: Alexandre Belloni @ 2016-10-06 18:23 UTC (permalink / raw)
  To: Icenowy Zheng
  Cc: Maxime Ripard, Mylène Josserand, mark.rutland, devicetree,
	alsa-devel, linux-sunxi, thomas.petazzoni, vinod.koul,
	linux-kernel, mturquette, tiwai, sboyd, lgirdwood, robh+dt,
	perex, wens, broonie, dmaengine, lee.jones, linux-clk,
	linux-arm-kernel

On 07/10/2016 at 00:06:57 +0800, Icenowy Zheng wrote :
> 05.10.2016, 00:20, "Maxime Ripard" <maxime.ripard@free-electrons.com>:
> > Hi,
> >
> >>  +static const struct of_device_id sun8i_codec_of_match[] = {
> >>  + { .compatible = "allwinner,sun8i-a33-codec" },
> >>  + { .compatible = "allwinner,sun8i-a23-codec" },
> >
> > I thought that the A23 and A33 had different codecs? In that case, it
> > wouldn't be a good assumption to make
> 
> Yes.
> 
> >
> >>  + {}
> >>  +};
> >>  +MODULE_DEVICE_TABLE(of, sun8i_codec_of_match);
> >>  +
> >>  +static struct platform_driver sun8i_codec_driver = {
> >>  + .driver = {
> >>  + .name = "sun8i-codec",
> >>  + .owner = THIS_MODULE,
> >>  + .of_match_table = sun8i_codec_of_match,
> >>  + },
> >>  + .probe = sun8i_codec_probe,
> >>  + .remove = sun8i_codec_remove,
> >>  +};
> >>  +module_platform_driver(sun8i_codec_driver);
> >>  +
> >>  +MODULE_DESCRIPTION("Allwinner A33 (sun8i) codec driver");
> >>  +MODULE_AUTHOR("huanxin<huanxin@reuuimllatech.com>");
> >
> > Those obfuscated email adresses are not really helpful :)
> 
> This kind of email addresses  are kept in many places in mainline kernel.
> 
> e.g. drivers/mmc/host/sunxi-mmc.c have 'Aaron Maoye <leafy.myeh@reuuimllatech.com>'
> 

Well, that is only one place and it is a comment, not in the
MODULE_AUTHOR macro. I would agree that it is not useful to have a stale
email address in MODULE_AUTHOR.

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

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

* Re: [PATCH 06/14] ASoC: Add sun8i digital audio codec
@ 2016-10-06 18:23           ` Alexandre Belloni
  0 siblings, 0 replies; 170+ messages in thread
From: Alexandre Belloni @ 2016-10-06 18:23 UTC (permalink / raw)
  To: Icenowy Zheng
  Cc: Maxime Ripard, Mylène Josserand, mark.rutland-5wv7dgnIgG8,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	mturquette-rdvid1DuHRBWk0Htik3J/w, tiwai-IBi9RG/b67k,
	sboyd-sgV2jX0FEOL9JmXXK+q4OQ, lgirdwood-Re5JQEeQqe8AvxtiuMwx3w,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, perex-/Fr2/VpizcU,
	wens-jdAy2FN1RRM, broonie-DgEjT+Ai2ygdnm+yROfE0A

On 07/10/2016 at 00:06:57 +0800, Icenowy Zheng wrote :
> 05.10.2016, 00:20, "Maxime Ripard" <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>:
> > Hi,
> >
> >>  +static const struct of_device_id sun8i_codec_of_match[] = {
> >>  + { .compatible = "allwinner,sun8i-a33-codec" },
> >>  + { .compatible = "allwinner,sun8i-a23-codec" },
> >
> > I thought that the A23 and A33 had different codecs? In that case, it
> > wouldn't be a good assumption to make
> 
> Yes.
> 
> >
> >>  + {}
> >>  +};
> >>  +MODULE_DEVICE_TABLE(of, sun8i_codec_of_match);
> >>  +
> >>  +static struct platform_driver sun8i_codec_driver = {
> >>  + .driver = {
> >>  + .name = "sun8i-codec",
> >>  + .owner = THIS_MODULE,
> >>  + .of_match_table = sun8i_codec_of_match,
> >>  + },
> >>  + .probe = sun8i_codec_probe,
> >>  + .remove = sun8i_codec_remove,
> >>  +};
> >>  +module_platform_driver(sun8i_codec_driver);
> >>  +
> >>  +MODULE_DESCRIPTION("Allwinner A33 (sun8i) codec driver");
> >>  +MODULE_AUTHOR("huanxin<huanxin-jFKXxz0WcGyYHARAtoI1EgC/G2K4zDHf@public.gmane.org>");
> >
> > Those obfuscated email adresses are not really helpful :)
> 
> This kind of email addresses  are kept in many places in mainline kernel.
> 
> e.g. drivers/mmc/host/sunxi-mmc.c have 'Aaron Maoye <leafy.myeh@reuuimllatech.com>'
> 

Well, that is only one place and it is a comment, not in the
MODULE_AUTHOR macro. I would agree that it is not useful to have a stale
email address in MODULE_AUTHOR.

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

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

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

* [PATCH 06/14] ASoC: Add sun8i digital audio codec
@ 2016-10-06 18:23           ` Alexandre Belloni
  0 siblings, 0 replies; 170+ messages in thread
From: Alexandre Belloni @ 2016-10-06 18:23 UTC (permalink / raw)
  To: linux-arm-kernel

On 07/10/2016 at 00:06:57 +0800, Icenowy Zheng wrote :
> 05.10.2016, 00:20, "Maxime Ripard" <maxime.ripard@free-electrons.com>:
> > Hi,
> >
> >> ?+static const struct of_device_id sun8i_codec_of_match[] = {
> >> ?+ { .compatible = "allwinner,sun8i-a33-codec" },
> >> ?+ { .compatible = "allwinner,sun8i-a23-codec" },
> >
> > I thought that the A23 and A33 had different codecs? In that case, it
> > wouldn't be a good assumption to make
> 
> Yes.
> 
> >
> >> ?+ {}
> >> ?+};
> >> ?+MODULE_DEVICE_TABLE(of, sun8i_codec_of_match);
> >> ?+
> >> ?+static struct platform_driver sun8i_codec_driver = {
> >> ?+ .driver = {
> >> ?+ .name = "sun8i-codec",
> >> ?+ .owner = THIS_MODULE,
> >> ?+ .of_match_table = sun8i_codec_of_match,
> >> ?+ },
> >> ?+ .probe = sun8i_codec_probe,
> >> ?+ .remove = sun8i_codec_remove,
> >> ?+};
> >> ?+module_platform_driver(sun8i_codec_driver);
> >> ?+
> >> ?+MODULE_DESCRIPTION("Allwinner A33 (sun8i) codec driver");
> >> ?+MODULE_AUTHOR("huanxin<huanxin@reuuimllatech.com>");
> >
> > Those obfuscated email adresses are not really helpful :)
> 
> This kind of email addresses  are kept in many places in mainline kernel.
> 
> e.g. drivers/mmc/host/sunxi-mmc.c have 'Aaron Maoye <leafy.myeh@reuuimllatech.com>'
> 

Well, that is only one place and it is a comment, not in the
MODULE_AUTHOR macro. I would agree that it is not useful to have a stale
email address in MODULE_AUTHOR.

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

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

* Re: [PATCH 00/14] ASoc: sunxi: Add Allwinner A33 codec driver
  2016-10-04  9:46 ` Mylène Josserand
  (?)
@ 2016-10-07  8:35     ` Icenowy Zheng
  -1 siblings, 0 replies; 170+ messages in thread
From: Icenowy Zheng @ 2016-10-07  8:35 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8, wens-jdAy2FN1RRM,
	mturquette-rdvid1DuHRBWk0Htik3J/w, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A,
	perex-/Fr2/VpizcU, tiwai-IBi9RG/b67k,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Tue,  4 Oct 2016 11:46:13 +0200
Mylène Josserand <mylene.josserand-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:

> Hi everyone,
> 
> 
> This patchset add the audio codec for Allwinner A33 (sun8i) SoC.
> 
> It adds different drivers:
>    - sun8i-codec-analog (patch 4): This driver implements the analog
> part of the audio codec. The analog part is handled in PRCM registers
> so this driver must be added as prcm's subnode (patch 5).
>    - sun8i-codec (patch 6): This driver implements the digital part
> of the A33 codec.
>    - sun8i (patch 7): This driver implements a sound card for A33.
>    It links the DAI and the audio codec. The analog codec driver is
> handled as an "aux_device".
> 
> The DAI for this codec is the same than for A20: "sun4i-i2s".
> The digital codec code is coming from Allwinner's BSP (after some
> cleanup and DAPM conversion) [1]
> The analog codec driver is coming from Chen-Yu Tsai's driver [2]
> with some modifications (such as read/write regmap functions).
> 
> Currently, all the drivers handle only the playback feature.
> The other ones (such as capture) and all other interfaces except
> headphone are not supported.
> 
> These drivers are functional except for one issue. When playing a
> sound for the first time, a short delay can be noticed. On a second
> play (right after), the sound is played correctly. If we wait a short
> time (~5 sec), the delay is back.
> There is the same behavior for left/right channel. On the first
> time, a left sound is played on the left channel but in the second
> time, the sound will be played on wrong channel.
> 
> These issues will be fixed in a second time. Is someone have
> suggestions about it?
> 
> Examples of amixer commands:
> 	amixer set 'Headphone' 75%
> 	amixer set 'Headphone' on
> 	amixer set 'DAC' on
> 	amixer set 'Right DAC Mixer RSlot 0' on
> 	amixer set 'Left DAC Mixer LSlot 0' on
> 	amixer set 'DAC Reversed Right' on
> 	amixer set 'DAC Reversed Left' on
> 
> It was tested on Parrot and Sinlinx board where device tree's
> modifications are added (patch 11 to 14).

I tested it on my iNet D978 Rev2 board (dts available in linux-next now)
Directly output audio from mpg123 to the audio codec failed, with
noises appear in the earphone. (And the mpg123 process terminated very
fast, seems that the bitrate become wrong)

However, paplay works well with the decoded wav file, and ```mpg123 -o
pulse``` works properly.

> 
> Thank you in advance,
> Best regards,
> 
> [1]:
> https://github.com/allwinner-zh/linux-3.4-sunxi/blob/master/sound/soc/sunxi/audiocodec/sun8iw5_sndcodec.c
> [2]: https://github.com/wens/linux/tree/a31-audio
> 
> Mylène Josserand (14):
>   dma: sun6i-dma: Add burst case of 4
>   clk: ccu-sun8i-a33: Add CLK_SET_RATE_PARENT to ac-dig
>   ASoC: sun4i-i2s: Add apb reset
>   ASoC: Add sun8i analog codec driver
>   mfd: sun6i-prcm: Add sun8i analog codec as subnode
>   ASoC: Add sun8i digital audio codec
>   ASoC: Add sun8i audio card
>   dt-bindings: sound: Add sun8i analog codec documentation
>   dt-bindings: sound: Add sun8i codec documentation
>   dt-bindings: sound: Add sun8i audio card documentation
>   ARM: dts: sun8i: Add analog codec on prcm node
>   ARM: dts: sun8i: Add audio codec, dai and card for A33
>   ARM: dts: sun8i: parrot: Enable audio nodes
>   ARM: dts: sun8i: sinlinx: Enable audio nodes
> 
>  .../devicetree/bindings/sound/sun8i-audio.txt      |  17 +
>  .../bindings/sound/sun8i-codec-analog.txt          |  20 +
>  .../devicetree/bindings/sound/sun8i-codec.txt      |  24 +
>  arch/arm/boot/dts/sun8i-a23-a33.dtsi               |   7 +
>  arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts     |   8 +
>  arch/arm/boot/dts/sun8i-a33.dtsi                   |  33 ++
>  arch/arm/boot/dts/sun8i-r16-parrot.dts             |   8 +
>  drivers/clk/sunxi-ng/ccu-sun8i-a33.c               |   2 +-
>  drivers/dma/sun6i-dma.c                            |   2 +
>  drivers/mfd/sun6i-prcm.c                           |  16 +
>  sound/soc/sunxi/Kconfig                            |  30 ++
>  sound/soc/sunxi/Makefile                           |   3 +
>  sound/soc/sunxi/sun4i-i2s.c                        |  16 +-
>  sound/soc/sunxi/sun8i-codec-analog.c               | 305
> +++++++++++++ sound/soc/sunxi/sun8i-codec.c                      |
> 492 +++++++++++++++++++++
> sound/soc/sunxi/sun8i.c                            | 101 +++++ 16
> files changed, 1082 insertions(+), 2 deletions(-) create mode 100644
> Documentation/devicetree/bindings/sound/sun8i-audio.txt create mode
> 100644 Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
> create mode 100644
> Documentation/devicetree/bindings/sound/sun8i-codec.txt create mode
> 100644 sound/soc/sunxi/sun8i-codec-analog.c create mode 100644
> sound/soc/sunxi/sun8i-codec.c create mode 100644
> sound/soc/sunxi/sun8i.c
> 

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

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

* Re: [PATCH 00/14] ASoc: sunxi: Add Allwinner A33 codec driver
@ 2016-10-07  8:35     ` Icenowy Zheng
  0 siblings, 0 replies; 170+ messages in thread
From: Icenowy Zheng @ 2016-10-07  8:35 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, lee.jones, mark.rutland, robh+dt,
	thomas.petazzoni, devicetree, alsa-devel, linux-kernel,
	linux-sunxi, alexandre.belloni, dmaengine, linux-clk,
	linux-arm-kernel

On Tue,  4 Oct 2016 11:46:13 +0200
Myl=C3=A8ne Josserand <mylene.josserand@free-electrons.com> wrote:

> Hi everyone,
>=20
>=20
> This patchset add the audio codec for Allwinner A33 (sun8i) SoC.
>=20
> It adds different drivers:
>    - sun8i-codec-analog (patch 4): This driver implements the analog
> part of the audio codec. The analog part is handled in PRCM registers
> so this driver must be added as prcm's subnode (patch 5).
>    - sun8i-codec (patch 6): This driver implements the digital part
> of the A33 codec.
>    - sun8i (patch 7): This driver implements a sound card for A33.
>    It links the DAI and the audio codec. The analog codec driver is
> handled as an "aux_device".
>=20
> The DAI for this codec is the same than for A20: "sun4i-i2s".
> The digital codec code is coming from Allwinner's BSP (after some
> cleanup and DAPM conversion) [1]
> The analog codec driver is coming from Chen-Yu Tsai's driver [2]
> with some modifications (such as read/write regmap functions).
>=20
> Currently, all the drivers handle only the playback feature.
> The other ones (such as capture) and all other interfaces except
> headphone are not supported.
>=20
> These drivers are functional except for one issue. When playing a
> sound for the first time, a short delay can be noticed. On a second
> play (right after), the sound is played correctly. If we wait a short
> time (~5 sec), the delay is back.
> There is the same behavior for left/right channel. On the first
> time, a left sound is played on the left channel but in the second
> time, the sound will be played on wrong channel.
>=20
> These issues will be fixed in a second time. Is someone have
> suggestions about it?
>=20
> Examples of amixer commands:
> 	amixer set 'Headphone' 75%
> 	amixer set 'Headphone' on
> 	amixer set 'DAC' on
> 	amixer set 'Right DAC Mixer RSlot 0' on
> 	amixer set 'Left DAC Mixer LSlot 0' on
> 	amixer set 'DAC Reversed Right' on
> 	amixer set 'DAC Reversed Left' on
>=20
> It was tested on Parrot and Sinlinx board where device tree's
> modifications are added (patch 11 to 14).

I tested it on my iNet D978 Rev2 board (dts available in linux-next now)
Directly output audio from mpg123 to the audio codec failed, with
noises appear in the earphone. (And the mpg123 process terminated very
fast, seems that the bitrate become wrong)

However, paplay works well with the decoded wav file, and ```mpg123 -o
pulse``` works properly.

>=20
> Thank you in advance,
> Best regards,
>=20
> [1]:
> https://github.com/allwinner-zh/linux-3.4-sunxi/blob/master/sound/soc/sun=
xi/audiocodec/sun8iw5_sndcodec.c
> [2]: https://github.com/wens/linux/tree/a31-audio
>=20
> Myl=C3=A8ne Josserand (14):
>   dma: sun6i-dma: Add burst case of 4
>   clk: ccu-sun8i-a33: Add CLK_SET_RATE_PARENT to ac-dig
>   ASoC: sun4i-i2s: Add apb reset
>   ASoC: Add sun8i analog codec driver
>   mfd: sun6i-prcm: Add sun8i analog codec as subnode
>   ASoC: Add sun8i digital audio codec
>   ASoC: Add sun8i audio card
>   dt-bindings: sound: Add sun8i analog codec documentation
>   dt-bindings: sound: Add sun8i codec documentation
>   dt-bindings: sound: Add sun8i audio card documentation
>   ARM: dts: sun8i: Add analog codec on prcm node
>   ARM: dts: sun8i: Add audio codec, dai and card for A33
>   ARM: dts: sun8i: parrot: Enable audio nodes
>   ARM: dts: sun8i: sinlinx: Enable audio nodes
>=20
>  .../devicetree/bindings/sound/sun8i-audio.txt      |  17 +
>  .../bindings/sound/sun8i-codec-analog.txt          |  20 +
>  .../devicetree/bindings/sound/sun8i-codec.txt      |  24 +
>  arch/arm/boot/dts/sun8i-a23-a33.dtsi               |   7 +
>  arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts     |   8 +
>  arch/arm/boot/dts/sun8i-a33.dtsi                   |  33 ++
>  arch/arm/boot/dts/sun8i-r16-parrot.dts             |   8 +
>  drivers/clk/sunxi-ng/ccu-sun8i-a33.c               |   2 +-
>  drivers/dma/sun6i-dma.c                            |   2 +
>  drivers/mfd/sun6i-prcm.c                           |  16 +
>  sound/soc/sunxi/Kconfig                            |  30 ++
>  sound/soc/sunxi/Makefile                           |   3 +
>  sound/soc/sunxi/sun4i-i2s.c                        |  16 +-
>  sound/soc/sunxi/sun8i-codec-analog.c               | 305
> +++++++++++++ sound/soc/sunxi/sun8i-codec.c                      |
> 492 +++++++++++++++++++++
> sound/soc/sunxi/sun8i.c                            | 101 +++++ 16
> files changed, 1082 insertions(+), 2 deletions(-) create mode 100644
> Documentation/devicetree/bindings/sound/sun8i-audio.txt create mode
> 100644 Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
> create mode 100644
> Documentation/devicetree/bindings/sound/sun8i-codec.txt create mode
> 100644 sound/soc/sunxi/sun8i-codec-analog.c create mode 100644
> sound/soc/sunxi/sun8i-codec.c create mode 100644
> sound/soc/sunxi/sun8i.c
>=20

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

* [PATCH 00/14] ASoc: sunxi: Add Allwinner A33 codec driver
@ 2016-10-07  8:35     ` Icenowy Zheng
  0 siblings, 0 replies; 170+ messages in thread
From: Icenowy Zheng @ 2016-10-07  8:35 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue,  4 Oct 2016 11:46:13 +0200
Myl?ne Josserand <mylene.josserand@free-electrons.com> wrote:

> Hi everyone,
> 
> 
> This patchset add the audio codec for Allwinner A33 (sun8i) SoC.
> 
> It adds different drivers:
>    - sun8i-codec-analog (patch 4): This driver implements the analog
> part of the audio codec. The analog part is handled in PRCM registers
> so this driver must be added as prcm's subnode (patch 5).
>    - sun8i-codec (patch 6): This driver implements the digital part
> of the A33 codec.
>    - sun8i (patch 7): This driver implements a sound card for A33.
>    It links the DAI and the audio codec. The analog codec driver is
> handled as an "aux_device".
> 
> The DAI for this codec is the same than for A20: "sun4i-i2s".
> The digital codec code is coming from Allwinner's BSP (after some
> cleanup and DAPM conversion) [1]
> The analog codec driver is coming from Chen-Yu Tsai's driver [2]
> with some modifications (such as read/write regmap functions).
> 
> Currently, all the drivers handle only the playback feature.
> The other ones (such as capture) and all other interfaces except
> headphone are not supported.
> 
> These drivers are functional except for one issue. When playing a
> sound for the first time, a short delay can be noticed. On a second
> play (right after), the sound is played correctly. If we wait a short
> time (~5 sec), the delay is back.
> There is the same behavior for left/right channel. On the first
> time, a left sound is played on the left channel but in the second
> time, the sound will be played on wrong channel.
> 
> These issues will be fixed in a second time. Is someone have
> suggestions about it?
> 
> Examples of amixer commands:
> 	amixer set 'Headphone' 75%
> 	amixer set 'Headphone' on
> 	amixer set 'DAC' on
> 	amixer set 'Right DAC Mixer RSlot 0' on
> 	amixer set 'Left DAC Mixer LSlot 0' on
> 	amixer set 'DAC Reversed Right' on
> 	amixer set 'DAC Reversed Left' on
> 
> It was tested on Parrot and Sinlinx board where device tree's
> modifications are added (patch 11 to 14).

I tested it on my iNet D978 Rev2 board (dts available in linux-next now)
Directly output audio from mpg123 to the audio codec failed, with
noises appear in the earphone. (And the mpg123 process terminated very
fast, seems that the bitrate become wrong)

However, paplay works well with the decoded wav file, and ```mpg123 -o
pulse``` works properly.

> 
> Thank you in advance,
> Best regards,
> 
> [1]:
> https://github.com/allwinner-zh/linux-3.4-sunxi/blob/master/sound/soc/sunxi/audiocodec/sun8iw5_sndcodec.c
> [2]: https://github.com/wens/linux/tree/a31-audio
> 
> Myl?ne Josserand (14):
>   dma: sun6i-dma: Add burst case of 4
>   clk: ccu-sun8i-a33: Add CLK_SET_RATE_PARENT to ac-dig
>   ASoC: sun4i-i2s: Add apb reset
>   ASoC: Add sun8i analog codec driver
>   mfd: sun6i-prcm: Add sun8i analog codec as subnode
>   ASoC: Add sun8i digital audio codec
>   ASoC: Add sun8i audio card
>   dt-bindings: sound: Add sun8i analog codec documentation
>   dt-bindings: sound: Add sun8i codec documentation
>   dt-bindings: sound: Add sun8i audio card documentation
>   ARM: dts: sun8i: Add analog codec on prcm node
>   ARM: dts: sun8i: Add audio codec, dai and card for A33
>   ARM: dts: sun8i: parrot: Enable audio nodes
>   ARM: dts: sun8i: sinlinx: Enable audio nodes
> 
>  .../devicetree/bindings/sound/sun8i-audio.txt      |  17 +
>  .../bindings/sound/sun8i-codec-analog.txt          |  20 +
>  .../devicetree/bindings/sound/sun8i-codec.txt      |  24 +
>  arch/arm/boot/dts/sun8i-a23-a33.dtsi               |   7 +
>  arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts     |   8 +
>  arch/arm/boot/dts/sun8i-a33.dtsi                   |  33 ++
>  arch/arm/boot/dts/sun8i-r16-parrot.dts             |   8 +
>  drivers/clk/sunxi-ng/ccu-sun8i-a33.c               |   2 +-
>  drivers/dma/sun6i-dma.c                            |   2 +
>  drivers/mfd/sun6i-prcm.c                           |  16 +
>  sound/soc/sunxi/Kconfig                            |  30 ++
>  sound/soc/sunxi/Makefile                           |   3 +
>  sound/soc/sunxi/sun4i-i2s.c                        |  16 +-
>  sound/soc/sunxi/sun8i-codec-analog.c               | 305
> +++++++++++++ sound/soc/sunxi/sun8i-codec.c                      |
> 492 +++++++++++++++++++++
> sound/soc/sunxi/sun8i.c                            | 101 +++++ 16
> files changed, 1082 insertions(+), 2 deletions(-) create mode 100644
> Documentation/devicetree/bindings/sound/sun8i-audio.txt create mode
> 100644 Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
> create mode 100644
> Documentation/devicetree/bindings/sound/sun8i-codec.txt create mode
> 100644 sound/soc/sunxi/sun8i-codec-analog.c create mode 100644
> sound/soc/sunxi/sun8i-codec.c create mode 100644
> sound/soc/sunxi/sun8i.c
> 

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

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
  2016-10-04 16:55         ` Maxime Ripard
  (?)
  (?)
@ 2016-10-23 16:31           ` Jean-Francois Moine
  -1 siblings, 0 replies; 170+ messages in thread
From: Jean-Francois Moine @ 2016-10-23 16:31 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Mylène Josserand, vinod.koul, wens, mturquette, sboyd,
	lgirdwood, broonie, perex, tiwai, lee.jones, mark.rutland,
	robh+dt, thomas.petazzoni, devicetree, alsa-devel, linux-kernel,
	linux-sunxi, alexandre.belloni, dmaengine, linux-clk,
	linux-arm-kernel

On Tue, 4 Oct 2016 18:55:54 +0200
Maxime Ripard <maxime.ripard@free-electrons.com> wrote:

> On Tue, Oct 04, 2016 at 12:40:11PM +0200, Jean-Francois Moine wrote:
> > On Tue,  4 Oct 2016 11:46:14 +0200
> > Mylène Josserand <mylene.josserand@free-electrons.com> wrote:
> > 
> > > Add the case of a burst of 4 which is handled by the SoC.
> > > 
> > > Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
> > > ---
> > >  drivers/dma/sun6i-dma.c | 2 ++
> > >  1 file changed, 2 insertions(+)
> > > 
> > > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> > > index 8346199..0485204 100644
> > > --- a/drivers/dma/sun6i-dma.c
> > > +++ b/drivers/dma/sun6i-dma.c
> > > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
> > >  	switch (maxburst) {
> > >  	case 1:
> > >  		return 0;
> > > +	case 4:
> > > +		return 1;
> > >  	case 8:
> > >  		return 2;
> > >  	default:
> > > -- 
> > > 2.9.3
> > 
> > This patch has already been rejected by Maxime in the threads
> > 	http://www.spinics.net/lists/dmaengine/msg08610.html
> > and
> > 	http://www.spinics.net/lists/dmaengine/msg08719.html
> > 
> > I hope you will find the way he wants for this maxburst to be added.
> 
> I was talking about something along these lines (not tested):

I wonder why you don't submit this yourself.

> -------8<---------
> diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> index 83461994e418..573ac4608293 100644
> --- a/drivers/dma/sun6i-dma.c
> +++ b/drivers/dma/sun6i-dma.c
> @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
>  	switch (maxburst) {
>  	case 1:
>  		return 0;
> +	case 4:
> +		return 1;
>  	case 8:
>  		return 2;
>  	default:
> @@ -1110,11 +1112,19 @@ static int sun6i_dma_probe(struct platform_device *pdev)
>  	sdc->slave.dst_addr_widths		= BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
>  						  BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
>  						  BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
> +	sdc->slave.dst_bursts			= BIT(1) | BIT(8);
> +	sdc->slave.src_bursts			= BIT(1) | BIT(8);
>  	sdc->slave.directions			= BIT(DMA_DEV_TO_MEM) |
>  						  BIT(DMA_MEM_TO_DEV);
>  	sdc->slave.residue_granularity		= DMA_RESIDUE_GRANULARITY_BURST;
>  	sdc->slave.dev = &pdev->dev;
>  
> +	if (of_device_is_compatible(pdev->dev.of_node,
> +				    "allwinner,sun8i-h3-dma")) {
> +		sdc->slave.dst_bursts |= BIT(4);
> +		sdc->slave.src_bursts |= BIT(4);
> +	}
> +
>  	sdc->pchans = devm_kcalloc(&pdev->dev, sdc->cfg->nr_max_channels,
>  				   sizeof(struct sun6i_pchan), GFP_KERNEL);
>  	if (!sdc->pchans)
> diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
> index cc535a478bae..f7bbec24bb58 100644
> --- a/include/linux/dmaengine.h
> +++ b/include/linux/dmaengine.h
> @@ -673,6 +673,8 @@ struct dma_filter {
>   * 	each type of direction, the dma controller should fill (1 <<
>   * 	<TYPE>) and same should be checked by controller as well
>   * @max_burst: max burst capability per-transfer
> + * @dst_bursts: bitfield of the available burst sizes for the destination
> + * @src_bursts: bitfield of the available burst sizes for the source

You did not define dst_bursts nor src_bursts.

>   * @residue_granularity: granularity of the transfer residue reported
>   *	by tx_status
>   * @device_alloc_chan_resources: allocate resources and return the
> @@ -800,6 +802,14 @@ struct dma_device {
>  static inline int dmaengine_slave_config(struct dma_chan *chan,
>  					  struct dma_slave_config *config)
>  {
> +	if (config->src_maxburst && config->device->src_bursts &&
> +	    !(BIT(config->src_maxburst) & config->device->src_bursts))

The maxburst may be as big as 4Kibytes, then, I am not sure that this
code will work!

> +		return -EINVAL;
> +
> +	if (config->dst_maxburst && config->device->dst_bursts &&
> +	    !(BIT(config->dst_maxburst) & config->device->dst_bursts))
> +		return -EINVAL;
> +
>  	if (chan->device->device_config)
>  		return chan->device->device_config(chan, config);
> -------8<------------ 

Yes, I know that the burst size is always a power of 2.
The best way to check it would be to change the {src,dts}_maxburst to a
bitmap of the possible bursts as 0x0d for 1,4 and 8 bytes. But this
asks for a lot of changes...

-- 
Ken ar c'hentañ	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

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

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-10-23 16:31           ` Jean-Francois Moine
  0 siblings, 0 replies; 170+ messages in thread
From: Jean-Francois Moine @ 2016-10-23 16:31 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Mylène Josserand, vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
	wens-jdAy2FN1RRM, mturquette-rdvid1DuHRBWk0Htik3J/w,
	sboyd-sgV2jX0FEOL9JmXXK+q4OQ, lgirdwood-Re5JQEeQqe8AvxtiuMwx3w,
	broonie-DgEjT+Ai2ygdnm+yROfE0A, perex-/Fr2/VpizcU,
	tiwai-IBi9RG/b67k, lee.jones-QSEj5FYQhm4dnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Tue, 4 Oct 2016 18:55:54 +0200
Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:

> On Tue, Oct 04, 2016 at 12:40:11PM +0200, Jean-Francois Moine wrote:
> > On Tue,  4 Oct 2016 11:46:14 +0200
> > Mylène Josserand <mylene.josserand-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> > 
> > > Add the case of a burst of 4 which is handled by the SoC.
> > > 
> > > Signed-off-by: Mylène Josserand <mylene.josserand-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> > > ---
> > >  drivers/dma/sun6i-dma.c | 2 ++
> > >  1 file changed, 2 insertions(+)
> > > 
> > > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> > > index 8346199..0485204 100644
> > > --- a/drivers/dma/sun6i-dma.c
> > > +++ b/drivers/dma/sun6i-dma.c
> > > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
> > >  	switch (maxburst) {
> > >  	case 1:
> > >  		return 0;
> > > +	case 4:
> > > +		return 1;
> > >  	case 8:
> > >  		return 2;
> > >  	default:
> > > -- 
> > > 2.9.3
> > 
> > This patch has already been rejected by Maxime in the threads
> > 	http://www.spinics.net/lists/dmaengine/msg08610.html
> > and
> > 	http://www.spinics.net/lists/dmaengine/msg08719.html
> > 
> > I hope you will find the way he wants for this maxburst to be added.
> 
> I was talking about something along these lines (not tested):

I wonder why you don't submit this yourself.

> -------8<---------
> diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> index 83461994e418..573ac4608293 100644
> --- a/drivers/dma/sun6i-dma.c
> +++ b/drivers/dma/sun6i-dma.c
> @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
>  	switch (maxburst) {
>  	case 1:
>  		return 0;
> +	case 4:
> +		return 1;
>  	case 8:
>  		return 2;
>  	default:
> @@ -1110,11 +1112,19 @@ static int sun6i_dma_probe(struct platform_device *pdev)
>  	sdc->slave.dst_addr_widths		= BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
>  						  BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
>  						  BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
> +	sdc->slave.dst_bursts			= BIT(1) | BIT(8);
> +	sdc->slave.src_bursts			= BIT(1) | BIT(8);
>  	sdc->slave.directions			= BIT(DMA_DEV_TO_MEM) |
>  						  BIT(DMA_MEM_TO_DEV);
>  	sdc->slave.residue_granularity		= DMA_RESIDUE_GRANULARITY_BURST;
>  	sdc->slave.dev = &pdev->dev;
>  
> +	if (of_device_is_compatible(pdev->dev.of_node,
> +				    "allwinner,sun8i-h3-dma")) {
> +		sdc->slave.dst_bursts |= BIT(4);
> +		sdc->slave.src_bursts |= BIT(4);
> +	}
> +
>  	sdc->pchans = devm_kcalloc(&pdev->dev, sdc->cfg->nr_max_channels,
>  				   sizeof(struct sun6i_pchan), GFP_KERNEL);
>  	if (!sdc->pchans)
> diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
> index cc535a478bae..f7bbec24bb58 100644
> --- a/include/linux/dmaengine.h
> +++ b/include/linux/dmaengine.h
> @@ -673,6 +673,8 @@ struct dma_filter {
>   * 	each type of direction, the dma controller should fill (1 <<
>   * 	<TYPE>) and same should be checked by controller as well
>   * @max_burst: max burst capability per-transfer
> + * @dst_bursts: bitfield of the available burst sizes for the destination
> + * @src_bursts: bitfield of the available burst sizes for the source

You did not define dst_bursts nor src_bursts.

>   * @residue_granularity: granularity of the transfer residue reported
>   *	by tx_status
>   * @device_alloc_chan_resources: allocate resources and return the
> @@ -800,6 +802,14 @@ struct dma_device {
>  static inline int dmaengine_slave_config(struct dma_chan *chan,
>  					  struct dma_slave_config *config)
>  {
> +	if (config->src_maxburst && config->device->src_bursts &&
> +	    !(BIT(config->src_maxburst) & config->device->src_bursts))

The maxburst may be as big as 4Kibytes, then, I am not sure that this
code will work!

> +		return -EINVAL;
> +
> +	if (config->dst_maxburst && config->device->dst_bursts &&
> +	    !(BIT(config->dst_maxburst) & config->device->dst_bursts))
> +		return -EINVAL;
> +
>  	if (chan->device->device_config)
>  		return chan->device->device_config(chan, config);
> -------8<------------ 

Yes, I know that the burst size is always a power of 2.
The best way to check it would be to change the {src,dts}_maxburst to a
bitmap of the possible bursts as 0x0d for 1,4 and 8 bytes. But this
asks for a lot of changes...

-- 
Ken ar c'hentañ	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/
--
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] 170+ messages in thread

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-10-23 16:31           ` Jean-Francois Moine
  0 siblings, 0 replies; 170+ messages in thread
From: Jean-Francois Moine @ 2016-10-23 16:31 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Mylène Josserand, vinod.koul, wens, mturquette, sboyd,
	lgirdwood, broonie, perex, tiwai, lee.jones, mark.rutland,
	robh+dt, thomas.petazzoni, devicetree, alsa-devel, linux-kernel,
	linux-sunxi, alexandre.belloni, dmaengine, linux-clk,
	linux-arm-kernel

On Tue, 4 Oct 2016 18:55:54 +0200
Maxime Ripard <maxime.ripard@free-electrons.com> wrote:

> On Tue, Oct 04, 2016 at 12:40:11PM +0200, Jean-Francois Moine wrote:
> > On Tue,  4 Oct 2016 11:46:14 +0200
> > Myl=E8ne Josserand <mylene.josserand@free-electrons.com> wrote:
> >=20
> > > Add the case of a burst of 4 which is handled by the SoC.
> > >=20
> > > Signed-off-by: Myl=E8ne Josserand <mylene.josserand@free-electrons.co=
m>
> > > ---
> > >  drivers/dma/sun6i-dma.c | 2 ++
> > >  1 file changed, 2 insertions(+)
> > >=20
> > > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> > > index 8346199..0485204 100644
> > > --- a/drivers/dma/sun6i-dma.c
> > > +++ b/drivers/dma/sun6i-dma.c
> > > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
> > >  	switch (maxburst) {
> > >  	case 1:
> > >  		return 0;
> > > +	case 4:
> > > +		return 1;
> > >  	case 8:
> > >  		return 2;
> > >  	default:
> > > --=20
> > > 2.9.3
> >=20
> > This patch has already been rejected by Maxime in the threads
> > 	http://www.spinics.net/lists/dmaengine/msg08610.html
> > and
> > 	http://www.spinics.net/lists/dmaengine/msg08719.html
> >=20
> > I hope you will find the way he wants for this maxburst to be added.
>=20
> I was talking about something along these lines (not tested):

I wonder why you don't submit this yourself.

> -------8<---------
> diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> index 83461994e418..573ac4608293 100644
> --- a/drivers/dma/sun6i-dma.c
> +++ b/drivers/dma/sun6i-dma.c
> @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
>  	switch (maxburst) {
>  	case 1:
>  		return 0;
> +	case 4:
> +		return 1;
>  	case 8:
>  		return 2;
>  	default:
> @@ -1110,11 +1112,19 @@ static int sun6i_dma_probe(struct platform_device=
 *pdev)
>  	sdc->slave.dst_addr_widths		=3D BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
>  						  BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
>  						  BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
> +	sdc->slave.dst_bursts			=3D BIT(1) | BIT(8);
> +	sdc->slave.src_bursts			=3D BIT(1) | BIT(8);
>  	sdc->slave.directions			=3D BIT(DMA_DEV_TO_MEM) |
>  						  BIT(DMA_MEM_TO_DEV);
>  	sdc->slave.residue_granularity		=3D DMA_RESIDUE_GRANULARITY_BURST;
>  	sdc->slave.dev =3D &pdev->dev;
> =20
> +	if (of_device_is_compatible(pdev->dev.of_node,
> +				    "allwinner,sun8i-h3-dma")) {
> +		sdc->slave.dst_bursts |=3D BIT(4);
> +		sdc->slave.src_bursts |=3D BIT(4);
> +	}
> +
>  	sdc->pchans =3D devm_kcalloc(&pdev->dev, sdc->cfg->nr_max_channels,
>  				   sizeof(struct sun6i_pchan), GFP_KERNEL);
>  	if (!sdc->pchans)
> diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
> index cc535a478bae..f7bbec24bb58 100644
> --- a/include/linux/dmaengine.h
> +++ b/include/linux/dmaengine.h
> @@ -673,6 +673,8 @@ struct dma_filter {
>   * 	each type of direction, the dma controller should fill (1 <<
>   * 	<TYPE>) and same should be checked by controller as well
>   * @max_burst: max burst capability per-transfer
> + * @dst_bursts: bitfield of the available burst sizes for the destination
> + * @src_bursts: bitfield of the available burst sizes for the source

You did not define dst_bursts nor src_bursts.

>   * @residue_granularity: granularity of the transfer residue reported
>   *	by tx_status
>   * @device_alloc_chan_resources: allocate resources and return the
> @@ -800,6 +802,14 @@ struct dma_device {
>  static inline int dmaengine_slave_config(struct dma_chan *chan,
>  					  struct dma_slave_config *config)
>  {
> +	if (config->src_maxburst && config->device->src_bursts &&
> +	    !(BIT(config->src_maxburst) & config->device->src_bursts))

The maxburst may be as big as 4Kibytes, then, I am not sure that this
code will work!

> +		return -EINVAL;
> +
> +	if (config->dst_maxburst && config->device->dst_bursts &&
> +	    !(BIT(config->dst_maxburst) & config->device->dst_bursts))
> +		return -EINVAL;
> +
>  	if (chan->device->device_config)
>  		return chan->device->device_config(chan, config);
> -------8<------------=20

Yes, I know that the burst size is always a power of 2.
The best way to check it would be to change the {src,dts}_maxburst to a
bitmap of the possible bursts as 0x0d for 1,4 and 8 bytes. But this
asks for a lot of changes...

--=20
Ken ar c'henta=F1	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

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

* [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-10-23 16:31           ` Jean-Francois Moine
  0 siblings, 0 replies; 170+ messages in thread
From: Jean-Francois Moine @ 2016-10-23 16:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 4 Oct 2016 18:55:54 +0200
Maxime Ripard <maxime.ripard@free-electrons.com> wrote:

> On Tue, Oct 04, 2016 at 12:40:11PM +0200, Jean-Francois Moine wrote:
> > On Tue,  4 Oct 2016 11:46:14 +0200
> > Myl?ne Josserand <mylene.josserand@free-electrons.com> wrote:
> > 
> > > Add the case of a burst of 4 which is handled by the SoC.
> > > 
> > > Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
> > > ---
> > >  drivers/dma/sun6i-dma.c | 2 ++
> > >  1 file changed, 2 insertions(+)
> > > 
> > > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> > > index 8346199..0485204 100644
> > > --- a/drivers/dma/sun6i-dma.c
> > > +++ b/drivers/dma/sun6i-dma.c
> > > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
> > >  	switch (maxburst) {
> > >  	case 1:
> > >  		return 0;
> > > +	case 4:
> > > +		return 1;
> > >  	case 8:
> > >  		return 2;
> > >  	default:
> > > -- 
> > > 2.9.3
> > 
> > This patch has already been rejected by Maxime in the threads
> > 	http://www.spinics.net/lists/dmaengine/msg08610.html
> > and
> > 	http://www.spinics.net/lists/dmaengine/msg08719.html
> > 
> > I hope you will find the way he wants for this maxburst to be added.
> 
> I was talking about something along these lines (not tested):

I wonder why you don't submit this yourself.

> -------8<---------
> diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> index 83461994e418..573ac4608293 100644
> --- a/drivers/dma/sun6i-dma.c
> +++ b/drivers/dma/sun6i-dma.c
> @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
>  	switch (maxburst) {
>  	case 1:
>  		return 0;
> +	case 4:
> +		return 1;
>  	case 8:
>  		return 2;
>  	default:
> @@ -1110,11 +1112,19 @@ static int sun6i_dma_probe(struct platform_device *pdev)
>  	sdc->slave.dst_addr_widths		= BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
>  						  BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
>  						  BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
> +	sdc->slave.dst_bursts			= BIT(1) | BIT(8);
> +	sdc->slave.src_bursts			= BIT(1) | BIT(8);
>  	sdc->slave.directions			= BIT(DMA_DEV_TO_MEM) |
>  						  BIT(DMA_MEM_TO_DEV);
>  	sdc->slave.residue_granularity		= DMA_RESIDUE_GRANULARITY_BURST;
>  	sdc->slave.dev = &pdev->dev;
>  
> +	if (of_device_is_compatible(pdev->dev.of_node,
> +				    "allwinner,sun8i-h3-dma")) {
> +		sdc->slave.dst_bursts |= BIT(4);
> +		sdc->slave.src_bursts |= BIT(4);
> +	}
> +
>  	sdc->pchans = devm_kcalloc(&pdev->dev, sdc->cfg->nr_max_channels,
>  				   sizeof(struct sun6i_pchan), GFP_KERNEL);
>  	if (!sdc->pchans)
> diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
> index cc535a478bae..f7bbec24bb58 100644
> --- a/include/linux/dmaengine.h
> +++ b/include/linux/dmaengine.h
> @@ -673,6 +673,8 @@ struct dma_filter {
>   * 	each type of direction, the dma controller should fill (1 <<
>   * 	<TYPE>) and same should be checked by controller as well
>   * @max_burst: max burst capability per-transfer
> + * @dst_bursts: bitfield of the available burst sizes for the destination
> + * @src_bursts: bitfield of the available burst sizes for the source

You did not define dst_bursts nor src_bursts.

>   * @residue_granularity: granularity of the transfer residue reported
>   *	by tx_status
>   * @device_alloc_chan_resources: allocate resources and return the
> @@ -800,6 +802,14 @@ struct dma_device {
>  static inline int dmaengine_slave_config(struct dma_chan *chan,
>  					  struct dma_slave_config *config)
>  {
> +	if (config->src_maxburst && config->device->src_bursts &&
> +	    !(BIT(config->src_maxburst) & config->device->src_bursts))

The maxburst may be as big as 4Kibytes, then, I am not sure that this
code will work!

> +		return -EINVAL;
> +
> +	if (config->dst_maxburst && config->device->dst_bursts &&
> +	    !(BIT(config->dst_maxburst) & config->device->dst_bursts))
> +		return -EINVAL;
> +
>  	if (chan->device->device_config)
>  		return chan->device->device_config(chan, config);
> -------8<------------ 

Yes, I know that the burst size is always a power of 2.
The best way to check it would be to change the {src,dts}_maxburst to a
bitmap of the possible bursts as 0x0d for 1,4 and 8 bytes. But this
asks for a lot of changes...

-- 
Ken ar c'henta?	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

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

* Re: [PATCH 05/14] mfd: sun6i-prcm: Add sun8i analog codec as subnode
@ 2016-10-26 14:05       ` Lee Jones
  0 siblings, 0 replies; 170+ messages in thread
From: Lee Jones @ 2016-10-26 14:05 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul, maxime.ripard, wens, mturquette, sboyd, lgirdwood,
	broonie, perex, tiwai, mark.rutland, robh+dt, linux-kernel,
	dmaengine, linux-arm-kernel, linux-clk, alsa-devel, devicetree,
	linux-sunxi, thomas.petazzoni, alexandre.belloni

On Tue, 04 Oct 2016, Mylène Josserand wrote:

> The sun8i audio codec is using PRCM registers to configure all the
> analog part of the audio codec. It is added as a subnode of the PRCM
> with his resource (offset of 0x1c0).
> 
> Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
> ---
>  drivers/mfd/sun6i-prcm.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/drivers/mfd/sun6i-prcm.c b/drivers/mfd/sun6i-prcm.c
> index 011fcc5..e0c6bf5 100644
> --- a/drivers/mfd/sun6i-prcm.c
> +++ b/drivers/mfd/sun6i-prcm.c
> @@ -12,6 +12,8 @@
>  #include <linux/init.h>
>  #include <linux/of.h>
>  
> +#define SUN6I_AUDIO_CODEC_ANALOG	0x1c0
> +
>  struct prcm_data {
>  	int nsubdevs;
>  	const struct mfd_cell *subdevs;
> @@ -57,6 +59,14 @@ static const struct resource sun6i_a31_apb0_rstc_res[] = {
>  	},
>  };
>  
> +static const struct resource sun8i_adda_res[] = {
> +	{
> +		.start = SUN6I_AUDIO_CODEC_ANALOG,
> +		.end = 0x1c3,

This also needs defining.  No magic numbers please.

> +		.flags = IORESOURCE_MEM,
> +	},
> +};
> +
>  static const struct mfd_cell sun6i_a31_prcm_subdevs[] = {
>  	{
>  		.name = "sun6i-a31-ar100-clk",
> @@ -109,6 +119,12 @@ static const struct mfd_cell sun8i_a23_prcm_subdevs[] = {
>  		.num_resources = ARRAY_SIZE(sun6i_a31_apb0_rstc_res),
>  		.resources = sun6i_a31_apb0_rstc_res,
>  	},
> +	{
> +		.name = "sun8i-codec-analog",
> +		.of_compatible = "allwinner,sun8i-codec-analog",
> +		.num_resources = ARRAY_SIZE(sun8i_adda_res),
> +		.resources = sun8i_adda_res,
> +	},
>  };
>  
>  static const struct prcm_data sun6i_a31_prcm_data = {

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* Re: [PATCH 05/14] mfd: sun6i-prcm: Add sun8i analog codec as subnode
@ 2016-10-26 14:05       ` Lee Jones
  0 siblings, 0 replies; 170+ messages in thread
From: Lee Jones @ 2016-10-26 14:05 UTC (permalink / raw)
  To: Mylène Josserand
  Cc: vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8, wens-jdAy2FN1RRM,
	mturquette-rdvid1DuHRBWk0Htik3J/w, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A,
	perex-/Fr2/VpizcU, tiwai-IBi9RG/b67k, mark.rutland-5wv7dgnIgG8,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8

On Tue, 04 Oct 2016, Mylène Josserand wrote:

> The sun8i audio codec is using PRCM registers to configure all the
> analog part of the audio codec. It is added as a subnode of the PRCM
> with his resource (offset of 0x1c0).
> 
> Signed-off-by: Mylène Josserand <mylene.josserand-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> ---
>  drivers/mfd/sun6i-prcm.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/drivers/mfd/sun6i-prcm.c b/drivers/mfd/sun6i-prcm.c
> index 011fcc5..e0c6bf5 100644
> --- a/drivers/mfd/sun6i-prcm.c
> +++ b/drivers/mfd/sun6i-prcm.c
> @@ -12,6 +12,8 @@
>  #include <linux/init.h>
>  #include <linux/of.h>
>  
> +#define SUN6I_AUDIO_CODEC_ANALOG	0x1c0
> +
>  struct prcm_data {
>  	int nsubdevs;
>  	const struct mfd_cell *subdevs;
> @@ -57,6 +59,14 @@ static const struct resource sun6i_a31_apb0_rstc_res[] = {
>  	},
>  };
>  
> +static const struct resource sun8i_adda_res[] = {
> +	{
> +		.start = SUN6I_AUDIO_CODEC_ANALOG,
> +		.end = 0x1c3,

This also needs defining.  No magic numbers please.

> +		.flags = IORESOURCE_MEM,
> +	},
> +};
> +
>  static const struct mfd_cell sun6i_a31_prcm_subdevs[] = {
>  	{
>  		.name = "sun6i-a31-ar100-clk",
> @@ -109,6 +119,12 @@ static const struct mfd_cell sun8i_a23_prcm_subdevs[] = {
>  		.num_resources = ARRAY_SIZE(sun6i_a31_apb0_rstc_res),
>  		.resources = sun6i_a31_apb0_rstc_res,
>  	},
> +	{
> +		.name = "sun8i-codec-analog",
> +		.of_compatible = "allwinner,sun8i-codec-analog",
> +		.num_resources = ARRAY_SIZE(sun8i_adda_res),
> +		.resources = sun8i_adda_res,
> +	},
>  };
>  
>  static const struct prcm_data sun6i_a31_prcm_data = {

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

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

* [PATCH 05/14] mfd: sun6i-prcm: Add sun8i analog codec as subnode
@ 2016-10-26 14:05       ` Lee Jones
  0 siblings, 0 replies; 170+ messages in thread
From: Lee Jones @ 2016-10-26 14:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 04 Oct 2016, Myl?ne Josserand wrote:

> The sun8i audio codec is using PRCM registers to configure all the
> analog part of the audio codec. It is added as a subnode of the PRCM
> with his resource (offset of 0x1c0).
> 
> Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
> ---
>  drivers/mfd/sun6i-prcm.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/drivers/mfd/sun6i-prcm.c b/drivers/mfd/sun6i-prcm.c
> index 011fcc5..e0c6bf5 100644
> --- a/drivers/mfd/sun6i-prcm.c
> +++ b/drivers/mfd/sun6i-prcm.c
> @@ -12,6 +12,8 @@
>  #include <linux/init.h>
>  #include <linux/of.h>
>  
> +#define SUN6I_AUDIO_CODEC_ANALOG	0x1c0
> +
>  struct prcm_data {
>  	int nsubdevs;
>  	const struct mfd_cell *subdevs;
> @@ -57,6 +59,14 @@ static const struct resource sun6i_a31_apb0_rstc_res[] = {
>  	},
>  };
>  
> +static const struct resource sun8i_adda_res[] = {
> +	{
> +		.start = SUN6I_AUDIO_CODEC_ANALOG,
> +		.end = 0x1c3,

This also needs defining.  No magic numbers please.

> +		.flags = IORESOURCE_MEM,
> +	},
> +};
> +
>  static const struct mfd_cell sun6i_a31_prcm_subdevs[] = {
>  	{
>  		.name = "sun6i-a31-ar100-clk",
> @@ -109,6 +119,12 @@ static const struct mfd_cell sun8i_a23_prcm_subdevs[] = {
>  		.num_resources = ARRAY_SIZE(sun6i_a31_apb0_rstc_res),
>  		.resources = sun6i_a31_apb0_rstc_res,
>  	},
> +	{
> +		.name = "sun8i-codec-analog",
> +		.of_compatible = "allwinner,sun8i-codec-analog",
> +		.num_resources = ARRAY_SIZE(sun8i_adda_res),
> +		.resources = sun8i_adda_res,
> +	},
>  };
>  
>  static const struct prcm_data sun6i_a31_prcm_data = {

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

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

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-10-27 17:51             ` Maxime Ripard
  0 siblings, 0 replies; 170+ messages in thread
From: Maxime Ripard @ 2016-10-27 17:51 UTC (permalink / raw)
  To: Jean-Francois Moine
  Cc: Mylène Josserand, vinod.koul, wens, mturquette, sboyd,
	lgirdwood, broonie, perex, tiwai, lee.jones, mark.rutland,
	robh+dt, thomas.petazzoni, devicetree, alsa-devel, linux-kernel,
	linux-sunxi, alexandre.belloni, dmaengine, linux-clk,
	linux-arm-kernel

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

On Sun, Oct 23, 2016 at 06:31:07PM +0200, Jean-Francois Moine wrote:
> On Tue, 4 Oct 2016 18:55:54 +0200
> Maxime Ripard <maxime.ripard@free-electrons.com> wrote:
> 
> > On Tue, Oct 04, 2016 at 12:40:11PM +0200, Jean-Francois Moine wrote:
> > > On Tue,  4 Oct 2016 11:46:14 +0200
> > > Mylène Josserand <mylene.josserand@free-electrons.com> wrote:
> > > 
> > > > Add the case of a burst of 4 which is handled by the SoC.
> > > > 
> > > > Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
> > > > ---
> > > >  drivers/dma/sun6i-dma.c | 2 ++
> > > >  1 file changed, 2 insertions(+)
> > > > 
> > > > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> > > > index 8346199..0485204 100644
> > > > --- a/drivers/dma/sun6i-dma.c
> > > > +++ b/drivers/dma/sun6i-dma.c
> > > > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
> > > >  	switch (maxburst) {
> > > >  	case 1:
> > > >  		return 0;
> > > > +	case 4:
> > > > +		return 1;
> > > >  	case 8:
> > > >  		return 2;
> > > >  	default:
> > > > -- 
> > > > 2.9.3
> > > 
> > > This patch has already been rejected by Maxime in the threads
> > > 	http://www.spinics.net/lists/dmaengine/msg08610.html
> > > and
> > > 	http://www.spinics.net/lists/dmaengine/msg08719.html
> > > 
> > > I hope you will find the way he wants for this maxburst to be added.
> > 
> > I was talking about something along these lines (not tested):
> 
> I wonder why you don't submit this yourself.

I thought you were the one who cared. You asked for what I had in
mind, here it is.

> > -------8<---------
> > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> > index 83461994e418..573ac4608293 100644
> > --- a/drivers/dma/sun6i-dma.c
> > +++ b/drivers/dma/sun6i-dma.c
> > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
> >  	switch (maxburst) {
> >  	case 1:
> >  		return 0;
> > +	case 4:
> > +		return 1;
> >  	case 8:
> >  		return 2;
> >  	default:
> > @@ -1110,11 +1112,19 @@ static int sun6i_dma_probe(struct platform_device *pdev)
> >  	sdc->slave.dst_addr_widths		= BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
> >  						  BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
> >  						  BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
> > +	sdc->slave.dst_bursts			= BIT(1) | BIT(8);
> > +	sdc->slave.src_bursts			= BIT(1) | BIT(8);
> >  	sdc->slave.directions			= BIT(DMA_DEV_TO_MEM) |
> >  						  BIT(DMA_MEM_TO_DEV);
> >  	sdc->slave.residue_granularity		= DMA_RESIDUE_GRANULARITY_BURST;
> >  	sdc->slave.dev = &pdev->dev;
> >  
> > +	if (of_device_is_compatible(pdev->dev.of_node,
> > +				    "allwinner,sun8i-h3-dma")) {
> > +		sdc->slave.dst_bursts |= BIT(4);
> > +		sdc->slave.src_bursts |= BIT(4);
> > +	}
> > +
> >  	sdc->pchans = devm_kcalloc(&pdev->dev, sdc->cfg->nr_max_channels,
> >  				   sizeof(struct sun6i_pchan), GFP_KERNEL);
> >  	if (!sdc->pchans)
> > diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
> > index cc535a478bae..f7bbec24bb58 100644
> > --- a/include/linux/dmaengine.h
> > +++ b/include/linux/dmaengine.h
> > @@ -673,6 +673,8 @@ struct dma_filter {
> >   * 	each type of direction, the dma controller should fill (1 <<
> >   * 	<TYPE>) and same should be checked by controller as well
> >   * @max_burst: max burst capability per-transfer
> > + * @dst_bursts: bitfield of the available burst sizes for the destination
> > + * @src_bursts: bitfield of the available burst sizes for the source
> 
> You did not define dst_bursts nor src_bursts.
> 
> >   * @residue_granularity: granularity of the transfer residue reported
> >   *	by tx_status
> >   * @device_alloc_chan_resources: allocate resources and return the
> > @@ -800,6 +802,14 @@ struct dma_device {
> >  static inline int dmaengine_slave_config(struct dma_chan *chan,
> >  					  struct dma_slave_config *config)
> >  {
> > +	if (config->src_maxburst && config->device->src_bursts &&
> > +	    !(BIT(config->src_maxburst) & config->device->src_bursts))
> 
> The maxburst may be as big as 4Kibytes, then, I am not sure that this
> code will work!
> 
> > +		return -EINVAL;
> > +
> > +	if (config->dst_maxburst && config->device->dst_bursts &&
> > +	    !(BIT(config->dst_maxburst) & config->device->dst_bursts))
> > +		return -EINVAL;
> > +
> >  	if (chan->device->device_config)
> >  		return chan->device->device_config(chan, config);
> > -------8<------------ 
> 
> Yes, I know that the burst size is always a power of 2.
> The best way to check it would be to change the {src,dts}_maxburst to a
> bitmap of the possible bursts as 0x0d for 1,4 and 8 bytes. But this
> asks for a lot of changes...

To be honest, I'm not really a big fan of those tree wide changes
without any way to maintain compatibility. It ends up in a single,
huge patch if we want to maintain bisectability that just isn't
reviewable.

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] 170+ messages in thread

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-10-27 17:51             ` Maxime Ripard
  0 siblings, 0 replies; 170+ messages in thread
From: Maxime Ripard @ 2016-10-27 17:51 UTC (permalink / raw)
  To: Jean-Francois Moine
  Cc: Mylène Josserand, vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
	wens-jdAy2FN1RRM, mturquette-rdvid1DuHRBWk0Htik3J/w,
	sboyd-sgV2jX0FEOL9JmXXK+q4OQ, lgirdwood-Re5JQEeQqe8AvxtiuMwx3w,
	broonie-DgEjT+Ai2ygdnm+yROfE0A, perex-/Fr2/VpizcU,
	tiwai-IBi9RG/b67k, lee.jones-QSEj5FYQhm4dnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

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

On Sun, Oct 23, 2016 at 06:31:07PM +0200, Jean-Francois Moine wrote:
> On Tue, 4 Oct 2016 18:55:54 +0200
> Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> 
> > On Tue, Oct 04, 2016 at 12:40:11PM +0200, Jean-Francois Moine wrote:
> > > On Tue,  4 Oct 2016 11:46:14 +0200
> > > Mylène Josserand <mylene.josserand-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> > > 
> > > > Add the case of a burst of 4 which is handled by the SoC.
> > > > 
> > > > Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
> > > > ---
> > > >  drivers/dma/sun6i-dma.c | 2 ++
> > > >  1 file changed, 2 insertions(+)
> > > > 
> > > > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> > > > index 8346199..0485204 100644
> > > > --- a/drivers/dma/sun6i-dma.c
> > > > +++ b/drivers/dma/sun6i-dma.c
> > > > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
> > > >  	switch (maxburst) {
> > > >  	case 1:
> > > >  		return 0;
> > > > +	case 4:
> > > > +		return 1;
> > > >  	case 8:
> > > >  		return 2;
> > > >  	default:
> > > > -- 
> > > > 2.9.3
> > > 
> > > This patch has already been rejected by Maxime in the threads
> > > 	http://www.spinics.net/lists/dmaengine/msg08610.html
> > > and
> > > 	http://www.spinics.net/lists/dmaengine/msg08719.html
> > > 
> > > I hope you will find the way he wants for this maxburst to be added.
> > 
> > I was talking about something along these lines (not tested):
> 
> I wonder why you don't submit this yourself.

I thought you were the one who cared. You asked for what I had in
mind, here it is.

> > -------8<---------
> > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> > index 83461994e418..573ac4608293 100644
> > --- a/drivers/dma/sun6i-dma.c
> > +++ b/drivers/dma/sun6i-dma.c
> > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
> >  	switch (maxburst) {
> >  	case 1:
> >  		return 0;
> > +	case 4:
> > +		return 1;
> >  	case 8:
> >  		return 2;
> >  	default:
> > @@ -1110,11 +1112,19 @@ static int sun6i_dma_probe(struct platform_device *pdev)
> >  	sdc->slave.dst_addr_widths		= BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
> >  						  BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
> >  						  BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
> > +	sdc->slave.dst_bursts			= BIT(1) | BIT(8);
> > +	sdc->slave.src_bursts			= BIT(1) | BIT(8);
> >  	sdc->slave.directions			= BIT(DMA_DEV_TO_MEM) |
> >  						  BIT(DMA_MEM_TO_DEV);
> >  	sdc->slave.residue_granularity		= DMA_RESIDUE_GRANULARITY_BURST;
> >  	sdc->slave.dev = &pdev->dev;
> >  
> > +	if (of_device_is_compatible(pdev->dev.of_node,
> > +				    "allwinner,sun8i-h3-dma")) {
> > +		sdc->slave.dst_bursts |= BIT(4);
> > +		sdc->slave.src_bursts |= BIT(4);
> > +	}
> > +
> >  	sdc->pchans = devm_kcalloc(&pdev->dev, sdc->cfg->nr_max_channels,
> >  				   sizeof(struct sun6i_pchan), GFP_KERNEL);
> >  	if (!sdc->pchans)
> > diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
> > index cc535a478bae..f7bbec24bb58 100644
> > --- a/include/linux/dmaengine.h
> > +++ b/include/linux/dmaengine.h
> > @@ -673,6 +673,8 @@ struct dma_filter {
> >   * 	each type of direction, the dma controller should fill (1 <<
> >   * 	<TYPE>) and same should be checked by controller as well
> >   * @max_burst: max burst capability per-transfer
> > + * @dst_bursts: bitfield of the available burst sizes for the destination
> > + * @src_bursts: bitfield of the available burst sizes for the source
> 
> You did not define dst_bursts nor src_bursts.
> 
> >   * @residue_granularity: granularity of the transfer residue reported
> >   *	by tx_status
> >   * @device_alloc_chan_resources: allocate resources and return the
> > @@ -800,6 +802,14 @@ struct dma_device {
> >  static inline int dmaengine_slave_config(struct dma_chan *chan,
> >  					  struct dma_slave_config *config)
> >  {
> > +	if (config->src_maxburst && config->device->src_bursts &&
> > +	    !(BIT(config->src_maxburst) & config->device->src_bursts))
> 
> The maxburst may be as big as 4Kibytes, then, I am not sure that this
> code will work!
> 
> > +		return -EINVAL;
> > +
> > +	if (config->dst_maxburst && config->device->dst_bursts &&
> > +	    !(BIT(config->dst_maxburst) & config->device->dst_bursts))
> > +		return -EINVAL;
> > +
> >  	if (chan->device->device_config)
> >  		return chan->device->device_config(chan, config);
> > -------8<------------ 
> 
> Yes, I know that the burst size is always a power of 2.
> The best way to check it would be to change the {src,dts}_maxburst to a
> bitmap of the possible bursts as 0x0d for 1,4 and 8 bytes. But this
> asks for a lot of changes...

To be honest, I'm not really a big fan of those tree wide changes
without any way to maintain compatibility. It ends up in a single,
huge patch if we want to maintain bisectability that just isn't
reviewable.

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] 170+ messages in thread

* [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-10-27 17:51             ` Maxime Ripard
  0 siblings, 0 replies; 170+ messages in thread
From: Maxime Ripard @ 2016-10-27 17:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Oct 23, 2016 at 06:31:07PM +0200, Jean-Francois Moine wrote:
> On Tue, 4 Oct 2016 18:55:54 +0200
> Maxime Ripard <maxime.ripard@free-electrons.com> wrote:
> 
> > On Tue, Oct 04, 2016 at 12:40:11PM +0200, Jean-Francois Moine wrote:
> > > On Tue,  4 Oct 2016 11:46:14 +0200
> > > Myl?ne Josserand <mylene.josserand@free-electrons.com> wrote:
> > > 
> > > > Add the case of a burst of 4 which is handled by the SoC.
> > > > 
> > > > Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
> > > > ---
> > > >  drivers/dma/sun6i-dma.c | 2 ++
> > > >  1 file changed, 2 insertions(+)
> > > > 
> > > > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> > > > index 8346199..0485204 100644
> > > > --- a/drivers/dma/sun6i-dma.c
> > > > +++ b/drivers/dma/sun6i-dma.c
> > > > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
> > > >  	switch (maxburst) {
> > > >  	case 1:
> > > >  		return 0;
> > > > +	case 4:
> > > > +		return 1;
> > > >  	case 8:
> > > >  		return 2;
> > > >  	default:
> > > > -- 
> > > > 2.9.3
> > > 
> > > This patch has already been rejected by Maxime in the threads
> > > 	http://www.spinics.net/lists/dmaengine/msg08610.html
> > > and
> > > 	http://www.spinics.net/lists/dmaengine/msg08719.html
> > > 
> > > I hope you will find the way he wants for this maxburst to be added.
> > 
> > I was talking about something along these lines (not tested):
> 
> I wonder why you don't submit this yourself.

I thought you were the one who cared. You asked for what I had in
mind, here it is.

> > -------8<---------
> > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> > index 83461994e418..573ac4608293 100644
> > --- a/drivers/dma/sun6i-dma.c
> > +++ b/drivers/dma/sun6i-dma.c
> > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
> >  	switch (maxburst) {
> >  	case 1:
> >  		return 0;
> > +	case 4:
> > +		return 1;
> >  	case 8:
> >  		return 2;
> >  	default:
> > @@ -1110,11 +1112,19 @@ static int sun6i_dma_probe(struct platform_device *pdev)
> >  	sdc->slave.dst_addr_widths		= BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
> >  						  BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
> >  						  BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
> > +	sdc->slave.dst_bursts			= BIT(1) | BIT(8);
> > +	sdc->slave.src_bursts			= BIT(1) | BIT(8);
> >  	sdc->slave.directions			= BIT(DMA_DEV_TO_MEM) |
> >  						  BIT(DMA_MEM_TO_DEV);
> >  	sdc->slave.residue_granularity		= DMA_RESIDUE_GRANULARITY_BURST;
> >  	sdc->slave.dev = &pdev->dev;
> >  
> > +	if (of_device_is_compatible(pdev->dev.of_node,
> > +				    "allwinner,sun8i-h3-dma")) {
> > +		sdc->slave.dst_bursts |= BIT(4);
> > +		sdc->slave.src_bursts |= BIT(4);
> > +	}
> > +
> >  	sdc->pchans = devm_kcalloc(&pdev->dev, sdc->cfg->nr_max_channels,
> >  				   sizeof(struct sun6i_pchan), GFP_KERNEL);
> >  	if (!sdc->pchans)
> > diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
> > index cc535a478bae..f7bbec24bb58 100644
> > --- a/include/linux/dmaengine.h
> > +++ b/include/linux/dmaengine.h
> > @@ -673,6 +673,8 @@ struct dma_filter {
> >   * 	each type of direction, the dma controller should fill (1 <<
> >   * 	<TYPE>) and same should be checked by controller as well
> >   * @max_burst: max burst capability per-transfer
> > + * @dst_bursts: bitfield of the available burst sizes for the destination
> > + * @src_bursts: bitfield of the available burst sizes for the source
> 
> You did not define dst_bursts nor src_bursts.
> 
> >   * @residue_granularity: granularity of the transfer residue reported
> >   *	by tx_status
> >   * @device_alloc_chan_resources: allocate resources and return the
> > @@ -800,6 +802,14 @@ struct dma_device {
> >  static inline int dmaengine_slave_config(struct dma_chan *chan,
> >  					  struct dma_slave_config *config)
> >  {
> > +	if (config->src_maxburst && config->device->src_bursts &&
> > +	    !(BIT(config->src_maxburst) & config->device->src_bursts))
> 
> The maxburst may be as big as 4Kibytes, then, I am not sure that this
> code will work!
> 
> > +		return -EINVAL;
> > +
> > +	if (config->dst_maxburst && config->device->dst_bursts &&
> > +	    !(BIT(config->dst_maxburst) & config->device->dst_bursts))
> > +		return -EINVAL;
> > +
> >  	if (chan->device->device_config)
> >  		return chan->device->device_config(chan, config);
> > -------8<------------ 
> 
> Yes, I know that the burst size is always a power of 2.
> The best way to check it would be to change the {src,dts}_maxburst to a
> bitmap of the possible bursts as 0x0d for 1,4 and 8 bytes. But this
> asks for a lot of changes...

To be honest, I'm not really a big fan of those tree wide changes
without any way to maintain compatibility. It ends up in a single,
huge patch if we want to maintain bisectability that just isn't
reviewable.

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/20161027/aaa8cf73/attachment.sig>

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

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
  2016-10-27 17:51             ` Maxime Ripard
  (?)
  (?)
@ 2016-10-30  2:06               ` Chen-Yu Tsai
  -1 siblings, 0 replies; 170+ messages in thread
From: Chen-Yu Tsai @ 2016-10-30  2:06 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Jean-Francois Moine, Mylène Josserand, Vinod Koul,
	Chen-Yu Tsai, Mike Turquette, Stephen Boyd, Liam Girdwood,
	Mark Brown, Jaroslav Kysela, Takashi Iwai, Lee Jones,
	Mark Rutland, Rob Herring, Thomas Petazzoni, devicetree,
	Linux-ALSA, linux-kernel, linux-sunxi, Alexandre Belloni,
	dmaengine, linux-clk, linux-arm-kernel

Hi,

On Fri, Oct 28, 2016 at 1:51 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> On Sun, Oct 23, 2016 at 06:31:07PM +0200, Jean-Francois Moine wrote:
>> On Tue, 4 Oct 2016 18:55:54 +0200
>> Maxime Ripard <maxime.ripard@free-electrons.com> wrote:
>>
>> > On Tue, Oct 04, 2016 at 12:40:11PM +0200, Jean-Francois Moine wrote:
>> > > On Tue,  4 Oct 2016 11:46:14 +0200
>> > > Mylène Josserand <mylene.josserand@free-electrons.com> wrote:
>> > >
>> > > > Add the case of a burst of 4 which is handled by the SoC.
>> > > >
>> > > > Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
>> > > > ---
>> > > >  drivers/dma/sun6i-dma.c | 2 ++
>> > > >  1 file changed, 2 insertions(+)
>> > > >
>> > > > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
>> > > > index 8346199..0485204 100644
>> > > > --- a/drivers/dma/sun6i-dma.c
>> > > > +++ b/drivers/dma/sun6i-dma.c
>> > > > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
>> > > >         switch (maxburst) {
>> > > >         case 1:
>> > > >                 return 0;
>> > > > +       case 4:
>> > > > +               return 1;
>> > > >         case 8:
>> > > >                 return 2;
>> > > >         default:
>> > > > --
>> > > > 2.9.3
>> > >
>> > > This patch has already been rejected by Maxime in the threads
>> > >   http://www.spinics.net/lists/dmaengine/msg08610.html
>> > > and
>> > >   http://www.spinics.net/lists/dmaengine/msg08719.html
>> > >
>> > > I hope you will find the way he wants for this maxburst to be added.
>> >
>> > I was talking about something along these lines (not tested):
>>
>> I wonder why you don't submit this yourself.
>
> I thought you were the one who cared. You asked for what I had in
> mind, here it is.
>
>> > -------8<---------
>> > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
>> > index 83461994e418..573ac4608293 100644
>> > --- a/drivers/dma/sun6i-dma.c
>> > +++ b/drivers/dma/sun6i-dma.c
>> > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
>> >     switch (maxburst) {
>> >     case 1:
>> >             return 0;
>> > +   case 4:
>> > +           return 1;
>> >     case 8:
>> >             return 2;
>> >     default:
>> > @@ -1110,11 +1112,19 @@ static int sun6i_dma_probe(struct platform_device *pdev)
>> >     sdc->slave.dst_addr_widths              = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
>> >                                               BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
>> >                                               BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
>> > +   sdc->slave.dst_bursts                   = BIT(1) | BIT(8);
>> > +   sdc->slave.src_bursts                   = BIT(1) | BIT(8);
>> >     sdc->slave.directions                   = BIT(DMA_DEV_TO_MEM) |
>> >                                               BIT(DMA_MEM_TO_DEV);
>> >     sdc->slave.residue_granularity          = DMA_RESIDUE_GRANULARITY_BURST;
>> >     sdc->slave.dev = &pdev->dev;
>> >
>> > +   if (of_device_is_compatible(pdev->dev.of_node,
>> > +                               "allwinner,sun8i-h3-dma")) {
>> > +           sdc->slave.dst_bursts |= BIT(4);
>> > +           sdc->slave.src_bursts |= BIT(4);
>> > +   }
>> > +
>> >     sdc->pchans = devm_kcalloc(&pdev->dev, sdc->cfg->nr_max_channels,
>> >                                sizeof(struct sun6i_pchan), GFP_KERNEL);
>> >     if (!sdc->pchans)
>> > diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
>> > index cc535a478bae..f7bbec24bb58 100644
>> > --- a/include/linux/dmaengine.h
>> > +++ b/include/linux/dmaengine.h
>> > @@ -673,6 +673,8 @@ struct dma_filter {
>> >   *         each type of direction, the dma controller should fill (1 <<
>> >   *         <TYPE>) and same should be checked by controller as well
>> >   * @max_burst: max burst capability per-transfer
>> > + * @dst_bursts: bitfield of the available burst sizes for the destination
>> > + * @src_bursts: bitfield of the available burst sizes for the source
>>
>> You did not define dst_bursts nor src_bursts.
>>
>> >   * @residue_granularity: granularity of the transfer residue reported
>> >   * by tx_status
>> >   * @device_alloc_chan_resources: allocate resources and return the
>> > @@ -800,6 +802,14 @@ struct dma_device {
>> >  static inline int dmaengine_slave_config(struct dma_chan *chan,
>> >                                       struct dma_slave_config *config)
>> >  {
>> > +   if (config->src_maxburst && config->device->src_bursts &&
>> > +       !(BIT(config->src_maxburst) & config->device->src_bursts))
>>
>> The maxburst may be as big as 4Kibytes, then, I am not sure that this
>> code will work!
>>
>> > +           return -EINVAL;
>> > +
>> > +   if (config->dst_maxburst && config->device->dst_bursts &&
>> > +       !(BIT(config->dst_maxburst) & config->device->dst_bursts))
>> > +           return -EINVAL;
>> > +
>> >     if (chan->device->device_config)
>> >             return chan->device->device_config(chan, config);
>> > -------8<------------
>>
>> Yes, I know that the burst size is always a power of 2.
>> The best way to check it would be to change the {src,dts}_maxburst to a
>> bitmap of the possible bursts as 0x0d for 1,4 and 8 bytes. But this
>> asks for a lot of changes...
>
> To be honest, I'm not really a big fan of those tree wide changes
> without any way to maintain compatibility. It ends up in a single,
> huge patch if we want to maintain bisectability that just isn't
> reviewable.

Looking at the dmaengine API, I believe we got it wrong.

max_burst in dma_slave_config denotes the largest amount of data
a single transfer should be, as described in dmaengine.h:

 * @src_maxburst: the maximum number of words (note: words, as in
 * units of the src_addr_width member, not bytes) that can be sent
 * in one burst to the device. Typically something like half the
 * FIFO depth on I/O peripherals so you don't overflow it. This
 * may or may not be applicable on memory sources.
 * @dst_maxburst: same as src_maxburst but for destination target
 * mutatis mutandis.

The DMA engine driver should be free to select whatever burst size
that doesn't exceed this. So for max_burst = 4, the driver can select
burst = 4 for controllers that do support it, or burst = 1 for those
that don't, and do more bursts.

This also means we can increase max_burst for the audio codec, as
the FIFO is 64 samples deep for stereo, or 128 samples for mono.


If we agree on the above I can send some patches for this.


Regards
ChenYu

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

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-10-30  2:06               ` Chen-Yu Tsai
  0 siblings, 0 replies; 170+ messages in thread
From: Chen-Yu Tsai @ 2016-10-30  2:06 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Jean-Francois Moine, Mylène Josserand, Vinod Koul,
	Chen-Yu Tsai, Mike Turquette, Stephen Boyd, Liam Girdwood,
	Mark Brown, Jaroslav Kysela, Takashi Iwai, Lee Jones,
	Mark Rutland, Rob Herring, Thomas Petazzoni, devicetree,
	Linux-ALSA, linux-kernel, linux-sunxi, Alexandre Belloni,
	dmaengine-u79uwXL29TY76Z2rM5mHXA, linux-clk

Hi,

On Fri, Oct 28, 2016 at 1:51 AM, Maxime Ripard
<maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
> On Sun, Oct 23, 2016 at 06:31:07PM +0200, Jean-Francois Moine wrote:
>> On Tue, 4 Oct 2016 18:55:54 +0200
>> Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
>>
>> > On Tue, Oct 04, 2016 at 12:40:11PM +0200, Jean-Francois Moine wrote:
>> > > On Tue,  4 Oct 2016 11:46:14 +0200
>> > > Mylène Josserand <mylene.josserand-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
>> > >
>> > > > Add the case of a burst of 4 which is handled by the SoC.
>> > > >
>> > > > Signed-off-by: Mylène Josserand <mylene.josserand@free-electrons.com>
>> > > > ---
>> > > >  drivers/dma/sun6i-dma.c | 2 ++
>> > > >  1 file changed, 2 insertions(+)
>> > > >
>> > > > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
>> > > > index 8346199..0485204 100644
>> > > > --- a/drivers/dma/sun6i-dma.c
>> > > > +++ b/drivers/dma/sun6i-dma.c
>> > > > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
>> > > >         switch (maxburst) {
>> > > >         case 1:
>> > > >                 return 0;
>> > > > +       case 4:
>> > > > +               return 1;
>> > > >         case 8:
>> > > >                 return 2;
>> > > >         default:
>> > > > --
>> > > > 2.9.3
>> > >
>> > > This patch has already been rejected by Maxime in the threads
>> > >   http://www.spinics.net/lists/dmaengine/msg08610.html
>> > > and
>> > >   http://www.spinics.net/lists/dmaengine/msg08719.html
>> > >
>> > > I hope you will find the way he wants for this maxburst to be added.
>> >
>> > I was talking about something along these lines (not tested):
>>
>> I wonder why you don't submit this yourself.
>
> I thought you were the one who cared. You asked for what I had in
> mind, here it is.
>
>> > -------8<---------
>> > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
>> > index 83461994e418..573ac4608293 100644
>> > --- a/drivers/dma/sun6i-dma.c
>> > +++ b/drivers/dma/sun6i-dma.c
>> > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
>> >     switch (maxburst) {
>> >     case 1:
>> >             return 0;
>> > +   case 4:
>> > +           return 1;
>> >     case 8:
>> >             return 2;
>> >     default:
>> > @@ -1110,11 +1112,19 @@ static int sun6i_dma_probe(struct platform_device *pdev)
>> >     sdc->slave.dst_addr_widths              = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
>> >                                               BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
>> >                                               BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
>> > +   sdc->slave.dst_bursts                   = BIT(1) | BIT(8);
>> > +   sdc->slave.src_bursts                   = BIT(1) | BIT(8);
>> >     sdc->slave.directions                   = BIT(DMA_DEV_TO_MEM) |
>> >                                               BIT(DMA_MEM_TO_DEV);
>> >     sdc->slave.residue_granularity          = DMA_RESIDUE_GRANULARITY_BURST;
>> >     sdc->slave.dev = &pdev->dev;
>> >
>> > +   if (of_device_is_compatible(pdev->dev.of_node,
>> > +                               "allwinner,sun8i-h3-dma")) {
>> > +           sdc->slave.dst_bursts |= BIT(4);
>> > +           sdc->slave.src_bursts |= BIT(4);
>> > +   }
>> > +
>> >     sdc->pchans = devm_kcalloc(&pdev->dev, sdc->cfg->nr_max_channels,
>> >                                sizeof(struct sun6i_pchan), GFP_KERNEL);
>> >     if (!sdc->pchans)
>> > diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
>> > index cc535a478bae..f7bbec24bb58 100644
>> > --- a/include/linux/dmaengine.h
>> > +++ b/include/linux/dmaengine.h
>> > @@ -673,6 +673,8 @@ struct dma_filter {
>> >   *         each type of direction, the dma controller should fill (1 <<
>> >   *         <TYPE>) and same should be checked by controller as well
>> >   * @max_burst: max burst capability per-transfer
>> > + * @dst_bursts: bitfield of the available burst sizes for the destination
>> > + * @src_bursts: bitfield of the available burst sizes for the source
>>
>> You did not define dst_bursts nor src_bursts.
>>
>> >   * @residue_granularity: granularity of the transfer residue reported
>> >   * by tx_status
>> >   * @device_alloc_chan_resources: allocate resources and return the
>> > @@ -800,6 +802,14 @@ struct dma_device {
>> >  static inline int dmaengine_slave_config(struct dma_chan *chan,
>> >                                       struct dma_slave_config *config)
>> >  {
>> > +   if (config->src_maxburst && config->device->src_bursts &&
>> > +       !(BIT(config->src_maxburst) & config->device->src_bursts))
>>
>> The maxburst may be as big as 4Kibytes, then, I am not sure that this
>> code will work!
>>
>> > +           return -EINVAL;
>> > +
>> > +   if (config->dst_maxburst && config->device->dst_bursts &&
>> > +       !(BIT(config->dst_maxburst) & config->device->dst_bursts))
>> > +           return -EINVAL;
>> > +
>> >     if (chan->device->device_config)
>> >             return chan->device->device_config(chan, config);
>> > -------8<------------
>>
>> Yes, I know that the burst size is always a power of 2.
>> The best way to check it would be to change the {src,dts}_maxburst to a
>> bitmap of the possible bursts as 0x0d for 1,4 and 8 bytes. But this
>> asks for a lot of changes...
>
> To be honest, I'm not really a big fan of those tree wide changes
> without any way to maintain compatibility. It ends up in a single,
> huge patch if we want to maintain bisectability that just isn't
> reviewable.

Looking at the dmaengine API, I believe we got it wrong.

max_burst in dma_slave_config denotes the largest amount of data
a single transfer should be, as described in dmaengine.h:

 * @src_maxburst: the maximum number of words (note: words, as in
 * units of the src_addr_width member, not bytes) that can be sent
 * in one burst to the device. Typically something like half the
 * FIFO depth on I/O peripherals so you don't overflow it. This
 * may or may not be applicable on memory sources.
 * @dst_maxburst: same as src_maxburst but for destination target
 * mutatis mutandis.

The DMA engine driver should be free to select whatever burst size
that doesn't exceed this. So for max_burst = 4, the driver can select
burst = 4 for controllers that do support it, or burst = 1 for those
that don't, and do more bursts.

This also means we can increase max_burst for the audio codec, as
the FIFO is 64 samples deep for stereo, or 128 samples for mono.


If we agree on the above I can send some patches for this.


Regards
ChenYu

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

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

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-10-30  2:06               ` Chen-Yu Tsai
  0 siblings, 0 replies; 170+ messages in thread
From: Chen-Yu Tsai @ 2016-10-30  2:06 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Jean-Francois Moine, Mylène Josserand, Vinod Koul,
	Chen-Yu Tsai, Mike Turquette, Stephen Boyd, Liam Girdwood,
	Mark Brown, Jaroslav Kysela, Takashi Iwai, Lee Jones,
	Mark Rutland, Rob Herring, Thomas Petazzoni, devicetree,
	Linux-ALSA, linux-kernel, linux-sunxi, Alexandre Belloni,
	dmaengine, linux-clk, linux-arm-kernel

Hi,

On Fri, Oct 28, 2016 at 1:51 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> On Sun, Oct 23, 2016 at 06:31:07PM +0200, Jean-Francois Moine wrote:
>> On Tue, 4 Oct 2016 18:55:54 +0200
>> Maxime Ripard <maxime.ripard@free-electrons.com> wrote:
>>
>> > On Tue, Oct 04, 2016 at 12:40:11PM +0200, Jean-Francois Moine wrote:
>> > > On Tue,  4 Oct 2016 11:46:14 +0200
>> > > Myl=C3=A8ne Josserand <mylene.josserand@free-electrons.com> wrote:
>> > >
>> > > > Add the case of a burst of 4 which is handled by the SoC.
>> > > >
>> > > > Signed-off-by: Myl=C3=A8ne Josserand <mylene.josserand@free-electr=
ons.com>
>> > > > ---
>> > > >  drivers/dma/sun6i-dma.c | 2 ++
>> > > >  1 file changed, 2 insertions(+)
>> > > >
>> > > > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
>> > > > index 8346199..0485204 100644
>> > > > --- a/drivers/dma/sun6i-dma.c
>> > > > +++ b/drivers/dma/sun6i-dma.c
>> > > > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
>> > > >         switch (maxburst) {
>> > > >         case 1:
>> > > >                 return 0;
>> > > > +       case 4:
>> > > > +               return 1;
>> > > >         case 8:
>> > > >                 return 2;
>> > > >         default:
>> > > > --
>> > > > 2.9.3
>> > >
>> > > This patch has already been rejected by Maxime in the threads
>> > >   http://www.spinics.net/lists/dmaengine/msg08610.html
>> > > and
>> > >   http://www.spinics.net/lists/dmaengine/msg08719.html
>> > >
>> > > I hope you will find the way he wants for this maxburst to be added.
>> >
>> > I was talking about something along these lines (not tested):
>>
>> I wonder why you don't submit this yourself.
>
> I thought you were the one who cared. You asked for what I had in
> mind, here it is.
>
>> > -------8<---------
>> > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
>> > index 83461994e418..573ac4608293 100644
>> > --- a/drivers/dma/sun6i-dma.c
>> > +++ b/drivers/dma/sun6i-dma.c
>> > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
>> >     switch (maxburst) {
>> >     case 1:
>> >             return 0;
>> > +   case 4:
>> > +           return 1;
>> >     case 8:
>> >             return 2;
>> >     default:
>> > @@ -1110,11 +1112,19 @@ static int sun6i_dma_probe(struct platform_dev=
ice *pdev)
>> >     sdc->slave.dst_addr_widths              =3D BIT(DMA_SLAVE_BUSWIDTH=
_1_BYTE) |
>> >                                               BIT(DMA_SLAVE_BUSWIDTH_2=
_BYTES) |
>> >                                               BIT(DMA_SLAVE_BUSWIDTH_4=
_BYTES);
>> > +   sdc->slave.dst_bursts                   =3D BIT(1) | BIT(8);
>> > +   sdc->slave.src_bursts                   =3D BIT(1) | BIT(8);
>> >     sdc->slave.directions                   =3D BIT(DMA_DEV_TO_MEM) |
>> >                                               BIT(DMA_MEM_TO_DEV);
>> >     sdc->slave.residue_granularity          =3D DMA_RESIDUE_GRANULARIT=
Y_BURST;
>> >     sdc->slave.dev =3D &pdev->dev;
>> >
>> > +   if (of_device_is_compatible(pdev->dev.of_node,
>> > +                               "allwinner,sun8i-h3-dma")) {
>> > +           sdc->slave.dst_bursts |=3D BIT(4);
>> > +           sdc->slave.src_bursts |=3D BIT(4);
>> > +   }
>> > +
>> >     sdc->pchans =3D devm_kcalloc(&pdev->dev, sdc->cfg->nr_max_channels=
,
>> >                                sizeof(struct sun6i_pchan), GFP_KERNEL)=
;
>> >     if (!sdc->pchans)
>> > diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
>> > index cc535a478bae..f7bbec24bb58 100644
>> > --- a/include/linux/dmaengine.h
>> > +++ b/include/linux/dmaengine.h
>> > @@ -673,6 +673,8 @@ struct dma_filter {
>> >   *         each type of direction, the dma controller should fill (1 =
<<
>> >   *         <TYPE>) and same should be checked by controller as well
>> >   * @max_burst: max burst capability per-transfer
>> > + * @dst_bursts: bitfield of the available burst sizes for the destina=
tion
>> > + * @src_bursts: bitfield of the available burst sizes for the source
>>
>> You did not define dst_bursts nor src_bursts.
>>
>> >   * @residue_granularity: granularity of the transfer residue reported
>> >   * by tx_status
>> >   * @device_alloc_chan_resources: allocate resources and return the
>> > @@ -800,6 +802,14 @@ struct dma_device {
>> >  static inline int dmaengine_slave_config(struct dma_chan *chan,
>> >                                       struct dma_slave_config *config)
>> >  {
>> > +   if (config->src_maxburst && config->device->src_bursts &&
>> > +       !(BIT(config->src_maxburst) & config->device->src_bursts))
>>
>> The maxburst may be as big as 4Kibytes, then, I am not sure that this
>> code will work!
>>
>> > +           return -EINVAL;
>> > +
>> > +   if (config->dst_maxburst && config->device->dst_bursts &&
>> > +       !(BIT(config->dst_maxburst) & config->device->dst_bursts))
>> > +           return -EINVAL;
>> > +
>> >     if (chan->device->device_config)
>> >             return chan->device->device_config(chan, config);
>> > -------8<------------
>>
>> Yes, I know that the burst size is always a power of 2.
>> The best way to check it would be to change the {src,dts}_maxburst to a
>> bitmap of the possible bursts as 0x0d for 1,4 and 8 bytes. But this
>> asks for a lot of changes...
>
> To be honest, I'm not really a big fan of those tree wide changes
> without any way to maintain compatibility. It ends up in a single,
> huge patch if we want to maintain bisectability that just isn't
> reviewable.

Looking at the dmaengine API, I believe we got it wrong.

max_burst in dma_slave_config denotes the largest amount of data
a single transfer should be, as described in dmaengine.h:

 * @src_maxburst: the maximum number of words (note: words, as in
 * units of the src_addr_width member, not bytes) that can be sent
 * in one burst to the device. Typically something like half the
 * FIFO depth on I/O peripherals so you don't overflow it. This
 * may or may not be applicable on memory sources.
 * @dst_maxburst: same as src_maxburst but for destination target
 * mutatis mutandis.

The DMA engine driver should be free to select whatever burst size
that doesn't exceed this. So for max_burst =3D 4, the driver can select
burst =3D 4 for controllers that do support it, or burst =3D 1 for those
that don't, and do more bursts.

This also means we can increase max_burst for the audio codec, as
the FIFO is 64 samples deep for stereo, or 128 samples for mono.


If we agree on the above I can send some patches for this.


Regards
ChenYu

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

* [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-10-30  2:06               ` Chen-Yu Tsai
  0 siblings, 0 replies; 170+ messages in thread
From: Chen-Yu Tsai @ 2016-10-30  2:06 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Fri, Oct 28, 2016 at 1:51 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> On Sun, Oct 23, 2016 at 06:31:07PM +0200, Jean-Francois Moine wrote:
>> On Tue, 4 Oct 2016 18:55:54 +0200
>> Maxime Ripard <maxime.ripard@free-electrons.com> wrote:
>>
>> > On Tue, Oct 04, 2016 at 12:40:11PM +0200, Jean-Francois Moine wrote:
>> > > On Tue,  4 Oct 2016 11:46:14 +0200
>> > > Myl?ne Josserand <mylene.josserand@free-electrons.com> wrote:
>> > >
>> > > > Add the case of a burst of 4 which is handled by the SoC.
>> > > >
>> > > > Signed-off-by: Myl?ne Josserand <mylene.josserand@free-electrons.com>
>> > > > ---
>> > > >  drivers/dma/sun6i-dma.c | 2 ++
>> > > >  1 file changed, 2 insertions(+)
>> > > >
>> > > > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
>> > > > index 8346199..0485204 100644
>> > > > --- a/drivers/dma/sun6i-dma.c
>> > > > +++ b/drivers/dma/sun6i-dma.c
>> > > > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
>> > > >         switch (maxburst) {
>> > > >         case 1:
>> > > >                 return 0;
>> > > > +       case 4:
>> > > > +               return 1;
>> > > >         case 8:
>> > > >                 return 2;
>> > > >         default:
>> > > > --
>> > > > 2.9.3
>> > >
>> > > This patch has already been rejected by Maxime in the threads
>> > >   http://www.spinics.net/lists/dmaengine/msg08610.html
>> > > and
>> > >   http://www.spinics.net/lists/dmaengine/msg08719.html
>> > >
>> > > I hope you will find the way he wants for this maxburst to be added.
>> >
>> > I was talking about something along these lines (not tested):
>>
>> I wonder why you don't submit this yourself.
>
> I thought you were the one who cared. You asked for what I had in
> mind, here it is.
>
>> > -------8<---------
>> > diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
>> > index 83461994e418..573ac4608293 100644
>> > --- a/drivers/dma/sun6i-dma.c
>> > +++ b/drivers/dma/sun6i-dma.c
>> > @@ -240,6 +240,8 @@ static inline s8 convert_burst(u32 maxburst)
>> >     switch (maxburst) {
>> >     case 1:
>> >             return 0;
>> > +   case 4:
>> > +           return 1;
>> >     case 8:
>> >             return 2;
>> >     default:
>> > @@ -1110,11 +1112,19 @@ static int sun6i_dma_probe(struct platform_device *pdev)
>> >     sdc->slave.dst_addr_widths              = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
>> >                                               BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
>> >                                               BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
>> > +   sdc->slave.dst_bursts                   = BIT(1) | BIT(8);
>> > +   sdc->slave.src_bursts                   = BIT(1) | BIT(8);
>> >     sdc->slave.directions                   = BIT(DMA_DEV_TO_MEM) |
>> >                                               BIT(DMA_MEM_TO_DEV);
>> >     sdc->slave.residue_granularity          = DMA_RESIDUE_GRANULARITY_BURST;
>> >     sdc->slave.dev = &pdev->dev;
>> >
>> > +   if (of_device_is_compatible(pdev->dev.of_node,
>> > +                               "allwinner,sun8i-h3-dma")) {
>> > +           sdc->slave.dst_bursts |= BIT(4);
>> > +           sdc->slave.src_bursts |= BIT(4);
>> > +   }
>> > +
>> >     sdc->pchans = devm_kcalloc(&pdev->dev, sdc->cfg->nr_max_channels,
>> >                                sizeof(struct sun6i_pchan), GFP_KERNEL);
>> >     if (!sdc->pchans)
>> > diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
>> > index cc535a478bae..f7bbec24bb58 100644
>> > --- a/include/linux/dmaengine.h
>> > +++ b/include/linux/dmaengine.h
>> > @@ -673,6 +673,8 @@ struct dma_filter {
>> >   *         each type of direction, the dma controller should fill (1 <<
>> >   *         <TYPE>) and same should be checked by controller as well
>> >   * @max_burst: max burst capability per-transfer
>> > + * @dst_bursts: bitfield of the available burst sizes for the destination
>> > + * @src_bursts: bitfield of the available burst sizes for the source
>>
>> You did not define dst_bursts nor src_bursts.
>>
>> >   * @residue_granularity: granularity of the transfer residue reported
>> >   * by tx_status
>> >   * @device_alloc_chan_resources: allocate resources and return the
>> > @@ -800,6 +802,14 @@ struct dma_device {
>> >  static inline int dmaengine_slave_config(struct dma_chan *chan,
>> >                                       struct dma_slave_config *config)
>> >  {
>> > +   if (config->src_maxburst && config->device->src_bursts &&
>> > +       !(BIT(config->src_maxburst) & config->device->src_bursts))
>>
>> The maxburst may be as big as 4Kibytes, then, I am not sure that this
>> code will work!
>>
>> > +           return -EINVAL;
>> > +
>> > +   if (config->dst_maxburst && config->device->dst_bursts &&
>> > +       !(BIT(config->dst_maxburst) & config->device->dst_bursts))
>> > +           return -EINVAL;
>> > +
>> >     if (chan->device->device_config)
>> >             return chan->device->device_config(chan, config);
>> > -------8<------------
>>
>> Yes, I know that the burst size is always a power of 2.
>> The best way to check it would be to change the {src,dts}_maxburst to a
>> bitmap of the possible bursts as 0x0d for 1,4 and 8 bytes. But this
>> asks for a lot of changes...
>
> To be honest, I'm not really a big fan of those tree wide changes
> without any way to maintain compatibility. It ends up in a single,
> huge patch if we want to maintain bisectability that just isn't
> reviewable.

Looking at the dmaengine API, I believe we got it wrong.

max_burst in dma_slave_config denotes the largest amount of data
a single transfer should be, as described in dmaengine.h:

 * @src_maxburst: the maximum number of words (note: words, as in
 * units of the src_addr_width member, not bytes) that can be sent
 * in one burst to the device. Typically something like half the
 * FIFO depth on I/O peripherals so you don't overflow it. This
 * may or may not be applicable on memory sources.
 * @dst_maxburst: same as src_maxburst but for destination target
 * mutatis mutandis.

The DMA engine driver should be free to select whatever burst size
that doesn't exceed this. So for max_burst = 4, the driver can select
burst = 4 for controllers that do support it, or burst = 1 for those
that don't, and do more bursts.

This also means we can increase max_burst for the audio codec, as
the FIFO is 64 samples deep for stereo, or 128 samples for mono.


If we agree on the above I can send some patches for this.


Regards
ChenYu

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

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-10-30  6:16                 ` Jean-Francois Moine
  0 siblings, 0 replies; 170+ messages in thread
From: Jean-Francois Moine @ 2016-10-30  6:16 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Maxime Ripard, Mark Rutland, Linux-ALSA, Liam Girdwood,
	Mike Turquette, Takashi Iwai, linux-sunxi, Alexandre Belloni,
	Lee Jones, linux-clk, Vinod Koul, Mylène Josserand,
	devicetree, Rob Herring, Jaroslav Kysela, linux-arm-kernel,
	Thomas Petazzoni, Stephen Boyd, linux-kernel, Mark Brown,
	dmaengine

On Sun, 30 Oct 2016 10:06:20 +0800
Chen-Yu Tsai <wens@csie.org> wrote:

> >> Yes, I know that the burst size is always a power of 2.
> >> The best way to check it would be to change the {src,dts}_maxburst to a
> >> bitmap of the possible bursts as 0x0d for 1,4 and 8 bytes. But this
> >> asks for a lot of changes...
> >
> > To be honest, I'm not really a big fan of those tree wide changes
> > without any way to maintain compatibility. It ends up in a single,
> > huge patch if we want to maintain bisectability that just isn't
> > reviewable.
> 
> Looking at the dmaengine API, I believe we got it wrong.
> 
> max_burst in dma_slave_config denotes the largest amount of data
> a single transfer should be, as described in dmaengine.h:
> 
>  * @src_maxburst: the maximum number of words (note: words, as in
>  * units of the src_addr_width member, not bytes) that can be sent
>  * in one burst to the device. Typically something like half the
>  * FIFO depth on I/O peripherals so you don't overflow it. This
>  * may or may not be applicable on memory sources.
>  * @dst_maxburst: same as src_maxburst but for destination target
>  * mutatis mutandis.
> 
> The DMA engine driver should be free to select whatever burst size
> that doesn't exceed this. So for max_burst = 4, the driver can select
> burst = 4 for controllers that do support it, or burst = 1 for those
> that don't, and do more bursts.
> 
> This also means we can increase max_burst for the audio codec, as
> the FIFO is 64 samples deep for stereo, or 128 samples for mono.
> 
> 
> If we agree on the above I can send some patches for this.

That's fine to me, but this does not solve the main problem which is
how/where are defined the possible bursts of a SoC.

-- 
Ken ar c'hentañ	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

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

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-10-30  6:16                 ` Jean-Francois Moine
  0 siblings, 0 replies; 170+ messages in thread
From: Jean-Francois Moine @ 2016-10-30  6:16 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Maxime Ripard, Mark Rutland, Linux-ALSA, Liam Girdwood,
	Mike Turquette, Takashi Iwai, linux-sunxi, Alexandre Belloni,
	Lee Jones, linux-clk, Vinod Koul, Mylène Josserand,
	devicetree, Rob Herring, Jaroslav Kysela, linux-arm-kernel,
	Thomas Petazzoni, Stephen Boyd, linux-kernel, Mark Brown,
	dmaengine-u79uwXL29TasMV2rI37PzA

On Sun, 30 Oct 2016 10:06:20 +0800
Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org> wrote:

> >> Yes, I know that the burst size is always a power of 2.
> >> The best way to check it would be to change the {src,dts}_maxburst to a
> >> bitmap of the possible bursts as 0x0d for 1,4 and 8 bytes. But this
> >> asks for a lot of changes...
> >
> > To be honest, I'm not really a big fan of those tree wide changes
> > without any way to maintain compatibility. It ends up in a single,
> > huge patch if we want to maintain bisectability that just isn't
> > reviewable.
> 
> Looking at the dmaengine API, I believe we got it wrong.
> 
> max_burst in dma_slave_config denotes the largest amount of data
> a single transfer should be, as described in dmaengine.h:
> 
>  * @src_maxburst: the maximum number of words (note: words, as in
>  * units of the src_addr_width member, not bytes) that can be sent
>  * in one burst to the device. Typically something like half the
>  * FIFO depth on I/O peripherals so you don't overflow it. This
>  * may or may not be applicable on memory sources.
>  * @dst_maxburst: same as src_maxburst but for destination target
>  * mutatis mutandis.
> 
> The DMA engine driver should be free to select whatever burst size
> that doesn't exceed this. So for max_burst = 4, the driver can select
> burst = 4 for controllers that do support it, or burst = 1 for those
> that don't, and do more bursts.
> 
> This also means we can increase max_burst for the audio codec, as
> the FIFO is 64 samples deep for stereo, or 128 samples for mono.
> 
> 
> If we agree on the above I can send some patches for this.

That's fine to me, but this does not solve the main problem which is
how/where are defined the possible bursts of a SoC.

-- 
Ken ar c'hentañ	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

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

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-10-30  6:16                 ` Jean-Francois Moine
  0 siblings, 0 replies; 170+ messages in thread
From: Jean-Francois Moine @ 2016-10-30  6:16 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: Maxime Ripard, Mark Rutland, Linux-ALSA, Liam Girdwood,
	Mike Turquette, Takashi Iwai, linux-sunxi, Alexandre Belloni,
	Lee Jones, linux-clk, Vinod Koul, Mylène Josserand,
	devicetree, Rob Herring, Jaroslav Kysela, linux-arm-kernel,
	Thomas Petazzoni, Stephen Boyd, linux-kernel, Mark Brown,
	dmaengine

On Sun, 30 Oct 2016 10:06:20 +0800
Chen-Yu Tsai <wens@csie.org> wrote:

> >> Yes, I know that the burst size is always a power of 2.
> >> The best way to check it would be to change the {src,dts}_maxburst to a
> >> bitmap of the possible bursts as 0x0d for 1,4 and 8 bytes. But this
> >> asks for a lot of changes...
> >
> > To be honest, I'm not really a big fan of those tree wide changes
> > without any way to maintain compatibility. It ends up in a single,
> > huge patch if we want to maintain bisectability that just isn't
> > reviewable.
>=20
> Looking at the dmaengine API, I believe we got it wrong.
>=20
> max_burst in dma_slave_config denotes the largest amount of data
> a single transfer should be, as described in dmaengine.h:
>=20
>  * @src_maxburst: the maximum number of words (note: words, as in
>  * units of the src_addr_width member, not bytes) that can be sent
>  * in one burst to the device. Typically something like half the
>  * FIFO depth on I/O peripherals so you don't overflow it. This
>  * may or may not be applicable on memory sources.
>  * @dst_maxburst: same as src_maxburst but for destination target
>  * mutatis mutandis.
>=20
> The DMA engine driver should be free to select whatever burst size
> that doesn't exceed this. So for max_burst =3D 4, the driver can select
> burst =3D 4 for controllers that do support it, or burst =3D 1 for those
> that don't, and do more bursts.
>=20
> This also means we can increase max_burst for the audio codec, as
> the FIFO is 64 samples deep for stereo, or 128 samples for mono.
>=20
>=20
> If we agree on the above I can send some patches for this.

That's fine to me, but this does not solve the main problem which is
how/where are defined the possible bursts of a SoC.

--=20
Ken ar c'henta=F1	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

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

* [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-10-30  6:16                 ` Jean-Francois Moine
  0 siblings, 0 replies; 170+ messages in thread
From: Jean-Francois Moine @ 2016-10-30  6:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, 30 Oct 2016 10:06:20 +0800
Chen-Yu Tsai <wens@csie.org> wrote:

> >> Yes, I know that the burst size is always a power of 2.
> >> The best way to check it would be to change the {src,dts}_maxburst to a
> >> bitmap of the possible bursts as 0x0d for 1,4 and 8 bytes. But this
> >> asks for a lot of changes...
> >
> > To be honest, I'm not really a big fan of those tree wide changes
> > without any way to maintain compatibility. It ends up in a single,
> > huge patch if we want to maintain bisectability that just isn't
> > reviewable.
> 
> Looking at the dmaengine API, I believe we got it wrong.
> 
> max_burst in dma_slave_config denotes the largest amount of data
> a single transfer should be, as described in dmaengine.h:
> 
>  * @src_maxburst: the maximum number of words (note: words, as in
>  * units of the src_addr_width member, not bytes) that can be sent
>  * in one burst to the device. Typically something like half the
>  * FIFO depth on I/O peripherals so you don't overflow it. This
>  * may or may not be applicable on memory sources.
>  * @dst_maxburst: same as src_maxburst but for destination target
>  * mutatis mutandis.
> 
> The DMA engine driver should be free to select whatever burst size
> that doesn't exceed this. So for max_burst = 4, the driver can select
> burst = 4 for controllers that do support it, or burst = 1 for those
> that don't, and do more bursts.
> 
> This also means we can increase max_burst for the audio codec, as
> the FIFO is 64 samples deep for stereo, or 128 samples for mono.
> 
> 
> If we agree on the above I can send some patches for this.

That's fine to me, but this does not solve the main problem which is
how/where are defined the possible bursts of a SoC.

-- 
Ken ar c'henta?	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/

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

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-11-01 13:46                 ` Koul, Vinod
  0 siblings, 0 replies; 170+ messages in thread
From: Koul, Vinod @ 2016-11-01 13:46 UTC (permalink / raw)
  To: wens, maxime.ripard
  Cc: linux-kernel, robh+dt, thomas.petazzoni, mturquette, moinejf,
	devicetree, linux-sunxi, lee.jones, broonie, mark.rutland,
	alexandre.belloni, dmaengine, tiwai, lgirdwood, linux-arm-kernel,
	mylene.josserand, sboyd, perex, alsa-devel, linux-clk

On Sun, 2016-10-30 at 10:06 +0800, Chen-Yu Tsai wrote:
> Looking at the dmaengine API, I believe we got it wrong.
> 
> max_burst in dma_slave_config denotes the largest amount of data
> a single transfer should be, as described in dmaengine.h:

Not a single transfer but smallest transaction within a transfer of a
block. So dmaengines transfer data in bursts from source to destination,
this parameter decides the size of that bursts

> 
>  * @src_maxburst: the maximum number of words (note: words, as in
>  * units of the src_addr_width member, not bytes) that can be sent
>  * in one burst to the device. Typically something like half the
>  * FIFO depth on I/O peripherals so you don't overflow it. This
>  * may or may not be applicable on memory sources.
>  * @dst_maxburst: same as src_maxburst but for destination target
>  * mutatis mutandis.
> 
> The DMA engine driver should be free to select whatever burst size
> that doesn't exceed this. So for max_burst = 4, the driver can select
> burst = 4 for controllers that do support it, or burst = 1 for those
> that don't, and do more bursts.

Nope, the client configures these parameters and dmaengine driver
validates and programs

> 
> This also means we can increase max_burst for the audio codec, as
> the FIFO is 64 samples deep for stereo, or 128 samples for mono.

Beware that higher bursts means chance of underrun of FIFO. This value
is selected with consideration of power and performance required. Lazy
allocation would be half of FIFO size..

-- 
~Vinod

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

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-11-01 13:46                 ` Koul, Vinod
  0 siblings, 0 replies; 170+ messages in thread
From: Koul, Vinod @ 2016-11-01 13:46 UTC (permalink / raw)
  To: wens-jdAy2FN1RRM, maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	mturquette-rdvid1DuHRBWk0Htik3J/w, moinejf-GANU6spQydw,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A, broonie-DgEjT+Ai2ygdnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8,
	alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	dmaengine-u79uwXL29TY76Z2rM5mHXA, tiwai-IBi9RG/b67k,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	mylene.josserand-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org

On Sun, 2016-10-30 at 10:06 +0800, Chen-Yu Tsai wrote:
> Looking at the dmaengine API, I believe we got it wrong.
> 
> max_burst in dma_slave_config denotes the largest amount of data
> a single transfer should be, as described in dmaengine.h:

Not a single transfer but smallest transaction within a transfer of a
block. So dmaengines transfer data in bursts from source to destination,
this parameter decides the size of that bursts

> 
>  * @src_maxburst: the maximum number of words (note: words, as in
>  * units of the src_addr_width member, not bytes) that can be sent
>  * in one burst to the device. Typically something like half the
>  * FIFO depth on I/O peripherals so you don't overflow it. This
>  * may or may not be applicable on memory sources.
>  * @dst_maxburst: same as src_maxburst but for destination target
>  * mutatis mutandis.
> 
> The DMA engine driver should be free to select whatever burst size
> that doesn't exceed this. So for max_burst = 4, the driver can select
> burst = 4 for controllers that do support it, or burst = 1 for those
> that don't, and do more bursts.

Nope, the client configures these parameters and dmaengine driver
validates and programs

> 
> This also means we can increase max_burst for the audio codec, as
> the FIFO is 64 samples deep for stereo, or 128 samples for mono.

Beware that higher bursts means chance of underrun of FIFO. This value
is selected with consideration of power and performance required. Lazy
allocation would be half of FIFO size..

-- 
~Vinod

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

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

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-11-01 13:46                 ` Koul, Vinod
  0 siblings, 0 replies; 170+ messages in thread
From: Koul, Vinod @ 2016-11-01 13:46 UTC (permalink / raw)
  To: wens, maxime.ripard
  Cc: linux-kernel, robh+dt, thomas.petazzoni, mturquette, moinejf,
	devicetree, linux-sunxi, lee.jones, broonie, mark.rutland,
	alexandre.belloni, dmaengine, tiwai, lgirdwood, linux-arm-kernel,
	mylene.josserand, sboyd, perex, alsa-devel, linux-clk

On Sun, 2016-10-30 at 10:06 +0800, Chen-Yu Tsai wrote:
> Looking at the dmaengine API, I believe we got it wrong.
>=20
> max_burst in dma_slave_config denotes the largest amount =
of data
> a single transfer should be, as described in dmaengine.h:

Not a single transfer but smallest transaction within a transfer of a
block. So dmaengines transfer data in bursts from source to destination,
this parameter decides the size of that bursts

>=20
>  * @src_maxburst: the maximum number of words (note: wo=
rds, as in
>  * units of the src_addr_width member, not bytes) that =
can be sent
>  * in one burst to the device. Typically something like half th=
e
>  * FIFO depth on I/O peripherals so you don't overflow it. This
>  * may or may not be applicable on memory sources.
>  * @dst_maxburst: same as src_maxburst but for dest=
ination target
>  * mutatis mutandis.
>=20
> The DMA engine driver should be free to select whatever burst size
> that doesn't exceed this. So for max_burst = 4, the driver ca=
n select
> burst = 4 for controllers that do support it, or burst = 1 fo=
r those
> that don't, and do more bursts.

Nope, the client configures these parameters and dmaengine driver
validates and programs

>=20
> This also means we can increase max_burst for the audio codec, as
> the FIFO is 64 samples deep for stereo, or 128 samples for mono.

Beware that higher bursts means chance of underrun of FIFO. This value
is selected with consideration of power and performance required. Lazy
allocation would be half of FIFO size..

-- 
~Vinod

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

* [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-11-01 13:46                 ` Koul, Vinod
  0 siblings, 0 replies; 170+ messages in thread
From: Koul, Vinod @ 2016-11-01 13:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, 2016-10-30 at 10:06 +0800, Chen-Yu Tsai wrote:
> Looking at the dmaengine API, I believe we got it wrong.
> 
> max_burst in dma_slave_config denotes the largest amount of data
> a single transfer should be, as described in dmaengine.h:

Not a single transfer but smallest transaction within a transfer of a
block. So dmaengines transfer data in bursts from source to destination,
this parameter decides the size of that bursts

> 
> ?* @src_maxburst: the maximum number of words (note: words, as in
> ?* units of the src_addr_width member, not bytes) that can be sent
> ?* in one burst to the device. Typically something like half the
> ?* FIFO depth on I/O peripherals so you don't overflow it. This
> ?* may or may not be applicable on memory sources.
> ?* @dst_maxburst: same as src_maxburst but for destination target
> ?* mutatis mutandis.
> 
> The DMA engine driver should be free to select whatever burst size
> that doesn't exceed this. So for max_burst = 4, the driver can select
> burst = 4 for controllers that do support it, or burst = 1 for those
> that don't, and do more bursts.

Nope, the client configures these parameters and dmaengine driver
validates and programs

> 
> This also means we can increase max_burst for the audio codec, as
> the FIFO is 64 samples deep for stereo, or 128 samples for mono.

Beware that higher bursts means chance of underrun of FIFO. This value
is selected with consideration of power and performance required. Lazy
allocation would be half of FIFO size..

--?
~Vinod

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

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-11-01 14:55                   ` Chen-Yu Tsai
  0 siblings, 0 replies; 170+ messages in thread
From: Chen-Yu Tsai @ 2016-11-01 14:55 UTC (permalink / raw)
  To: Koul, Vinod
  Cc: wens, maxime.ripard, linux-kernel, robh+dt, thomas.petazzoni,
	mturquette, moinejf, devicetree, linux-sunxi, lee.jones, broonie,
	mark.rutland, alexandre.belloni, dmaengine, tiwai, lgirdwood,
	linux-arm-kernel, mylene.josserand, sboyd, perex, alsa-devel,
	linux-clk

On Tue, Nov 1, 2016 at 9:46 PM, Koul, Vinod <vinod.koul@intel.com> wrote:
> On Sun, 2016-10-30 at 10:06 +0800, Chen-Yu Tsai wrote:
>> Looking at the dmaengine API, I believe we got it wrong.
>>
>> max_burst in dma_slave_config denotes the largest amount of data
>> a single transfer should be, as described in dmaengine.h:
>
> Not a single transfer but smallest transaction within a transfer of a
> block. So dmaengines transfer data in bursts from source to destination,
> this parameter decides the size of that bursts

Right.

>
>>
>>  * @src_maxburst: the maximum number of words (note: words, as in
>>  * units of the src_addr_width member, not bytes) that can be sent
>>  * in one burst to the device. Typically something like half the
>>  * FIFO depth on I/O peripherals so you don't overflow it. This
>>  * may or may not be applicable on memory sources.
>>  * @dst_maxburst: same as src_maxburst but for destination target
>>  * mutatis mutandis.
>>
>> The DMA engine driver should be free to select whatever burst size
>> that doesn't exceed this. So for max_burst = 4, the driver can select
>> burst = 4 for controllers that do support it, or burst = 1 for those
>> that don't, and do more bursts.
>
> Nope, the client configures these parameters and dmaengine driver
> validates and programs

Shouldn't we just name it "burst_size" then if it's meant to be what
the client specifically asks for?

My understanding is that the client configures its own parameters,
such as the trigger level for the DRQ, like raise DRQ when level < 1/4
FIFO depth, request maxburst = 1/4 or 1/2 FIFO depth, so as not to
overrun the FIFO. When the DRQ is raised, the DMA engine will do a
burst, and after the burst the DRQ would be low again, so the DMA
engine will wait. So the DMA engine driver should be free to
program the actual burst size to something less than maxburst, shouldn't
it?

>>
>> This also means we can increase max_burst for the audio codec, as
>> the FIFO is 64 samples deep for stereo, or 128 samples for mono.
>
> Beware that higher bursts means chance of underrun of FIFO. This value
> is selected with consideration of power and performance required. Lazy
> allocation would be half of FIFO size..

You mean underrun if its the source right? So the client setting maxburst
should take the DRQ trigger level into account for this.


Regards
ChenYu

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

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-11-01 14:55                   ` Chen-Yu Tsai
  0 siblings, 0 replies; 170+ messages in thread
From: Chen-Yu Tsai @ 2016-11-01 14:55 UTC (permalink / raw)
  To: Koul, Vinod
  Cc: wens-jdAy2FN1RRM, maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	mturquette-rdvid1DuHRBWk0Htik3J/w, moinejf-GANU6spQydw,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A, broonie-DgEjT+Ai2ygdnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8,
	alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	dmaengine-u79uwXL29TY76Z2rM5mHXA, tiwai-IBi9RG/b67k,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, linux-arm-kernel

On Tue, Nov 1, 2016 at 9:46 PM, Koul, Vinod <vinod.koul-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org> wrote:
> On Sun, 2016-10-30 at 10:06 +0800, Chen-Yu Tsai wrote:
>> Looking at the dmaengine API, I believe we got it wrong.
>>
>> max_burst in dma_slave_config denotes the largest amount of data
>> a single transfer should be, as described in dmaengine.h:
>
> Not a single transfer but smallest transaction within a transfer of a
> block. So dmaengines transfer data in bursts from source to destination,
> this parameter decides the size of that bursts

Right.

>
>>
>>  * @src_maxburst: the maximum number of words (note: words, as in
>>  * units of the src_addr_width member, not bytes) that can be sent
>>  * in one burst to the device. Typically something like half the
>>  * FIFO depth on I/O peripherals so you don't overflow it. This
>>  * may or may not be applicable on memory sources.
>>  * @dst_maxburst: same as src_maxburst but for destination target
>>  * mutatis mutandis.
>>
>> The DMA engine driver should be free to select whatever burst size
>> that doesn't exceed this. So for max_burst = 4, the driver can select
>> burst = 4 for controllers that do support it, or burst = 1 for those
>> that don't, and do more bursts.
>
> Nope, the client configures these parameters and dmaengine driver
> validates and programs

Shouldn't we just name it "burst_size" then if it's meant to be what
the client specifically asks for?

My understanding is that the client configures its own parameters,
such as the trigger level for the DRQ, like raise DRQ when level < 1/4
FIFO depth, request maxburst = 1/4 or 1/2 FIFO depth, so as not to
overrun the FIFO. When the DRQ is raised, the DMA engine will do a
burst, and after the burst the DRQ would be low again, so the DMA
engine will wait. So the DMA engine driver should be free to
program the actual burst size to something less than maxburst, shouldn't
it?

>>
>> This also means we can increase max_burst for the audio codec, as
>> the FIFO is 64 samples deep for stereo, or 128 samples for mono.
>
> Beware that higher bursts means chance of underrun of FIFO. This value
> is selected with consideration of power and performance required. Lazy
> allocation would be half of FIFO size..

You mean underrun if its the source right? So the client setting maxburst
should take the DRQ trigger level into account for this.


Regards
ChenYu

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

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-11-01 14:55                   ` Chen-Yu Tsai
  0 siblings, 0 replies; 170+ messages in thread
From: Chen-Yu Tsai @ 2016-11-01 14:55 UTC (permalink / raw)
  To: Koul, Vinod
  Cc: wens, maxime.ripard, linux-kernel, robh+dt, thomas.petazzoni,
	mturquette, moinejf, devicetree, linux-sunxi, lee.jones, broonie,
	mark.rutland, alexandre.belloni, dmaengine, tiwai, lgirdwood,
	linux-arm-kernel, mylene.josserand, sboyd, perex, alsa-devel,
	linux-clk

On Tue, Nov 1, 2016 at 9:46 PM, Koul, Vinod <vinod.koul@intel.com> wrote:
> On Sun, 2016-10-30 at 10:06 +0800, Chen-Yu Tsai wrote:
>> Looking at the dmaengine API, I believe we got it wrong.
>>
>> max_burst in dma_slave_config denotes the largest amount of data
>> a single transfer should be, as described in dmaengine.h:
>
> Not a single transfer but smallest transaction within a transfer of a
> block. So dmaengines transfer data in bursts from source to destination,
> this parameter decides the size of that bursts

Right.

>
>>
>>  * @src_maxburst: the maximum number of words (note: words, as in
>>  * units of the src_addr_width member, not bytes) that can be sent
>>  * in one burst to the device. Typically something like half the
>>  * FIFO depth on I/O peripherals so you don't overflow it. This
>>  * may or may not be applicable on memory sources.
>>  * @dst_maxburst: same as src_maxburst but for destination target
>>  * mutatis mutandis.
>>
>> The DMA engine driver should be free to select whatever burst size
>> that doesn't exceed this. So for max_burst = 4, the driver can select
>> burst = 4 for controllers that do support it, or burst = 1 for those
>> that don't, and do more bursts.
>
> Nope, the client configures these parameters and dmaengine driver
> validates and programs

Shouldn't we just name it "burst_size" then if it's meant to be what
the client specifically asks for?

My understanding is that the client configures its own parameters,
such as the trigger level for the DRQ, like raise DRQ when level < 1/4
FIFO depth, request maxburst = 1/4 or 1/2 FIFO depth, so as not to
overrun the FIFO. When the DRQ is raised, the DMA engine will do a
burst, and after the burst the DRQ would be low again, so the DMA
engine will wait. So the DMA engine driver should be free to
program the actual burst size to something less than maxburst, shouldn't
it?

>>
>> This also means we can increase max_burst for the audio codec, as
>> the FIFO is 64 samples deep for stereo, or 128 samples for mono.
>
> Beware that higher bursts means chance of underrun of FIFO. This value
> is selected with consideration of power and performance required. Lazy
> allocation would be half of FIFO size..

You mean underrun if its the source right? So the client setting maxburst
should take the DRQ trigger level into account for this.


Regards
ChenYu

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

* [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-11-01 14:55                   ` Chen-Yu Tsai
  0 siblings, 0 replies; 170+ messages in thread
From: Chen-Yu Tsai @ 2016-11-01 14:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Nov 1, 2016 at 9:46 PM, Koul, Vinod <vinod.koul@intel.com> wrote:
> On Sun, 2016-10-30 at 10:06 +0800, Chen-Yu Tsai wrote:
>> Looking at the dmaengine API, I believe we got it wrong.
>>
>> max_burst in dma_slave_config denotes the largest amount of data
>> a single transfer should be, as described in dmaengine.h:
>
> Not a single transfer but smallest transaction within a transfer of a
> block. So dmaengines transfer data in bursts from source to destination,
> this parameter decides the size of that bursts

Right.

>
>>
>>  * @src_maxburst: the maximum number of words (note: words, as in
>>  * units of the src_addr_width member, not bytes) that can be sent
>>  * in one burst to the device. Typically something like half the
>>  * FIFO depth on I/O peripherals so you don't overflow it. This
>>  * may or may not be applicable on memory sources.
>>  * @dst_maxburst: same as src_maxburst but for destination target
>>  * mutatis mutandis.
>>
>> The DMA engine driver should be free to select whatever burst size
>> that doesn't exceed this. So for max_burst = 4, the driver can select
>> burst = 4 for controllers that do support it, or burst = 1 for those
>> that don't, and do more bursts.
>
> Nope, the client configures these parameters and dmaengine driver
> validates and programs

Shouldn't we just name it "burst_size" then if it's meant to be what
the client specifically asks for?

My understanding is that the client configures its own parameters,
such as the trigger level for the DRQ, like raise DRQ when level < 1/4
FIFO depth, request maxburst = 1/4 or 1/2 FIFO depth, so as not to
overrun the FIFO. When the DRQ is raised, the DMA engine will do a
burst, and after the burst the DRQ would be low again, so the DMA
engine will wait. So the DMA engine driver should be free to
program the actual burst size to something less than maxburst, shouldn't
it?

>>
>> This also means we can increase max_burst for the audio codec, as
>> the FIFO is 64 samples deep for stereo, or 128 samples for mono.
>
> Beware that higher bursts means chance of underrun of FIFO. This value
> is selected with consideration of power and performance required. Lazy
> allocation would be half of FIFO size..

You mean underrun if its the source right? So the client setting maxburst
should take the DRQ trigger level into account for this.


Regards
ChenYu

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

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
  2016-11-01 14:55                   ` Chen-Yu Tsai
  (?)
  (?)
@ 2016-11-14  4:54                     ` Vinod Koul
  -1 siblings, 0 replies; 170+ messages in thread
From: Vinod Koul @ 2016-11-14  4:54 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: maxime.ripard, linux-kernel, robh+dt, thomas.petazzoni,
	mturquette, moinejf, devicetree, linux-sunxi, lee.jones, broonie,
	mark.rutland, alexandre.belloni, dmaengine, tiwai, lgirdwood,
	linux-arm-kernel, mylene.josserand, sboyd, perex, alsa-devel,
	linux-clk

On Tue, Nov 01, 2016 at 10:55:13PM +0800, Chen-Yu Tsai wrote:

> >>  * @src_maxburst: the maximum number of words (note: words, as in
> >>  * units of the src_addr_width member, not bytes) that can be sent
> >>  * in one burst to the device. Typically something like half the
> >>  * FIFO depth on I/O peripherals so you don't overflow it. This
> >>  * may or may not be applicable on memory sources.
> >>  * @dst_maxburst: same as src_maxburst but for destination target
> >>  * mutatis mutandis.
> >>
> >> The DMA engine driver should be free to select whatever burst size
> >> that doesn't exceed this. So for max_burst = 4, the driver can select
> >> burst = 4 for controllers that do support it, or burst = 1 for those
> >> that don't, and do more bursts.
> >
> > Nope, the client configures these parameters and dmaengine driver
> > validates and programs
> 
> Shouldn't we just name it "burst_size" then if it's meant to be what
> the client specifically asks for?

Well if for some reason we program lesser than than max it would work
technically. But a larger burst wont work at all, so thats why maxburst is
significant.

> My understanding is that the client configures its own parameters,
> such as the trigger level for the DRQ, like raise DRQ when level < 1/4
> FIFO depth, request maxburst = 1/4 or 1/2 FIFO depth, so as not to
> overrun the FIFO. When the DRQ is raised, the DMA engine will do a
> burst, and after the burst the DRQ would be low again, so the DMA
> engine will wait. So the DMA engine driver should be free to
> program the actual burst size to something less than maxburst, shouldn't
> it?

Yup but not more that max..

> >> This also means we can increase max_burst for the audio codec, as
> >> the FIFO is 64 samples deep for stereo, or 128 samples for mono.
> >
> > Beware that higher bursts means chance of underrun of FIFO. This value
> > is selected with consideration of power and performance required. Lazy
> > allocation would be half of FIFO size..
> 
> You mean underrun if its the source right? So the client setting maxburst
> should take the DRQ trigger level into account for this.

Yes

-- 
~Vinod

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

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-11-14  4:54                     ` Vinod Koul
  0 siblings, 0 replies; 170+ messages in thread
From: Vinod Koul @ 2016-11-14  4:54 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: maxime.ripard, linux-kernel, robh+dt, thomas.petazzoni,
	mturquette, moinejf, devicetree, linux-sunxi, lee.jones, broonie,
	mark.rutland, alexandre.belloni, dmaengine, tiwai

On Tue, Nov 01, 2016 at 10:55:13PM +0800, Chen-Yu Tsai wrote:

> >>  * @src_maxburst: the maximum number of words (note: words, as in
> >>  * units of the src_addr_width member, not bytes) that can be sent
> >>  * in one burst to the device. Typically something like half the
> >>  * FIFO depth on I/O peripherals so you don't overflow it. This
> >>  * may or may not be applicable on memory sources.
> >>  * @dst_maxburst: same as src_maxburst but for destination target
> >>  * mutatis mutandis.
> >>
> >> The DMA engine driver should be free to select whatever burst size
> >> that doesn't exceed this. So for max_burst = 4, the driver can select
> >> burst = 4 for controllers that do support it, or burst = 1 for those
> >> that don't, and do more bursts.
> >
> > Nope, the client configures these parameters and dmaengine driver
> > validates and programs
> 
> Shouldn't we just name it "burst_size" then if it's meant to be what
> the client specifically asks for?

Well if for some reason we program lesser than than max it would work
technically. But a larger burst wont work at all, so thats why maxburst is
significant.

> My understanding is that the client configures its own parameters,
> such as the trigger level for the DRQ, like raise DRQ when level < 1/4
> FIFO depth, request maxburst = 1/4 or 1/2 FIFO depth, so as not to
> overrun the FIFO. When the DRQ is raised, the DMA engine will do a
> burst, and after the burst the DRQ would be low again, so the DMA
> engine will wait. So the DMA engine driver should be free to
> program the actual burst size to something less than maxburst, shouldn't
> it?

Yup but not more that max..

> >> This also means we can increase max_burst for the audio codec, as
> >> the FIFO is 64 samples deep for stereo, or 128 samples for mono.
> >
> > Beware that higher bursts means chance of underrun of FIFO. This value
> > is selected with consideration of power and performance required. Lazy
> > allocation would be half of FIFO size..
> 
> You mean underrun if its the source right? So the client setting maxburst
> should take the DRQ trigger level into account for this.

Yes

-- 
~Vinod

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

* Re: [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-11-14  4:54                     ` Vinod Koul
  0 siblings, 0 replies; 170+ messages in thread
From: Vinod Koul @ 2016-11-14  4:54 UTC (permalink / raw)
  To: Chen-Yu Tsai
  Cc: maxime.ripard, linux-kernel, robh+dt, thomas.petazzoni,
	mturquette, moinejf, devicetree, linux-sunxi, lee.jones, broonie,
	mark.rutland, alexandre.belloni, dmaengine, tiwai, lgirdwood,
	linux-arm-kernel, mylene.josserand, sboyd, perex, alsa-devel,
	linux-clk

On Tue, Nov 01, 2016 at 10:55:13PM +0800, Chen-Yu Tsai wrote:

> >>  * @src_maxburst: the maximum number of words (note: words, as in
> >>  * units of the src_addr_width member, not bytes) that can be sent
> >>  * in one burst to the device. Typically something like half the
> >>  * FIFO depth on I/O peripherals so you don't overflow it. This
> >>  * may or may not be applicable on memory sources.
> >>  * @dst_maxburst: same as src_maxburst but for destination target
> >>  * mutatis mutandis.
> >>
> >> The DMA engine driver should be free to select whatever burst size
> >> that doesn't exceed this. So for max_burst = 4, the driver can select
> >> burst = 4 for controllers that do support it, or burst = 1 for those
> >> that don't, and do more bursts.
> >
> > Nope, the client configures these parameters and dmaengine driver
> > validates and programs
> 
> Shouldn't we just name it "burst_size" then if it's meant to be what
> the client specifically asks for?

Well if for some reason we program lesser than than max it would work
technically. But a larger burst wont work at all, so thats why maxburst is
significant.

> My understanding is that the client configures its own parameters,
> such as the trigger level for the DRQ, like raise DRQ when level < 1/4
> FIFO depth, request maxburst = 1/4 or 1/2 FIFO depth, so as not to
> overrun the FIFO. When the DRQ is raised, the DMA engine will do a
> burst, and after the burst the DRQ would be low again, so the DMA
> engine will wait. So the DMA engine driver should be free to
> program the actual burst size to something less than maxburst, shouldn't
> it?

Yup but not more that max..

> >> This also means we can increase max_burst for the audio codec, as
> >> the FIFO is 64 samples deep for stereo, or 128 samples for mono.
> >
> > Beware that higher bursts means chance of underrun of FIFO. This value
> > is selected with consideration of power and performance required. Lazy
> > allocation would be half of FIFO size..
> 
> You mean underrun if its the source right? So the client setting maxburst
> should take the DRQ trigger level into account for this.

Yes

-- 
~Vinod

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

* [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
@ 2016-11-14  4:54                     ` Vinod Koul
  0 siblings, 0 replies; 170+ messages in thread
From: Vinod Koul @ 2016-11-14  4:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Nov 01, 2016 at 10:55:13PM +0800, Chen-Yu Tsai wrote:

> >>  * @src_maxburst: the maximum number of words (note: words, as in
> >>  * units of the src_addr_width member, not bytes) that can be sent
> >>  * in one burst to the device. Typically something like half the
> >>  * FIFO depth on I/O peripherals so you don't overflow it. This
> >>  * may or may not be applicable on memory sources.
> >>  * @dst_maxburst: same as src_maxburst but for destination target
> >>  * mutatis mutandis.
> >>
> >> The DMA engine driver should be free to select whatever burst size
> >> that doesn't exceed this. So for max_burst = 4, the driver can select
> >> burst = 4 for controllers that do support it, or burst = 1 for those
> >> that don't, and do more bursts.
> >
> > Nope, the client configures these parameters and dmaengine driver
> > validates and programs
> 
> Shouldn't we just name it "burst_size" then if it's meant to be what
> the client specifically asks for?

Well if for some reason we program lesser than than max it would work
technically. But a larger burst wont work at all, so thats why maxburst is
significant.

> My understanding is that the client configures its own parameters,
> such as the trigger level for the DRQ, like raise DRQ when level < 1/4
> FIFO depth, request maxburst = 1/4 or 1/2 FIFO depth, so as not to
> overrun the FIFO. When the DRQ is raised, the DMA engine will do a
> burst, and after the burst the DRQ would be low again, so the DMA
> engine will wait. So the DMA engine driver should be free to
> program the actual burst size to something less than maxburst, shouldn't
> it?

Yup but not more that max..

> >> This also means we can increase max_burst for the audio codec, as
> >> the FIFO is 64 samples deep for stereo, or 128 samples for mono.
> >
> > Beware that higher bursts means chance of underrun of FIFO. This value
> > is selected with consideration of power and performance required. Lazy
> > allocation would be half of FIFO size..
> 
> You mean underrun if its the source right? So the client setting maxburst
> should take the DRQ trigger level into account for this.

Yes

-- 
~Vinod

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

end of thread, other threads:[~2016-11-14  4:54 UTC | newest]

Thread overview: 170+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-04  9:46 [PATCH 00/14] ASoc: sunxi: Add Allwinner A33 codec driver Mylène Josserand
2016-10-04  9:46 ` Mylène Josserand
     [not found] ` <cover.1475571575.git.mylene.josserand@free-electrons.com>
2016-10-04  9:46   ` [PATCH 01/14] dma: sun6i-dma: Add burst case of 4 Mylène Josserand
2016-10-04  9:46     ` Mylène Josserand
2016-10-04 10:40     ` Jean-Francois Moine
2016-10-04 10:40       ` Jean-Francois Moine
2016-10-04 10:40       ` Jean-Francois Moine
2016-10-04 12:12       ` Thomas Petazzoni
2016-10-04 12:12         ` Thomas Petazzoni
2016-10-04 12:12         ` Thomas Petazzoni
2016-10-04 12:12         ` Thomas Petazzoni
2016-10-04 13:46         ` Jean-Francois Moine
2016-10-04 13:46           ` Jean-Francois Moine
2016-10-04 13:46           ` Jean-Francois Moine
2016-10-04 13:46           ` Jean-Francois Moine
2016-10-04 15:40           ` Vinod Koul
2016-10-04 15:40             ` Vinod Koul
2016-10-04 15:40             ` Vinod Koul
2016-10-04 16:55       ` Maxime Ripard
2016-10-04 16:55         ` Maxime Ripard
2016-10-23 16:31         ` Jean-Francois Moine
2016-10-23 16:31           ` Jean-Francois Moine
2016-10-23 16:31           ` Jean-Francois Moine
2016-10-23 16:31           ` Jean-Francois Moine
2016-10-27 17:51           ` Maxime Ripard
2016-10-27 17:51             ` Maxime Ripard
2016-10-27 17:51             ` Maxime Ripard
2016-10-30  2:06             ` Chen-Yu Tsai
2016-10-30  2:06               ` Chen-Yu Tsai
2016-10-30  2:06               ` Chen-Yu Tsai
2016-10-30  2:06               ` Chen-Yu Tsai
2016-10-30  6:16               ` Jean-Francois Moine
2016-10-30  6:16                 ` Jean-Francois Moine
2016-10-30  6:16                 ` Jean-Francois Moine
2016-10-30  6:16                 ` Jean-Francois Moine
2016-11-01 13:46               ` Koul, Vinod
2016-11-01 13:46                 ` Koul, Vinod
2016-11-01 13:46                 ` Koul, Vinod
2016-11-01 13:46                 ` Koul, Vinod
2016-11-01 14:55                 ` Chen-Yu Tsai
2016-11-01 14:55                   ` Chen-Yu Tsai
2016-11-01 14:55                   ` Chen-Yu Tsai
2016-11-01 14:55                   ` Chen-Yu Tsai
2016-11-14  4:54                   ` Vinod Koul
2016-11-14  4:54                     ` Vinod Koul
2016-11-14  4:54                     ` Vinod Koul
2016-11-14  4:54                     ` Vinod Koul
2016-10-04  9:46   ` [PATCH 02/14] clk: ccu-sun8i-a33: Add CLK_SET_RATE_PARENT to ac-dig Mylène Josserand
2016-10-04  9:46     ` Mylène Josserand
2016-10-04 12:12     ` Thomas Petazzoni
2016-10-04 12:12       ` Thomas Petazzoni
2016-10-04 12:12       ` Thomas Petazzoni
2016-10-04 12:12       ` Thomas Petazzoni
2016-10-05  9:37       ` Mylene Josserand
2016-10-05  9:37         ` Mylene Josserand
2016-10-04  9:46   ` [PATCH 03/14] ASoC: sun4i-i2s: Add apb reset Mylène Josserand
2016-10-04  9:46     ` Mylène Josserand
2016-10-04 12:15     ` Thomas Petazzoni
2016-10-04 12:15       ` Thomas Petazzoni
2016-10-04 12:15       ` Thomas Petazzoni
2016-10-04 15:42       ` Maxime Ripard
2016-10-04 15:42         ` Maxime Ripard
2016-10-05  9:43         ` Mylene Josserand
2016-10-05  9:43           ` Mylene Josserand
2016-10-04 12:22     ` Code Kipper
2016-10-04 12:22       ` Code Kipper
2016-10-04 12:22       ` Code Kipper
2016-10-04  9:46   ` [PATCH 04/14] ASoC: Add sun8i analog codec driver Mylène Josserand
2016-10-04  9:46     ` Mylène Josserand
2016-10-04  9:46     ` Mylène Josserand
2016-10-04 10:21     ` Code Kipper
2016-10-04 10:21       ` Code Kipper
2016-10-04 10:21       ` Code Kipper
2016-10-04 10:21       ` Code Kipper
2016-10-04 10:56       ` Chen-Yu Tsai
2016-10-04 10:56         ` Chen-Yu Tsai
2016-10-04 10:56         ` Chen-Yu Tsai
2016-10-04 10:56         ` Chen-Yu Tsai
2016-10-04  9:46   ` [PATCH 05/14] mfd: sun6i-prcm: Add sun8i analog codec as subnode Mylène Josserand
2016-10-04  9:46     ` Mylène Josserand
2016-10-04 10:52     ` Jean-Francois Moine
2016-10-04 10:52       ` Jean-Francois Moine
2016-10-04 10:52       ` Jean-Francois Moine
2016-10-26 14:05     ` Lee Jones
2016-10-26 14:05       ` Lee Jones
2016-10-26 14:05       ` Lee Jones
2016-10-04  9:46   ` [PATCH 06/14] ASoC: Add sun8i digital audio codec Mylène Josserand
2016-10-04  9:46     ` Mylène Josserand
2016-10-04 12:40     ` Thomas Petazzoni
2016-10-04 12:40       ` Thomas Petazzoni
2016-10-04 12:40       ` Thomas Petazzoni
2016-10-04 13:07       ` Mark Brown
2016-10-04 13:07         ` Mark Brown
2016-10-04 13:07         ` Mark Brown
2016-10-04 13:16         ` Thomas Petazzoni
2016-10-04 13:16           ` Thomas Petazzoni
2016-10-04 16:09       ` Maxime Ripard
2016-10-04 16:09         ` Maxime Ripard
2016-10-04 16:09         ` Maxime Ripard
2016-10-05 11:54       ` Mylene Josserand
2016-10-05 11:54         ` Mylene Josserand
2016-10-04 16:15     ` Maxime Ripard
2016-10-04 16:15       ` Maxime Ripard
2016-10-06 16:06       ` Icenowy Zheng
2016-10-06 16:06         ` Icenowy Zheng
2016-10-06 16:06         ` Icenowy Zheng
2016-10-06 18:23         ` Alexandre Belloni
2016-10-06 18:23           ` Alexandre Belloni
2016-10-06 18:23           ` Alexandre Belloni
     [not found]     ` <85cbd9926e52d0aa03f6bbfd8794373d8db491e0.1475571575.git.mylene.josserand-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2016-10-05 10:19       ` Icenowy Zheng
2016-10-05 10:19         ` Icenowy Zheng
2016-10-05 10:19         ` Icenowy Zheng
2016-10-04  9:46   ` [PATCH 07/14] ASoC: Add sun8i audio card Mylène Josserand
2016-10-04  9:46     ` Mylène Josserand
2016-10-04 10:16     ` Code Kipper
2016-10-04 10:16       ` Code Kipper
2016-10-04 10:16       ` Code Kipper
2016-10-04 10:16       ` Code Kipper
2016-10-04 10:59       ` Chen-Yu Tsai
2016-10-04 10:59         ` Chen-Yu Tsai
2016-10-04 10:59         ` Chen-Yu Tsai
2016-10-04 10:59         ` Chen-Yu Tsai
2016-10-04 12:25     ` Thomas Petazzoni
2016-10-04 12:25       ` Thomas Petazzoni
2016-10-04 12:25       ` Thomas Petazzoni
2016-10-05  6:04     ` Code Kipper
2016-10-05  6:04       ` Code Kipper
2016-10-05  6:04       ` Code Kipper
2016-10-05  6:04       ` Code Kipper
2016-10-05 10:03       ` Jean-Francois Moine
2016-10-05 10:03         ` Jean-Francois Moine
2016-10-05 10:03         ` Jean-Francois Moine
2016-10-05 10:03         ` Jean-Francois Moine
2016-10-04  9:46   ` [PATCH 08/14] dt-bindings: sound: Add sun8i analog codec documentation Mylène Josserand
2016-10-04  9:46     ` Mylène Josserand
2016-10-04 10:32     ` Mark Brown
2016-10-04 10:32       ` Mark Brown
2016-10-04 10:32       ` Mark Brown
2016-10-04 16:24     ` Maxime Ripard
2016-10-04 16:24       ` Maxime Ripard
2016-10-04 16:24       ` Maxime Ripard
2016-10-05  2:59       ` Chen-Yu Tsai
2016-10-05  2:59         ` Chen-Yu Tsai
2016-10-05  2:59         ` Chen-Yu Tsai
2016-10-05  2:59         ` Chen-Yu Tsai
2016-10-05 12:08         ` Mylene Josserand
2016-10-05 12:08           ` Mylene Josserand
2016-10-05 12:08           ` Mylene Josserand
2016-10-04  9:46   ` [PATCH 09/14] dt-bindings: sound: Add sun8i " Mylène Josserand
2016-10-04  9:46     ` Mylène Josserand
2016-10-04  9:46     ` Mylène Josserand
2016-10-04 16:19     ` Maxime Ripard
2016-10-04 16:19       ` Maxime Ripard
2016-10-04  9:46   ` [PATCH 10/14] dt-bindings: sound: Add sun8i audio card documentation Mylène Josserand
2016-10-04  9:46     ` Mylène Josserand
2016-10-04  9:46     ` Mylène Josserand
2016-10-04 16:32     ` Maxime Ripard
2016-10-04 16:32       ` Maxime Ripard
2016-10-04 16:32       ` Maxime Ripard
2016-10-04  9:46   ` [PATCH 11/14] ARM: dts: sun8i: Add analog codec on prcm node Mylène Josserand
2016-10-04  9:46     ` Mylène Josserand
2016-10-04  9:46   ` [PATCH 12/14] ARM: dts: sun8i: Add audio codec, dai and card for A33 Mylène Josserand
2016-10-04  9:46     ` Mylène Josserand
2016-10-04  9:46   ` [PATCH 13/14] ARM: dts: sun8i: parrot: Enable audio nodes Mylène Josserand
2016-10-04  9:46     ` Mylène Josserand
2016-10-04  9:46   ` [PATCH 14/14] ARM: dts: sun8i: sinlinx: " Mylène Josserand
2016-10-04  9:46     ` Mylène Josserand
     [not found] ` <cover.1475569400.git.mylene.josserand-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
2016-10-07  8:35   ` [PATCH 00/14] ASoc: sunxi: Add Allwinner A33 codec driver Icenowy Zheng
2016-10-07  8:35     ` Icenowy Zheng
2016-10-07  8:35     ` Icenowy Zheng

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.