Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] MAINTAINERS: Add ARM64-specific ACPI maintainers entry
From: Lorenzo Pieralisi @ 2016-10-05 11:25 UTC (permalink / raw)
  To: linux-arm-kernel

The ARM64 architecture defines ARM64 specific ACPI bindings to
configure and set-up arch specific components. To simplify
code reviews/updates and streamline the maintainership structure
supporting the arch specific code, a new arm64 directory was created in
/drivers/acpi, to contain ACPI code that is specific to ARM64
architecture.

Add the ARM64-specific ACPI maintainers entry in MAINTAINERS for
the newly created subdirectory and respective code content.

Lorenzo Pieralisi will be in charge of submitting and managing
the pull requests on behalf of all maintainers listed.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Hanjun Guo <hanjun.guo@linaro.org>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Link: http://lkml.kernel.org/r/1603704.EGiVTcCxLR at vostro.rjw.lan
---
 MAINTAINERS | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index f593300..2a70dd9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -316,6 +316,14 @@ W:	https://01.org/linux-acpi
 S:	Supported
 F:	drivers/acpi/fan.c
 
+ACPI FOR ARM64 (ACPI/arm64)
+M:	Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+M:	Hanjun Guo <hanjun.guo@linaro.org>
+M:	Sudeep Holla <sudeep.holla@arm.com>
+L:	linux-acpi at vger.kernel.org
+S:	Maintained
+F:	drivers/acpi/arm64
+
 ACPI THERMAL DRIVER
 M:	Zhang Rui <rui.zhang@intel.com>
 L:	linux-acpi at vger.kernel.org
-- 
2.10.0

^ permalink raw reply related

* Coresight ETF trace dump failed in Juno r1 with 4.8-rc8
From: Sudeep Holla @ 2016-10-05 10:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAGhh56GeZkLT=sN4cEhUJMeuz+ZD6jMnU2sbb3yRVLESUcWrtg@mail.gmail.com>


On 05/10/16 06:27, Venkatesh Vivekanandan wrote:

[...]

>
> Hang is seen while trying to dump trace _after_ disabling the ETM
> source. Is it not supposed to work?.
> It works fine, when dumped before disabling ETM source. Please find
> the log below.
>
> linaro-test [rc=0]# echo 1 > 20010000.etf/enable_sink
> linaro-test [rc=0]# echo 1 > 22140000.etm/enable_source
> [   91.792145] coresight-tmc 20010000.etf: TMC-ETB/ETF enabled
> [   91.797719] coresight-funnel 20040000.main-funnel: FUNNEL inport 0 enabled
> [   91.804552] coresight-funnel 220c0000.cluster0-funnel: FUNNEL
> inport 1 enabled
> [   91.815990] coresight-etm4x 22140000.etm: ETM tracing enabled
> linaro-test [rc=0]# dd if=/dev/20010000.etf of=/cstrace.bin bs=1
> [  108.105492] coresight-tmc 20010000.etf: TMC read start
> [  108.404335] coresight-tmc 20010000.etf: TMC read end
> 65536+0 records in
> 65536+0 records out
> linaro-test [rc=0]# echo 0 > 20010000.etf/enable_sink
> linaro-test [rc=0]# dd if=/dev/20010000.etf of=/cstrace.bin bs=1
> [  125.069740] coresight-tmc 20010000.etf: TMC read start
> [  125.184370] coresight-tmc 20010000.etf: TMC read end
> 65536+0 records in
> 65536+0 records out
> linaro-test [rc=0]# echo 0 > 22140000.etm/enable_source
> [  140.271163] coresight-etm4x 22140000.etm: ETM tracing disabled
> [  140.276964] coresight-funnel 220c0000.cluster0-funnel: FUNNEL
> inport 1 disabled
> [  140.284211] coresight-funnel 20040000.main-funnel: FUNNEL inport 0 disabled
> [  140.291128] coresight-tmc 20010000.etf: TMC-ETB/ETF disabled
> linaro-test [rc=0]# dd if=/dev/20010000.etf of=/cstrace.bin bs=1
> <---- It hangs here...
>

I get dd: failed to open '/dev/20010000.etf': Invalid argument
once all the data is read.

> My firmware version,
>
> NOTICE:  Booting Trusted Firmware
> NOTICE:  BL1: v1.1(debug):4a1dcde
> NOTICE:  BL1: Built : 17:54:40, Nov 24 2015
> NOTICE:  BL1: Booting BL2
> NOTICE:  BL2: v1.1(debug):4a1dcde
> NOTICE:  BL2: Built : 17:54:40, Nov 24 2015
> NOTICE:  BL1: Booting BL3-1
> NOTICE:  BL3-1: v1.1(debug):4a1dcde
> NOTICE:  BL3-1: Built : 17:54:40, Nov 24 2015
> UEFI firmware (version 9ed6f7e built at 17:54:28 on Nov 24 2015)
>

OK, this looks as good as what Suzuki has, so should be fine.
But it doesn't list SCP version, can you see that from the Linux boot
logs ?(something like below)

"scpi_protocol scpi: SCP Protocol 1.2 Firmware 1.17.0 version"

-- 
Regards,
Sudeep

^ permalink raw reply

* [PATCH RFC v2 4/12] ARM: shmobile: r8a7743: basic SoC support
From: Laurent Pinchart @ 2016-10-05 10:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <3178356.WuR0emdY7D@wasted.cogentembedded.com>

Hi Sergei,

Thank you for the patch.

On Friday 30 Sep 2016 01:23:52 Sergei Shtylyov wrote:
> Add minimal support for the RZ/G1M (R8A7743) SoC.
> 
> Based on the original (and large) patch by Dmitry Shifrin
> <dmitry.shifrin@cogentembedded.com>.
> 
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
> 
> ---
> Changes in version 2:
> - removed "select I2C" from the R8A7743 Kconfig entry;
> - documented the R8A7743 device tree binding;
> - added Geert's tag.
> 
>  Documentation/devicetree/bindings/arm/shmobile.txt |    2 +
>  arch/arm/mach-shmobile/Kconfig                     |    4 ++
>  arch/arm/mach-shmobile/Makefile                    |    1
>  arch/arm/mach-shmobile/setup-r8a7743.c             |   34 +++++++++++++++++

We should work towards removing files from arch/arm/mach-shmobile/, not adding 
new ones :-) I've just sent a patch to do so ("[PATCH] ARM: shmobile: 
Consolidate R8A779[234] machine definitions'") and CC'ed you.

>  4 files changed, 41 insertions(+)
> 
> Index: renesas/Documentation/devicetree/bindings/arm/shmobile.txt
> ===================================================================
> --- renesas.orig/Documentation/devicetree/bindings/arm/shmobile.txt
> +++ renesas/Documentation/devicetree/bindings/arm/shmobile.txt
> @@ -13,6 +13,8 @@ SoCs:
>      compatible = "renesas,r8a73a4"
>    - R-Mobile A1 (R8A77400)
>      compatible = "renesas,r8a7740"
> +  - RZ/G1M (R8A77430)
> +    compatible = "renesas,r8a7743"
>    - R-Car M1A (R8A77781)
>      compatible = "renesas,r8a7778"
>    - R-Car H1 (R8A77790)
> Index: renesas/arch/arm/mach-shmobile/Kconfig
> ===================================================================
> --- renesas.orig/arch/arm/mach-shmobile/Kconfig
> +++ renesas/arch/arm/mach-shmobile/Kconfig
> @@ -68,6 +68,10 @@ config ARCH_R8A7740
>  	select ARCH_RMOBILE
>  	select RENESAS_INTC_IRQPIN
> 
> +config ARCH_R8A7743
> +	bool "RZ/G1M (R8A77430)"
> +	select ARCH_RCAR_GEN2
> +
>  config ARCH_R8A7778
>  	bool "R-Car M1A (R8A77781)"
>  	select ARCH_RCAR_GEN1
> Index: renesas/arch/arm/mach-shmobile/Makefile
> ===================================================================
> --- renesas.orig/arch/arm/mach-shmobile/Makefile
> +++ renesas/arch/arm/mach-shmobile/Makefile
> @@ -9,6 +9,7 @@ obj-y				:= timer.o
>  obj-$(CONFIG_ARCH_SH73A0)	+= setup-sh73a0.o
>  obj-$(CONFIG_ARCH_R8A73A4)	+= setup-r8a73a4.o
>  obj-$(CONFIG_ARCH_R8A7740)	+= setup-r8a7740.o
> +obj-$(CONFIG_ARCH_R8A7743)	+= setup-r8a7743.o
>  obj-$(CONFIG_ARCH_R8A7778)	+= setup-r8a7778.o
>  obj-$(CONFIG_ARCH_R8A7779)	+= setup-r8a7779.o pm-r8a7779.o
>  obj-$(CONFIG_ARCH_R8A7790)	+= setup-r8a7790.o
> Index: renesas/arch/arm/mach-shmobile/setup-r8a7743.c
> ===================================================================
> --- /dev/null
> +++ renesas/arch/arm/mach-shmobile/setup-r8a7743.c
> @@ -0,0 +1,34 @@
> +/*
> + * r8a7743 processor support
> + *
> + * Copyright (C) 2016 Cogent Embedded, Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + *  published by the Free Software Foundation; of the License.
> + *
> + * 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/init.h>
> +
> +#include <asm/mach/arch.h>
> +
> +#include "common.h"
> +#include "rcar-gen2.h"
> +
> +static const char * const r8a7743_boards_compat_dt[] __initconst = {
> +	"renesas,r8a7743",
> +	NULL,
> +};
> +
> +DT_MACHINE_START(R8A7743_DT, "Generic R8A7743 (Flattened Device Tree)")
> +	.init_early	= shmobile_init_delay,
> +	.init_time	= rcar_gen2_timer_init,
> +	.init_late	= shmobile_init_late,
> +	.reserve	= rcar_gen2_reserve,
> +	.dt_compat	= r8a7743_boards_compat_dt,
> +MACHINE_END

-- 
Regards,

Laurent Pinchart

^ permalink raw reply

* [PATCH] ARM: shmobile: Consolidate R8A779[234] machine definitions
From: Laurent Pinchart @ 2016-10-05 10:31 UTC (permalink / raw)
  To: linux-arm-kernel

The three SoCs use the exact same machine definition, consolidate them
into a single one.

Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
 arch/arm/mach-shmobile/Makefile          |  3 ---
 arch/arm/mach-shmobile/setup-r8a7792.c   | 35 --------------------------------
 arch/arm/mach-shmobile/setup-r8a7793.c   | 33 ------------------------------
 arch/arm/mach-shmobile/setup-r8a7794.c   | 33 ------------------------------
 arch/arm/mach-shmobile/setup-rcar-gen2.c | 20 ++++++++++++++++++
 5 files changed, 20 insertions(+), 104 deletions(-)
 delete mode 100644 arch/arm/mach-shmobile/setup-r8a7792.c
 delete mode 100644 arch/arm/mach-shmobile/setup-r8a7793.c
 delete mode 100644 arch/arm/mach-shmobile/setup-r8a7794.c

I don't have access to any R8A779[234] board, I'd appreciate if someone could
test the patch series.

diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index 3fc48b02eb4f..64611a1b4276 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -13,9 +13,6 @@ obj-$(CONFIG_ARCH_R8A7778)	+= setup-r8a7778.o
 obj-$(CONFIG_ARCH_R8A7779)	+= setup-r8a7779.o pm-r8a7779.o
 obj-$(CONFIG_ARCH_R8A7790)	+= setup-r8a7790.o
 obj-$(CONFIG_ARCH_R8A7791)	+= setup-r8a7791.o
-obj-$(CONFIG_ARCH_R8A7792)	+= setup-r8a7792.o
-obj-$(CONFIG_ARCH_R8A7793)	+= setup-r8a7793.o
-obj-$(CONFIG_ARCH_R8A7794)	+= setup-r8a7794.o
 obj-$(CONFIG_ARCH_EMEV2)	+= setup-emev2.o
 obj-$(CONFIG_ARCH_R7S72100)	+= setup-r7s72100.o
 
diff --git a/arch/arm/mach-shmobile/setup-r8a7792.c b/arch/arm/mach-shmobile/setup-r8a7792.c
deleted file mode 100644
index a0910395da09..000000000000
--- a/arch/arm/mach-shmobile/setup-r8a7792.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * r8a7792 processor support
- *
- * Copyright (C) 2014 Renesas Electronics Corporation
- * Copyright (C) 2016 Cogent  Embedded, Inc.
- *
- * 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; version 2 of the License.
- *
- * 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/of_platform.h>
-
-#include <asm/mach/arch.h>
-
-#include "common.h"
-#include "rcar-gen2.h"
-
-static const char * const r8a7792_boards_compat_dt[] __initconst = {
-	"renesas,r8a7792",
-	NULL,
-};
-
-DT_MACHINE_START(R8A7792_DT, "Generic R8A7792 (Flattened Device Tree)")
-	.init_early	= shmobile_init_delay,
-	.init_late	= shmobile_init_late,
-	.init_time	= rcar_gen2_timer_init,
-	.reserve	= rcar_gen2_reserve,
-	.dt_compat	= r8a7792_boards_compat_dt,
-MACHINE_END
diff --git a/arch/arm/mach-shmobile/setup-r8a7793.c b/arch/arm/mach-shmobile/setup-r8a7793.c
deleted file mode 100644
index 5fce87f7f254..000000000000
--- a/arch/arm/mach-shmobile/setup-r8a7793.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * r8a7793 processor support
- *
- * Copyright (C) 2015  Ulrich Hecht
- *
- * 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; version 2 of the License.
- *
- * 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/init.h>
-#include <asm/mach/arch.h>
-
-#include "common.h"
-#include "rcar-gen2.h"
-
-static const char * const r8a7793_boards_compat_dt[] __initconst = {
-	"renesas,r8a7793",
-	NULL,
-};
-
-DT_MACHINE_START(R8A7793_DT, "Generic R8A7793 (Flattened Device Tree)")
-	.init_early	= shmobile_init_delay,
-	.init_time	= rcar_gen2_timer_init,
-	.init_late	= shmobile_init_late,
-	.reserve	= rcar_gen2_reserve,
-	.dt_compat	= r8a7793_boards_compat_dt,
-MACHINE_END
diff --git a/arch/arm/mach-shmobile/setup-r8a7794.c b/arch/arm/mach-shmobile/setup-r8a7794.c
deleted file mode 100644
index d2b093033132..000000000000
--- a/arch/arm/mach-shmobile/setup-r8a7794.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * r8a7794 processor support
- *
- * Copyright (C) 2014  Renesas Electronics Corporation
- * Copyright (C) 2014  Ulrich Hecht
- *
- * 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; version 2 of the License.
- *
- * 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/of_platform.h>
-#include "common.h"
-#include "rcar-gen2.h"
-#include <asm/mach/arch.h>
-
-static const char * const r8a7794_boards_compat_dt[] __initconst = {
-	"renesas,r8a7794",
-	NULL,
-};
-
-DT_MACHINE_START(R8A7794_DT, "Generic R8A7794 (Flattened Device Tree)")
-	.init_early	= shmobile_init_delay,
-	.init_late	= shmobile_init_late,
-	.init_time	= rcar_gen2_timer_init,
-	.reserve	= rcar_gen2_reserve,
-	.dt_compat	= r8a7794_boards_compat_dt,
-MACHINE_END
diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c
index afb9fdcd3d90..4d5052564f21 100644
--- a/arch/arm/mach-shmobile/setup-rcar-gen2.c
+++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c
@@ -24,6 +24,7 @@
 #include <linux/memblock.h>
 #include <linux/of.h>
 #include <linux/of_fdt.h>
+#include <linux/of_platform.h>
 #include <asm/mach/arch.h>
 #include "common.h"
 #include "rcar-gen2.h"
@@ -203,3 +204,22 @@ void __init rcar_gen2_reserve(void)
 	}
 #endif
 }
+
+static const char * const rcar_gen2_boards_compat_dt[] __initconst = {
+	/*
+	 * R8A7790 and R8A7791 can't be handled here as long as they need SMP
+	 * initialization fallback.
+	 */
+	"renesas,r8a7792",
+	"renesas,r8a7793",
+	"renesas,r8a7794",
+	NULL,
+};
+
+DT_MACHINE_START(RCAR_GEN2_DT, "Generic Gen2 (Flattened Device Tree)")
+	.init_early	= shmobile_init_delay,
+	.init_late	= shmobile_init_late,
+	.init_time	= rcar_gen2_timer_init,
+	.reserve	= rcar_gen2_reserve,
+	.dt_compat	= rcar_gen2_boards_compat_dt,
+MACHINE_END
-- 
Regards,

Laurent Pinchart

^ permalink raw reply related

* [PATCH] Adding missing features of Coresight PTM components
From: Muhammad Abdul WAHAB @ 2016-10-05 10:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CANLsYkybp0Lm-WStT=__yyug1Z9hFG7dgCp8E=iL5_x9C1vv-w@mail.gmail.com>

Hi Mathieu,

> The rule of thumb when writing a patch description is to specify "why"
> rather than "what" you are doing.  The above describe the why alright
> and should be kept.  Everything below until your SOB describe what you
> are doing and should be removed.

I modified the patch according to your remarks and will submit it.

 > There is indeed an indentation problem here but it can't be fixed in
 > this patch.  Please do another patch for this.

I created another patch for it.

 > The sysFS mode users can do what they want, including configurations
 > not supported by the HW.  There are so many rules and exception that
 > adding a check for every one of they doesn't scale up.  I suggest to
 > remove the above check.

This check was removed. The return stack feature is not available in ETM 
and the corresponding bit is reserved and should be zero. That's why an 
additional check was made.

 > You patch doesn't apply on my tree.  Please use "git format-patch" for
 > your next submission.  Last but not least the email address in the
 > "from:" part of the submission doesn't match the one in the SOB - they
 > have to be similar.

All the above suggestions were made and will be submitted in the 2nd 
version of the patch.

Thank you,
M.Abdul WAHAB

^ permalink raw reply

* [PATCH] ARM: dt: sun8i-h3: Add sunxi-sid to dts for sun8i-h3
From: Jean-Francois Moine @ 2016-10-05 10:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1475660904-7959-1-git-send-email-clabbe.montjoie@gmail.com>

On Wed,  5 Oct 2016 11:48:24 +0200
Corentin Labbe <clabbe.montjoie@gmail.com> wrote:

> This patch add support for the sunxi-sid driver to the device tree for sun8i-h3.
> 
> Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
> ---
>  arch/arm/boot/dts/sun8i-h3.dtsi | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
> index 9f58bb4..abfd29c 100644
> --- a/arch/arm/boot/dts/sun8i-h3.dtsi
> +++ b/arch/arm/boot/dts/sun8i-h3.dtsi
> @@ -211,6 +211,11 @@
>  			#size-cells = <0>;
>  		};
>  
> +		sid: eeprom at 01c14200 {
> +			compatible = "allwinner,sun7i-a20-sid";
> +			reg = <0x01c14200 0x200>;

The datasheet says 1Kb starting at 0x01c14000.
Is there any reason to reduce the area and to shift the offset?

> +		};
> +
>  		usbphy: phy at 01c19400 {
>  			compatible = "allwinner,sun8i-h3-usb-phy";
>  			reg = <0x01c19400 0x2c>,
> -- 
> 2.7.3

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

^ permalink raw reply

* [PATCH 06/14] ASoC: Add sun8i digital audio codec
From: Icenowy Zheng @ 2016-10-05 10:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <85cbd9926e52d0aa03f6bbfd8794373d8db491e0.1475571575.git.mylene.josserand@free-electrons.com>



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

* [PATCH 07/14] ASoC: Add sun8i audio card
From: Jean-Francois Moine @ 2016-10-05 10:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAEKpxBkUbCGJdToReQx7P+5i92doUdNeMvA5fiDACGcniY=nJg@mail.gmail.com>

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

* [PATCH v7 21/22] iommu/dma: Add support for mapping MSIs
From: Robin Murphy @ 2016-10-05  9:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <DB6PR0402MB2694B2E5AE266F138784D2C2E6C40@DB6PR0402MB2694.eurprd04.prod.outlook.com>

On 05/10/16 08:00, Nipun Gupta wrote:
> 
> 
>> -----Original Message-----
>> From: iommu-bounces at lists.linux-foundation.org [mailto:iommu-
>> bounces at lists.linux-foundation.org] On Behalf Of Robin Murphy
>> Sent: Monday, September 12, 2016 21:44
>> To: will.deacon at arm.com; joro at 8bytes.org; iommu at lists.linux-
>> foundation.org; linux-arm-kernel at lists.infradead.org
>> Cc: devicetree at vger.kernel.org; punit.agrawal at arm.com;
>> thunder.leizhen at huawei.com
>> Subject: [PATCH v7 21/22] iommu/dma: Add support for mapping MSIs
>>
>> When an MSI doorbell is located downstream of an IOMMU, attaching devices
>> to a DMA ops domain and switching on translation leads to a rude shock when
>> their attempt to write to the physical address returned by the irqchip driver
>> faults (or worse, writes into some already-mapped
>> buffer) and no interrupt is forthcoming.
>>
>> Address this by adding a hook for relevant irqchip drivers to call from their
>> compose_msi_msg() callback, to swizzle the physical address with an
>> appropriatly-mapped IOVA for any device attached to one of our DMA ops
>> domains.
>>
>> Acked-by: Thomas Gleixner <tglx@linutronix.de>
>> Acked-by: Marc Zyngier <marc.zyngier@arm.com>
>> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
>> ---
>>  drivers/iommu/dma-iommu.c        | 136
>> ++++++++++++++++++++++++++++++++++-----
>>  drivers/irqchip/irq-gic-v2m.c    |   3 +
>>  drivers/irqchip/irq-gic-v3-its.c |   3 +
>>  include/linux/dma-iommu.h        |   9 +++
>>  4 files changed, 136 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index
>> 00c8a08d56e7..4329d18080cf 100644
>> --- a/drivers/iommu/dma-iommu.c
>> +++ b/drivers/iommu/dma-iommu.c
>> @@ -25,10 +25,28 @@
>>  #include <linux/huge_mm.h>
>>  #include <linux/iommu.h>
>>  #include <linux/iova.h>
>> +#include <linux/irq.h>
>>  #include <linux/mm.h>
>>  #include <linux/scatterlist.h>
>>  #include <linux/vmalloc.h>
>>
>> +struct iommu_dma_msi_page {
>> +	struct list_head	list;
>> +	dma_addr_t		iova;
>> +	phys_addr_t		phys;
>> +};
>> +
>> +struct iommu_dma_cookie {
>> +	struct iova_domain	iovad;
>> +	struct list_head	msi_page_list;
>> +	spinlock_t		msi_lock;
>> +};
>> +
>> +static inline struct iova_domain *cookie_iovad(struct iommu_domain
>> +*domain) {
>> +	return &((struct iommu_dma_cookie *)domain->iova_cookie)->iovad; }
>> +
>>  int iommu_dma_init(void)
>>  {
>>  	return iova_cache_get();
>> @@ -43,15 +61,19 @@ int iommu_dma_init(void)
>>   */
>>  int iommu_get_dma_cookie(struct iommu_domain *domain)  {
>> -	struct iova_domain *iovad;
>> +	struct iommu_dma_cookie *cookie;
>>
>>  	if (domain->iova_cookie)
>>  		return -EEXIST;
>>
>> -	iovad = kzalloc(sizeof(*iovad), GFP_KERNEL);
>> -	domain->iova_cookie = iovad;
>> +	cookie = kzalloc(sizeof(*cookie), GFP_KERNEL);
>> +	if (!cookie)
>> +		return -ENOMEM;
>>
>> -	return iovad ? 0 : -ENOMEM;
>> +	spin_lock_init(&cookie->msi_lock);
>> +	INIT_LIST_HEAD(&cookie->msi_page_list);
>> +	domain->iova_cookie = cookie;
>> +	return 0;
>>  }
>>  EXPORT_SYMBOL(iommu_get_dma_cookie);
>>
>> @@ -63,14 +85,20 @@ EXPORT_SYMBOL(iommu_get_dma_cookie);
>>   */
>>  void iommu_put_dma_cookie(struct iommu_domain *domain)  {
>> -	struct iova_domain *iovad = domain->iova_cookie;
>> +	struct iommu_dma_cookie *cookie = domain->iova_cookie;
>> +	struct iommu_dma_msi_page *msi, *tmp;
>>
>> -	if (!iovad)
>> +	if (!cookie)
>>  		return;
>>
>> -	if (iovad->granule)
>> -		put_iova_domain(iovad);
>> -	kfree(iovad);
>> +	if (cookie->iovad.granule)
>> +		put_iova_domain(&cookie->iovad);
>> +
>> +	list_for_each_entry_safe(msi, tmp, &cookie->msi_page_list, list) {
>> +		list_del(&msi->list);
>> +		kfree(msi);
>> +	}
>> +	kfree(cookie);
>>  	domain->iova_cookie = NULL;
>>  }
>>  EXPORT_SYMBOL(iommu_put_dma_cookie);
>> @@ -88,7 +116,7 @@ EXPORT_SYMBOL(iommu_put_dma_cookie);
>>   */
>>  int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t
>> base, u64 size)  {
>> -	struct iova_domain *iovad = domain->iova_cookie;
>> +	struct iova_domain *iovad = cookie_iovad(domain);
>>  	unsigned long order, base_pfn, end_pfn;
>>
>>  	if (!iovad)
>> @@ -155,7 +183,7 @@ int dma_direction_to_prot(enum dma_data_direction
>> dir, bool coherent)  static struct iova *__alloc_iova(struct iommu_domain
>> *domain, size_t size,
>>  		dma_addr_t dma_limit)
>>  {
>> -	struct iova_domain *iovad = domain->iova_cookie;
>> +	struct iova_domain *iovad = cookie_iovad(domain);
>>  	unsigned long shift = iova_shift(iovad);
>>  	unsigned long length = iova_align(iovad, size) >> shift;
>>
>> @@ -171,7 +199,7 @@ static struct iova *__alloc_iova(struct iommu_domain
>> *domain, size_t size,
>>  /* The IOVA allocator knows what we mapped, so just unmap whatever that
>> was */  static void __iommu_dma_unmap(struct iommu_domain *domain,
>> dma_addr_t dma_addr)  {
>> -	struct iova_domain *iovad = domain->iova_cookie;
>> +	struct iova_domain *iovad = cookie_iovad(domain);
>>  	unsigned long shift = iova_shift(iovad);
>>  	unsigned long pfn = dma_addr >> shift;
>>  	struct iova *iova = find_iova(iovad, pfn); @@ -294,7 +322,7 @@ struct
>> page **iommu_dma_alloc(struct device *dev, size_t size, gfp_t gfp,
>>  		void (*flush_page)(struct device *, const void *, phys_addr_t))  {
>>  	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
>> -	struct iova_domain *iovad = domain->iova_cookie;
>> +	struct iova_domain *iovad = cookie_iovad(domain);
>>  	struct iova *iova;
>>  	struct page **pages;
>>  	struct sg_table sgt;
>> @@ -386,7 +414,7 @@ dma_addr_t iommu_dma_map_page(struct device
>> *dev, struct page *page,  {
>>  	dma_addr_t dma_addr;
>>  	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
>> -	struct iova_domain *iovad = domain->iova_cookie;
>> +	struct iova_domain *iovad = cookie_iovad(domain);
>>  	phys_addr_t phys = page_to_phys(page) + offset;
>>  	size_t iova_off = iova_offset(iovad, phys);
>>  	size_t len = iova_align(iovad, size + iova_off); @@ -495,7 +523,7 @@
>> int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg,
>>  		int nents, int prot)
>>  {
>>  	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
>> -	struct iova_domain *iovad = domain->iova_cookie;
>> +	struct iova_domain *iovad = cookie_iovad(domain);
>>  	struct iova *iova;
>>  	struct scatterlist *s, *prev = NULL;
>>  	dma_addr_t dma_addr;
>> @@ -587,3 +615,81 @@ int iommu_dma_mapping_error(struct device *dev,
>> dma_addr_t dma_addr)  {
>>  	return dma_addr == DMA_ERROR_CODE;
>>  }
>> +
>> +static struct iommu_dma_msi_page *iommu_dma_get_msi_page(struct device
>> *dev,
>> +		phys_addr_t msi_addr, struct iommu_domain *domain) {
>> +	struct iommu_dma_cookie *cookie = domain->iova_cookie;
>> +	struct iommu_dma_msi_page *msi_page;
>> +	struct iova_domain *iovad = &cookie->iovad;
>> +	struct iova *iova;
>> +	int prot = IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_MMIO;
>> +
>> +	msi_addr &= ~(phys_addr_t)iova_mask(iovad);
>> +	list_for_each_entry(msi_page, &cookie->msi_page_list, list)
>> +		if (msi_page->phys == msi_addr)
>> +			return msi_page;
>> +
>> +	msi_page = kzalloc(sizeof(*msi_page), GFP_ATOMIC);
>> +	if (!msi_page)
>> +		return NULL;
>> +
>> +	iova = __alloc_iova(domain, iovad->granule, dma_get_mask(dev));
> 
> I think this should be 'iova = __alloc_iova(domain, iovad->granule, dma_get_mask(dev));'

Er, yes... I fully agree. That's why it is exactly that.

> as __alloc_iova takes input parameter as 'struct iova_domain *'

Joking aside, though, I guess you've overlooked the change introduced by
c987ff0d3cb3 ("iommu/dma: Respect IOMMU aperture when allocating")?

Robin.

> 
> Regards,
> Nipun
> 
>> +	if (!iova)
>> +		goto out_free_page;
>> +
>> +	msi_page->phys = msi_addr;
>> +	msi_page->iova = iova_dma_addr(iovad, iova);
>> +	if (iommu_map(domain, msi_page->iova, msi_addr, iovad->granule,
>> prot))
>> +		goto out_free_iova;
>> +
>> +	INIT_LIST_HEAD(&msi_page->list);
>> +	list_add(&msi_page->list, &cookie->msi_page_list);
>> +	return msi_page;
>> +
>> +out_free_iova:
>> +	__free_iova(iovad, iova);
>> +out_free_page:
>> +	kfree(msi_page);
>> +	return NULL;
>> +}
>> +
>> +void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg) {
>> +	struct device *dev = msi_desc_to_dev(irq_get_msi_desc(irq));
>> +	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
>> +	struct iommu_dma_cookie *cookie;
>> +	struct iommu_dma_msi_page *msi_page;
>> +	phys_addr_t msi_addr = (u64)msg->address_hi << 32 | msg->address_lo;
>> +	unsigned long flags;
>> +
>> +	if (!domain || !domain->iova_cookie)
>> +		return;
>> +
>> +	cookie = domain->iova_cookie;
>> +
>> +	/*
>> +	 * We disable IRQs to rule out a possible inversion against
>> +	 * irq_desc_lock if, say, someone tries to retarget the affinity
>> +	 * of an MSI from within an IPI handler.
>> +	 */
>> +	spin_lock_irqsave(&cookie->msi_lock, flags);
>> +	msi_page = iommu_dma_get_msi_page(dev, msi_addr, domain);
>> +	spin_unlock_irqrestore(&cookie->msi_lock, flags);
>> +
>> +	if (WARN_ON(!msi_page)) {
>> +		/*
>> +		 * We're called from a void callback, so the best we can do is
>> +		 * 'fail' by filling the message with obviously bogus values.
>> +		 * Since we got this far due to an IOMMU being present, it's
>> +		 * not like the existing address would have worked anyway...
>> +		 */
>> +		msg->address_hi = ~0U;
>> +		msg->address_lo = ~0U;
>> +		msg->data = ~0U;
>> +	} else {
>> +		msg->address_hi = upper_32_bits(msi_page->iova);
>> +		msg->address_lo &= iova_mask(&cookie->iovad);
>> +		msg->address_lo += lower_32_bits(msi_page->iova);
>> +	}
>> +}
>> diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c index
>> 35eb7ac5d21f..863e073c6f7f 100644
>> --- a/drivers/irqchip/irq-gic-v2m.c
>> +++ b/drivers/irqchip/irq-gic-v2m.c
>> @@ -16,6 +16,7 @@
>>  #define pr_fmt(fmt) "GICv2m: " fmt
>>
>>  #include <linux/acpi.h>
>> +#include <linux/dma-iommu.h>
>>  #include <linux/irq.h>
>>  #include <linux/irqdomain.h>
>>  #include <linux/kernel.h>
>> @@ -108,6 +109,8 @@ static void gicv2m_compose_msi_msg(struct irq_data
>> *data, struct msi_msg *msg)
>>
>>  	if (v2m->flags & GICV2M_NEEDS_SPI_OFFSET)
>>  		msg->data -= v2m->spi_offset;
>> +
>> +	iommu_dma_map_msi_msg(data->irq, msg);
>>  }
>>
>>  static struct irq_chip gicv2m_irq_chip = { diff --git a/drivers/irqchip/irq-gic-v3-
>> its.c b/drivers/irqchip/irq-gic-v3-its.c
>> index 36b9c28a5c91..98ff669d5962 100644
>> --- a/drivers/irqchip/irq-gic-v3-its.c
>> +++ b/drivers/irqchip/irq-gic-v3-its.c
>> @@ -18,6 +18,7 @@
>>  #include <linux/bitmap.h>
>>  #include <linux/cpu.h>
>>  #include <linux/delay.h>
>> +#include <linux/dma-iommu.h>
>>  #include <linux/interrupt.h>
>>  #include <linux/log2.h>
>>  #include <linux/mm.h>
>> @@ -655,6 +656,8 @@ static void its_irq_compose_msi_msg(struct irq_data
>> *d, struct msi_msg *msg)
>>  	msg->address_lo		= addr & ((1UL << 32) - 1);
>>  	msg->address_hi		= addr >> 32;
>>  	msg->data		= its_get_event_id(d);
>> +
>> +	iommu_dma_map_msi_msg(d->irq, msg);
>>  }
>>
>>  static struct irq_chip its_irq_chip = { diff --git a/include/linux/dma-iommu.h
>> b/include/linux/dma-iommu.h index 81c5c8d167ad..5ee806e41b5c 100644
>> --- a/include/linux/dma-iommu.h
>> +++ b/include/linux/dma-iommu.h
>> @@ -21,6 +21,7 @@
>>
>>  #ifdef CONFIG_IOMMU_DMA
>>  #include <linux/iommu.h>
>> +#include <linux/msi.h>
>>
>>  int iommu_dma_init(void);
>>
>> @@ -62,9 +63,13 @@ void iommu_dma_unmap_sg(struct device *dev, struct
>> scatterlist *sg, int nents,  int iommu_dma_supported(struct device *dev, u64
>> mask);  int iommu_dma_mapping_error(struct device *dev, dma_addr_t
>> dma_addr);
>>
>> +/* The DMA API isn't _quite_ the whole story, though... */ void
>> +iommu_dma_map_msi_msg(int irq, struct msi_msg *msg);
>> +
>>  #else
>>
>>  struct iommu_domain;
>> +struct msi_msg;
>>
>>  static inline int iommu_dma_init(void)
>>  {
>> @@ -80,6 +85,10 @@ static inline void iommu_put_dma_cookie(struct
>> iommu_domain *domain)  {  }
>>
>> +static inline void iommu_dma_map_msi_msg(int irq, struct msi_msg *msg)
>> +{ }
>> +
>>  #endif	/* CONFIG_IOMMU_DMA */
>>  #endif	/* __KERNEL__ */
>>  #endif	/* __DMA_IOMMU_H */
>> --
>> 2.8.1.dirty
>>
>> _______________________________________________
>> iommu mailing list
>> iommu at lists.linux-foundation.org
>> https://lists.linuxfoundation.org/mailman/listinfo/iommu
> 

^ permalink raw reply

* [PATCH] ARM: dt: sun8i-h3: Add sunxi-sid to dts for sun8i-h3
From: Corentin Labbe @ 2016-10-05  9:48 UTC (permalink / raw)
  To: linux-arm-kernel

This patch add support for the sunxi-sid driver to the device tree for sun8i-h3.

Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
---
 arch/arm/boot/dts/sun8i-h3.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
index 9f58bb4..abfd29c 100644
--- a/arch/arm/boot/dts/sun8i-h3.dtsi
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
@@ -211,6 +211,11 @@
 			#size-cells = <0>;
 		};
 
+		sid: eeprom at 01c14200 {
+			compatible = "allwinner,sun7i-a20-sid";
+			reg = <0x01c14200 0x200>;
+		};
+
 		usbphy: phy at 01c19400 {
 			compatible = "allwinner,sun8i-h3-usb-phy";
 			reg = <0x01c19400 0x2c>,
-- 
2.7.3

^ permalink raw reply related

* [PATCH 03/14] ASoC: sun4i-i2s: Add apb reset
From: Mylene Josserand @ 2016-10-05  9:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161004154218.GM5228@lukather>

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

* [PATCH 02/14] clk: ccu-sun8i-a33: Add CLK_SET_RATE_PARENT to ac-dig
From: Mylene Josserand @ 2016-10-05  9:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161004141251.4e82378e@free-electrons.com>

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

* [PATCH v3 2/4] drivers: iio: ti_am335x_adc: add dma support
From: Peter Ujfalusi @ 2016-10-05  9:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161005090443.24576-3-mugunthanvnm@ti.com>

On 10/05/16 12:04, Mugunthan V N wrote:
> This patch adds the required pieces to ti_am335x_adc driver for
> DMA support
> 
> Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
> ---
>  drivers/iio/adc/ti_am335x_adc.c      | 148 ++++++++++++++++++++++++++++++++++-
>  include/linux/mfd/ti_am335x_tscadc.h |   7 ++
>  2 files changed, 152 insertions(+), 3 deletions(-)

Reviewed-by: Peter Ujfalusi <peter.ujfalusi@ti.com>

> 
> diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
> index c3cfacca..ad9dec3 100644
> --- a/drivers/iio/adc/ti_am335x_adc.c
> +++ b/drivers/iio/adc/ti_am335x_adc.c
> @@ -30,10 +30,28 @@
>  #include <linux/iio/buffer.h>
>  #include <linux/iio/kfifo_buf.h>
>  
> +#include <linux/dmaengine.h>
> +#include <linux/dma-mapping.h>
> +
> +#define DMA_BUFFER_SIZE		SZ_2K
> +
> +struct tiadc_dma {
> +	struct dma_slave_config	conf;
> +	struct dma_chan		*chan;
> +	dma_addr_t		addr;
> +	dma_cookie_t		cookie;
> +	u8			*buf;
> +	int			current_period;
> +	int			period_size;
> +	u8			fifo_thresh;
> +};
> +
>  struct tiadc_device {
>  	struct ti_tscadc_dev *mfd_tscadc;
> +	struct tiadc_dma dma;
>  	struct mutex fifo1_lock; /* to protect fifo access */
>  	int channels;
> +	int total_ch_enabled;
>  	u8 channel_line[8];
>  	u8 channel_step[8];
>  	int buffer_en_ch_steps;
> @@ -198,6 +216,67 @@ static irqreturn_t tiadc_worker_h(int irq, void *private)
>  	return IRQ_HANDLED;
>  }
>  
> +static void tiadc_dma_rx_complete(void *param)
> +{
> +	struct iio_dev *indio_dev = param;
> +	struct tiadc_device *adc_dev = iio_priv(indio_dev);
> +	struct tiadc_dma *dma = &adc_dev->dma;
> +	u8 *data;
> +	int i;
> +
> +	data = dma->buf + dma->current_period * dma->period_size;
> +	dma->current_period = 1 - dma->current_period; /* swap the buffer ID */
> +
> +	for (i = 0; i < dma->period_size; i += indio_dev->scan_bytes) {
> +		iio_push_to_buffers(indio_dev, data);
> +		data += indio_dev->scan_bytes;
> +	}
> +}
> +
> +static int tiadc_start_dma(struct iio_dev *indio_dev)
> +{
> +	struct tiadc_device *adc_dev = iio_priv(indio_dev);
> +	struct tiadc_dma *dma = &adc_dev->dma;
> +	struct dma_async_tx_descriptor *desc;
> +
> +	dma->current_period = 0; /* We start to fill period 0 */
> +	/*
> +	 * Make the fifo thresh as the multiple of total number of
> +	 * channels enabled, so make sure that cyclic DMA period
> +	 * length is also a multiple of total number of channels
> +	 * enabled. This ensures that no invalid data is reported
> +	 * to the stack via iio_push_to_buffers().
> +	 */
> +	dma->fifo_thresh = rounddown(FIFO1_THRESHOLD + 1,
> +				     adc_dev->total_ch_enabled) - 1;
> +	/* Make sure that period length is multiple of fifo thresh level */
> +	dma->period_size = rounddown(DMA_BUFFER_SIZE / 2,
> +				    (dma->fifo_thresh + 1) * sizeof(u16));
> +
> +	dma->conf.src_maxburst = dma->fifo_thresh + 1;
> +	dmaengine_slave_config(dma->chan, &dma->conf);
> +
> +	desc = dmaengine_prep_dma_cyclic(dma->chan, dma->addr,
> +					 dma->period_size * 2,
> +					 dma->period_size, DMA_DEV_TO_MEM,
> +					 DMA_PREP_INTERRUPT);
> +	if (!desc)
> +		return -EBUSY;
> +
> +	desc->callback = tiadc_dma_rx_complete;
> +	desc->callback_param = indio_dev;
> +
> +	dma->cookie = dmaengine_submit(desc);
> +
> +	dma_async_issue_pending(dma->chan);
> +
> +	tiadc_writel(adc_dev, REG_FIFO1THR, dma->fifo_thresh);
> +	tiadc_writel(adc_dev, REG_DMA1REQ, dma->fifo_thresh);
> +	tiadc_writel(adc_dev, REG_DMAENABLE_SET, DMA_FIFO1);
> +
> +	return 0;
> +}
> +
>  static int tiadc_buffer_preenable(struct iio_dev *indio_dev)
>  {
>  	struct tiadc_device *adc_dev = iio_priv(indio_dev);
> @@ -218,20 +297,30 @@ static int tiadc_buffer_preenable(struct iio_dev *indio_dev)
>  static int tiadc_buffer_postenable(struct iio_dev *indio_dev)
>  {
>  	struct tiadc_device *adc_dev = iio_priv(indio_dev);
> +	struct tiadc_dma *dma = &adc_dev->dma;
> +	unsigned int irq_enable;
>  	unsigned int enb = 0;
>  	u8 bit;
>  
>  	tiadc_step_config(indio_dev);
> -	for_each_set_bit(bit, indio_dev->active_scan_mask, adc_dev->channels)
> +	for_each_set_bit(bit, indio_dev->active_scan_mask, adc_dev->channels) {
>  		enb |= (get_adc_step_bit(adc_dev, bit) << 1);
> +		adc_dev->total_ch_enabled++;
> +	}
>  	adc_dev->buffer_en_ch_steps = enb;
>  
> +	if (dma->chan)
> +		tiadc_start_dma(indio_dev);
> +
>  	am335x_tsc_se_set_cache(adc_dev->mfd_tscadc, enb);
>  
>  	tiadc_writel(adc_dev,  REG_IRQSTATUS, IRQENB_FIFO1THRES
>  				| IRQENB_FIFO1OVRRUN | IRQENB_FIFO1UNDRFLW);
> -	tiadc_writel(adc_dev,  REG_IRQENABLE, IRQENB_FIFO1THRES
> -				| IRQENB_FIFO1OVRRUN);
> +
> +	irq_enable = IRQENB_FIFO1OVRRUN;
> +	if (!dma->chan)
> +		irq_enable |= IRQENB_FIFO1THRES;
> +	tiadc_writel(adc_dev,  REG_IRQENABLE, irq_enable);
>  
>  	return 0;
>  }
> @@ -239,12 +328,18 @@ static int tiadc_buffer_postenable(struct iio_dev *indio_dev)
>  static int tiadc_buffer_predisable(struct iio_dev *indio_dev)
>  {
>  	struct tiadc_device *adc_dev = iio_priv(indio_dev);
> +	struct tiadc_dma *dma = &adc_dev->dma;
>  	int fifo1count, i, read;
>  
>  	tiadc_writel(adc_dev, REG_IRQCLR, (IRQENB_FIFO1THRES |
>  				IRQENB_FIFO1OVRRUN | IRQENB_FIFO1UNDRFLW));
>  	am335x_tsc_se_clr(adc_dev->mfd_tscadc, adc_dev->buffer_en_ch_steps);
>  	adc_dev->buffer_en_ch_steps = 0;
> +	adc_dev->total_ch_enabled = 0;
> +	if (dma->chan) {
> +		tiadc_writel(adc_dev, REG_DMAENABLE_CLEAR, 0x2);
> +		dmaengine_terminate_async(dma->chan);
> +	}
>  
>  	/* Flush FIFO of leftover data in the time it takes to disable adc */
>  	fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
> @@ -430,6 +525,41 @@ static const struct iio_info tiadc_info = {
>  	.driver_module = THIS_MODULE,
>  };
>  
> +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 (IS_ERR(dma->chan)) {
> +		int ret = PTR_ERR(dma->chan);
> +
> +		dma->chan = NULL;
> +		return ret;
> +	}
> +
> +	/* 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 +642,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 == -EPROBE_DEFER)
> +		goto err_dma;
> +
>  	return 0;
>  
> +err_dma:
> +	iio_device_unregister(indio_dev);
>  err_buffer_unregister:
>  	tiadc_iio_buffered_hardware_remove(indio_dev);
>  err_free_channels:
> @@ -525,8 +661,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 v3 4/4] ARM: dts: am4372: add DMA properties for tscadc
From: Mugunthan V N @ 2016-10-05  9:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161005090443.24576-1-mugunthanvnm@ti.com>

Add DMA properties for tscadc

Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 arch/arm/boot/dts/am4372.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
index 0fadae5..6094d17 100644
--- a/arch/arm/boot/dts/am4372.dtsi
+++ b/arch/arm/boot/dts/am4372.dtsi
@@ -867,6 +867,8 @@
 			clocks = <&adc_tsc_fck>;
 			clock-names = "fck";
 			status = "disabled";
+			dmas = <&edma 53 0>, <&edma 57 0>;
+			dma-names = "fifo0", "fifo1";
 
 			tsc {
 				compatible = "ti,am3359-tsc";
-- 
2.10.0.372.g6fe1b14

^ permalink raw reply related

* [PATCH v3 3/4] ARM: dts: am33xx: add DMA properties for tscadc
From: Mugunthan V N @ 2016-10-05  9:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161005090443.24576-1-mugunthanvnm@ti.com>

Add DMA properties for tscadc

Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 arch/arm/boot/dts/am33xx.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index 98748c6..6d607b8 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -917,6 +917,8 @@
 			interrupts = <16>;
 			ti,hwmods = "adc_tsc";
 			status = "disabled";
+			dmas = <&edma 53 0>, <&edma 57 0>;
+			dma-names = "fifo0", "fifo1";
 
 			tsc {
 				compatible = "ti,am3359-tsc";
-- 
2.10.0.372.g6fe1b14

^ permalink raw reply related

* [PATCH v3 2/4] drivers: iio: ti_am335x_adc: add dma support
From: Mugunthan V N @ 2016-10-05  9:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161005090443.24576-1-mugunthanvnm@ti.com>

This patch adds the required pieces to ti_am335x_adc driver for
DMA support

Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 drivers/iio/adc/ti_am335x_adc.c      | 148 ++++++++++++++++++++++++++++++++++-
 include/linux/mfd/ti_am335x_tscadc.h |   7 ++
 2 files changed, 152 insertions(+), 3 deletions(-)

diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
index c3cfacca..ad9dec3 100644
--- a/drivers/iio/adc/ti_am335x_adc.c
+++ b/drivers/iio/adc/ti_am335x_adc.c
@@ -30,10 +30,28 @@
 #include <linux/iio/buffer.h>
 #include <linux/iio/kfifo_buf.h>
 
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+
+#define DMA_BUFFER_SIZE		SZ_2K
+
+struct tiadc_dma {
+	struct dma_slave_config	conf;
+	struct dma_chan		*chan;
+	dma_addr_t		addr;
+	dma_cookie_t		cookie;
+	u8			*buf;
+	int			current_period;
+	int			period_size;
+	u8			fifo_thresh;
+};
+
 struct tiadc_device {
 	struct ti_tscadc_dev *mfd_tscadc;
+	struct tiadc_dma dma;
 	struct mutex fifo1_lock; /* to protect fifo access */
 	int channels;
+	int total_ch_enabled;
 	u8 channel_line[8];
 	u8 channel_step[8];
 	int buffer_en_ch_steps;
@@ -198,6 +216,67 @@ static irqreturn_t tiadc_worker_h(int irq, void *private)
 	return IRQ_HANDLED;
 }
 
+static void tiadc_dma_rx_complete(void *param)
+{
+	struct iio_dev *indio_dev = param;
+	struct tiadc_device *adc_dev = iio_priv(indio_dev);
+	struct tiadc_dma *dma = &adc_dev->dma;
+	u8 *data;
+	int i;
+
+	data = dma->buf + dma->current_period * dma->period_size;
+	dma->current_period = 1 - dma->current_period; /* swap the buffer ID */
+
+	for (i = 0; i < dma->period_size; i += indio_dev->scan_bytes) {
+		iio_push_to_buffers(indio_dev, data);
+		data += indio_dev->scan_bytes;
+	}
+}
+
+static int tiadc_start_dma(struct iio_dev *indio_dev)
+{
+	struct tiadc_device *adc_dev = iio_priv(indio_dev);
+	struct tiadc_dma *dma = &adc_dev->dma;
+	struct dma_async_tx_descriptor *desc;
+
+	dma->current_period = 0; /* We start to fill period 0 */
+	/*
+	 * Make the fifo thresh as the multiple of total number of
+	 * channels enabled, so make sure that cyclic DMA period
+	 * length is also a multiple of total number of channels
+	 * enabled. This ensures that no invalid data is reported
+	 * to the stack via iio_push_to_buffers().
+	 */
+	dma->fifo_thresh = rounddown(FIFO1_THRESHOLD + 1,
+				     adc_dev->total_ch_enabled) - 1;
+	/* Make sure that period length is multiple of fifo thresh level */
+	dma->period_size = rounddown(DMA_BUFFER_SIZE / 2,
+				    (dma->fifo_thresh + 1) * sizeof(u16));
+
+	dma->conf.src_maxburst = dma->fifo_thresh + 1;
+	dmaengine_slave_config(dma->chan, &dma->conf);
+
+	desc = dmaengine_prep_dma_cyclic(dma->chan, dma->addr,
+					 dma->period_size * 2,
+					 dma->period_size, DMA_DEV_TO_MEM,
+					 DMA_PREP_INTERRUPT);
+	if (!desc)
+		return -EBUSY;
+
+	desc->callback = tiadc_dma_rx_complete;
+	desc->callback_param = indio_dev;
+
+	dma->cookie = dmaengine_submit(desc);
+
+	dma_async_issue_pending(dma->chan);
+
+	tiadc_writel(adc_dev, REG_FIFO1THR, dma->fifo_thresh);
+	tiadc_writel(adc_dev, REG_DMA1REQ, dma->fifo_thresh);
+	tiadc_writel(adc_dev, REG_DMAENABLE_SET, DMA_FIFO1);
+
+	return 0;
+}
+
 static int tiadc_buffer_preenable(struct iio_dev *indio_dev)
 {
 	struct tiadc_device *adc_dev = iio_priv(indio_dev);
@@ -218,20 +297,30 @@ static int tiadc_buffer_preenable(struct iio_dev *indio_dev)
 static int tiadc_buffer_postenable(struct iio_dev *indio_dev)
 {
 	struct tiadc_device *adc_dev = iio_priv(indio_dev);
+	struct tiadc_dma *dma = &adc_dev->dma;
+	unsigned int irq_enable;
 	unsigned int enb = 0;
 	u8 bit;
 
 	tiadc_step_config(indio_dev);
-	for_each_set_bit(bit, indio_dev->active_scan_mask, adc_dev->channels)
+	for_each_set_bit(bit, indio_dev->active_scan_mask, adc_dev->channels) {
 		enb |= (get_adc_step_bit(adc_dev, bit) << 1);
+		adc_dev->total_ch_enabled++;
+	}
 	adc_dev->buffer_en_ch_steps = enb;
 
+	if (dma->chan)
+		tiadc_start_dma(indio_dev);
+
 	am335x_tsc_se_set_cache(adc_dev->mfd_tscadc, enb);
 
 	tiadc_writel(adc_dev,  REG_IRQSTATUS, IRQENB_FIFO1THRES
 				| IRQENB_FIFO1OVRRUN | IRQENB_FIFO1UNDRFLW);
-	tiadc_writel(adc_dev,  REG_IRQENABLE, IRQENB_FIFO1THRES
-				| IRQENB_FIFO1OVRRUN);
+
+	irq_enable = IRQENB_FIFO1OVRRUN;
+	if (!dma->chan)
+		irq_enable |= IRQENB_FIFO1THRES;
+	tiadc_writel(adc_dev,  REG_IRQENABLE, irq_enable);
 
 	return 0;
 }
@@ -239,12 +328,18 @@ static int tiadc_buffer_postenable(struct iio_dev *indio_dev)
 static int tiadc_buffer_predisable(struct iio_dev *indio_dev)
 {
 	struct tiadc_device *adc_dev = iio_priv(indio_dev);
+	struct tiadc_dma *dma = &adc_dev->dma;
 	int fifo1count, i, read;
 
 	tiadc_writel(adc_dev, REG_IRQCLR, (IRQENB_FIFO1THRES |
 				IRQENB_FIFO1OVRRUN | IRQENB_FIFO1UNDRFLW));
 	am335x_tsc_se_clr(adc_dev->mfd_tscadc, adc_dev->buffer_en_ch_steps);
 	adc_dev->buffer_en_ch_steps = 0;
+	adc_dev->total_ch_enabled = 0;
+	if (dma->chan) {
+		tiadc_writel(adc_dev, REG_DMAENABLE_CLEAR, 0x2);
+		dmaengine_terminate_async(dma->chan);
+	}
 
 	/* Flush FIFO of leftover data in the time it takes to disable adc */
 	fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
@@ -430,6 +525,41 @@ static const struct iio_info tiadc_info = {
 	.driver_module = THIS_MODULE,
 };
 
+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 (IS_ERR(dma->chan)) {
+		int ret = PTR_ERR(dma->chan);
+
+		dma->chan = NULL;
+		return ret;
+	}
+
+	/* 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 +642,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 == -EPROBE_DEFER)
+		goto err_dma;
+
 	return 0;
 
+err_dma:
+	iio_device_unregister(indio_dev);
 err_buffer_unregister:
 	tiadc_iio_buffered_hardware_remove(indio_dev);
 err_free_channels:
@@ -525,8 +661,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
-- 
2.10.0.372.g6fe1b14

^ permalink raw reply related

* [PATCH v3 1/4] mfd: ti_am335x_tscadc: store physical address
From: Mugunthan V N @ 2016-10-05  9:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161005090443.24576-1-mugunthanvnm@ti.com>

store the physical address of the device in its priv to use it
for DMA addressing in the client drivers.

Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
---
 drivers/mfd/ti_am335x_tscadc.c       | 1 +
 include/linux/mfd/ti_am335x_tscadc.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
index c8f027b..0f3fab4 100644
--- a/drivers/mfd/ti_am335x_tscadc.c
+++ b/drivers/mfd/ti_am335x_tscadc.c
@@ -183,6 +183,7 @@ static	int ti_tscadc_probe(struct platform_device *pdev)
 		tscadc->irq = err;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	tscadc->tscadc_phys_base = res->start;
 	tscadc->tscadc_base = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(tscadc->tscadc_base))
 		return PTR_ERR(tscadc->tscadc_base);
diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
index 7f55b8b..e45a208 100644
--- a/include/linux/mfd/ti_am335x_tscadc.h
+++ b/include/linux/mfd/ti_am335x_tscadc.h
@@ -155,6 +155,7 @@ struct ti_tscadc_dev {
 	struct device *dev;
 	struct regmap *regmap;
 	void __iomem *tscadc_base;
+	phys_addr_t tscadc_phys_base;
 	int irq;
 	int used_cells;	/* 1-2 */
 	int tsc_wires;
-- 
2.10.0.372.g6fe1b14

^ permalink raw reply related

* [PATCH v3 0/4] Add DMA support for ti_am335x_adc driver
From: Mugunthan V N @ 2016-10-05  9:04 UTC (permalink / raw)
  To: linux-arm-kernel

The ADC has a 64 word depth fifo length which holds the ADC data
till the CPU reads. So when a user program needs a large ADC data
to operate on, then it has to do multiple reads to get its
buffer. Currently if the application asks for 4 samples per
channel with all 8 channels are enabled, kernel can provide only
3 samples per channel when all 8 channels are enabled (logs at
[1]). So with DMA support user can request for large number of
samples at a time (logs at [1]).

Tested the patch on AM437x-gp-evm and AM335x Boneblack with the
patch [2] to enable ADC and pushed a branch for testing [3]

Changes from v2:
* Fixed an issue on handling of error return from dma_request_chan().

Changes from Initial version:
* Changed DMA api from dma_request_slave_channel_compat() to
  dma_request_chan()
* Changed variable names to have more clear information as per
  comments from Peter.

[1] - http://pastebin.ubuntu.com/23278405/
[2] - http://pastebin.ubuntu.com/23211494/
[3] - git://git.ti.com/~mugunthanvnm/ti-linux-kernel/linux.git iio-dma-v2

Mugunthan V N (4):
  mfd: ti_am335x_tscadc: store physical address
  drivers: iio: ti_am335x_adc: add dma support
  ARM: dts: am33xx: add DMA properties for tscadc
  ARM: dts: am4372: add DMA properties for tscadc

 arch/arm/boot/dts/am33xx.dtsi        |   2 +
 arch/arm/boot/dts/am4372.dtsi        |   2 +
 drivers/iio/adc/ti_am335x_adc.c      | 148 ++++++++++++++++++++++++++++++++++-
 drivers/mfd/ti_am335x_tscadc.c       |   1 +
 include/linux/mfd/ti_am335x_tscadc.h |   8 ++
 5 files changed, 158 insertions(+), 3 deletions(-)

-- 
2.10.0.372.g6fe1b14

^ permalink raw reply

* [PATCH v2 2/4] drivers: iio: ti_am335x_adc: add dma support
From: Mugunthan V N @ 2016-10-05  8:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <f00632fa-a542-c633-ae5e-3a42cf364a9f@ti.com>

On Wednesday 05 October 2016 02:16 PM, Peter Ujfalusi wrote:
> On 10/05/16 11:17, Mugunthan V N wrote:
>> On Wednesday 05 October 2016 12:01 PM, Peter Ujfalusi wrote:
>>> On 10/05/16 09:21, Mugunthan V N wrote:
>>>> On Tuesday 04 October 2016 02:02 PM, Peter Ujfalusi wrote:
>>>>> 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.
>>>>
>>>> Will fix this in v3.
>>>>
>>>>>
>>>>>> +
>>>>>> +	/* 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.
>>>>
>>>> +	dma->chan = dma_request_chan(adc_dev->mfd_tscadc->dev, "fifo1");
>>>> +	if (IS_ERR(dma->chan)) {
>>>> +		int ret = PTR_ERR(dma->chan);
>>>> +
>>>> +		dma->chan = NULL;
>>>> +		return ret;
>>>
>>> You don't need the 'ret' variable:
>>> 		return PTR_ERR(dma->chan);
>>
>> So you mean change all *if (dma->chan)* to *if (IS_ERR(dma->chan))*?
> 
> Oh, sorry. Your version was fine as you NULL the dma->chan before the return.
> 
>>
>>>
>>>> +	}
>>>>
>>>> With this probe defer will be taken care and ADC will continue without
>>>> DMA when request channel returns -ENODEV.
>>>
>>> I would rather have explicit check for deferred probe:
>>>
>>> err = tiadc_request_dma(pdev, adc_dev);
>>> if (err && err == -EPROBE_DEFER)
>>> 	goto err_dma;
>>
>> But in this case any other failure other than -EPROBE_DEFER will be
>> masked and ADC will be in PIO mode?
> 
> Yes, exactly. If we fail to get the DMA channel we should not use the DMA and
> we only want to handle the deferred probing.
> 

Okay, will update accordingly in next version.

Regards
Mugunthan V N

^ permalink raw reply

* [PATCH v2 2/4] drivers: iio: ti_am335x_adc: add dma support
From: Peter Ujfalusi @ 2016-10-05  8:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1ffce826-b94a-5b9f-ffb4-ba2d0324b246@ti.com>

On 10/05/16 11:17, Mugunthan V N wrote:
> On Wednesday 05 October 2016 12:01 PM, Peter Ujfalusi wrote:
>> On 10/05/16 09:21, Mugunthan V N wrote:
>>> On Tuesday 04 October 2016 02:02 PM, Peter Ujfalusi wrote:
>>>> 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.
>>>
>>> Will fix this in v3.
>>>
>>>>
>>>>> +
>>>>> +	/* 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.
>>>
>>> +	dma->chan = dma_request_chan(adc_dev->mfd_tscadc->dev, "fifo1");
>>> +	if (IS_ERR(dma->chan)) {
>>> +		int ret = PTR_ERR(dma->chan);
>>> +
>>> +		dma->chan = NULL;
>>> +		return ret;
>>
>> You don't need the 'ret' variable:
>> 		return PTR_ERR(dma->chan);
> 
> So you mean change all *if (dma->chan)* to *if (IS_ERR(dma->chan))*?

Oh, sorry. Your version was fine as you NULL the dma->chan before the return.

> 
>>
>>> +	}
>>>
>>> With this probe defer will be taken care and ADC will continue without
>>> DMA when request channel returns -ENODEV.
>>
>> I would rather have explicit check for deferred probe:
>>
>> err = tiadc_request_dma(pdev, adc_dev);
>> if (err && err == -EPROBE_DEFER)
>> 	goto err_dma;
> 
> But in this case any other failure other than -EPROBE_DEFER will be
> masked and ADC will be in PIO mode?

Yes, exactly. If we fail to get the DMA channel we should not use the DMA and
we only want to handle the deferred probing.

> 
> Regards
> Mugunthan V N
> 


-- 
P?ter

^ permalink raw reply

* [PATCH 6/6] ARM: da850: adjust memory settings for tilcdc
From: Peter Ujfalusi @ 2016-10-05  8:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <7hvax8ferr.fsf@baylibre.com>

On 10/04/16 16:02, Kevin Hilman wrote:
> Peter Ujfalusi <peter.ujfalusi@ti.com> writes:
> 
>> On 10/01/16 12:24, Sekhar Nori wrote:
> 
> [...]
> 
>>> In any case, to configure the PBBR, you will have to introduce a driver
>>> for it in drivers/memory. Then you can set it up per board using a DT
>>> parameter.
>>
>> and we can reuse the introduced bindings for am335x and OMAP1/2 as well. On
>> OMAP the legacy DMA API provided a call to raise the priority of the sDMA in
>> EMIF :o That needs to be removed and replaced.
> 
> Can you point us to the bindings you're referring to?

We don't have one atm.

And the DMA priority hack in legacy sDMA code is for OMAP1:
omap_set_dma_priority(). Basically it can change the sDMA priority in
OCPT1_PRIOR, OCPT2_PRIOR, EMIFF_PRIOR and EMIFS_PRIOR registers.

> Also, a new driver in drivers/memory is fine for setting the PBBR, but
> what about the SYSCFG0 registers.  Are you OK with leaving those in the
> init code as proposed in $SUBJECT patch?

My problem is - as I described it in reply to Bartosz - is that for example I
don't want the LCDC to get high priority on OMAP-L138 EVM from Logic as it
does not have LCD/VGA by default. ifdef for LCDC is not good either since my
kernel have LCDC compiled in, but it is disabled.

The easiest way would be to have pdata quirk to handle the LCDK until we have
proper handling of the priority configuration.

-- 
P?ter

^ permalink raw reply

* [PATCH v2 2/4] drivers: iio: ti_am335x_adc: add dma support
From: Mugunthan V N @ 2016-10-05  8:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <de6bbf1c-e9e2-83b1-73c2-49aa64cc939c@ti.com>

On Wednesday 05 October 2016 12:01 PM, Peter Ujfalusi wrote:
> On 10/05/16 09:21, Mugunthan V N wrote:
>> On Tuesday 04 October 2016 02:02 PM, Peter Ujfalusi wrote:
>>> 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.
>>
>> Will fix this in v3.
>>
>>>
>>>> +
>>>> +	/* 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.
>>
>> +	dma->chan = dma_request_chan(adc_dev->mfd_tscadc->dev, "fifo1");
>> +	if (IS_ERR(dma->chan)) {
>> +		int ret = PTR_ERR(dma->chan);
>> +
>> +		dma->chan = NULL;
>> +		return ret;
> 
> You don't need the 'ret' variable:
> 		return PTR_ERR(dma->chan);

So you mean change all *if (dma->chan)* to *if (IS_ERR(dma->chan))*?

> 
>> +	}
>>
>> With this probe defer will be taken care and ADC will continue without
>> DMA when request channel returns -ENODEV.
> 
> I would rather have explicit check for deferred probe:
> 
> err = tiadc_request_dma(pdev, adc_dev);
> if (err && err == -EPROBE_DEFER)
> 	goto err_dma;

But in this case any other failure other than -EPROBE_DEFER will be
masked and ADC will be in PIO mode?

Regards
Mugunthan V N

^ permalink raw reply

* [PATCH v2 2/2] ARM: dts: meson-gxbb: Add support for the Nexbox A95X Board
From: Neil Armstrong @ 2016-10-05  8:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1475654980-16414-1-git-send-email-narmstrong@baylibre.com>

Add support for the S905 (GXBB) version of the Nexbox A95X.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 arch/arm64/boot/dts/amlogic/Makefile               |   1 +
 .../boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts    | 108 +++++++++++++++++++++
 2 files changed, 109 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts

diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index 57e0ae0..5a64050 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -1,3 +1,4 @@
+dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-nexbox-a95x.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-odroidc2.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-p200.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-p201.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
new file mode 100644
index 0000000..80d7b35
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2016 Andreas F?rber
+ * Copyright (c) 2016 BayLibre, Inc.
+ * Author: Neil Armstrong <narmstrong@kernel.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This library 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 library 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.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include "meson-gxbb.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	compatible = "nexbox,a95x", "amlogic,meson-gxbb";
+	model = "NEXBOX A95X";
+	
+	aliases {
+		serial0 = &uart_AO;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory at 0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x40000000>;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		blue {
+			label = "a95x:system-status";
+			gpios = <&gpio_ao GPIOAO_13 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "heartbeat";
+			default-state = "off";
+		};
+	};
+
+	gpio-keys-polled {
+		compatible = "gpio-keys-polled";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		poll-interval = <100>;
+
+		button at 0 {
+			label = "reset";
+			linux,code = <KEY_RESTART>;
+			gpios = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&uart_AO {
+	status = "okay";
+	pinctrl-0 = <&uart_ao_a_pins>;
+	pinctrl-names = "default";
+};
+
+&ethmac {
+	status = "okay";
+	pinctrl-0 = <&eth_pins>;
+	pinctrl-names = "default";
+};
+
+&ir {
+	status = "okay";
+	pinctrl-0 = <&remote_input_ao_pins>;
+	pinctrl-names = "default";
+};
-- 
1.9.1

^ permalink raw reply related

* [PATCH v2 1/2] devicetree: Add vendor prefix for Nexbox
From: Neil Armstrong @ 2016-10-05  8:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1475654980-16414-1-git-send-email-narmstrong@baylibre.com>

Nexbox is an IPTV set-top-box distributor, mainly with Amlogic SoCs:
        https://www.inexbox.com

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index a9999a3..ecb360f 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -182,6 +182,7 @@ neonode		Neonode Inc.
 netgear	NETGEAR
 netlogic	Broadcom Corporation (formerly NetLogic Microsystems)
 netxeon		Shenzhen Netxeon Technology CO., LTD
+nexbox	Nexbox
 newhaven	Newhaven Display International
 nintendo	Nintendo
 nokia	Nokia
-- 
1.9.1

^ permalink raw reply related

* [PATCH v2 0/2] ARM64: meson-gxbb: Add support for the Nexbox A95X Board
From: Neil Armstrong @ 2016-10-05  8:09 UTC (permalink / raw)
  To: linux-arm-kernel

Add support for the Amlogic S905 (GXBB) version of the Nexbox A95X, an IPTV
set-top-box with Ethernet, SDCard, eMMC, USB, HDMI, IR, Led, Reset button and Audio Jack.

Changes since v1 at: http://lkml.kernel.org/r/1471951370-29269-1-git-send-email-narmstrong at baylibre.com
 - Rebase on linux-next-20161004 with patchset [1]
 - Add nexbox vendor prefix

[1] http://lkml.kernel.org/r/1475595430-30075-1-git-send-email-narmstrong at baylibre.com

Neil Armstrong (2):
  devicetree: Add vendor prefix for Nexbox
  ARM: dts: meson-gxbb: Add support for the Nexbox A95X Board

 .../devicetree/bindings/vendor-prefixes.txt        |   1 +
 arch/arm64/boot/dts/amlogic/Makefile               |   1 +
 .../boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts    | 108 +++++++++++++++++++++
 3 files changed, 110 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts

-- 
1.9.1

^ 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