Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 2/4] drivers: iio: ti_am335x_adc: add dma support
From: Peter Ujfalusi @ 2016-10-04  8:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161003130318.12591-3-mugunthanvnm@ti.com>

On 10/03/16 16:03, Mugunthan V N wrote:
> +static int tiadc_request_dma(struct platform_device *pdev,
> +			     struct tiadc_device *adc_dev)
> +{
> +	struct tiadc_dma	*dma = &adc_dev->dma;
> +	dma_cap_mask_t		mask;
> +
> +	/* Default slave configuration parameters */
> +	dma->conf.direction = DMA_DEV_TO_MEM;
> +	dma->conf.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
> +	dma->conf.src_addr = adc_dev->mfd_tscadc->tscadc_phys_base + REG_FIFO1;
> +
> +	dma_cap_zero(mask);
> +	dma_cap_set(DMA_CYCLIC, mask);
> +
> +	/* Get a channel for RX */
> +	dma->chan = dma_request_chan(adc_dev->mfd_tscadc->dev, "fifo1");
> +	if (!dma->chan)
> +		return -ENODEV;

dma_request_chan() ERR_PTR in case of failure, never NULL. You should reuse
the returned error code to support deferred probing.

> +
> +	/* RX buffer */
> +	dma->buf = dma_alloc_coherent(dma->chan->device->dev, DMA_BUFFER_SIZE,
> +				      &dma->addr, GFP_KERNEL);
> +	if (!dma->buf)
> +		goto err;
> +
> +	return 0;
> +err:
> +	dma_release_channel(dma->chan);
> +
> +	return -ENOMEM;
> +}
> +
>  static int tiadc_parse_dt(struct platform_device *pdev,
>  			  struct tiadc_device *adc_dev)
>  {
> @@ -512,8 +639,14 @@ static int tiadc_probe(struct platform_device *pdev)
>  
>  	platform_set_drvdata(pdev, indio_dev);
>  
> +	err = tiadc_request_dma(pdev, adc_dev);
> +	if (err && err != -ENODEV)
> +		goto err_dma;

You should handle the deferred probing for DMA channel.

> +
>  	return 0;
>  
> +err_dma:
> +	iio_device_unregister(indio_dev);
>  err_buffer_unregister:
>  	tiadc_iio_buffered_hardware_remove(indio_dev);
>  err_free_channels:
> @@ -525,8 +658,14 @@ static int tiadc_remove(struct platform_device *pdev)
>  {
>  	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
>  	struct tiadc_device *adc_dev = iio_priv(indio_dev);
> +	struct tiadc_dma *dma = &adc_dev->dma;
>  	u32 step_en;
>  
> +	if (dma->chan) {
> +		dma_free_coherent(dma->chan->device->dev, DMA_BUFFER_SIZE,
> +				  dma->buf, dma->addr);
> +		dma_release_channel(dma->chan);
> +	}
>  	iio_device_unregister(indio_dev);
>  	tiadc_iio_buffered_hardware_remove(indio_dev);
>  	tiadc_channels_remove(indio_dev);
> diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
> index e45a208..b9a53e0 100644
> --- a/include/linux/mfd/ti_am335x_tscadc.h
> +++ b/include/linux/mfd/ti_am335x_tscadc.h
> @@ -23,6 +23,8 @@
>  #define REG_IRQENABLE		0x02C
>  #define REG_IRQCLR		0x030
>  #define REG_IRQWAKEUP		0x034
> +#define REG_DMAENABLE_SET	0x038
> +#define REG_DMAENABLE_CLEAR	0x03c
>  #define REG_CTRL		0x040
>  #define REG_ADCFSM		0x044
>  #define REG_CLKDIV		0x04C
> @@ -36,6 +38,7 @@
>  #define REG_FIFO0THR		0xE8
>  #define REG_FIFO1CNT		0xF0
>  #define REG_FIFO1THR		0xF4
> +#define REG_DMA1REQ		0xF8
>  #define REG_FIFO0		0x100
>  #define REG_FIFO1		0x200
>  
> @@ -126,6 +129,10 @@
>  #define FIFOREAD_DATA_MASK (0xfff << 0)
>  #define FIFOREAD_CHNLID_MASK (0xf << 16)
>  
> +/* DMA ENABLE/CLEAR Register */
> +#define DMA_FIFO0		BIT(0)
> +#define DMA_FIFO1		BIT(1)
> +
>  /* Sequencer Status */
>  #define SEQ_STATUS BIT(5)
>  #define CHARGE_STEP		0x11
> 


-- 
P?ter

^ permalink raw reply

* [PATCH 6/6] ARM: da850: adjust memory settings for tilcdc
From: Bartosz Golaszewski @ 2016-10-04  9:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <91db8934-bfd6-8fc4-74e3-4844ef3bd3e7@ti.com>

2016-09-30 21:19 GMT+02:00 Peter Ujfalusi <peter.ujfalusi@ti.com>:
> On 09/30/2016 06:06 PM, Bartosz Golaszewski wrote:
>>
>> Just ran a quick test with speaker-test -c2 -twav. Besides the fact
>> that the left and right channels are inverted (I'm looking into that),
>> I didn't notice any problems. Even at 1024x768 resolution, playing
>> audio at the same time seems to work fine.
>

Hi Peter

> That's good to hear, but I think the priorities should be set:
> LCDC and EDMA30TC1 to highest priority
> EDMA30TC0 to priority 2
>
> The 0TC0 is used by MMC and if you want to play a video you might need the
> servicing TC to be higher priority then other masters.
>
> If audio playback would trigger sync losts in lcdc then we might need to move
> 0TC1 to priority 1.
>

Did you mean "set EDMA31TC0 to priority 2"? EDMA30TC0 is already at
the highest priority. Or did you mean that we need to lower the
EDMA30TC0 priority? In that case: is 2 the correct value? EDMA31TC0 is
used by mmc1 and its priority is 4. Shouldn't we set both to be the
same?

> I agree that LCDC priority needs to be higher, but I do wonder why the default
> (5) is not working and if it is not working why it is 5...
>
> My guess is that the change in the PBBPR register is the one actually helping
> here.
>

While it seems that lowering the EDMA30TC0 priority is indeed
unnecessary, if I don't set the LCDC master to priority 0, I still get
FIFO underflows even with the change in PBBPR.

Thanks,
Bartosz

^ permalink raw reply

* [PATCH] bus: qcom-ebi2: depend on HAS_IOMEM
From: Arnd Bergmann @ 2016-10-04  9:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <e3b1a575-7f97-ed6c-e2c0-16ae193b1b49@codeaurora.org>

On Monday, October 3, 2016 12:04:00 PM CEST Stephen Boyd wrote:
> On 10/02/2016 02:53 PM, Linus Walleij wrote:
> > After being asked to not depend on ARCH_QCOM* or similar,
> > unsurprisingly compilation fails on UM as it has no I/O
> > memory:
> 
> We could have depends on ARCH_QCOM || COMPILE_TEST and then life is
> good. The HAS_IOMEM would of course stick around for compile testing.

Agreed, that would be nice also since most x86 don't want to
see the Kconfig option unless they set COMPILE_TEST.

Note that COMPILE_TEST now depends on !UML, so we don't have
to worry about that any more.

	Arnd

^ permalink raw reply

* Applied "spi: omap2-mcspi: Fix modifying platform resource data" to the spi tree
From: Mark Brown @ 2016-10-04  9:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1405683053-14104-1-git-send-email-LW@KARO-electronics.de>

The patch

   spi: omap2-mcspi: Fix modifying platform resource data

has been applied to the spi tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 0142d2ee7e9f107248ebf69bd66037c536d3f6cc Mon Sep 17 00:00:00 2001
From: Vikram N <vicky773@gmail.com>
Date: Fri, 30 Sep 2016 19:53:11 +0530
Subject: [PATCH] spi: omap2-mcspi: Fix modifying platform resource data

currently during probe the resource data gets modified and device
physical address remains valid only during first load. If the module is
unloaded and loaded again, the ioremp will be done on a incorrect address
as the resource was modified during previous module load.
This patch fixes this issue.

Signed-off-by: Vikram N <vicky773@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 drivers/spi/spi-omap2-mcspi.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c
index d5157b2222ce..3567e1dfd30d 100644
--- a/drivers/spi/spi-omap2-mcspi.c
+++ b/drivers/spi/spi-omap2-mcspi.c
@@ -1391,15 +1391,13 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
 		goto free_master;
 	}
 
-	r->start += regs_offset;
-	r->end += regs_offset;
-	mcspi->phys = r->start;
-
 	mcspi->base = devm_ioremap_resource(&pdev->dev, r);
 	if (IS_ERR(mcspi->base)) {
 		status = PTR_ERR(mcspi->base);
 		goto free_master;
 	}
+	mcspi->phys = r->start + regs_offset;
+	mcspi->base += regs_offset;
 
 	mcspi->dev = &pdev->dev;
 
-- 
2.9.3

^ permalink raw reply related

* [PATCH 00/14] ASoc: sunxi: Add Allwinner A33 codec driver
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

* [PATCH 01/14] dma: sun6i-dma: Add burst case of 4
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1475569400.git.mylene.josserand@free-electrons.com>

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

* [PATCH 02/14] clk: ccu-sun8i-a33: Add CLK_SET_RATE_PARENT to ac-dig
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1475569400.git.mylene.josserand@free-electrons.com>

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

* [PATCH 03/14] ASoC: sun4i-i2s: Add apb reset
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1475569400.git.mylene.josserand@free-electrons.com>

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

* [PATCH 04/14] ASoC: Add sun8i analog codec driver
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1475569400.git.mylene.josserand@free-electrons.com>

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

* [PATCH 05/14] mfd: sun6i-prcm: Add sun8i analog codec as subnode
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1475569400.git.mylene.josserand@free-electrons.com>

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

* [PATCH 06/14] ASoC: Add sun8i digital audio codec
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1475569400.git.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
+#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

* [PATCH 07/14] ASoC: Add sun8i audio card
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1475569400.git.mylene.josserand@free-electrons.com>

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

* [PATCH 08/14] dt-bindings: sound: Add sun8i analog codec documentation
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1475569400.git.mylene.josserand@free-electrons.com>

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

* [PATCH 09/14] dt-bindings: sound: Add sun8i codec documentation
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1475569400.git.mylene.josserand@free-electrons.com>

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

* [PATCH 10/14] dt-bindings: sound: Add sun8i audio card documentation
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1475569400.git.mylene.josserand@free-electrons.com>

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

* [PATCH 11/14] ARM: dts: sun8i: Add analog codec on prcm node
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1475569400.git.mylene.josserand@free-electrons.com>

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

* [PATCH 12/14] ARM: dts: sun8i: Add audio codec, dai and card for A33
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1475569400.git.mylene.josserand@free-electrons.com>

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

* [PATCH 13/14] ARM: dts: sun8i: parrot: Enable audio nodes
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1475569400.git.mylene.josserand@free-electrons.com>

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

* [PATCH v26 0/7] arm64: add kdump support
From: James Morse @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1ae717d6-b2aa-105b-4f47-d879882ca5d3@caviumnetworks.com>

Hi Manish,

On 03/10/16 13:41, Manish Jaggi wrote:
> On 10/03/2016 04:34 PM, AKASHI Takahiro wrote:
>> On Mon, Oct 03, 2016 at 01:24:34PM +0530, Manish Jaggi wrote:
>>> With the v26 kdump and v3 kexec-tools and top of tree crash.git, below are the tests done
>>> Attached is a patch in crash.git (symbols.c) to make crash utility work on my setup.
>>> Can you please have a look and provide your comments.
>>>
>>> To generate a panic, i have a kernel module which on init calls panic.

... modules ... I haven't tested that. I bet it causes some problems!
We probably need to include module_alloc_base as an elf note in the vmcore file...


>>> First kernel is booted with mem=2G crashkernel=1G command line option.
>>> While the system has 64G memory.

>> Are you saying that "mem=..." doesn't have any effect?
> What I am saying it that If the first kernel is booted using mem= option and crashkernel= option
> the memory for second kernel has to be withing the crashkernel size.
> As per /proc/iomem System RAM the information is correct, but the /proc/meminfo is showing total memory
> much more than the first kernel had in first place.

So your second crashkernel has 63G of memory? Unless you provide the same 'mem='
to the kdump kernel, this is the expected behaviour. The
DT:/reserved-memory/crash_dump describes the memory not to use.

On your first boot with 'mem=2G' memblock_mem_limit_remove_map() called from
arm64_memblock_init() removed the top 62G of memory. Neither the first kernel
nor kexec-tools know about the top 62G.
When you run kexec-tools, it describes what it sees in /proc/iomem in the
DT:/reserved-memory/crash_dump, which is just the remaining 1G of memory.

When we crash and reboot, the crash kernel discovers all 64G of memory from the
EFI memory map.
kexec-tools described the 1G of memory that the first kernel was using in the
DT:/reserved-memory/crash_dump node, so early_init_fdt_scan_reserved_mem()
reserves the 1G of memory the first kernel used. This leaves us with 63G of memory.

This may change with the next version of kdump if it switches back to using
DT:/chosen/linux,usable-memory-range.
If you need v26 to avoid the top 62G of memory, you need to provide the same
'mem=' to the first and second kernel.


>>> 1.2 Live crash dump fails with error

... do we expect this to work? I don't think it has anything to do with this
series...


Thanks,

James

^ permalink raw reply

* [PATCH 14/14] ARM: dts: sun8i: sinlinx: Enable audio nodes
From: Mylène Josserand @ 2016-10-04  9:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1475569400.git.mylene.josserand@free-electrons.com>

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

* [PATCH v26 0/7] arm64: add kdump support
From: Manish Jaggi @ 2016-10-04 10:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <57F37A73.3030105@arm.com>



On 10/04/2016 03:16 PM, James Morse wrote:
> Hi Manish,
> 
> On 03/10/16 13:41, Manish Jaggi wrote:
>> On 10/03/2016 04:34 PM, AKASHI Takahiro wrote:
>>> On Mon, Oct 03, 2016 at 01:24:34PM +0530, Manish Jaggi wrote:
>>>> With the v26 kdump and v3 kexec-tools and top of tree crash.git, below are the tests done
>>>> Attached is a patch in crash.git (symbols.c) to make crash utility work on my setup.
>>>> Can you please have a look and provide your comments.
>>>>
>>>> To generate a panic, i have a kernel module which on init calls panic.
> 
> ... modules ... I haven't tested that. I bet it causes some problems!
> We probably need to include module_alloc_base as an elf note in the vmcore file...
> 
> 
>>>> First kernel is booted with mem=2G crashkernel=1G command line option.
>>>> While the system has 64G memory.
> 
>>> Are you saying that "mem=..." doesn't have any effect?
>> What I am saying it that If the first kernel is booted using mem= option and crashkernel= option
>> the memory for second kernel has to be withing the crashkernel size.
>> As per /proc/iomem System RAM the information is correct, but the /proc/meminfo is showing total memory
>> much more than the first kernel had in first place.
> 
> So your second crashkernel has 63G of memory? Unless you provide the same 'mem='
> to the kdump kernel, this is the expected behaviour. The
> DT:/reserved-memory/crash_dump describes the memory not to use.
> 
> On your first boot with 'mem=2G' memblock_mem_limit_remove_map() called from
> arm64_memblock_init() removed the top 62G of memory. Neither the first kernel
> nor kexec-tools know about the top 62G.
> When you run kexec-tools, it describes what it sees in /proc/iomem in the
> DT:/reserved-memory/crash_dump, which is just the remaining 1G of memory.
> 
> When we crash and reboot, the crash kernel discovers all 64G of memory from the
> EFI memory map.
So the iomem and meminfo should be same or different for the second kernel?
Also i assumed that crashkernel=1G should restrict the second kernels to 1G.
This is my understanding from the description. It should not require a second mem= option
> kexec-tools described the 1G of memory that the first kernel was using in the
> DT:/reserved-memory/crash_dump node, so early_init_fdt_scan_reserved_mem()
> reserves the 1G of memory the first kernel used. This leaves us with 63G of memory.
> 
> This may change with the next version of kdump if it switches back to using
> DT:/chosen/linux,usable-memory-range.
> If you need v26 to avoid the top 62G of memory, you need to provide the same
> 'mem=' to the first and second kernel.
If I provide for second kernel, I dont see any prints after Bye.
Have you tired this anytime?
> 
> 
>>>> 1.2 Live crash dump fails with error
> 
> ... do we expect this to work? I don't think it has anything to do with this
> series...
> 
Why it should not?
I saved the vmcore file while in second kernel. Since crash without vmcore file didnt run,
Tried with vmcore file and it worked. Its just that if you want to boot a second kernel
 with read only file system without network live crash dump analysis is handy.
> 
> Thanks,
> 
> James
> 

^ permalink raw reply

* [RFC] arm64: Enforce observed order for spinlock and data
From: Mark Rutland @ 2016-10-04 10:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <b86926dc0203384522e0e6ce18bbb132@codeaurora.org>

On Mon, Oct 03, 2016 at 03:20:57PM -0400, bdegraaf at codeaurora.org wrote:
> On 2016-10-01 14:11, Mark Rutland wrote:
> >Hi Brent,
> >
> >Evidently my questions weren't sufficiently clear; even with your
> >answers it's not clear to me what precise issue you're attempting to
> >solve.  I've tried to be more specific this time.
> >
> >At a high-level, can you clarify whether you're attempting to solve is:
> >
> >(a) a functional correctness issue (e.g. data corruption)
> >(b) a performance issue
> >
> >And whether this was seen in practice, or found through code
> >inspection?

> Thinking about this, as the reader/writer code has no known "abuse"
> case, I'll remove it from the patchset, then provide a v2 patchset
> with a detailed explanation for the lockref problem using the commits
> you provided as an example, as well as performance consideration.

If there's a functional problem, let's consider that in isolation first.
Once we understand that, then we can consider doing what is optimal.

As should be obvious from the above, I'm confused because this patch
conflates functional details with performance optimisations which (to
me) sound architecturally dubious.

I completely agree with Peter that if the problem lies with lockref, it
should be solved in the lockref code.

Thanks,
Mark.

^ permalink raw reply

* [PATCH] efi/arm: fix absolute relocation detection for older toolchains
From: Jon Hunter @ 2016-10-04 10:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1475276515-21801-1-git-send-email-ard.biesheuvel@linaro.org>


On 01/10/16 00:01, Ard Biesheuvel wrote:
> When building the ARM kernel with CONFIG_EFI=y, the following build
> error may occur when using a less recent version of binutils (2.23 or
> older):
> 
>    STUBCPY drivers/firmware/efi/libstub/lib-sort.stub.o
>  00000000 R_ARM_ABS32       sort
>  00000004 R_ARM_ABS32       __ksymtab_strings
>  drivers/firmware/efi/libstub/lib-sort.stub.o: absolute symbol references
>  not allowed in the EFI stub
> 
> (and when building with debug symbols, the list above is much longer, and
> contains all the internal references between the .debug sections and the
> actual code)
> 
> This issue is caused by the fact that objcopy v2.23 or earlier does not
> support wildcards in its -R and -j options, which means the following
> line from the Makefile:
> 
>   STUBCOPY_FLAGS-y		:= -R .debug* -R *ksymtab* -R *kcrctab*
> 
> fails to take effect, leaving harmless absolute relocations in the binary
> that are indistinguishable from relocations that may cause crashes at
> runtime due to the fact that these relocations are resolved at link time
> using the virtual address of the kernel, which is always different from
> the address at which the EFI firmware loads and invokes the stub.
> 
> So, as a workaround, disable debug symbols explicitly when building the
> stub for ARM, and strip the ksymtab and kcrctab symbols for the only
> exported symbol we currently reuse in the stub, which is 'sort'.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

Thanks fixes the issues I was seeing. So ...

Tested-by: Jon Hunter <jonathanh@nvidia.com>

Cheers
Jon

-- 
nvpublic

^ permalink raw reply

* [PATCH 07/14] ASoC: Add sun8i audio card
From: Code Kipper @ 2016-10-04 10:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <33d641ff43f0c0349cdfa2cdbbfdcdde66205596.1475571575.git.mylene.josserand@free-electrons.com>

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

* [PATCH v26 0/7] arm64: add kdump support
From: Mark Rutland @ 2016-10-04 10:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1ae717d6-b2aa-105b-4f47-d879882ca5d3@caviumnetworks.com>

On Mon, Oct 03, 2016 at 06:11:40PM +0530, Manish Jaggi wrote:
> On 10/03/2016 04:34 PM, AKASHI Takahiro wrote:
> > On Mon, Oct 03, 2016 at 01:24:34PM +0530, Manish Jaggi wrote:
> >> Observations:
> >> 1.1. Dump capture kernel shows different memory map.
> >> ---------------------------------------------------
> >> In dump capture kernel /proc/meminfo and /proc/iomem differ
> >>
> >> root at arm64:/home/ubuntu/CODE/crash#
> >> MemTotal:       65882432 kB
> >> MemFree:        65507136 kB
> >> MemAvailable:   60373632 kB
> >> Buffers:           29248 kB
> >> Cached:            46720 kB
> >> SwapCached:            0 kB
> >> Active:            63872 kB
> >> Inactive:          19776 kB
> >> Active(anon):       8256 kB
> >> Inactive(anon):     7616 kB
> >>
> >> First kernel is booted with mem=2G crashkernel=1G command line option.
> >> While the system has 64G memory.
> >>
> >> root at arm64:/home/ubuntu/CODE/crash# cat /proc/iomem
> >> 41400000-fffeffff : System RAM
> >>   41480000-420cffff : Kernel code
> >>   42490000-4278ffff : Kernel data
> >> ffff0000-ffffffff : reserved
> >> 100000000-ffaa7ffff : System RAM
> >> ffaa80000-ffaabffff : reserved
> >> ffaac0000-fffa6ffff : System RAM
> >> fffa70000-fffacffff : reserved
> >> fffad0000-fffffffff : System RAM
> > 
> > Are you saying that "mem=..." doesn't have any effect?
> What I am saying it that If the first kernel is booted using mem= option and crashkernel= option
> the memory for second kernel has to be withing the crashkernel size.

Please don't try to use mem= to limit the kernel to a specific range of
memory. It's really only there as a tool to test handling of low-memory
situations. 

While it guarantees that at most, the amount requested will be used
(modulo a number of edge cases with reserved memory ranges), it does not
guarantee *which* memory will be used. It is *very* fragile.

Thanks,
Mark.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox