Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH 1/2] hwmon: (lm70) Utilize dev_warn instead of pr_warn
From: Guenter Roeck @ 2017-01-23  7:01 UTC (permalink / raw)
  To: Joe Perches, Florian Fainelli, linux-kernel, Julia Lawall
  Cc: Rob Herring, Mark Rutland, Jean Delvare, Jonathan Corbet,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list:HARDWARE MONITORING, open list:DOCUMENTATION
In-Reply-To: <1485153837.12563.23.camel@perches.com>

On 01/22/2017 10:43 PM, Joe Perches wrote:
> On Sat, 2017-01-21 at 11:20 -0800, Florian Fainelli wrote:
>> We have a device reference, utilize it instead of pr_warn().
>
> There is at least one more hwmon to convert in applesmc.c
>
> Perhaps a coccinelle script?
>
> Two questions for Julia Lawall:
>
> o is there a better way to do this than repeat the blocks
>   one for each replacement
> o can struct device * dev be made an arbitrary identifier

Definitely yes here; otherwise you only catch the ones named 'dev'.
Did you try "identifier dev;" ?

The type of fn is irrelevant; you don't need to specify it.

There is also the case where 'struct device *dev' is a local variable

fn(...) {
...
struct device *dev = e;
<...
...>
}

or when it isn't but is still available

fn (..., struct \(platform_device\|i2c_device\|spi_device\) *pdev, ...) {
}

>
> $ cat dev_printk.cocci
> @@
> identifier fn;
> type T;
> @@
>
> T fn ( ..., struct device * dev, ... ) {
> <...
> -	pr_emerg(
> +	dev_emerg(dev,
> 	...);
> ...>
> }
>
> @@
> identifier fn;
> type T;
> @@
>
> T fn ( ..., struct device * dev, ... ) {
> <...
> -	pr_crit(
> +	dev_crit(dev,
> 	...);
> ...>
> }
>
> @@
> identifier fn;
> type T;
> @@
>
> T fn ( ..., struct device * dev, ... ) {
> <...
> -	pr_alert(
> +	dev_alert(dev,
> 	...);
> ...>
> }
>
> @@
> identifier fn;
> type T;
> @@
>
> T fn ( ..., struct device * dev, ... ) {
> <...
> -	pr_err(
> +	dev_err(dev,
> 	...);
> ...>
> }
>
> @@
> identifier fn;
> type T;
> @@
>
> T fn ( ..., struct device * dev, ... ) {
> <...
> -	pr_notice(
> +	dev_notice(dev,
> 	...);
> ...>
> }
>
> @@
> identifier fn;
> type T;
> @@
>
> T fn ( ..., struct device * dev, ... ) {
> <...
> -	pr_warn(
> +	dev_warn(dev,
> 	...);
> ...>
> }
>
> @@
> identifier fn;
> type T;
> @@
>
> T fn ( ..., struct device * dev, ... ) {
> <...
> -	pr_info(
> +	dev_info(dev,
> 	...);
> ...>
> }
>
> @@
> identifier fn;
> type T;
> @@
>
> T fn ( ..., struct device * dev, ... ) {
> <...
> -	pr_debug(
> +	dev_dbg(dev,
> 	...);
> ...>
> }
>
>


^ permalink raw reply

* Re: Question about OF-graph ports
From: Kuninori Morimoto @ 2017-01-23  6:58 UTC (permalink / raw)
  To: Rob Herring; +Cc: Mark Brown, Linux-DT, Linux-ALSA
In-Reply-To: <CAL_JsqLOwQn_hz3B5gFL-zr-Pm_8PX+b-sAQhLwkioD7E-ODAw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>


Hi Rob

> >         sound_dai0 {
> >                 ports {
> >                         port { /* SoC.0  */ }
> >                         port { /* Codec0 */ }
> 
> This is probably closer, but I don't know what SoC.0 is. The input
> should be some audio processor I guess.

Thanks.
I created OF-graph sound card based on this DT binding.
Will post soon

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

^ permalink raw reply

* Re: [PATCH 1/2] hwmon: (lm70) Utilize dev_warn instead of pr_warn
From: Joe Perches @ 2017-01-23  6:56 UTC (permalink / raw)
  To: Florian Fainelli, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	Julia Lawall
  Cc: Rob Herring, Mark Rutland, Jean Delvare, Guenter Roeck,
	Jonathan Corbet,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list:HARDWARE MONITORING, open list:DOCUMENTATION
In-Reply-To: <1485153837.12563.23.camel-6d6DIl74uiNBDgjK7y7TUQ@public.gmane.org>

On Sun, 2017-01-22 at 22:43 -0800, Joe Perches wrote:
> Two questions for Julia Lawall:
> 
> o is there a better way to do this than repeat the blocks
>   one for each replacement
> o can struct device * dev be made an arbitrary identifier
> 
> $ cat dev_printk.cocci
> @@
> identifier fn;
> type T;
> @@
> 
> T fn ( ..., struct device * dev, ... ) {
> <...
> -	pr_emerg(
> +	dev_emerg(dev,
> 	...);
> ...>
> }

Well, the second question is simple if I would just
think a little before asking...

@@
identifier fn;
identifier dev;
type T;
@@

T fn ( ..., struct device * dev, ... ) {
<...
-	pr_emerg(
+	dev_emerg(dev,
	...);
...>
}

etc...

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

^ permalink raw reply

* Re: [PATCH 1/3] watchdog: add DT bindings for Cortina Gemini
From: Guenter Roeck @ 2017-01-23  6:51 UTC (permalink / raw)
  To: Linus Walleij, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Hans Ulli Kroll, Florian Fainelli, Wim Van Sebroeck
  Cc: Janos Laube, Paulius Zaleckas,
	openwrt-devel-p3rKhJxN3npAfugRpC6u6w,
	linux-watchdog-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170122223826.29178-1-linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

On 01/22/2017 02:38 PM, Linus Walleij wrote:
> This adds DT bindings for the Cortina systems Gemini SoC
> watchdog timer.
>
> Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Signed-off-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> ---
>  .../bindings/watchdog/cortina,gemin-watchdog.txt        | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/watchdog/cortina,gemin-watchdog.txt
>
> diff --git a/Documentation/devicetree/bindings/watchdog/cortina,gemin-watchdog.txt b/Documentation/devicetree/bindings/watchdog/cortina,gemin-watchdog.txt
> new file mode 100644
> index 000000000000..d8dfb9cc41cf
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/watchdog/cortina,gemin-watchdog.txt
> @@ -0,0 +1,17 @@
> +Cortina Systems Gemini SoC Watchdog
> +
> +Required properties :
> +- compatible : must be "cortina,gemini-watchdog"
> +- reg : shall contain base register location and length
> +- interrupts : shall contain the interrupt for the watchdog
> +
> +- timeout-sec : shall contain the default watchdog timeout in seconds,
> +                if unset, the default timeout is 13 seconds
> +

The default is a linux driver detail, not a HW detail, and thus probably should not be mentioned here.

> +Example:
> +
> +watchdog@41000000 {
> +	compatible = "cortina,gemini-watchdog";
> +	reg = <0x41000000 0x1000>;
> +	interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
> +};
>

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

^ permalink raw reply

* Re: [PATCH 1/2] hwmon: (lm70) Utilize dev_warn instead of pr_warn
From: Joe Perches @ 2017-01-23  6:43 UTC (permalink / raw)
  To: Florian Fainelli, linux-kernel, Julia Lawall
  Cc: Rob Herring, Mark Rutland, Jean Delvare, Guenter Roeck,
	Jonathan Corbet,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	open list:HARDWARE MONITORING, open list:DOCUMENTATION
In-Reply-To: <20170121192010.30681-2-f.fainelli@gmail.com>

On Sat, 2017-01-21 at 11:20 -0800, Florian Fainelli wrote:
> We have a device reference, utilize it instead of pr_warn().

There is at least one more hwmon to convert in applesmc.c

Perhaps a coccinelle script?

Two questions for Julia Lawall:

o is there a better way to do this than repeat the blocks
  one for each replacement
o can struct device * dev be made an arbitrary identifier

$ cat dev_printk.cocci
@@
identifier fn;
type T;
@@

T fn ( ..., struct device * dev, ... ) {
<...
-	pr_emerg(
+	dev_emerg(dev,
	...);
...>
}

@@
identifier fn;
type T;
@@

T fn ( ..., struct device * dev, ... ) {
<...
-	pr_crit(
+	dev_crit(dev,
	...);
...>
}

@@
identifier fn;
type T;
@@

T fn ( ..., struct device * dev, ... ) {
<...
-	pr_alert(
+	dev_alert(dev,
	...);
...>
}

@@
identifier fn;
type T;
@@

T fn ( ..., struct device * dev, ... ) {
<...
-	pr_err(
+	dev_err(dev,
	...);
...>
}

@@
identifier fn;
type T;
@@

T fn ( ..., struct device * dev, ... ) {
<...
-	pr_notice(
+	dev_notice(dev,
	...);
...>
}

@@
identifier fn;
type T;
@@

T fn ( ..., struct device * dev, ... ) {
<...
-	pr_warn(
+	dev_warn(dev,
	...);
...>
}

@@
identifier fn;
type T;
@@

T fn ( ..., struct device * dev, ... ) {
<...
-	pr_info(
+	dev_info(dev,
	...);
...>
}

@@
identifier fn;
type T;
@@

T fn ( ..., struct device * dev, ... ) {
<...
-	pr_debug(
+	dev_dbg(dev,
	...);
...>
}

^ permalink raw reply

* Re: [PATCH v2 00/12] Add basic code support for imx6sll
From: Shawn Guo @ 2017-01-23  6:10 UTC (permalink / raw)
  To: Bai Ping
  Cc: mturquette, sboyd, robh+dt, mark.rutland, linus.walleij,
	devicetree, kernel, daniel.lezcano, linux-gpio, p.zabel,
	jacky.baip, fabio.estevam, tglx, linux-clk, linux-arm-kernel
In-Reply-To: <1482832070-22668-1-git-send-email-ping.bai@nxp.com>

On Tue, Dec 27, 2016 at 05:47:38PM +0800, Bai Ping wrote:
> The i.MX 6SoloLiteLite application processors are NXP's
> latest additions to a growing family of multimedia-focused
> products offering high-performance processing optimized for
> lowest power consumption. The i.MX 6SoloLiteLite processors
> feature NXP's advanced implementation of the ARM Cortex-A9 core,
> which can be interfaced with LPDDR3 and LPDDR2 DRAM memory devices.
> 
> i.MX6SLL is a new SOC of the i.MX6 family, shares many common modules,
> so most of the MSL code can be resued from i.MX6 serious SOC.
> 
> 
> change for V2:
>     -  address comments in dts and dtsi from Fabio.
>     -  split the doc update into two patch, fix typo.
>     -  address comments in clock driver, add necessary 'const'qualifier.
> 
> Bai Ping (12):
>   ARM: imx: Add basic msl support for imx6sll
>   driver: clocksource: add gpt timer for imx6sll
>   Document: dt: binding: imx: update clock doc for imx6sll
>   driver: clk: imx: Add clock driver for imx6sll
>   Document: dt: binding: imx: update pinctrl doc for imx6sll
>   driver: pinctrl: imx: Add pinctrl driver support for imx6sll
>   ARM: dts: imx: Add basic dtsi for imx6sll
>   ARM: dts: imx: Add imx6sll EVK board dts support
>   ARM: debug: Add low level debug support for imx6sll
>   ARM: imx: Add suspend/resume support for imx6sll
>   ARM: imx: correct i.mx6sll dram io low power mode
>   ARM: configs: enable imx6sll support in defconfig

I do not think you need to necessarily put them into a series, since
they will go through different sub-system maintainers.  If there are
dependencies between them, you should manage to get the prerequisite
parts get merged first.

Shawn

^ permalink raw reply

* Re: [PATCH v2 05/12] Document: dt: binding: imx: update pinctrl doc for imx6sll
From: Shawn Guo @ 2017-01-23  6:04 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Jacky Bai, Michael Turquette, Stephen Boyd, Rob Herring,
	Mark Rutland, Sascha Hauer, Fabio Estevam, Daniel Lezcano,
	Thomas Gleixner, Philipp Zabel, linux-clk,
	devicetree@vger.kernel.org, linux-gpio@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, jacky.baip@gmail.com
In-Reply-To: <CACRpkdaxvf6eHujfvKuOsRb69aL8+4jTE-aR3a6ywhytTEu6Hw@mail.gmail.com>

On Wed, Jan 18, 2017 at 01:24:30PM +0100, Linus Walleij wrote:
> On Tue, Jan 17, 2017 at 7:35 AM, Jacky Bai <ping.bai@nxp.com> wrote:
> >> Subject: Re: [PATCH v2 05/12] Document: dt: binding: imx: update pinctrl doc
> >> On Thu, Jan 12, 2017 at 3:57 AM, Jacky Bai <ping.bai@nxp.com> wrote:
> >>
> >> > Another thing is that we can use a pins-tool program developed by NXP
> >> > to  generate the pinctrl configuration code that can be used directly
> >> > in dts. This tiny program can avoid pin function conflict. As on i.MX,
> >> > there are so may pins, each pin can be used for up 8  function.
> >> > Configuring the pins is a time-consuming work.  This tools is very useful for
> >> customer to generate the dts code.
> >>
> >> I understand, but every silicon vendor has such a tool, all are different,
> >> proprietary and unfriendly to programmers and open source developers, who
> >> need to understand how the hardware is working without magic tools and
> >> secret data sheets to fix bugs.
> >>
> >> For the people working with maintaining the code it is paramount that DTS files
> >> are self-descriptive.
> >
> > OK.  Thanks for your comments.  Adding generic-pinconf in imx pinctrl needs some time
> > to finish and the legacy method still need be here even if generic-pinconf is added.
> > Do you plan to pick this legacy binding patch for now?
> 
> As I said earlier:
> 
> > atleast I need an indication from one of the i.MX maintainers how they
> > want to proceed.

Sorry for being late for the discussion.

To be honest, I did not really expect so many i.MX6 variants coming to
us.  Just out of curiosity, are there any more in the pipeline to come,
or is this the last known one?

I understand that there are now more generic support available at
pinctrl core level for us to use than the time we initial designed i.MX
pinctrl driver.  But I intend to agree with Jacky that imx6sll can be
supported by the existing driver, since it doesn't require any
additional driver changes.

If any new generation of i.MX family require changes on the existing
pinctrl driver, we should probably push back for a redesign to use
generic support as much as possible.  @Jacky, how does i.MX8 pinctrl
look like?  How same or different as/from i.MX6 pinctrl?

Just my opinion.

Shawn

^ permalink raw reply

* [PATCH] aspeed: dts: g5: Update GPIO pin range to mux extra banks
From: Andrew Jeffery @ 2017-01-23  5:27 UTC (permalink / raw)
  To: Joel Stanley
  Cc: Andrew Jeffery, Rob Herring, Mark Rutland, Russell King,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	openbmc-uLR06cmDAlY/bJ5BZ2RsiQ

The Aspeed GPIO driver recently gained support for banks Y, Z, AA, AB and AC.
Update the devicetree so GPIO requests for these pins are routed via pinmux,
else the export succeeds but the GPIOs are non-functional.

Signed-off-by: Andrew Jeffery <andrew-zrmu5oMJ5Fs@public.gmane.org>
---
 arch/arm/boot/dts/aspeed-g5.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi
index b664fe380936..a9305b964b11 100644
--- a/arch/arm/boot/dts/aspeed-g5.dtsi
+++ b/arch/arm/boot/dts/aspeed-g5.dtsi
@@ -920,8 +920,8 @@
 				compatible = "aspeed,ast2500-gpio";
 				reg = <0x1e780000 0x1000>;
 				interrupts = <20>;
-				gpio-ranges = <&pinctrl 0 0 220>;
 				interrupt-controller;
+				gpio-ranges = <&pinctrl 0 0 232>;
 			};
 
 			timer: timer@1e782000 {
-- 
2.9.3

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

^ permalink raw reply related

* Re: [PATCH] ARM: dts: imx6q-utilite-pro: enable 2nd display pipeline
From: Shawn Guo @ 2017-01-23  5:24 UTC (permalink / raw)
  To: christopher.spinrath-vA1bhqPz9FBZXbeN9DUtxg
  Cc: kernel-bIcnvbaLZ9MEGnE8C9+IrQ, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8, linux-I+IVW8TIWO2tmTQ+vhA3Yw,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	grinberg-UTxiZqZC01RS1MOuV/RT9w, fabio.estevam-3arQi8VN3Tc,
	p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ
In-Reply-To: <ec9676f344eb4786a28a3c7b969f0e94-gtPewvpZjL8umhiu9RXYRl5UTUQ924AY@public.gmane.org>

On Fri, Dec 02, 2016 at 03:37:22PM +0100, christopher.spinrath-vA1bhqPz9FBZXbeN9DUtxg@public.gmane.org wrote:
> From: Christopher Spinrath <christopher.spinrath-vA1bhqPz9FBZXbeN9DUtxg@public.gmane.org>
> 
> Apart from the already enabled Designware HDMI port, the Utilite Pro
> has a second display pipeline which has the following shape:
> 
>   IPU1 DI0 --> Parallel display --> tfp410 rgb24 to DVI encoder
>                                 --> HDMI connector.
> Enable support for it.
> 
> In addition, since this pipeline is hardwired to IPU1, sever the link
> between IPU1 and the SoC-internal Designware HDMI encoder forcing the
> latter to be connected to IPU2 instead of IPU1. Otherwise, it is not
> possible to drive both displays at high resolution due to the bandwidth
> limitations of a single IPU.
> 
> Signed-off-by: Christopher Spinrath <christopher.spinrath-vA1bhqPz9FBZXbeN9DUtxg@public.gmane.org>

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

^ permalink raw reply

* [PATCH v2 3/3] i2c: zx2967: add i2c controller driver for ZTE's zx2967 family
From: Baoyou Xie @ 2017-01-23  5:03 UTC (permalink / raw)
  To: andy.shevchenko, jun.nie, wsa, robh+dt, mark.rutland
  Cc: linux-arm-kernel, linux-i2c, devicetree, linux-kernel, shawnguo,
	baoyou.xie, xie.baoyou, chen.chaokai, wang.qiang01
In-Reply-To: <1485147806-17792-1-git-send-email-baoyou.xie@linaro.org>

This patch adds i2c controller driver for ZTE's zx2967 family.

Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
---
 drivers/i2c/busses/Kconfig      |   9 +
 drivers/i2c/busses/Makefile     |   1 +
 drivers/i2c/busses/i2c-zx2967.c | 690 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 700 insertions(+)
 create mode 100644 drivers/i2c/busses/i2c-zx2967.c

diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index e4a603e..9609f45 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -1246,4 +1246,13 @@ config I2C_OPAL
 	  This driver can also be built as a module. If so, the module will be
 	  called as i2c-opal.
 
+config I2C_ZX2967
+	tristate "ZTE zx2967 I2C support"
+	depends on ARCH_ZX
+	default y
+	help
+	  Selecting this option will add ZX2967 I2C driver.
+	  This driver can also be built as a module. If so, the module will be
+	  called zx2967_i2c.
+
 endmenu
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index beb4809..16b2901 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -101,6 +101,7 @@ obj-$(CONFIG_I2C_XILINX)	+= i2c-xiic.o
 obj-$(CONFIG_I2C_XLR)		+= i2c-xlr.o
 obj-$(CONFIG_I2C_XLP9XX)	+= i2c-xlp9xx.o
 obj-$(CONFIG_I2C_RCAR)		+= i2c-rcar.o
+obj-$(CONFIG_I2C_ZX2967)	+= i2c-zx2967.o
 
 # External I2C/SMBus adapter drivers
 obj-$(CONFIG_I2C_DIOLAN_U2C)	+= i2c-diolan-u2c.o
diff --git a/drivers/i2c/busses/i2c-zx2967.c b/drivers/i2c/busses/i2c-zx2967.c
new file mode 100644
index 0000000..d38b7b7
--- /dev/null
+++ b/drivers/i2c/busses/i2c-zx2967.c
@@ -0,0 +1,690 @@
+/*
+ * ZTE's zx2967 family i2c bus controller driver
+ *
+ * Copyright (C) 2017 ZTE Ltd.
+ *
+ * Author: Baoyou Xie <baoyou.xie@linaro.org>
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/platform_device.h>
+
+#define REG_CMD				0x04
+#define REG_DEVADDR_H			0x0C
+#define REG_DEVADDR_L			0x10
+#define REG_CLK_DIV_FS			0x14
+#define REG_CLK_DIV_HS			0x18
+#define REG_WRCONF			0x1C
+#define REG_RDCONF			0x20
+#define REG_DATA			0x24
+#define REG_STAT			0x28
+
+#define I2C_STOP			0
+#define I2C_MASTER			BIT(0)
+#define I2C_ADDR_MODE_TEN		BIT(1)
+#define I2C_IRQ_MSK_ENABLE		BIT(3)
+#define I2C_RW_READ			BIT(4)
+#define I2C_CMB_RW_EN			BIT(5)
+#define I2C_START			BIT(6)
+#define I2C_ADDR_MODE_TEN		BIT(1)
+
+#define I2C_WFIFO_RESET			BIT(7)
+#define I2C_RFIFO_RESET			BIT(7)
+
+#define I2C_IRQ_ACK_CLEAR		BIT(7)
+#define I2C_INT_MASK			GENMASK(6, 0)
+
+#define I2C_TRANS_DONE			BIT(0)
+#define I2C_ERROR_DEVICE		BIT(1)
+#define I2C_ERROR_DATA			BIT(2)
+#define I2C_ERROR_MASK			GENMASK(2, 1)
+
+#define I2C_SR_BUSY			BIT(6)
+
+#define I2C_SR_EDEVICE			BIT(1)
+#define I2C_SR_EDATA			BIT(2)
+
+#define I2C_FIFO_MAX			16
+
+#define I2C_TIMEOUT			msecs_to_jiffies(1000)
+
+struct zx2967_i2c_info {
+	spinlock_t		lock;
+	struct device		*dev;
+	struct i2c_adapter	adap;
+	struct clk		*clk;
+	struct completion	complete;
+	u32			clk_freq;
+	struct pinctrl		*pin_ctrl;
+	void __iomem		*reg_base;
+	size_t			residue;
+	int			id;
+	int			irq;
+	int			msg_rd;
+	u8			*buf;
+	u8			access_cnt;
+	bool			is_suspended;
+};
+
+static void zx2967_i2c_writel(struct zx2967_i2c_info *zx_i2c,
+			      u32 val, unsigned long reg)
+{
+	writel_relaxed(val, zx_i2c->reg_base + reg);
+}
+
+static u32 zx2967_i2c_readl(struct zx2967_i2c_info *zx_i2c, unsigned long reg)
+{
+	return readl_relaxed(zx_i2c->reg_base + reg);
+}
+
+static void zx2967_i2c_writesb(struct zx2967_i2c_info *zx_i2c,
+			       void *data, unsigned long reg, int len)
+{
+	writesb(zx_i2c->reg_base + reg, data, len);
+}
+
+static void zx2967_i2c_readsb(struct zx2967_i2c_info *zx_i2c,
+			      void *data, unsigned long reg, int len)
+{
+	readsb(zx_i2c->reg_base + reg, data, len);
+}
+
+static void zx2967_i2c_start_ctrl(struct zx2967_i2c_info *zx_i2c)
+{
+	u32 status;
+	u32 ctl;
+
+	status = zx2967_i2c_readl(zx_i2c, REG_STAT);
+	status |= I2C_IRQ_ACK_CLEAR;
+	zx2967_i2c_writel(zx_i2c, status, REG_STAT);
+
+	ctl = zx2967_i2c_readl(zx_i2c, REG_CMD);
+	if (zx_i2c->msg_rd)
+		ctl |= I2C_RW_READ;
+	else
+		ctl &= ~I2C_RW_READ;
+	ctl &= ~I2C_CMB_RW_EN;
+	ctl |= I2C_START;
+	zx2967_i2c_writel(zx_i2c, ctl, REG_CMD);
+}
+
+static int zx2967_i2c_flush_fifos(struct zx2967_i2c_info *zx_i2c)
+{
+	u32 val;
+	u32 offset;
+
+	if (zx_i2c->msg_rd) {
+		offset = REG_RDCONF;
+		val = I2C_RFIFO_RESET;
+	} else {
+		offset = REG_WRCONF;
+		val = I2C_WFIFO_RESET;
+	}
+
+	val |= zx2967_i2c_readl(zx_i2c, offset);
+	zx2967_i2c_writel(zx_i2c, val, offset);
+
+	return 0;
+}
+
+static int zx2967_i2c_empty_rx_fifo(struct zx2967_i2c_info *zx_i2c, u32 size)
+{
+	u8  val[I2C_FIFO_MAX] = {0};
+	int i;
+
+	if (size > I2C_FIFO_MAX) {
+		dev_err(zx_i2c->dev, "fifo size %d over the max value %d\n",
+			size, I2C_FIFO_MAX);
+		return -EINVAL;
+	}
+
+	zx2967_i2c_readsb(zx_i2c, val, REG_DATA, size);
+	for (i = 0; i < size; i++) {
+		*(zx_i2c->buf++) = val[i];
+		zx_i2c->residue--;
+		if (zx_i2c->residue <= 0)
+			break;
+	}
+
+	barrier();
+
+	return 0;
+}
+
+static int zx2967_i2c_fill_tx_fifo(struct zx2967_i2c_info *zx_i2c)
+{
+	u8 *buf = zx_i2c->buf;
+	size_t residue = zx_i2c->residue;
+
+	if (residue == 0) {
+		dev_err(zx_i2c->dev, "residue is %d\n", (int)residue);
+		return -EINVAL;
+	}
+
+	if (residue <= I2C_FIFO_MAX) {
+		zx2967_i2c_writesb(zx_i2c, buf, REG_DATA, residue);
+
+		/* Again update before writing to FIFO to make sure isr sees. */
+		zx_i2c->residue = 0;
+		zx_i2c->buf = NULL;
+	} else {
+		zx2967_i2c_writesb(zx_i2c, buf, REG_DATA, I2C_FIFO_MAX);
+		zx_i2c->residue -= I2C_FIFO_MAX;
+		zx_i2c->buf += I2C_FIFO_MAX;
+	}
+
+	barrier();
+
+	return 0;
+}
+
+static int zx2967_i2c_reset_hardware(struct zx2967_i2c_info *zx_i2c)
+{
+	u32 val;
+	u32 clk_div;
+	u32 status;
+
+	val = I2C_MASTER | I2C_IRQ_MSK_ENABLE;
+	zx2967_i2c_writel(zx_i2c, val, REG_CMD);
+
+	clk_div = clk_get_rate(zx_i2c->clk) / zx_i2c->clk_freq - 1;
+	zx2967_i2c_writel(zx_i2c, clk_div, REG_CLK_DIV_FS);
+	zx2967_i2c_writel(zx_i2c, clk_div, REG_CLK_DIV_HS);
+
+	zx2967_i2c_writel(zx_i2c, I2C_FIFO_MAX - 1, REG_WRCONF);
+	zx2967_i2c_writel(zx_i2c, I2C_FIFO_MAX - 1, REG_RDCONF);
+	zx2967_i2c_writel(zx_i2c, 1, REG_RDCONF);
+
+	if (zx2967_i2c_flush_fifos(zx_i2c))
+		return -ETIMEDOUT;
+
+	status = zx2967_i2c_readl(zx_i2c, REG_STAT);
+	if (status & (I2C_SR_BUSY))
+		return -EBUSY;
+	if (status & (I2C_SR_EDEVICE | I2C_SR_EDATA))
+		return -EIO;
+
+	enable_irq(zx_i2c->irq);
+
+	return 0;
+}
+
+static void zx2967_i2c_isr_clr(struct zx2967_i2c_info *zx_i2c)
+{
+	u32 status;
+
+	status = zx2967_i2c_readl(zx_i2c, REG_STAT);
+	status |= I2C_IRQ_ACK_CLEAR;
+	zx2967_i2c_writel(zx_i2c, status, REG_STAT);
+}
+
+static irqreturn_t zx2967_i2c_isr(int irq, void *dev_id)
+{
+	u32 status;
+	struct zx2967_i2c_info *zx_i2c = (struct zx2967_i2c_info *)dev_id;
+	unsigned long flags;
+
+	spin_lock_irqsave(&zx_i2c->lock, flags);
+
+	status = zx2967_i2c_readl(zx_i2c, REG_STAT) & I2C_INT_MASK;
+	zx2967_i2c_isr_clr(zx_i2c);
+
+	if (status & I2C_ERROR_MASK) {
+		spin_unlock_irqrestore(&zx_i2c->lock, flags);
+		return IRQ_HANDLED;
+	}
+
+	if (status & I2C_TRANS_DONE)
+		complete(&zx_i2c->complete);
+
+	spin_unlock_irqrestore(&zx_i2c->lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+static void zx2967_enable_tenbit(struct zx2967_i2c_info *zx_i2c, __u16 addr)
+{
+	u16 val = (addr >> 7) & 0x7;
+
+	if (val > 0) {
+		zx2967_i2c_writel(zx_i2c, val, REG_DEVADDR_H);
+		val = (zx2967_i2c_readl(zx_i2c, REG_CMD)) | I2C_ADDR_MODE_TEN;
+		zx2967_i2c_writel(zx_i2c, val, REG_CMD);
+	}
+}
+
+static int
+zx2967_i2c_xfer_read_bytes(struct zx2967_i2c_info *zx_i2c, u32 bytes)
+{
+	unsigned long time_left;
+
+	reinit_completion(&zx_i2c->complete);
+	zx2967_i2c_writel(zx_i2c, bytes - 1, REG_RDCONF);
+	zx2967_i2c_start_ctrl(zx_i2c);
+
+	time_left = wait_for_completion_timeout(&zx_i2c->complete,
+				I2C_TIMEOUT);
+	if (time_left == 0) {
+		dev_err(zx_i2c->dev, "read i2c transfer timed out\n");
+		disable_irq(zx_i2c->irq);
+		zx2967_i2c_reset_hardware(zx_i2c);
+		return -EIO;
+	}
+
+	zx2967_i2c_empty_rx_fifo(zx_i2c, bytes);
+	return 0;
+}
+
+static int zx2967_i2c_xfer_read(struct zx2967_i2c_info *zx_i2c)
+{
+	int ret;
+	int i;
+
+	for (i = 0; i < zx_i2c->access_cnt; i++) {
+		ret = zx2967_i2c_xfer_read_bytes(zx_i2c, I2C_FIFO_MAX);
+		if (ret)
+			return ret;
+	}
+
+	if (zx_i2c->residue > 0) {
+		ret = zx2967_i2c_xfer_read_bytes(zx_i2c, I2C_FIFO_MAX);
+		if (ret)
+			return ret;
+	}
+
+	zx_i2c->residue = 0;
+	zx_i2c->access_cnt = 0;
+	return 0;
+}
+
+static int
+zx2967_i2c_xfer_write_bytes(struct zx2967_i2c_info *zx_i2c, u32 bytes)
+{
+	unsigned long time_left;
+
+	reinit_completion(&zx_i2c->complete);
+	zx2967_i2c_fill_tx_fifo(zx_i2c);
+	zx2967_i2c_start_ctrl(zx_i2c);
+
+	time_left = wait_for_completion_timeout(&zx_i2c->complete,
+				I2C_TIMEOUT);
+	if (time_left == 0) {
+		dev_err(zx_i2c->dev, "write i2c transfer timed out\n");
+		disable_irq(zx_i2c->irq);
+		zx2967_i2c_reset_hardware(zx_i2c);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int zx2967_i2c_xfer_write(struct zx2967_i2c_info *zx_i2c)
+{
+	int ret;
+	int i;
+
+	for (i = 0; i < zx_i2c->access_cnt; i++) {
+		ret = zx2967_i2c_xfer_write_bytes(zx_i2c, I2C_FIFO_MAX);
+		if (ret)
+			return ret;
+	}
+
+	if (zx_i2c->residue > 0) {
+		ret = zx2967_i2c_xfer_write_bytes(zx_i2c, I2C_FIFO_MAX);
+		if (ret)
+			return ret;
+	}
+
+	zx_i2c->residue = 0;
+	zx_i2c->access_cnt = 0;
+	return 0;
+}
+
+static int zx2967_i2c_xfer_msg(struct zx2967_i2c_info *zx_i2c,
+			       struct i2c_msg *msg)
+{
+	if (msg->len == 0)
+		return -EINVAL;
+
+	zx2967_i2c_flush_fifos(zx_i2c);
+
+	zx_i2c->buf = msg->buf;
+	zx_i2c->residue = msg->len;
+	zx_i2c->access_cnt = msg->len / I2C_FIFO_MAX;
+	zx_i2c->msg_rd = (msg->flags & I2C_M_RD);
+
+	if (zx_i2c->msg_rd)
+		return zx2967_i2c_xfer_read(zx_i2c);
+
+	return zx2967_i2c_xfer_write(zx_i2c);
+}
+
+static int zx2967_i2c_xfer(struct i2c_adapter *adap,
+			   struct i2c_msg *msgs, int num)
+{
+	struct zx2967_i2c_info *zx_i2c = i2c_get_adapdata(adap);
+	int ret;
+	int i;
+
+	if (zx_i2c->is_suspended)
+		return -EBUSY;
+
+	zx2967_i2c_writel(zx_i2c, (msgs->addr & 0x7f), REG_DEVADDR_L);
+	zx2967_i2c_writel(zx_i2c, (msgs->addr >> 7) & 0x7, REG_DEVADDR_H);
+	if (zx2967_i2c_readl(zx_i2c, REG_DEVADDR_H) > 0)
+		zx2967_enable_tenbit(zx_i2c, msgs->addr);
+
+	for (i = 0; i < num; i++) {
+		ret = zx2967_i2c_xfer_msg(zx_i2c, &msgs[i]);
+		if (num > 1)
+			usleep_range(1000, 2000);
+		if (ret)
+			return ret;
+	}
+
+	return num;
+}
+
+static void
+zx2967_smbus_xfer_prepare(struct zx2967_i2c_info *zx_i2c, u16 addr,
+			  char read_write, u8 command, int size,
+			  union i2c_smbus_data *data)
+{
+	u32 val;
+
+	val = zx2967_i2c_readl(zx_i2c, REG_RDCONF);
+	val |= I2C_RFIFO_RESET;
+	zx2967_i2c_writel(zx_i2c, val, REG_RDCONF);
+	zx2967_i2c_writel(zx_i2c, (addr & 0x7f), REG_DEVADDR_L);
+
+	zx2967_enable_tenbit(zx_i2c, addr);
+	val = zx2967_i2c_readl(zx_i2c, REG_CMD);
+	val &= ~I2C_RW_READ;
+	zx2967_i2c_writel(zx_i2c, val, REG_CMD);
+
+	switch (size) {
+	case I2C_SMBUS_BYTE:
+		zx2967_i2c_writel(zx_i2c, command, REG_DATA);
+		break;
+	case I2C_SMBUS_BYTE_DATA:
+		zx2967_i2c_writel(zx_i2c, command, REG_DATA);
+		if (read_write == I2C_SMBUS_WRITE)
+			zx2967_i2c_writel(zx_i2c, data->byte, REG_DATA);
+		break;
+	case I2C_SMBUS_WORD_DATA:
+		zx2967_i2c_writel(zx_i2c, command, REG_DATA);
+		if (read_write == I2C_SMBUS_WRITE) {
+			zx2967_i2c_writel(zx_i2c, (data->word >> 8), REG_DATA);
+			zx2967_i2c_writel(zx_i2c, (data->word & 0xff),
+					  REG_DATA);
+		}
+		break;
+	}
+}
+
+static int zx2967_smbus_xfer_read(struct zx2967_i2c_info *zx_i2c, int size,
+				  union i2c_smbus_data *data)
+{
+	unsigned long time_left;
+	u8 buf[2];
+	u32 val;
+
+	reinit_completion(&zx_i2c->complete);
+
+	val = zx2967_i2c_readl(zx_i2c, REG_CMD);
+	val |= I2C_CMB_RW_EN;
+	zx2967_i2c_writel(zx_i2c, val, REG_CMD);
+
+	val = zx2967_i2c_readl(zx_i2c, REG_CMD);
+	val |= I2C_START;
+	zx2967_i2c_writel(zx_i2c, val, REG_CMD);
+
+	time_left = wait_for_completion_timeout(&zx_i2c->complete,
+						I2C_TIMEOUT);
+	if (time_left == 0) {
+		dev_err(zx_i2c->dev, "i2c read transfer timed out\n");
+		disable_irq(zx_i2c->irq);
+		zx2967_i2c_reset_hardware(zx_i2c);
+		return -EIO;
+	}
+
+	usleep_range(1000, 2000);
+	switch (size) {
+	case I2C_SMBUS_BYTE:
+	case I2C_SMBUS_BYTE_DATA:
+		val = zx2967_i2c_readl(zx_i2c, REG_DATA);
+		data->byte = val;
+		break;
+	case I2C_SMBUS_WORD_DATA:
+	case I2C_SMBUS_PROC_CALL:
+		buf[0] = zx2967_i2c_readl(zx_i2c, REG_DATA);
+		buf[1] = zx2967_i2c_readl(zx_i2c, REG_DATA);
+		data->word = (buf[0] << 8) | buf[1];
+		break;
+	default:
+		dev_warn(zx_i2c->dev, "Unsupported transaction %d\n", size);
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+static int zx2967_smbus_xfer_write(struct zx2967_i2c_info *zx_i2c)
+{
+	unsigned long time_left;
+	u32 val;
+
+	reinit_completion(&zx_i2c->complete);
+	val = zx2967_i2c_readl(zx_i2c, REG_CMD);
+	val |= I2C_START;
+	zx2967_i2c_writel(zx_i2c, val, REG_CMD);
+
+	time_left = wait_for_completion_timeout(&zx_i2c->complete,
+						I2C_TIMEOUT);
+	if (time_left == 0) {
+		dev_err(zx_i2c->dev, "i2c write transfer timed out\n");
+		disable_irq(zx_i2c->irq);
+		zx2967_i2c_reset_hardware(zx_i2c);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int zx2967_smbus_xfer(struct i2c_adapter *adap, u16 addr,
+			     unsigned short flags, char read_write,
+			     u8 command, int size, union i2c_smbus_data *data)
+{
+	struct zx2967_i2c_info *zx_i2c = i2c_get_adapdata(adap);
+
+	if (size == I2C_SMBUS_QUICK)
+		read_write = I2C_SMBUS_WRITE;
+
+	switch (size) {
+	case I2C_SMBUS_QUICK:
+	case I2C_SMBUS_BYTE:
+	case I2C_SMBUS_BYTE_DATA:
+	case I2C_SMBUS_WORD_DATA:
+		zx2967_smbus_xfer_prepare(zx_i2c, addr, read_write,
+					  command, size, data);
+		break;
+	default:
+		dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
+		return -EOPNOTSUPP;
+	}
+
+	if (read_write == I2C_SMBUS_READ)
+		return zx2967_smbus_xfer_read(zx_i2c, size, data);
+
+	return zx2967_smbus_xfer_write(zx_i2c);
+}
+
+#define ZX2967_I2C_FUNCS (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |	\
+		I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |	\
+		I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_PROC_CALL |	\
+		I2C_FUNC_I2C | I2C_FUNC_SMBUS_I2C_BLOCK)
+static u32 zx2967_i2c_func(struct i2c_adapter *adap)
+{
+	return ZX2967_I2C_FUNCS;
+}
+
+static int __maybe_unused zx2967_i2c_suspend(struct device *dev)
+{
+	struct zx2967_i2c_info *zx_i2c = dev_get_drvdata(dev);
+
+	zx_i2c->is_suspended = true;
+	if (__clk_get_enable_count(zx_i2c->clk) == 1)
+		clk_disable_unprepare(zx_i2c->clk);
+
+	return 0;
+}
+
+static int __maybe_unused zx2967_i2c_resume(struct device *dev)
+{
+	struct zx2967_i2c_info *zx_i2c = dev_get_drvdata(dev);
+
+	zx_i2c->is_suspended = false;
+	clk_prepare_enable(zx_i2c->clk);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static const struct dev_pm_ops zx2967_i2c_dev_pm_ops = {
+	.suspend	= zx2967_i2c_suspend,
+	.resume		= zx2967_i2c_resume,
+};
+#define ZX2967_I2C_DEV_PM_OPS	(&zx2967_i2c_dev_pm_ops)
+#else
+#define	ZX2967_I2C_DEV_PM_OPS	NULL
+#endif
+
+static const struct i2c_algorithm zx2967_i2c_algo = {
+	.master_xfer = zx2967_i2c_xfer,
+	.smbus_xfer = zx2967_smbus_xfer,
+	.functionality = zx2967_i2c_func,
+};
+
+static const struct of_device_id zx2967_i2c_of_match[] = {
+	{ .compatible = "zte,zx296718-i2c", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, zx2967_i2c_of_match);
+
+static int zx2967_i2c_probe(struct platform_device *pdev)
+{
+	struct zx2967_i2c_info *zx_i2c;
+	void __iomem *reg_base;
+	struct resource *res;
+	struct clk *clk;
+	int ret;
+
+	zx_i2c = devm_kzalloc(&pdev->dev, sizeof(*zx_i2c), GFP_KERNEL);
+	if (!zx_i2c)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	reg_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(reg_base))
+		return PTR_ERR(reg_base);
+
+	clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(clk)) {
+		dev_err(&pdev->dev, "missing controller clock");
+		return PTR_ERR(clk);
+	}
+
+	ret = clk_prepare_enable(clk);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to enable i2c_clk\n");
+		return ret;
+	}
+
+	ret = platform_get_irq(pdev, 0);
+	if (ret < 0)
+		return ret;
+	zx_i2c->irq = ret;
+
+	device_property_read_u32(&pdev->dev, "clock-frequency",
+				 &zx_i2c->clk_freq);
+	zx_i2c->reg_base = reg_base;
+	zx_i2c->clk = clk;
+	zx_i2c->id = pdev->id;
+	zx_i2c->dev = &pdev->dev;
+
+	zx_i2c->pin_ctrl = devm_pinctrl_get_select(&pdev->dev, "pinctrl-0");
+	if (IS_ERR(zx_i2c->pin_ctrl))
+		dev_info(&pdev->dev, "pinctrl-0 pin is not specified in dts\n");
+
+	spin_lock_init(&zx_i2c->lock);
+	init_completion(&zx_i2c->complete);
+	platform_set_drvdata(pdev, zx_i2c);
+
+	ret = zx2967_i2c_reset_hardware(zx_i2c);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to initialize i2c controller\n");
+		goto err_clk_unprepare;
+	}
+
+	ret = devm_request_irq(&pdev->dev, zx_i2c->irq,
+			zx2967_i2c_isr, 0, dev_name(&pdev->dev), zx_i2c);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to request irq %i\n", zx_i2c->irq);
+		goto err_clk_unprepare;
+	}
+
+	i2c_set_adapdata(&zx_i2c->adap, zx_i2c);
+	zx_i2c->adap.owner = THIS_MODULE;
+	zx_i2c->adap.class = I2C_CLASS_DEPRECATED;
+	strlcpy(zx_i2c->adap.name, "zx2967 i2c adapter",
+		sizeof(zx_i2c->adap.name));
+	zx_i2c->adap.algo = &zx2967_i2c_algo;
+	zx_i2c->adap.dev.parent = &pdev->dev;
+	zx_i2c->adap.nr = pdev->id;
+	zx_i2c->adap.dev.of_node = pdev->dev.of_node;
+
+	ret = i2c_add_numbered_adapter(&zx_i2c->adap);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to add zx2967 i2c adapter\n");
+		goto err_clk_unprepare;
+	}
+
+	return 0;
+
+err_clk_unprepare:
+	clk_disable_unprepare(zx_i2c->clk);
+	return ret;
+}
+
+static int zx2967_i2c_remove(struct platform_device *pdev)
+{
+	struct zx2967_i2c_info *zx_i2c = platform_get_drvdata(pdev);
+
+	i2c_del_adapter(&zx_i2c->adap);
+	clk_disable_unprepare(zx_i2c->clk);
+
+	return 0;
+}
+
+static struct platform_driver zx2967_i2c_driver = {
+	.probe	= zx2967_i2c_probe,
+	.remove	= zx2967_i2c_remove,
+	.driver	= {
+		.name  = "zx2967_i2c",
+		.of_match_table = zx2967_i2c_of_match,
+		.pm		= ZX2967_I2C_DEV_PM_OPS,
+	},
+};
+module_platform_driver(zx2967_i2c_driver);
+
+MODULE_AUTHOR("Baoyou Xie <baoyou.xie@linaro.org>");
+MODULE_DESCRIPTION("ZTE zx2967 I2C Bus Controller driver");
+MODULE_LICENSE("GPL v2");
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 2/3] MAINTAINERS: add zx2967 i2c controller driver to ARM ZTE architecture
From: Baoyou Xie @ 2017-01-23  5:03 UTC (permalink / raw)
  To: andy.shevchenko, jun.nie, wsa, robh+dt, mark.rutland
  Cc: linux-arm-kernel, linux-i2c, devicetree, linux-kernel, shawnguo,
	baoyou.xie, xie.baoyou, chen.chaokai, wang.qiang01
In-Reply-To: <1485147806-17792-1-git-send-email-baoyou.xie@linaro.org>

Add the zx2967 i2c controller driver as maintained by ARM ZTE
architecture maintainers, as they're parts of the core IP.

Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
---
 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 275c434..757c098 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1987,12 +1987,14 @@ L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
 F:	arch/arm/mach-zx/
 F:	drivers/clk/zte/
+F:	drivers/i2c/busses/i2c-zx2967.c
 F:	drivers/reset/reset-zx2967.c
 F:	drivers/soc/zte/
 F:	drivers/thermal/zx*
 F:	drivers/watchdog/zx2967_wdt.c
 F:	Documentation/devicetree/bindings/arm/zte.txt
 F:	Documentation/devicetree/bindings/clock/zx296702-clk.txt
+F:	Documentation/devicetree/bindings/i2c/i2c-zx2967.txt
 F:	Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt
 F:	Documentation/devicetree/bindings/soc/zte/
 F:	Documentation/devicetree/bindings/thermal/zx*
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 1/3] dt: bindings: add documentation for zx2967 family i2c controller
From: Baoyou Xie @ 2017-01-23  5:03 UTC (permalink / raw)
  To: andy.shevchenko-Re5JQEeQqe8AvxtiuMwx3w,
	jun.nie-QSEj5FYQhm4dnm+yROfE0A, wsa-z923LK4zBo2bacvFa/9K2g,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	shawnguo-DgEjT+Ai2ygdnm+yROfE0A,
	baoyou.xie-QSEj5FYQhm4dnm+yROfE0A,
	xie.baoyou-Th6q7B73Y6EnDS1+zs4M5A,
	chen.chaokai-Th6q7B73Y6EnDS1+zs4M5A,
	wang.qiang01-Th6q7B73Y6EnDS1+zs4M5A

This patch adds dt-binding documentation for zx2967 family
i2c controller.

Signed-off-by: Baoyou Xie <baoyou.xie-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 .../devicetree/bindings/i2c/i2c-zx2967.txt         | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/i2c/i2c-zx2967.txt

diff --git a/Documentation/devicetree/bindings/i2c/i2c-zx2967.txt b/Documentation/devicetree/bindings/i2c/i2c-zx2967.txt
new file mode 100644
index 0000000..cb806d1
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-zx2967.txt
@@ -0,0 +1,22 @@
+ZTE zx2967 I2C controller
+
+Required properties:
+ - compatible: must be "zte,zx296718-i2c"
+ - reg: physical address and length of the device registers
+ - interrupts: a single interrupt specifier
+ - clocks: clock for the device
+ - #address-cells: should be <1>
+ - #size-cells: should be <0>
+ - clock-frequency: the desired I2C bus clock frequency.
+
+Examples:
+
+	i2c@112000 {
+		compatible = "zte,zx296718-i2c";
+		reg = <0x00112000 0x1000>;
+		interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&osc24m>;
+		#address-cells = <1>
+		#size-cells = <0>;
+		clock-frequency = <1600000>;
+	};
-- 
2.7.4

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

^ permalink raw reply related

* [PATCH 4/4] mfd: mt6397: Add MT6323 LED support into MT6397 driver
From: sean.wang-NuS5LvNUpcJWk0Htik3J/w @ 2017-01-23  3:54 UTC (permalink / raw)
  To: rpurdie-Fm38FmjxZ/leoWH0uzbU5w,
	jacek.anaszewski-Re5JQEeQqe8AvxtiuMwx3w,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A,
	matthias.bgg-Re5JQEeQqe8AvxtiuMwx3w, pavel-+ZI9xUNit7I,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-leds-u79uwXL29TY76Z2rM5mHXA,
	linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	keyhaede-Re5JQEeQqe8AvxtiuMwx3w, Sean Wang
In-Reply-To: <1485143685-11808-1-git-send-email-sean.wang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>

From: Sean Wang <sean.wang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>

Add compatible string as "mt6323-led" that will make
the OF core spawn child devices for the LED subnode
of that MT6323 MFD device.

Signed-off-by: Sean Wang <sean.wang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
---
 drivers/mfd/mt6397-core.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
index e14d8b0..8e601c8 100644
--- a/drivers/mfd/mt6397-core.c
+++ b/drivers/mfd/mt6397-core.c
@@ -48,6 +48,10 @@
 		.name = "mt6323-regulator",
 		.of_compatible = "mediatek,mt6323-regulator"
 	},
+	{
+		.name = "mt6323-led",
+		.of_compatible = "mediatek,mt6323-led"
+	},
 };
 
 static const struct mfd_cell mt6397_devs[] = {
-- 
1.9.1

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

^ permalink raw reply related

* [PATCH 3/4] leds: Add LED support for MT6323 PMIC
From: sean.wang @ 2017-01-23  3:54 UTC (permalink / raw)
  To: rpurdie, jacek.anaszewski, lee.jones, matthias.bgg, pavel,
	robh+dt, mark.rutland
  Cc: devicetree, linux-leds, linux-mediatek, linux-arm-kernel,
	linux-kernel, keyhaede, Sean Wang
In-Reply-To: <1485143685-11808-1-git-send-email-sean.wang@mediatek.com>

From: Sean Wang <sean.wang@mediatek.com>

MT6323 PMIC is a multi-function device that includes
LED function. It allows attaching upto 4 LEDs which can
either be on, off or dimmed and/or blinked with the the
controller.

Signed-off-by: Sean Wang <sean.wang@mediatek.com>
---
 drivers/leds/Kconfig       |   8 +
 drivers/leds/Makefile      |   1 +
 drivers/leds/leds-mt6323.c | 391 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 400 insertions(+)
 create mode 100644 drivers/leds/leds-mt6323.c

diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index c621cbb..30095fc 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -117,6 +117,14 @@ config LEDS_MIKROTIK_RB532
 	  This option enables support for the so called "User LED" of
 	  Mikrotik's Routerboard 532.
 
+config LEDS_MT6323
+	tristate "LED Support for Mediatek MT6323 PMIC"
+	depends on LEDS_CLASS
+	depends on MFD_MT6397
+	help
+	  This option enables support for on-chip LED drivers found on
+	  Mediatek MT6323 PMIC.
+
 config LEDS_S3C24XX
 	tristate "LED Support for Samsung S3C24XX GPIO LEDs"
 	depends on LEDS_CLASS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 6b82737..4feb332 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -72,6 +72,7 @@ obj-$(CONFIG_LEDS_IS31FL32XX)		+= leds-is31fl32xx.o
 obj-$(CONFIG_LEDS_PM8058)		+= leds-pm8058.o
 obj-$(CONFIG_LEDS_MLXCPLD)		+= leds-mlxcpld.o
 obj-$(CONFIG_LEDS_NIC78BX)		+= leds-nic78bx.o
+obj-$(CONFIG_LEDS_MT6323)		+= leds-mt6323.o
 
 # LED SPI Drivers
 obj-$(CONFIG_LEDS_DAC124S085)		+= leds-dac124s085.o
diff --git a/drivers/leds/leds-mt6323.c b/drivers/leds/leds-mt6323.c
new file mode 100644
index 0000000..de3006d
--- /dev/null
+++ b/drivers/leds/leds-mt6323.c
@@ -0,0 +1,391 @@
+/*
+ * LED driver for Mediatek MT6323 PMIC
+ *
+ * Copyright (C) 2017 Sean Wang <sean.wang@mediatek.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/kernel.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/regmap.h>
+#include <linux/mfd/mt6397/core.h>
+#include <linux/mfd/mt6323/registers.h>
+#include <linux/module.h>
+
+/* Register to enable 32K clock common for LED device */
+#define MTK_MT6323_TOP_CKPDN0         0x0102
+#define RG_DRV_32K_CK_PDN	      BIT(11)
+#define RG_DRV_32K_CK_PDN_MASK	      BIT(11)
+
+/* Register to enable individual clock for LED device */
+#define MTK_MT6323_TOP_CKPDN2         0x010E
+#define RG_ISINK_CK_PDN(i)	      BIT(i)
+#define RG_ISINK_CK_PDN_MASK(i)       BIT(i)
+
+/* Register to select clock source */
+#define MTK_MT6323_TOP_CKCON1	      0x0126
+#define RG_ISINK_CK_SEL_MASK(i)	      (BIT(10) << (i))
+
+/* Register to setup the duty cycle of the blink */
+#define MTK_MT6323_ISINK_CON0(i)      (0x0330 + 0x8 * (i))
+#define ISINK_DIM_DUTY(i)	      (((i) << 8) & GENMASK(12, 8))
+#define ISINK_DIM_DUTY_MASK	      GENMASK(12, 8)
+
+/* Register to setup the period of the blink */
+#define MTK_MT6323_ISINK_CON1(i)      (0x0332 + 0x8 * (i))
+#define ISINK_DIM_FSEL(i)	      ((i) & GENMASK(15, 0))
+#define ISINK_DIM_FSEL_MASK	      GENMASK(15, 0)
+
+/* Register to control the brightness */
+#define MTK_MT6323_ISINK_CON2(i)      (0x0334 + 0x8 * (i))
+#define ISINK_CH_STEP(i)	      (((i) << 12) & GENMASK(14, 12))
+#define ISINK_CH_STEP_MASK	      GENMASK(14, 12)
+#define ISINK_SFSTR0_TC(i)	      (((i) << 1) & GENMASK(2, 1))
+#define ISINK_SFSTR0_TC_MASK	      GENMASK(2, 1)
+#define ISINK_SFSTR0_EN		      BIT(0)
+#define ISINK_SFSTR0_EN_MASK	      BIT(0)
+
+/* Register to LED channel enablement */
+#define MTK_MT6323_ISINK_EN_CTRL      0x0356
+#define ISINK_CH_EN(i)		      BIT(i)
+#define ISINK_CH_EN_MASK(i)	      BIT(i)
+
+#define MTK_MAX_PERIOD		      10000
+#define MTK_MAX_DEVICES			  4
+#define MTK_MAX_BRIGHTNESS		  6
+
+struct mtk_led;
+struct mtk_leds;
+
+/**
+ * struct mtk_led - state container for the LED device
+ * @id: the identifier in MT6323 LED device
+ * @parent: the pointer to MT6323 LED controller
+ * @cdev: LED class device for this LED device
+ * @current_brightness: current state of the LED device
+ */
+struct mtk_led {
+	int    id;
+	struct mtk_leds *parent;
+	struct led_classdev cdev;
+	u8 current_brightness;
+};
+
+/* struct mtk_leds -	state container for holding LED controller
+ *			of the driver
+ * @dev:		The device pointer
+ * @hw:			The underlying hardware providing shared
+			bus for the register operations
+ * @led_num:		How much the LED device the controller could control
+ * @lock:		The lock among process context
+ * @led:		The array that contains the state of individual
+			LED device
+ */
+struct mtk_leds {
+	struct device	*dev;
+	struct mt6397_chip *hw;
+	u8     led_num;
+	/* protect among process context */
+	struct mutex	 lock;
+	struct mtk_led	 led[4];
+};
+
+static void mtk_led_hw_off(struct led_classdev *cdev)
+{
+	struct mtk_led *led = container_of(cdev, struct mtk_led, cdev);
+	struct mtk_leds *leds = led->parent;
+	struct regmap *regmap = leds->hw->regmap;
+	unsigned int status;
+
+	status = ISINK_CH_EN(led->id);
+	regmap_update_bits(regmap, MTK_MT6323_ISINK_EN_CTRL,
+			   ISINK_CH_EN_MASK(led->id), ~status);
+
+	usleep_range(100, 300);
+	regmap_update_bits(regmap, MTK_MT6323_TOP_CKPDN2,
+			   RG_ISINK_CK_PDN_MASK(led->id),
+			   RG_ISINK_CK_PDN(led->id));
+
+	dev_dbg(leds->dev, "%s called for led%d\n",
+		__func__, led->id);
+}
+
+static u8 get_mtk_led_hw_brightness(struct led_classdev *cdev)
+{
+	struct mtk_led *led = container_of(cdev, struct mtk_led, cdev);
+	struct mtk_leds *leds = led->parent;
+	struct regmap *regmap = leds->hw->regmap;
+	unsigned int status;
+
+	regmap_read(regmap, MTK_MT6323_TOP_CKPDN2, &status);
+	if (status & RG_ISINK_CK_PDN_MASK(led->id))
+		return 0;
+
+	regmap_read(regmap, MTK_MT6323_ISINK_EN_CTRL, &status);
+	if (!(status & ISINK_CH_EN(led->id)))
+		return 0;
+
+	regmap_read(regmap, MTK_MT6323_ISINK_CON2(led->id), &status);
+	return  ((status & ISINK_CH_STEP_MASK) >> 12) + 1;
+}
+
+static void mtk_led_hw_on(struct led_classdev *cdev)
+{
+	struct mtk_led *led = container_of(cdev, struct mtk_led, cdev);
+	struct mtk_leds *leds = led->parent;
+	struct regmap *regmap = leds->hw->regmap;
+	unsigned int status;
+
+	/* Setup required clock source, enable the corresponding
+	 * clock and channel and let work with continuous blink as
+	 * the default
+	 */
+	regmap_update_bits(regmap, MTK_MT6323_TOP_CKCON1,
+			   RG_ISINK_CK_SEL_MASK(led->id), 0);
+
+	status = RG_ISINK_CK_PDN(led->id);
+	regmap_update_bits(regmap, MTK_MT6323_TOP_CKPDN2,
+			   RG_ISINK_CK_PDN_MASK(led->id), ~status);
+
+	usleep_range(100, 300);
+
+	regmap_update_bits(regmap, MTK_MT6323_ISINK_EN_CTRL,
+			   ISINK_CH_EN_MASK(led->id),
+			   ISINK_CH_EN(led->id));
+
+	regmap_update_bits(regmap, MTK_MT6323_ISINK_CON2(led->id),
+			   ISINK_CH_STEP_MASK,
+			   ISINK_CH_STEP(1));
+
+	regmap_update_bits(regmap, MTK_MT6323_ISINK_CON0(led->id),
+			   ISINK_DIM_DUTY_MASK, ISINK_DIM_DUTY(31));
+
+	regmap_update_bits(regmap, MTK_MT6323_ISINK_CON1(led->id),
+			   ISINK_DIM_FSEL_MASK, ISINK_DIM_FSEL(1000));
+
+	led->current_brightness = 1;
+
+	dev_dbg(leds->dev, "%s called for led%d\n",
+		__func__, led->id);
+}
+
+static int mtk_led_set_blink(struct led_classdev *cdev,
+			     unsigned long *delay_on,
+			     unsigned long *delay_off)
+{
+	struct mtk_led *led = container_of(cdev, struct mtk_led, cdev);
+	struct mtk_leds *leds = led->parent;
+	struct regmap *regmap = leds->hw->regmap;
+	u16 period;
+	u8 duty_cycle, duty_hw;
+
+	/* Units are in ms , if over the hardware able
+	 * to support, fallback into software blink
+	 */
+	if (*delay_on + *delay_off > MTK_MAX_PERIOD)
+		return -EINVAL;
+
+	/* LED subsystem requires a default user
+	 * friendly blink pattern for the LED so using
+	 * 1Hz duty cycle 50% here if without specific
+	 * value delay_on and delay off being assigned
+	 */
+	if (*delay_on == 0 && *delay_off == 0) {
+		*delay_on = 500;
+		*delay_off = 500;
+	}
+
+	period = *delay_on + *delay_off;
+
+	/* duty_cycle is the percentage of period during
+	 * which the led is ON
+	 */
+	duty_cycle = 100 * (*delay_on) / period;
+
+	mutex_lock(&leds->lock);
+
+	if (!led->current_brightness)
+		mtk_led_hw_on(cdev);
+
+	duty_hw = DIV_ROUND_CLOSEST(duty_cycle * 1000, 3125);
+	regmap_update_bits(regmap, MTK_MT6323_ISINK_CON0(led->id),
+			   ISINK_DIM_DUTY_MASK, ISINK_DIM_DUTY(duty_hw));
+
+	regmap_update_bits(regmap, MTK_MT6323_ISINK_CON1(led->id),
+			   ISINK_DIM_FSEL_MASK, ISINK_DIM_FSEL(period - 1));
+
+	mutex_unlock(&leds->lock);
+
+	dev_dbg(leds->dev, "%s: Hardware blink! period=%dms duty=%d for led%d\n",
+		__func__, period, duty_cycle, led->id);
+
+	return 0;
+}
+
+static int mtk_led_set_brightness(struct led_classdev *cdev,
+				  enum led_brightness brightness)
+{
+	struct mtk_led *led = container_of(cdev, struct mtk_led, cdev);
+	struct mtk_leds *leds = led->parent;
+	struct regmap *regmap = leds->hw->regmap;
+
+	mutex_lock(&leds->lock);
+
+	if (!led->current_brightness && brightness)
+		mtk_led_hw_on(cdev);
+
+	if (brightness) {
+		/* Setup current output for the corresponding
+		 * brightness level
+		 */
+		regmap_update_bits(regmap, MTK_MT6323_ISINK_CON2(led->id),
+				   ISINK_CH_STEP_MASK,
+				   ISINK_CH_STEP(brightness - 1));
+
+		regmap_update_bits(regmap, MTK_MT6323_ISINK_CON2(led->id),
+				   ISINK_SFSTR0_TC_MASK | ISINK_SFSTR0_EN_MASK,
+				   ISINK_SFSTR0_TC(2) | ISINK_SFSTR0_EN);
+
+		dev_dbg(leds->dev, "Update led brightness:%d\n",
+			brightness);
+	}
+
+	if (!brightness)
+		mtk_led_hw_off(cdev);
+	led->current_brightness = brightness;
+
+	mutex_unlock(&leds->lock);
+
+	return 0;
+}
+
+static int mt6323_led_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = pdev->dev.of_node;
+	struct device_node *child;
+	struct mt6397_chip *hw = dev_get_drvdata(pdev->dev.parent);
+	struct mtk_leds *leds;
+	int ret, i = 0, count;
+	const char *state;
+	unsigned int status;
+
+	count = of_get_child_count(np);
+	if (!count)
+		return -ENODEV;
+
+	/* The number the LEDs on MT6323 could be support is
+	 * up to MTK_MAX_DEVICES
+	 */
+	count = (count <= MTK_MAX_DEVICES) ? count : MTK_MAX_DEVICES;
+
+	leds = devm_kzalloc(dev, sizeof(struct mtk_leds) +
+			    sizeof(struct mtk_led) * count,
+			    GFP_KERNEL);
+	if (!leds)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, leds);
+	leds->dev = dev;
+
+	/* leds->hw points to the underlying bus for the register
+	 * controlled
+	 */
+	leds->hw = hw;
+	mutex_init(&leds->lock);
+	leds->led_num = count;
+
+	status = RG_DRV_32K_CK_PDN;
+	regmap_update_bits(leds->hw->regmap, MTK_MT6323_TOP_CKPDN0,
+			   RG_DRV_32K_CK_PDN_MASK, ~status);
+
+	/* Waiting for 32K stable prior to give the default value
+	 * to each LED state decided through these useful common
+	 * propertys such as label, linux,default-trigger and
+	 * default-state
+	 */
+	usleep_range(300, 500);
+
+	for_each_available_child_of_node(np, child) {
+		leds->led[i].cdev.name =
+			of_get_property(child, "label", NULL) ? :
+					child->name;
+		leds->led[i].cdev.default_trigger = of_get_property(child,
+						    "linux,default-trigger",
+						    NULL);
+		leds->led[i].cdev.max_brightness = MTK_MAX_BRIGHTNESS;
+		leds->led[i].cdev.brightness_set_blocking =
+					mtk_led_set_brightness;
+		leds->led[i].cdev.blink_set = mtk_led_set_blink;
+		leds->led[i].id = i;
+		leds->led[i].parent = leds;
+		state = of_get_property(child, "default-state", NULL);
+		if (state) {
+			if (!strcmp(state, "keep")) {
+				leds->led[i].current_brightness =
+				get_mtk_led_hw_brightness(&leds->led[i].cdev);
+			} else if (!strcmp(state, "on")) {
+				mtk_led_set_brightness(&leds->led[i].cdev, 1);
+			} else  {
+				mtk_led_set_brightness(&leds->led[i].cdev,
+						       0);
+			}
+		}
+		ret = devm_led_classdev_register(dev, &leds->led[i].cdev);
+		if (ret) {
+			dev_err(&pdev->dev, "Failed to register LED: %d\n",
+				ret);
+			return ret;
+		}
+		leds->led[i].cdev.dev->of_node = child;
+		i++;
+	}
+
+	return 0;
+}
+
+static int mt6323_led_remove(struct platform_device *pdev)
+{
+	struct mtk_leds *leds = platform_get_drvdata(pdev);
+	int i;
+
+	/* Turned the LED to OFF state if driver removal */
+	for (i = 0 ; i < leds->led_num ; i++)
+		mtk_led_hw_off(&leds->led[i].cdev);
+
+	regmap_update_bits(leds->hw->regmap, MTK_MT6323_TOP_CKPDN0,
+			   RG_DRV_32K_CK_PDN_MASK, RG_DRV_32K_CK_PDN);
+	return 0;
+}
+
+static const struct of_device_id mt6323_led_dt_match[] = {
+	{ .compatible = "mediatek,mt6323-led" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, mt6323_led_dt_match);
+
+static struct platform_driver mt6323_led_driver = {
+	.probe		= mt6323_led_probe,
+	.remove		= mt6323_led_remove,
+	.driver		= {
+		.name	= "mt6323-led",
+		.of_match_table = mt6323_led_dt_match,
+	},
+};
+
+module_platform_driver(mt6323_led_driver);
+
+MODULE_DESCRIPTION("LED driver for Mediatek MT6323 PMIC");
+MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1

^ permalink raw reply related

* [PATCH 2/4] Documentation: devicetree: Add LED subnode binding for MT6323 PMIC
From: sean.wang @ 2017-01-23  3:54 UTC (permalink / raw)
  To: rpurdie, jacek.anaszewski, lee.jones, matthias.bgg, pavel,
	robh+dt, mark.rutland
  Cc: devicetree, linux-leds, linux-mediatek, linux-arm-kernel,
	linux-kernel, keyhaede, Sean Wang
In-Reply-To: <1485143685-11808-1-git-send-email-sean.wang@mediatek.com>

From: Sean Wang <sean.wang@mediatek.com>

This patch adds documentation for devicetree bindings
for LED support as the subnode of MT6323 PMIC

Signed-off-by: Sean Wang <sean.wang@mediatek.com>
---
 Documentation/devicetree/bindings/mfd/mt6397.txt | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/mt6397.txt b/Documentation/devicetree/bindings/mfd/mt6397.txt
index 949c85f..c568d52 100644
--- a/Documentation/devicetree/bindings/mfd/mt6397.txt
+++ b/Documentation/devicetree/bindings/mfd/mt6397.txt
@@ -34,6 +34,10 @@ Optional subnodes:
 - clk
 	Required properties:
 		- compatible: "mediatek,mt6397-clk"
+- led
+	Required properties:
+		- compatible: "mediatek,mt6323-led"
+	see Documentation/devicetree/bindings/leds/leds-mt6323.txt
 
 Example:
 	pwrap: pwrap@1000f000 {
-- 
1.9.1

^ permalink raw reply related

* [PATCH 1/4] Documentation: devicetree: Add document bindings for leds-mt6323
From: sean.wang @ 2017-01-23  3:54 UTC (permalink / raw)
  To: rpurdie, jacek.anaszewski, lee.jones, matthias.bgg, pavel,
	robh+dt, mark.rutland
  Cc: devicetree, linux-leds, linux-mediatek, linux-arm-kernel,
	linux-kernel, keyhaede, Sean Wang
In-Reply-To: <1485143685-11808-1-git-send-email-sean.wang@mediatek.com>

From: Sean Wang <sean.wang@mediatek.com>

This patch adds documentation for devicetree bindings
for LED support on MT6323 PMIC

Signed-off-by: Sean Wang <sean.wang@mediatek.com>
---
 .../devicetree/bindings/leds/leds-mt6323.txt       | 60 ++++++++++++++++++++++
 1 file changed, 60 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-mt6323.txt

diff --git a/Documentation/devicetree/bindings/leds/leds-mt6323.txt b/Documentation/devicetree/bindings/leds/leds-mt6323.txt
new file mode 100644
index 0000000..82bbf0c
--- /dev/null
+++ b/Documentation/devicetree/bindings/leds/leds-mt6323.txt
@@ -0,0 +1,60 @@
+Device Tree Bindings for LED support on MT6323 PMIC
+
+MT6323 LED controller is subfunction provided by
+MT6323 PMIC, so the LED controller are defined as
+the subnode of the function node provided by MT6323
+PMIC controller that is being defined as one kind of
+Muti-Function Device (MFD) using shared bus called
+PMIC wrapper for each subfunction to access remote
+MT6323 PMIC hardware.
+
+For MT6323 MFD bindings see:
+Documentation/devicetree/bindings/mfd/mt6397.txt
+For MediaTek PMIC wrapper bindings see:
+Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
+
+There's sub-node for the LED controller that describes
+the initial behavior for each LED physcially and currently
+only four LED sub-nodes could be supported.
+
+Required properties:
+- compatible : must be "mediatek,mt6323-led"
+
+Optional properties:
+- label : (optional)
+  see Documentation/devicetree/bindings/leds/common.txt
+- linux,default-trigger : (optional)
+  see Documentation/devicetree/bindings/leds/common.txt
+- default-state: (optional) The initial state of the LED
+  see Documentation/devicetree/bindings/leds/common.txt
+
+Example:
+
+&pwrap {
+	pmic: mt6323 {
+		compatible = "mediatek,mt6323";
+		interrupt-parent = <&pio>;
+		interrupts = <150 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		mt6323led: mt6323led{
+			compatible = "mediatek,mt6323-led";
+
+			led0: isink0 {
+				lebel = "LED0"
+				linux,default-trigger = "timer";
+				default-state = "on";
+			};
+			led1: isink1 {
+				label = "LED1";
+				default-state = "on";
+			};
+			led2: isink2 {
+				label = "LED2";
+				linux,default-trigger = "timer";
+				default-state = "off";
+			};
+		};
+	};
+};
-- 
1.9.1

^ permalink raw reply related

* [PATCH 0/4] leds: add leds-mt6323 support on MT7623 SoC
From: sean.wang @ 2017-01-23  3:54 UTC (permalink / raw)
  To: rpurdie, jacek.anaszewski, lee.jones, matthias.bgg, pavel,
	robh+dt, mark.rutland
  Cc: devicetree, linux-leds, linux-mediatek, linux-arm-kernel,
	linux-kernel, keyhaede, Sean Wang

From: Sean Wang <sean.wang@mediatek.com>

MT7623 SoC uses MT6323 PMIC as the default power supply
which has LED function insides. The patchset introduces
the LED support for MT6323 with on, off and hardware
dimmed and blinked and it should work on other similar
SoCs if also using MT6323.

Sean Wang (4):
  Documentation: devicetree: Add document bindings for leds-mt6323
  Documentation: devicetree: Add LED subnode binding for MT6323 PMIC
  leds: Add LED support for MT6323 PMIC
  mfd: mt6397: Add MT6323 LED support into MT6397 driver

 .../devicetree/bindings/leds/leds-mt6323.txt       |  60 ++++
 Documentation/devicetree/bindings/mfd/mt6397.txt   |   4 +
 drivers/leds/Kconfig                               |   8 +
 drivers/leds/Makefile                              |   3 +
 drivers/leds/leds-mt6323.c                         | 390 +++++++++++++++++++++
 drivers/mfd/mt6397-core.c                          |   4 +
 6 files changed, 469 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/leds/leds-mt6323.txt
 create mode 100644 drivers/leds/leds-mt6323.c

-- 
1.9.1

^ permalink raw reply

* Re: [PATCH v1 3/3] i2c: zx2967: add i2c controller driver for ZTE's zx2967 family
From: Shawn Guo @ 2017-01-23  2:50 UTC (permalink / raw)
  To: Baoyou Xie
  Cc: jun.nie, wsa, robh+dt, mark.rutland, linux-arm-kernel, linux-i2c,
	devicetree, linux-kernel, xie.baoyou, chen.chaokai, wang.qiang01
In-Reply-To: <1484901827-16369-3-git-send-email-baoyou.xie@linaro.org>

On Fri, Jan 20, 2017 at 04:43:47PM +0800, Baoyou Xie wrote:
> +static int zx2967_i2c_probe(struct platform_device *pdev)
> +{
> +	struct resource *res;
> +	struct zx2967_i2c_info *zx_i2c = NULL;
> +	struct clk *clk;
> +	void __iomem *reg_base;
> +	int ret = 0;
> +
> +	zx_i2c = devm_kzalloc(&pdev->dev, sizeof(*zx_i2c), GFP_KERNEL);
> +	if (!zx_i2c)
> +		return -ENOMEM;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res) {
> +		dev_err(&pdev->dev, "missing io resource\n");
> +		return -EINVAL;
> +	}
> +
> +	reg_base = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(reg_base))
> +		return PTR_ERR(reg_base);
> +
> +	clk = devm_clk_get(&pdev->dev, NULL);
> +	if (IS_ERR(clk)) {
> +		dev_err(&pdev->dev, "missing controller clock");
> +		return PTR_ERR(clk);
> +	}
> +
> +	ret = clk_prepare_enable(clk);
> +	if (ret) {
> +		dev_err(&pdev->dev, "failed to enable i2c_clk\n");
> +		return ret;
> +	}
> +
> +	of_property_read_u32(pdev->dev.of_node,
> +			"clock-frequency", &zx_i2c->clk_freq);
> +	zx_i2c->reg_base = reg_base;
> +	zx_i2c->clk = clk;
> +	zx_i2c->irq = platform_get_irq(pdev, 0);
> +	zx_i2c->id = pdev->id;
> +	zx_i2c->dev = &pdev->dev;
> +
> +	zx_i2c->pin_scl = devm_pinctrl_get_select(&pdev->dev, "scl");
> +	if (IS_ERR(zx_i2c->pin_scl))
> +		dev_info(&pdev->dev, "scl pin is not specified in dts\n");
> +
> +	zx_i2c->pin_sda = devm_pinctrl_get_select(&pdev->dev, "sda");
> +	if (IS_ERR(zx_i2c->pin_sda))
> +		dev_info(&pdev->dev, "sda pin is not specified in dts\n");

I don't understand why this is necessary.  For most cases, we only need
to specify needed pins in property 'pinctrl-0' and 'default' in
'pinctrl-names', and pinctrl/driver core will just set up the pins for
the device.

Shawn

^ permalink raw reply

* Re: [PATCH v3 16/24] media: Add i.MX media core driver
From: Steve Longerbeam @ 2017-01-23  2:31 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	shawnguo-DgEjT+Ai2ygdnm+yROfE0A, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
	fabio.estevam-3arQi8VN3Tc, linux-I+IVW8TIWO2tmTQ+vhA3Yw,
	mchehab-DgEjT+Ai2ygdnm+yROfE0A, hverkuil-qWit8jRvyhVmR6Xm/wNWPw,
	nick-gcszYUEDH4VrovVCs/uTlw, markus.heiser-O6JHGLzbNUwb1SvskN2V4Q,
	laurent.pinchart+renesas-ryLnwIuWjnjg/C1BVhZhaw,
	bparrot-l0cyMroinI0, geert-Td1EMuHUCqxL1ZNQvxDV9g,
	arnd-r2nGTMty4D4, sudipm.mukherjee-Re5JQEeQqe8AvxtiuMwx3w,
	minghsiu.tsai-NuS5LvNUpcJWk0Htik3J/w,
	tiffany.lin-NuS5LvNUpcJWk0Htik3J/w,
	jean-christophe.trotin-qxv4g6HH51o,
	horms+renesas-/R6kz+dDXgpPR4JQBCEnsQ,
	niklas.soderlund+renesas-1zkq55x86MTxsAP9Fp7wbw,
	robert.jarzmik-GANU6spQydw, songjun.wu-UWL1GkI3JZL3oGB3hsPCZA,
	andrew-ct.chen-NuS5LvNUpcJWk0Htik3J/w,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-media-u79uwXL29TY76Z2rM5mHXA,
	devel-gWbeCf7V1WCQmaza687I9mD2FQJk+8+b, Steve Longerbeam
In-Reply-To: <1484574468.8415.136.camel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>



On 01/16/2017 05:47 AM, Philipp Zabel wrote:
> On Sat, 2017-01-14 at 14:46 -0800, Steve Longerbeam wrote:
> [...]
>>>> +Unprocessed Video Capture:
>>>> +--------------------------
>>>> +
>>>> +Send frames directly from sensor to camera interface, with no
>>>> +conversions:
>>>> +
>>>> +-> ipu_smfc -> camif
>>> I'd call this capture interface, this is not just for cameras. Or maybe
>>> idmac if you want to mirror hardware names?
>> Camif is so named because it is the V4L2 user interface for video
>> capture. I suppose it could be named "capif", but that doesn't role
>> off the tongue quite as well.
> Agreed, capif sounds weird. I find camif a bit confusing though, because
> Samsung S3C has a camera interface that is actually called "CAMIF".

how about simply "capture" ?


<snip>

>>> +   media-ctl -V "\"camif1\":0 [fmt:UYVY2X8/640x480]"
>> I agree this looks very intuitive, but technically correct for the
>> csi1:1 and camif1:0 pads would be a 32-bit YUV format.
>> (MEDIA_BUS_FMT_YUV8_1X32_PADLO doesn't exist yet).
>>
>> I think it would be better to use the correct format
>> I'm not sure I follow you here.
> The ov5640 sends UYVY2X8 on the wire, so pads "ov5640_mipi 1-0040":0
> up to "ipu1_csi1":0 are correct. But the CSI writes 32-bit YUV values
> into the SMFC, so the CSI output pad and the IDMAC input pad should have
> a YUV8_1X32 format.
>
> Chapter 37.4.2.3 "FCW & FCR - Format converter write and read" in the
> IDMAC chapter states that all internal submodules only work on 8-bit per
> component formats with four components: YUVA or RGBA.

Right, the "direct" IPU internal (that do not transfer buffers to/from
memory via IDMAC channels) should only allow the IPU internal
formats YUVA and RGBA. I get you now.

The "direct" pads now only accept MEDIA_BUS_FMT_AYUV8_1X32 and
MEDIA_BUS_FMT_ARGB8888_1X32.

Those pads are:

ipu_csi:1
ipu_vdic:1
ipu_ic_prp:0
ipu_ic_prp:1
ipu_ic_prpenc:0
ipu_ic_prpenc:1
ipu_ic_prpvf:0
ipu_ic_prpvf:1


<snip>
>
>> There does not appear to be support in the FSU for linking a write channel
>> to the VDIC read channels (8, 9, 10) according to VDI_SRC_SEL field. There
>> is support for the direct link from CSI (which I am using), but that's
>> not an
>> IDMAC channel link.
>>
>> There is a PRP_SRC_SEL field, with linking from IDMAC (SMFC) channels
>> 0..2 (and 3? it's not clear, and not clear whether this includes channel 1).
> As I read it, that is 0 and 2 only, no idea why. But since there are
> only 2 CSIs, that shouldn't be a problem.

ipu_csi1 is now transferring on IDMAC/SMFC channel 2 (ipu_csi0 still
at channel 0).

<snip>

>>>> +static const u32 power_off_seq[] = {
>>>> +	IMX_MEDIA_GRP_ID_IC_PP,
>>>> +	IMX_MEDIA_GRP_ID_IC_PRPVF,
>>>> +	IMX_MEDIA_GRP_ID_IC_PRPENC,
>>>> +	IMX_MEDIA_GRP_ID_SMFC,
>>>> +	IMX_MEDIA_GRP_ID_CSI,
>>>> +	IMX_MEDIA_GRP_ID_VIDMUX,
>>>> +	IMX_MEDIA_GRP_ID_SENSOR,
>>>> +	IMX_MEDIA_GRP_ID_CSI2,
>>>> +};
>>> This seems somewhat arbitrary. Why is a power sequence needed?
>> The CSI-2 receiver must be powered up before the sensor, that's the
>> only requirement IIRC. The others have no s_power requirement. So I
>> can probably change this to power up in the frontend -> backend order
>> (IC_PP to sensor). And vice-versa for power off.
> Yes, I think that should work (see below).

Actually there are problems using this, see below.

>>> [...]
>>>> +/*
>>>> + * Turn current pipeline power on/off starting from start_entity.
>>>> + * Must be called with mdev->graph_mutex held.
>>>> + */
>>>> +int imx_media_pipeline_set_power(struct imx_media_dev *imxmd,
>>>> +				 struct media_entity_graph *graph,
>>>> +				 struct media_entity *start_entity, bool on)
>>>> +{
>>>> +	struct media_entity *entity;
>>>> +	struct v4l2_subdev *sd;
>>>> +	int i, ret = 0;
>>>> +	u32 id;
>>>> +
>>>> +	for (i = 0; i < NUM_POWER_ENTITIES; i++) {
>>>> +		id = on ? power_on_seq[i] : power_off_seq[i];
>>>> +		entity = find_pipeline_entity(imxmd, graph, start_entity, id);
>>>> +		if (!entity)
>>>> +			continue;
>>>> +
>>>> +		sd = media_entity_to_v4l2_subdev(entity);
>>>> +
>>>> +		ret = v4l2_subdev_call(sd, core, s_power, on);
>>>> +		if (ret && ret != -ENOIOCTLCMD)
>>>> +			break;
>>>> +	}
>>>> +
>>>> +	return (ret && ret != -ENOIOCTLCMD) ? ret : 0;
>>>> +}
>>>> +EXPORT_SYMBOL_GPL(imx_media_pipeline_set_power);
>>> This should really be handled by v4l2_pipeline_pm_use.
>> I thought about this earlier, but v4l2_pipeline_pm_use() seems to be
>> doing some other stuff that bothered me, at least that's what I remember.
>> I will revisit this.
> I have used it with a tc358743 -> mipi-csi2 pipeline, it didn't cause
> any problems. It would be better to reuse and, if necessary, fix the
> existing infrastructure where available.

I tried this API, by switching to v4l2_pipeline_pm_use() in camif 
open/release,
and switched to v4l2_pipeline_link_notify() instead of 
imx_media_link_notify()
in the media driver's media_device_ops.

This API assumes the video device has an open file handle while the media
links are being established. This doesn't work for me, I want to be able to
establish the links using 'media-ctl -l', and that won't work unless 
there is an
open file handle on the video capture device node.

Also, I looked into calling v4l2_pipeline_pm_use() during 
imx_media_link_notify(),
instead of imx_media_pipeline_set_power(). Again there are problems with 
that.

First, v4l2_pipeline_pm_use() acquires the graph mutex, so it can't be 
called inside
link_notify which already acquires that lock. The header for this 
function also
clearly states it should only be called in open/release.

Second, ignoring the above locking issue for a moment, 
v4l2_pipeline_pm_use()
will call s_power on the sensor _first_, then the mipi csi-2 s_power, 
when executing
media-ctl -l '"ov5640 1-003c":0 -> "imx6-mipi-csi2":0[1]'. Which is the 
wrong order.
In my version which enforces the correct power on order, the mipi csi-2 
s_power
is called first in that link setup, followed by the sensor.



>>>> +int imx_media_add_internal_subdevs(struct imx_media_dev *imxmd,
>>>> +				   struct imx_media_subdev *csi[4])
>>>> +{
>>>> +	int ret;
>>>> +
>>>> +	/* there must be at least one CSI in first IPU */
>>> Why?
>> Well yeah, imx-media doesn't necessarily need a CSI if things
>> like the VDIC or post-processor are being used by an output
>> overlay pipeline, for example. I'll fix this.
> I haven't even thought that far, but there could be boards with only a
> parallel sensor connected to IPU2 CSI1 and IPU1 disabled for power
> saving reasons.

done! A very simple change to imx_media_add_internal_subdevs(),
and now no CSI's are necessary, but the remaining IPU internal entities
are loaded and linked just fine without them, so for example with no
CSI's in IPU2, the VDIC entity in IPU2 is still present in the graph and
could still be used in the future by a mem2mem device for instance.

Steve

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

^ permalink raw reply

* Re: [PATCH 4/5] dt: add bindings for ZTE tvenc device
From: Shawn Guo @ 2017-01-23  1:33 UTC (permalink / raw)
  To: Lucas Stach
  Cc: Mark Rutland, devicetree, Daniel Vetter, Baoyou Xie, dri-devel,
	Rob Herring, Jun Nie
In-Reply-To: <1484845877.24339.51.camel@pengutronix.de>

On Thu, Jan 19, 2017 at 06:11:17PM +0100, Lucas Stach wrote:
> Am Freitag, den 20.01.2017, 00:24 +0800 schrieb Shawn Guo:
> > From: Shawn Guo <shawn.guo@linaro.org>
> > 
> > It adds bindings doc for ZTE VOU TV Encoder device.
> > 
> > Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> > ---
> >  Documentation/devicetree/bindings/display/zte,vou.txt | 15 +++++++++++++++
> >  1 file changed, 15 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/display/zte,vou.txt b/Documentation/devicetree/bindings/display/zte,vou.txt
> > index 740e5bd2e4f7..9c356284232b 100644
> > --- a/Documentation/devicetree/bindings/display/zte,vou.txt
> > +++ b/Documentation/devicetree/bindings/display/zte,vou.txt
> > @@ -49,6 +49,15 @@ Required properties:
> >  	"osc_clk"
> >  	"xclk"
> >  
> > +* TV Encoder output device
> > +
> > +Required properties:
> > + - compatible: should be "zte,zx296718-tvenc"
> > + - reg: Physical base address and length of the TVENC device IO region
> > + - zte,tvenc-power-control: the phandle to SYSCTRL block followed by two
> > +   integer cells.  The first cell is the offset of SYSCTRL register used
> > +   to control TV Encoder DAC power, and the second cell is the bit mask.
> 
> I don't know much about this platform, but shouldn't this be handled
> with a proper power domain driver, rather than bashing bits directly?

There is a power domain controller (PCU) on ZTE platform which controls
power for a list of hardware blocks [1].  TVENC DAC is not on the list.
Rather than PCU, it's controlled by SYSCTRL block which contains various
control bits for various aspects of the system.

Shawn

[1] https://git.kernel.org/cgit/linux/kernel/git/shawnguo/linux.git/commit/?h=zte/pm-domains&id=eea1d99b900fe19dce3042dac555c270221be147
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply

* Re: [PATCH linux v1 2/2] drivers: hwmon: hwmon driver for ASPEED AST2400/2500 PWM and Fan tach controller
From: kbuild test robot @ 2017-01-23  0:06 UTC (permalink / raw)
  Cc: kbuild-all, openbmc, joel, jdelvare, linux, linux-hwmon,
	linux-kernel, corbet, linux-doc, robh+dt, mark.rutland,
	devicetree, Jaghathiswari Rankappagounder Natarajan
In-Reply-To: <20170109215935.30067-3-jaghu@google.com>

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

Hi Jaghathiswari,

[auto build test WARNING on hwmon/hwmon-next]
[also build test WARNING on v4.10-rc5 next-20170120]
[cannot apply to linux/master]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Jaghathiswari-Rankappagounder-Natarajan/Support-for-ASPEED-AST2400-AST2500-PWM-and-Fan-Tach-driver/20170110-093628
base:   https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next
config: i386-randconfig-i1-01230650 (attached as .config)
compiler: gcc-4.8 (Debian 4.8.4-1) 4.8.4
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All warnings (new ones prefixed by >>):

   drivers/hwmon/aspeed-pwm-tacho.c: In function 'aspeed_create_type':
>> drivers/hwmon/aspeed-pwm-tacho.c:656:41: warning: 'div_h' is used uninitialized in this function [-Wuninitialized]
     priv->type_pwm_clock_division_h[index] = div_h;
                                            ^

vim +/div_h +656 drivers/hwmon/aspeed-pwm-tacho.c

   640	 * The PWM frequency = 24MHz / (type M clock division L bit *
   641	 * type M clock division H bit * (type M PWM period bit + 1))
   642	 * Calculate type M clock division L bit and H bits given the other values
   643	 */
   644	static int aspeed_create_type(struct device_node *child,
   645				      struct aspeed_pwm_tacho_data *priv,
   646				      u8 index)
   647	{
   648		u8 period, div_l, div_h;
   649		bool enable;
   650		u8 mode, div;
   651		u16 unit;
   652	
   653		of_property_read_u8(child, "pwm_period", &period);
   654		of_property_read_u8(child, "pwm_clock_division_h", &div_h);
   655		of_property_read_u8(child, "pwm_clock_division_l", &div_l);
 > 656		priv->type_pwm_clock_division_h[index] = div_h;
   657		priv->type_pwm_clock_division_l[index] = div_l;
   658		priv->type_pwm_clock_unit[index] = period;
   659		aspeed_set_pwm_clock_values(priv->base, index, div_h, div_l, period);
   660	
   661		enable = of_property_read_bool(child, "fan_tach_enable");
   662		aspeed_set_tacho_type_enable(priv->base, index, enable);
   663	
   664		of_property_read_u8(child, "fan_tach_clock_division", &div);

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 27607 bytes --]

^ permalink raw reply

* [PATCH 1/3] watchdog: add DT bindings for Cortina Gemini
From: Linus Walleij @ 2017-01-22 22:38 UTC (permalink / raw)
  To: linux-arm-kernel, Hans Ulli Kroll, Florian Fainelli,
	Wim Van Sebroeck, Guenter Roeck
  Cc: openwrt-devel, devicetree, linux-watchdog, Paulius Zaleckas,
	Janos Laube

This adds DT bindings for the Cortina systems Gemini SoC
watchdog timer.

Cc: devicetree@vger.kernel.org
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 .../bindings/watchdog/cortina,gemin-watchdog.txt        | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/watchdog/cortina,gemin-watchdog.txt

diff --git a/Documentation/devicetree/bindings/watchdog/cortina,gemin-watchdog.txt b/Documentation/devicetree/bindings/watchdog/cortina,gemin-watchdog.txt
new file mode 100644
index 000000000000..d8dfb9cc41cf
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/cortina,gemin-watchdog.txt
@@ -0,0 +1,17 @@
+Cortina Systems Gemini SoC Watchdog
+
+Required properties :
+- compatible : must be "cortina,gemini-watchdog"
+- reg : shall contain base register location and length
+- interrupts : shall contain the interrupt for the watchdog
+
+- timeout-sec : shall contain the default watchdog timeout in seconds,
+                if unset, the default timeout is 13 seconds
+
+Example:
+
+watchdog@41000000 {
+	compatible = "cortina,gemini-watchdog";
+	reg = <0x41000000 0x1000>;
+	interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
+};
-- 
2.9.3
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel

^ permalink raw reply related

* [PATCH v2 9/9] Documentation: DT: add entries for I2SE boards
From: Michael Heimpold @ 2017-01-22 22:22 UTC (permalink / raw)
  To: shawnguo-DgEjT+Ai2ygdnm+yROfE0A, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA, stefan.wahren-eS4NqCHxEME,
	Michael Heimpold
In-Reply-To: <1485123764-14754-1-git-send-email-mhei-Z/Lg1yOAjpkb1SvskN2V4Q@public.gmane.org>

This patch adds the missing devicetree binding documentation for I2SE's
Duckbill and Duckbill 2 series boards.

Signed-off-by: Michael Heimpold <mhei-Z/Lg1yOAjpkb1SvskN2V4Q@public.gmane.org>
Cc: Stefan Wahren <stefan.wahren-eS4NqCHxEME@public.gmane.org>
---
 Documentation/devicetree/bindings/arm/i2se.txt | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/i2se.txt

diff --git a/Documentation/devicetree/bindings/arm/i2se.txt b/Documentation/devicetree/bindings/arm/i2se.txt
new file mode 100644
index 0000000..9f30382
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/i2se.txt
@@ -0,0 +1,22 @@
+I2SE Device Tree Bindings
+-------------------------
+
+Duckbill Board
+Required root node properties:
+    - compatible = "i2se,duckbill", "fsl.imx28";
+
+Duckbill 2 Board
+Required root node properties:
+    - compatible = "i2se,duckbill", "fsl.imx28";
+
+Duckbill 2 485 Board
+Required root node properties:
+    - compatible = "i2se,duckbill", "fsl.imx28";
+
+Duckbill 2 EnOcean Board
+Required root node properties:
+    - compatible = "i2se,duckbill", "fsl.imx28";
+
+Duckbill 2 SPI Board
+Required root node properties:
+    - compatible = "i2se,duckbill", "fsl.imx28";
-- 
2.7.4

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

^ permalink raw reply related

* [PATCH v2 8/9] ARM: dts: add support for I2SE Duckbill 2 SPI
From: Michael Heimpold @ 2017-01-22 22:22 UTC (permalink / raw)
  To: shawnguo-DgEjT+Ai2ygdnm+yROfE0A, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA, stefan.wahren-eS4NqCHxEME,
	Michael Heimpold
In-Reply-To: <1485123764-14754-1-git-send-email-mhei-Z/Lg1yOAjpkb1SvskN2V4Q@public.gmane.org>

This machine is based on I2SE's Duckbill 2 board and is sold as part of I2SE's
PLC Bundle for IoT. This is a development kit for Homeplug Green PHY based
powerline products based on Qualcomms QCA7000 chip.

Signed-off-by: Michael Heimpold <mhei-Z/Lg1yOAjpkb1SvskN2V4Q@public.gmane.org>
Cc: Stefan Wahren <stefan.wahren-eS4NqCHxEME@public.gmane.org>
---
 arch/arm/boot/dts/Makefile                 |   1 +
 arch/arm/boot/dts/imx28-duckbill-2-spi.dts | 199 +++++++++++++++++++++++++++++
 2 files changed, 200 insertions(+)
 create mode 100644 arch/arm/boot/dts/imx28-duckbill-2-spi.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index d7fcb4dc..d2d2486 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -478,6 +478,7 @@ dtb-$(CONFIG_ARCH_MXS) += \
 	imx28-duckbill-2-485.dts \
 	imx28-duckbill-2.dtb \
 	imx28-duckbill-2-enocean.dts \
+	imx28-duckbill-2-spi.dts \
 	imx28-duckbill.dtb \
 	imx28-eukrea-mbmx283lc.dtb \
 	imx28-eukrea-mbmx287lc.dtb \
diff --git a/arch/arm/boot/dts/imx28-duckbill-2-spi.dts b/arch/arm/boot/dts/imx28-duckbill-2-spi.dts
new file mode 100644
index 0000000..738eaa7
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-duckbill-2-spi.dts
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2015-2017 I2SE GmbH <info-eS4NqCHxEME@public.gmane.org>
+ * Copyright (C) 2016 Michael Heimpold <mhei-Z/Lg1yOAjpkb1SvskN2V4Q@public.gmane.org>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "imx28.dtsi"
+
+/ {
+	model = "I2SE Duckbill 2 SPI";
+	compatible = "i2se,duckbill", "fsl,imx28";
+
+	aliases {
+		ethernet1 = &qca7000;
+	};
+
+	memory {
+		reg = <0x40000000 0x08000000>;
+	};
+
+	apb@80000000 {
+		apbh@80000000 {
+			ssp0: ssp@80010000 {
+				compatible = "fsl,imx28-mmc";
+				pinctrl-names = "default";
+				pinctrl-0 = <&mmc0_8bit_pins_a
+					&mmc0_cd_cfg &mmc0_sck_cfg>;
+				bus-width = <8>;
+				vmmc-supply = <&reg_3p3v>;
+				status = "okay";
+				non-removable;
+			};
+
+			ssp2: ssp@80014000 {
+				compatible = "fsl,imx28-spi";
+				pinctrl-names = "default";
+				pinctrl-0 = <&spi2_pins_a>;
+				status = "okay";
+
+				qca7000: ethernet@0 {
+					compatible = "qca,qca7000";
+					pinctrl-names = "default";
+					pinctrl-0 = <&qca7000_pins>;
+					reg = <0>;
+					interrupt-parent = <&gpio3>;
+					interrupts = <3 IRQ_TYPE_EDGE_RISING>;
+					spi-cpha;
+					spi-cpol;
+					spi-max-frequency = <8000000>;
+				};
+			};
+
+			pinctrl@80018000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&hog_pins_a>;
+
+				hog_pins_a: hog@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_LCD_D17__GPIO_1_17    /* Revision detection */
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				mac0_phy_reset_pin: mac0-phy-reset@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_GPMI_ALE__GPIO_0_26    /* PHY Reset */
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				mac0_phy_int_pin: mac0-phy-int@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_GPMI_D07__GPIO_0_7    /* PHY Interrupt */
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				led_pins: led@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_SAIF0_MCLK__GPIO_3_20
+						MX28_PAD_SAIF0_LRCLK__GPIO_3_21
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				qca7000_pins: qca7000@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_AUART0_RTS__GPIO_3_3    /* Interrupt */
+						MX28_PAD_LCD_D13__GPIO_1_13      /* QCA7K reset */
+						MX28_PAD_LCD_D14__GPIO_1_14      /* GPIO 0 */
+						MX28_PAD_LCD_D15__GPIO_1_15      /* GPIO 1 */
+						MX28_PAD_LCD_D18__GPIO_1_18      /* GPIO 2 */
+						MX28_PAD_LCD_D21__GPIO_1_21      /* GPIO 3 */
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+			};
+		};
+
+		apbx@80040000 {
+			lradc@80050000 {
+				status = "okay";
+			};
+
+			duart: serial@80074000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&duart_pins_a>;
+				status = "okay";
+			};
+
+			usbphy0: usbphy@8007c000 {
+				status = "okay";
+			};
+		};
+	};
+
+	ahb@80080000 {
+		usb0: usb@80080000 {
+			status = "okay";
+			dr_mode = "peripheral";
+		};
+
+		mac0: ethernet@800f0000 {
+			phy-mode = "rmii";
+			pinctrl-names = "default";
+			pinctrl-0 = <&mac0_pins_a>, <&mac0_phy_reset_pin>;
+			phy-supply = <&reg_3p3v>;
+			phy-reset-gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
+			phy-reset-duration = <25>;
+			phy-handle = <&ethphy>;
+			status = "okay";
+
+			mdio {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				ethphy: ethernet-phy@0 {
+					compatible = "ethernet-phy-ieee802.3-c22";
+					reg = <0>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&mac0_phy_int_pin>;
+					interrupt-parent = <&gpio0>;
+					interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
+					max-speed = <100>;
+				};
+			};
+		};
+	};
+
+	reg_3p3v: regulator-3p3v {
+		compatible = "regulator-fixed";
+		regulator-name = "3P3V";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&led_pins>;
+
+		status-red {
+			label = "duckbill:red:status";
+			gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "default-on";
+		};
+
+		status-green {
+			label = "duckbill:green:status";
+			gpios = <&gpio3 20 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+		};
+	};
+};
-- 
2.7.4

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

^ permalink raw reply related

* [PATCH v2 7/9] ARM: dts: add support for I2SE Duckbill 2 EnOcean
From: Michael Heimpold @ 2017-01-22 22:22 UTC (permalink / raw)
  To: shawnguo-DgEjT+Ai2ygdnm+yROfE0A, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA, stefan.wahren-eS4NqCHxEME,
	Michael Heimpold
In-Reply-To: <1485123764-14754-1-git-send-email-mhei-Z/Lg1yOAjpkb1SvskN2V4Q@public.gmane.org>

This machine is based on I2SE's Duckbill 2 board and features a
EnOcean daugther board based on the popular TCM310 chipset.
This product is intended to be used for e.g. home automation purposes.

Signed-off-by: Michael Heimpold <mhei-Z/Lg1yOAjpkb1SvskN2V4Q@public.gmane.org>
Cc: Stefan Wahren <stefan.wahren-eS4NqCHxEME@public.gmane.org>
---
 arch/arm/boot/dts/Makefile                     |   1 +
 arch/arm/boot/dts/imx28-duckbill-2-enocean.dts | 220 +++++++++++++++++++++++++
 2 files changed, 221 insertions(+)
 create mode 100644 arch/arm/boot/dts/imx28-duckbill-2-enocean.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index e0f3f4e..d7fcb4dc 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -477,6 +477,7 @@ dtb-$(CONFIG_ARCH_MXS) += \
 	imx28-cfa10058.dtb \
 	imx28-duckbill-2-485.dts \
 	imx28-duckbill-2.dtb \
+	imx28-duckbill-2-enocean.dts \
 	imx28-duckbill.dtb \
 	imx28-eukrea-mbmx283lc.dtb \
 	imx28-eukrea-mbmx287lc.dtb \
diff --git a/arch/arm/boot/dts/imx28-duckbill-2-enocean.dts b/arch/arm/boot/dts/imx28-duckbill-2-enocean.dts
new file mode 100644
index 0000000..6e7a71c
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-duckbill-2-enocean.dts
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2015-2017 I2SE GmbH <info-eS4NqCHxEME@public.gmane.org>
+ * Copyright (C) 2016 Michael Heimpold <mhei-Z/Lg1yOAjpkb1SvskN2V4Q@public.gmane.org>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "imx28.dtsi"
+
+/ {
+	model = "I2SE Duckbill 2 EnOcean";
+	compatible = "i2se,duckbill", "fsl,imx28";
+
+	memory {
+		reg = <0x40000000 0x08000000>;
+	};
+
+	apb@80000000 {
+		apbh@80000000 {
+			ssp0: ssp@80010000 {
+				compatible = "fsl,imx28-mmc";
+				pinctrl-names = "default";
+				pinctrl-0 = <&mmc0_8bit_pins_a
+					&mmc0_cd_cfg &mmc0_sck_cfg>;
+				bus-width = <8>;
+				vmmc-supply = <&reg_3p3v>;
+				status = "okay";
+				non-removable;
+			};
+
+			ssp2: ssp@80014000 {
+				compatible = "fsl,imx28-mmc";
+				pinctrl-names = "default";
+				pinctrl-0 = <&mmc2_4bit_pins_b
+					&mmc2_cd_cfg &mmc2_sck_cfg_b>;
+				bus-width = <4>;
+				vmmc-supply = <&reg_3p3v>;
+				status = "okay";
+			};
+
+			pinctrl@80018000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&hog_pins_a>;
+
+				hog_pins_a: hog@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_LCD_D17__GPIO_1_17    /* Revision detection */
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				mac0_phy_reset_pin: mac0-phy-reset@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_GPMI_ALE__GPIO_0_26    /* PHY Reset */
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				mac0_phy_int_pin: mac0-phy-int@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_GPMI_D07__GPIO_0_7    /* PHY Interrupt */
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				led_pins: leds@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_SAIF0_MCLK__GPIO_3_20
+						MX28_PAD_SAIF0_LRCLK__GPIO_3_21
+						MX28_PAD_AUART0_CTS__GPIO_3_2
+						MX28_PAD_I2C0_SCL__GPIO_3_24
+						MX28_PAD_I2C0_SDA__GPIO_3_25
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+
+				enocean_button: enocean-button@0 {
+					reg = <0>;
+					fsl,pinmux-ids = <
+						MX28_PAD_AUART0_RTS__GPIO_3_3
+					>;
+					fsl,drive-strength = <MXS_DRIVE_4mA>;
+					fsl,voltage = <MXS_VOLTAGE_HIGH>;
+					fsl,pull-up = <MXS_PULL_DISABLE>;
+				};
+			};
+		};
+
+		apbx@80040000 {
+			lradc@80050000 {
+				status = "okay";
+			};
+
+			auart0: serial@8006a000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&auart0_2pins_a>;
+				status = "okay";
+			};
+
+			duart: serial@80074000 {
+				pinctrl-names = "default";
+				pinctrl-0 = <&duart_pins_a>;
+				status = "okay";
+			};
+
+			usbphy0: usbphy@8007c000 {
+				status = "okay";
+			};
+		};
+	};
+
+	ahb@80080000 {
+		usb0: usb@80080000 {
+			status = "okay";
+			dr_mode = "peripheral";
+		};
+
+		mac0: ethernet@800f0000 {
+			phy-mode = "rmii";
+			pinctrl-names = "default";
+			pinctrl-0 = <&mac0_pins_a>, <&mac0_phy_reset_pin>;
+			phy-supply = <&reg_3p3v>;
+			phy-reset-gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
+			phy-reset-duration = <25>;
+			phy-handle = <&ethphy>;
+			status = "okay";
+
+			mdio {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				ethphy: ethernet-phy@0 {
+					compatible = "ethernet-phy-ieee802.3-c22";
+					reg = <0>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&mac0_phy_int_pin>;
+					interrupt-parent = <&gpio0>;
+					interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
+					max-speed = <100>;
+				};
+			};
+		};
+	};
+
+	reg_3p3v: regulator-3p3v {
+		compatible = "regulator-fixed";
+		regulator-name = "3P3V";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-always-on;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&led_pins>;
+
+		status-red {
+			label = "duckbill:red:status";
+			gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "default-on";
+		};
+
+		status-green {
+			label = "duckbill:green:status";
+			gpios = <&gpio3 20 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "heartbeat";
+		};
+
+		enocean-blue {
+			label = "duckbill:blue:enocean";
+			gpios = <&gpio3 24 GPIO_ACTIVE_LOW>;
+		};
+
+		enocean-red {
+			label = "duckbill:red:enocean";
+			gpios = <&gpio3 25 GPIO_ACTIVE_LOW>;
+		};
+
+		enocean-green {
+			label = "duckbill:green:enocean";
+			gpios = <&gpio3 2 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&enocean_button>;
+
+		enocean {
+			label = "EnOcean";
+			linux,code = <KEY_NEW>;
+			gpios = <&gpio3 3 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
-- 
2.7.4

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

^ permalink raw reply related


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