Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH 06/13] MIPS: lantiq: Convert the xbar driver to a platform_driver
From: Martin Blumenstingl @ 2017-04-21 18:28 UTC (permalink / raw)
  To: Hauke Mehrtens
  Cc: ralf-6z/3iImG2C8G8FEW9MqTrA, linux-mips-6z/3iImG2C8G8FEW9MqTrA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-watchdog-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, john-Pj+rj9U5foFAfugRpC6u6w,
	linux-spi-u79uwXL29TY76Z2rM5mHXA,
	hauke.mehrtens-ral2JQCrhuEAvxtiuMwx3w
In-Reply-To: <20170417192942.32219-7-hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org>

On Mon, Apr 17, 2017 at 9:29 PM, Hauke Mehrtens <hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org> wrote:
> From: Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
>
> This allows using the xbar driver on ARX300 based SoCs which require the
> same xbar setup as the xRX200 chipsets because the xbar driver
> initialization is not guarded by an xRX200 specific
> of_machine_is_compatible condition anymore. Additionally the new driver
> takes a syscon phandle to configure the XBAR endianness bits in RCU
> (before this was done in arch/mips/lantiq/xway/reset.c and also
> guarded by an xRX200 specific if-statement).
>
> Signed-off-by: Hauke Mehrtens <hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org>
> ---
>  .../devicetree/bindings/mips/lantiq/xbar.txt       |  22 +++++
>  MAINTAINERS                                        |   1 +
>  arch/mips/lantiq/xway/reset.c                      |   4 -
>  arch/mips/lantiq/xway/sysctrl.c                    |  41 ---------
>  drivers/soc/Makefile                               |   1 +
>  drivers/soc/lantiq/Makefile                        |   1 +
>  drivers/soc/lantiq/xbar.c                          | 100 +++++++++++++++++++++
>  7 files changed, 125 insertions(+), 45 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/mips/lantiq/xbar.txt
>  create mode 100644 drivers/soc/lantiq/Makefile
>  create mode 100644 drivers/soc/lantiq/xbar.c
>
> diff --git a/Documentation/devicetree/bindings/mips/lantiq/xbar.txt b/Documentation/devicetree/bindings/mips/lantiq/xbar.txt
> new file mode 100644
> index 000000000000..86e53ff3b0d5
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mips/lantiq/xbar.txt
> @@ -0,0 +1,22 @@
> +Lantiq XWAY SoC XBAR binding
> +============================
> +
> +
> +-------------------------------------------------------------------------------
> +Required properties:
> +- compatible   : Should be "lantiq,xbar-xway"
> +- reg          : The address and length of the XBAR registers
> +
> +Optional properties:
> +- lantiq,rcu-syscon    : A phandle and offset to the endianness configuration
> +                         registers in the RCU module
is the xbar module really coupled with the RCU mdoule? if it is then:

Signed-off-by: Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>

> +
> +
> +-------------------------------------------------------------------------------
> +Example for the XBAR on the xRX200 SoCs:
> +       xbar0: xbar@400000 {
> +               compatible = "lantiq,xbar-xway";
> +               reg = <0x400000 0x1000>;
> +               big-endian;
> +               lantiq,rcu-syscon = <&rcu0 0x4c>;
> +       };
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 676c139bc883..7c03776a56e9 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -7321,6 +7321,7 @@ M:        John Crispin <john-Pj+rj9U5foFAfugRpC6u6w@public.gmane.org>
>  L:     linux-mips-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org
>  S:     Maintained
>  F:     arch/mips/lantiq
> +F:     drivers/soc/lantiq
>
>  LAPB module
>  L:     linux-x25-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c
> index 83fd65d76e81..b6752c95a600 100644
> --- a/arch/mips/lantiq/xway/reset.c
> +++ b/arch/mips/lantiq/xway/reset.c
> @@ -373,10 +373,6 @@ static int __init mips_reboot_setup(void)
>             of_machine_is_compatible("lantiq,vr9"))
>                 ltq_usb_init();
>
> -       if (of_machine_is_compatible("lantiq,vr9"))
> -               ltq_rcu_w32(ltq_rcu_r32(RCU_AHB_ENDIAN) | RCU_VR9_BE_AHB1S,
> -                           RCU_AHB_ENDIAN);
> -
>         _machine_restart = ltq_machine_restart;
>         _machine_halt = ltq_machine_halt;
>         pm_power_off = ltq_machine_power_off;
> diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c
> index 95bec460b651..706639a343bc 100644
> --- a/arch/mips/lantiq/xway/sysctrl.c
> +++ b/arch/mips/lantiq/xway/sysctrl.c
> @@ -145,15 +145,7 @@ static u32 pmu_clk_cr_b[] = {
>  #define pmu_w32(x, y)  ltq_w32((x), pmu_membase + (y))
>  #define pmu_r32(x)     ltq_r32(pmu_membase + (x))
>
> -#define XBAR_ALWAYS_LAST       0x430
> -#define XBAR_FPI_BURST_EN      BIT(1)
> -#define XBAR_AHB_BURST_EN      BIT(2)
> -
> -#define xbar_w32(x, y) ltq_w32((x), ltq_xbar_membase + (y))
> -#define xbar_r32(x)    ltq_r32(ltq_xbar_membase + (x))
> -
>  static void __iomem *pmu_membase;
> -static void __iomem *ltq_xbar_membase;
>  void __iomem *ltq_cgu_membase;
>  void __iomem *ltq_ebu_membase;
>
> @@ -293,16 +285,6 @@ static void pci_ext_disable(struct clk *clk)
>         ltq_cgu_w32((1 << 31) | (1 << 30), pcicr);
>  }
>
> -static void xbar_fpi_burst_disable(void)
> -{
> -       u32 reg;
> -
> -       /* bit 1 as 1 --burst; bit 1 as 0 -- single */
> -       reg = xbar_r32(XBAR_ALWAYS_LAST);
> -       reg &= ~XBAR_FPI_BURST_EN;
> -       xbar_w32(reg, XBAR_ALWAYS_LAST);
> -}
> -
>  /* enable a clockout source */
>  static int clkout_enable(struct clk *clk)
>  {
> @@ -459,26 +441,6 @@ void __init ltq_soc_init(void)
>         if (!pmu_membase || !ltq_cgu_membase || !ltq_ebu_membase)
>                 panic("Failed to remap core resources");
>
> -       if (of_machine_is_compatible("lantiq,vr9")) {
> -               struct resource res_xbar;
> -               struct device_node *np_xbar =
> -                               of_find_compatible_node(NULL, NULL,
> -                                                       "lantiq,xbar-xway");
> -
> -               if (!np_xbar)
> -                       panic("Failed to load xbar nodes from devicetree");
> -               if (of_address_to_resource(np_xbar, 0, &res_xbar))
> -                       panic("Failed to get xbar resources");
> -               if (!request_mem_region(res_xbar.start, resource_size(&res_xbar),
> -                       res_xbar.name))
> -                       panic("Failed to get xbar resources");
> -
> -               ltq_xbar_membase = ioremap_nocache(res_xbar.start,
> -                                                  resource_size(&res_xbar));
> -               if (!ltq_xbar_membase)
> -                       panic("Failed to remap xbar resources");
> -       }
> -
>         /* make sure to unprotect the memory region where flash is located */
>         ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0);
>
> @@ -605,7 +567,4 @@ void __init ltq_soc_init(void)
>                 clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
>                 clkdev_add_pmu("1e100400.serial", NULL, 1, 0, PMU_ASC0);
>         }
> -
> -       if (of_machine_is_compatible("lantiq,vr9"))
> -               xbar_fpi_burst_disable();
>  }
> diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
> index 05eae52a30b4..8775d37ac158 100644
> --- a/drivers/soc/Makefile
> +++ b/drivers/soc/Makefile
> @@ -6,6 +6,7 @@ obj-y                           += bcm/
>  obj-$(CONFIG_ARCH_DOVE)                += dove/
>  obj-$(CONFIG_MACH_DOVE)                += dove/
>  obj-y                          += fsl/
> +obj-$(CONFIG_SOC_XWAY)         += lantiq/
>  obj-$(CONFIG_ARCH_MEDIATEK)    += mediatek/
>  obj-$(CONFIG_ARCH_QCOM)                += qcom/
>  obj-$(CONFIG_ARCH_RENESAS)     += renesas/
> diff --git a/drivers/soc/lantiq/Makefile b/drivers/soc/lantiq/Makefile
> new file mode 100644
> index 000000000000..7411bd23d58e
> --- /dev/null
> +++ b/drivers/soc/lantiq/Makefile
> @@ -0,0 +1 @@
> +obj-y                          += xbar.o
> diff --git a/drivers/soc/lantiq/xbar.c b/drivers/soc/lantiq/xbar.c
> new file mode 100644
> index 000000000000..dcd087817435
> --- /dev/null
> +++ b/drivers/soc/lantiq/xbar.c
> @@ -0,0 +1,100 @@
> +/*
> + *  This program is free software; you can redistribute it and/or modify it
> + *  under the terms of the GNU General Public License version 2 as published
> + *  by the Free Software Foundation.
> + *
> + *  Copyright (C) 2011-2015 John Crispin <blogic-p3rKhJxN3npAfugRpC6u6w@public.gmane.org>
> + *  Copyright (C) 2015 Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
> + */
> +
> +#include <linux/ioport.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_platform.h>
> +#include <linux/of_address.h>
> +#include <linux/regmap.h>
> +
> +#include <lantiq_soc.h>
> +
> +#define XBAR_ALWAYS_LAST       0x430
> +#define XBAR_FPI_BURST_EN      BIT(1)
> +#define XBAR_AHB_BURST_EN      BIT(2)
> +
> +#define RCU_VR9_BE_AHB1S       0x00000008
> +
> +static int ltq_xbar_probe(struct platform_device *pdev)
> +{
> +       struct device *dev = &pdev->dev;
> +       struct device_node *np = dev->of_node;
> +       struct resource res_xbar;
> +       struct regmap *rcu_regmap;
> +       void __iomem *xbar_membase;
> +       u32 rcu_ahb_endianness_reg_offset;
> +       u32 rcu_ahb_endianness_val;
> +       int ret;
> +
> +       ret = of_address_to_resource(np, 0, &res_xbar);
> +       if (ret) {
> +               dev_err(dev, "Failed to get xbar resources");
> +               return ret;
> +       }
> +
> +       if (!devm_request_mem_region(dev, res_xbar.start,
> +                                    resource_size(&res_xbar),
> +               res_xbar.name)) {
> +               dev_err(dev, "Failed to get xbar resources");
> +               return -ENODEV;
> +       }
> +
> +       xbar_membase = devm_ioremap_nocache(dev, res_xbar.start,
> +                                               resource_size(&res_xbar));
> +       if (!xbar_membase) {
> +               dev_err(dev, "Failed to remap xbar resources");
> +               return -ENODEV;
> +       }
> +
> +       /* RCU configuration is optional */
> +       rcu_regmap = syscon_regmap_lookup_by_phandle(np, "lantiq,rcu-syscon");
> +       if (!IS_ERR_OR_NULL(rcu_regmap)) {
> +               if (of_property_read_u32_index(np, "lantiq,rcu-syscon", 1,
> +                       &rcu_ahb_endianness_reg_offset)) {
> +                       dev_err(&pdev->dev, "Failed to get RCU reg offset\n");
> +                       return -EINVAL;
> +               }
> +
> +               if (of_device_is_big_endian(np))
> +                       rcu_ahb_endianness_val = RCU_VR9_BE_AHB1S;
> +               else
> +                       rcu_ahb_endianness_val = 0;
> +
> +               if (regmap_update_bits(rcu_regmap,
> +                                       rcu_ahb_endianness_reg_offset,
> +                                       RCU_VR9_BE_AHB1S,
> +                                       rcu_ahb_endianness_val))
> +                       dev_warn(&pdev->dev,
> +                               "Failed to configure RCU AHB endianness\n");
> +       }
> +
> +       /* disable fpi burst */
> +       ltq_w32_mask(XBAR_FPI_BURST_EN, 0,
> +                    xbar_membase + XBAR_ALWAYS_LAST);
> +
> +       return 0;
> +}
> +
> +static const struct of_device_id xbar_match[] = {
> +       { .compatible = "lantiq,xbar-xway" },
> +       {},
> +};
> +MODULE_DEVICE_TABLE(of, xbar_match);
> +
> +static struct platform_driver xbar_driver = {
> +       .probe = ltq_xbar_probe,
> +       .driver = {
> +               .name = "xbar-xway",
> +               .of_match_table = xbar_match,
> +       },
> +};
> +
> +builtin_platform_driver(xbar_driver);
> --
> 2.11.0
>
--
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 2/5] mtd: nand: gpmi: add i.MX 7 SoC support
From: Han Xu @ 2017-04-21 18:29 UTC (permalink / raw)
  To: Stefan Agner
  Cc: Marek Vasut, mark.rutland, Boris Brezillon, Fabio Estevam,
	devicetree, Richard Weinberger, linux-kernel, robh+dt,
	linux-mtd@lists.infradead.org, Sascha Hauer, Han Xu, Shawn Guo,
	Cyrille Pitchen, Brian Norris, David Woodhouse, linux-arm-kernel,
	LW
In-Reply-To: <a9cdc47795433e7b152dcdd123f9bd63@agner.ch>

On Fri, Apr 21, 2017 at 12:38 PM, Stefan Agner <stefan@agner.ch> wrote:
> On 2017-04-21 10:22, Marek Vasut wrote:
>> On 04/21/2017 06:19 PM, Stefan Agner wrote:
>>> On 2017-04-21 06:08, Marek Vasut wrote:
>>>> On 04/21/2017 05:15 AM, Stefan Agner wrote:
>>>>> On 2017-04-20 19:03, Marek Vasut wrote:
>>>>>> On 04/21/2017 03:07 AM, Stefan Agner wrote:
>>>>>>> Add support for i.MX 7 SoC. The i.MX 7 has a slightly different
>>>>>>> clock architecture requiring only two clocks to be referenced.
>>>>>>> The IP is slightly different compared to i.MX 6SoloX, but currently
>>>>>>> none of this differences are in use so there is no detection needed
>>>>>>> and the driver can reuse IS_MX6SX.
>>>>>>>
>>>>>>> Signed-off-by: Stefan Agner <stefan@agner.ch>
>>>>>>> ---
>>>>>>>  drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 15 +++++++++++++++
>>>>>>>  1 file changed, 15 insertions(+)
>>>>>>>
>>>>>>> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
>>>>>>> index c8bbf5da2ab8..4a45d37ddc80 100644
>>>>>>> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
>>>>>>> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
>>>>>>> @@ -127,6 +127,18 @@ static const struct gpmi_devdata gpmi_devdata_imx6sx = {
>>>>>>>          .clks_count = ARRAY_SIZE(gpmi_clks_for_mx6),
>>>>>>>  };
>>>>>>>
>>>>>>> +static const char * const gpmi_clks_for_mx7d[] = {
>>>>>>> +        "gpmi_io", "gpmi_bch_apb",
>>>>>>> +};
>>>>>>> +
>>>>>>> +static const struct gpmi_devdata gpmi_devdata_imx7d = {
>>>>>>> +        .type = IS_MX6SX,
>>>>>>
>>>>>> Would it make sense to use IS_MX7 here already to prevent future surprises ?
>>>>>>
>>>>>
>>>>> Yeah I was thinking we can do it once we have an actual reason to
>>>>> distinguish.
>>>>
>>>> So what are the differences anyway ?
>>>>
>>>
>>> I did not check the details, but Han's patchset (link in cover letter)
>>> mentions:
>>> "add the HW bitflip detection and correction for i.MX6QP and i.MX7D."...
>>
>> Oh, interesting.
>>
>>>>> But then, adding the type would only require 2-3 lines of change if I
>>>>> add it to the GPMI_IS_MX6 macro...
>>>>
>>>> Then at least add a comment because using type = IMX6SX right under
>>>> gpmi_data_mx7d can trigger some head-scratching. And put my R-B on V2.
>>>
>>> FWIW, I mentioned it in the commit message.
>>>
>>> I think rather then adding a comment it is cleaner to just add IS_IMX7D
>>> and add it to the GPMI_IS_MX6 macro. That does not need a comment since
>>> it implicitly says we have a i.MX 7 but treat it like i.MX 6 and it is a
>>> rather small change. Does that sound acceptable?
>>
>> Sure, that's even better, thanks.
>>
>> btw isn't there some single-core mx7 (mx7s ?) , maybe we should just go
>> with mx7 (without the d suffix). I dunno if it has GPMI NAND though, so
>> maybe mx7d is the right thing to do here ...
>>
>
> There is a Solo version yes, and it has GPMI NAND too. However, almost
> all i.MX 7 IPs have been named imx7d by NXP for some reason (including
> compatible strings, see grep -r -e imx7 Documentation/), so I thought I
> stay consistent here...

Hi Guys,

Yes, there should be a i.MX7 Solo version with one core fused out. IMO, can
we use QUIRK to distinguish them rather than SoC name. I know I also sent
some patch set with SoC Name but I prefer to use QUIRK now.

>
> --
> Stefan
>
>>> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
>>> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
>>> @@ -132,7 +132,7 @@ static const char * const gpmi_clks_for_mx7d[] = {
>>>  };
>>>
>>>  static const struct gpmi_devdata gpmi_devdata_imx7d = {
>>> -       .type = IS_MX6SX,
>>> +       .type = IS_MX7D,
>>>         .bch_max_ecc_strength = 62,
>>>         .max_chain_delay = 12,
>>>         .clks = gpmi_clks_for_mx7d,
>>> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
>>> b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
>>> index 2e584e18d980..f2cc13abc896 100644
>>> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
>>> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
>>> @@ -123,7 +123,8 @@ enum gpmi_type {
>>>         IS_MX23,
>>>         IS_MX28,
>>>         IS_MX6Q,
>>> -       IS_MX6SX
>>> +       IS_MX6SX,
>>> +       IS_MX7D,
>>>  };
>>>
>>>  struct gpmi_devdata {
>>> @@ -307,6 +308,8 @@ void gpmi_copy_bits(u8 *dst, size_t dst_bit_off,
>>>  #define GPMI_IS_MX28(x)                ((x)->devdata->type == IS_MX28)
>>>  #define GPMI_IS_MX6Q(x)                ((x)->devdata->type == IS_MX6Q)
>>>  #define GPMI_IS_MX6SX(x)       ((x)->devdata->type == IS_MX6SX)
>>> +#define GPMI_IS_MX7D(x)                ((x)->devdata->type == IS_MX7D)
>>>
>>> -#define GPMI_IS_MX6(x)         (GPMI_IS_MX6Q(x) || GPMI_IS_MX6SX(x))
>>> +#define GPMI_IS_MX6(x)         (GPMI_IS_MX6Q(x) || GPMI_IS_MX6SX(x) ||
>>> \
>>> +                                GPMI_IS_MX7D(x))
>>>  #endif
>>>
>>> --
>>> Stefan
>>>
>
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/



-- 
Sincerely,

Han XU

^ permalink raw reply

* Re: [PATCH 11/13] phy: Add an USB PHY driver for the Lantiq SoCs using the RCU module
From: Martin Blumenstingl @ 2017-04-21 18:41 UTC (permalink / raw)
  To: Hauke Mehrtens
  Cc: ralf-6z/3iImG2C8G8FEW9MqTrA, linux-mips-6z/3iImG2C8G8FEW9MqTrA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-watchdog-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, john-Pj+rj9U5foFAfugRpC6u6w,
	linux-spi-u79uwXL29TY76Z2rM5mHXA,
	hauke.mehrtens-ral2JQCrhuEAvxtiuMwx3w
In-Reply-To: <20170417192942.32219-12-hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org>

On Mon, Apr 17, 2017 at 9:29 PM, Hauke Mehrtens <hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org> wrote:
> From: Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
>
> This driver starts the DWC2 core(s) built into the XWAY SoCs and provides
> the PHY interfaces for each core. The phy instances can be passed to the
> dwc2 driver, which already supports the generic phy interface.
>
> Signed-off-by: Hauke Mehrtens <hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org>
> ---
>  .../bindings/phy/phy-lantiq-rcu-usb2.txt           |  59 ++++
>  arch/mips/lantiq/xway/reset.c                      |  43 ---
>  arch/mips/lantiq/xway/sysctrl.c                    |  24 +-
>  drivers/phy/Kconfig                                |   8 +
>  drivers/phy/Makefile                               |   1 +
>  drivers/phy/phy-lantiq-rcu-usb2.c                  | 325 +++++++++++++++++++++
>  6 files changed, 405 insertions(+), 55 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/phy/phy-lantiq-rcu-usb2.txt
>  create mode 100644 drivers/phy/phy-lantiq-rcu-usb2.c
>
> diff --git a/Documentation/devicetree/bindings/phy/phy-lantiq-rcu-usb2.txt b/Documentation/devicetree/bindings/phy/phy-lantiq-rcu-usb2.txt
> new file mode 100644
> index 000000000000..0ec9f790b6e0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/phy-lantiq-rcu-usb2.txt
> @@ -0,0 +1,59 @@
> +Lantiq XWAY SoC RCU USB 1.1/2.0 PHY binding
> +===========================================
> +
> +This binding describes the USB PHY hardware provided by the RCU module on the
> +Lantiq XWAY SoCs.
> +
> +
> +-------------------------------------------------------------------------------
> +Required properties (controller (parent) node):
> +- compatible           : Should be one of
> +                               "lantiq,ase-rcu-usb2-phy"
> +                               "lantiq,danube-rcu-usb2-phy"
> +                               "lantiq,xrx100-rcu-usb2-phy"
> +                               "lantiq,xrx200-rcu-usb2-phy"
> +                               "lantiq,xrx300-rcu-usb2-phy"
> +- lantiq,rcu-syscon    : A phandle to the RCU module and the offsets to the
> +                         USB PHY configuration and USB MAC registers.
> +- address-cells                : should be 1
> +- size-cells           : should be 0
> +- phy-cells            : from the generic PHY bindings, must be 1
> +
> +Optional properties (controller (parent) node):
> +- vbus-gpio            : References a GPIO which enables VBUS all given USB
> +                         ports.
> +
> +Required nodes         :  A sub-node is required for each USB PHY port.
> +
> +
> +-------------------------------------------------------------------------------
> +Required properties (port (child) node):
> +- reg          : The ID of the USB port, usually 0 or 1.
> +- clocks       : References to the (PMU) "ctrl" and "phy" clk gates.
> +- clock-names  : Must be one of the following:
> +                       "ctrl"
> +                       "phy"
> +- resets       : References to the RCU USB configuration reset bits.
> +- reset-names  : Must be one of the following:
> +                       "analog-config" (optional)
> +                       "statemachine-soft" (optional)
> +
> +Optional properties (port (child) node):
> +- vbus-gpio    : References a GPIO which enables VBUS for the USB port.
> +
> +
> +-------------------------------------------------------------------------------
> +Example for the USB PHYs on an xRX200 SoC:
> +       usb_phys0: rcu-usb2-phy@0 {
> +               compatible      = "lantiq,xrx200-rcu-usb2-phy";
> +               reg = <0>;
> +
> +               lantiq,rcu-syscon = <&rcu0 0x18 0x38>;
> +               clocks = <&pmu PMU_GATE_USB0_CTRL>,
> +                        <&pmu PMU_GATE_USB0_PHY>;
> +               clock-names = "ctrl", "phy";
> +               vbus-gpios = <&gpio 32 GPIO_ACTIVE_HIGH>;
> +               resets = <&rcu_reset1 4>, <&rcu_reset0 4>;
> +               reset-names = "phy", "ctrl";
> +               #phy-cells = <0>;
> +       };
> diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c
> index 3f30fb81a50f..5aec1f54275b 100644
> --- a/arch/mips/lantiq/xway/reset.c
> +++ b/arch/mips/lantiq/xway/reset.c
> @@ -124,45 +124,6 @@ static void ltq_machine_power_off(void)
>         unreachable();
>  }
>
> -static void ltq_usb_init(void)
> -{
> -       /* Power for USB cores 1 & 2 */
> -       ltq_pmu_enable(PMU_AHBM);
> -       ltq_pmu_enable(PMU_USB0);
> -       ltq_pmu_enable(PMU_USB1);
> -
> -       ltq_rcu_w32(ltq_rcu_r32(RCU_CFG1A) | BIT(0), RCU_CFG1A);
> -       ltq_rcu_w32(ltq_rcu_r32(RCU_CFG1B) | BIT(0), RCU_CFG1B);
> -
> -       /* Enable USB PHY power for cores 1 & 2 */
> -       ltq_pmu_enable(PMU_USB0_P);
> -       ltq_pmu_enable(PMU_USB1_P);
> -
> -       /* Configure cores to host mode */
> -       ltq_rcu_w32(ltq_rcu_r32(RCU_USB1CFG) & ~RCU_USBCFG_HDSEL_BIT,
> -               RCU_USB1CFG);
> -       ltq_rcu_w32(ltq_rcu_r32(RCU_USB2CFG) & ~RCU_USBCFG_HDSEL_BIT,
> -               RCU_USB2CFG);
> -
> -       /* Select DMA endianness (Host-endian: big-endian) */
> -       ltq_rcu_w32((ltq_rcu_r32(RCU_USB1CFG) & ~RCU_USBCFG_SLV_END_BIT)
> -               | RCU_USBCFG_HOST_END_BIT, RCU_USB1CFG);
> -       ltq_rcu_w32(ltq_rcu_r32((RCU_USB2CFG) & ~RCU_USBCFG_SLV_END_BIT)
> -               | RCU_USBCFG_HOST_END_BIT, RCU_USB2CFG);
> -
> -       /* Hard reset USB state machines */
> -       ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET) | USBRESET_BIT, RCU_USBRESET);
> -       udelay(50 * 1000);
> -       ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET) & ~USBRESET_BIT, RCU_USBRESET);
> -
> -       /* Soft reset USB state machines */
> -       ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET2)
> -               | USB1RESET_BIT | USB2RESET_BIT, RCU_USBRESET2);
> -       udelay(50 * 1000);
> -       ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET2)
> -               & ~(USB1RESET_BIT | USB2RESET_BIT), RCU_USBRESET2);
> -}
> -
>  static int __init mips_reboot_setup(void)
>  {
>         struct resource res;
> @@ -186,10 +147,6 @@ static int __init mips_reboot_setup(void)
>         if (!ltq_rcu_membase)
>                 panic("Failed to remap core memory");
>
> -       if (of_machine_is_compatible("lantiq,ar9") ||
> -           of_machine_is_compatible("lantiq,vr9"))
> -               ltq_usb_init();
> -
>         _machine_restart = ltq_machine_restart;
>         _machine_halt = ltq_machine_halt;
>         pm_power_off = ltq_machine_power_off;
> diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c
> index 5764d3ddce69..18725f2d5b67 100644
> --- a/arch/mips/lantiq/xway/sysctrl.c
> +++ b/arch/mips/lantiq/xway/sysctrl.c
> @@ -469,8 +469,8 @@ void __init ltq_soc_init(void)
>
>         if (of_machine_is_compatible("lantiq,grx390") ||
>             of_machine_is_compatible("lantiq,ar10")) {
> -               clkdev_add_pmu("1e101000.usb", "phy", 1, 2, PMU_ANALOG_USB0_P);
> -               clkdev_add_pmu("1e106000.usb", "phy", 1, 2, PMU_ANALOG_USB1_P);
> +               clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@0", "phy", 1, 2, PMU_ANALOG_USB0_P);
> +               clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@1", "phy", 1, 2, PMU_ANALOG_USB1_P);
>                 /* rc 0 */
>                 clkdev_add_pmu("1d900000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE0_P);
>                 clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI);
> @@ -490,8 +490,8 @@ void __init ltq_soc_init(void)
>                 else
>                         clkdev_add_static(CLOCK_133M, CLOCK_133M,
>                                                 CLOCK_133M, CLOCK_133M);
> -               clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0);
> -               clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P);
> +               clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@0", "ctrl", 1, 0, PMU_USB0);
> +               clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@0", "phy", 1, 0, PMU_USB0_P);
>                 clkdev_add_pmu("1e180000.etop", "ppe", 1, 0, PMU_PPE);
>                 clkdev_add_cgu("1e180000.etop", "ephycgu", CGU_EPHY);
>                 clkdev_add_pmu("1e180000.etop", "ephy", 1, 0, PMU_EPHY);
> @@ -525,10 +525,10 @@ void __init ltq_soc_init(void)
>         } else if (of_machine_is_compatible("lantiq,vr9")) {
>                 clkdev_add_static(ltq_vr9_cpu_hz(), ltq_vr9_fpi_hz(),
>                                 ltq_vr9_fpi_hz(), ltq_vr9_pp32_hz());
> -               clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P);
> -               clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0 | PMU_AHBM);
> -               clkdev_add_pmu("1e106000.usb", "phy", 1, 0, PMU_USB1_P);
> -               clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1 | PMU_AHBM);
> +               clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@0", "phy", 1, 0, PMU_USB0_P);
> +               clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@0", "ctrl", 1, 0, PMU_USB0 | PMU_AHBM);
> +               clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@1", "phy", 1, 0, PMU_USB1_P);
> +               clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@1", "ctrl", 1, 0, PMU_USB1 | PMU_AHBM);
>                 clkdev_add_pmu("1d900000.pcie", "phy", 1, 1, PMU1_PCIE_PHY);
>                 clkdev_add_pmu("1d900000.pcie", "bus", 1, 0, PMU_PCIE_CLK);
>                 clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI);
> @@ -548,8 +548,8 @@ void __init ltq_soc_init(void)
>         } else if (of_machine_is_compatible("lantiq,ar9")) {
>                 clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(),
>                                 ltq_ar9_fpi_hz(), CLOCK_250M);
> -               clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0);
> -               clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P);
> +               clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@0", "ctrl", 1, 0, PMU_USB0);
> +               clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@0", "phy", 1, 0, PMU_USB0_P);
>                 clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1);
>                 clkdev_add_pmu("1e106000.usb", "phy", 1, 0, PMU_USB1_P);
>                 clkdev_add_pmu("1e180000.etop", "switch", 1, 0, PMU_SWITCH);
> @@ -560,8 +560,8 @@ void __init ltq_soc_init(void)
>         } else {
>                 clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(),
>                                 ltq_danube_fpi_hz(), ltq_danube_pp32_hz());
> -               clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0);
> -               clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P);
> +               clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@0", "ctrl", 1, 0, PMU_USB0);
> +               clkdev_add_pmu("1f203000.rcu:rcu-usb2-phy@0", "phy", 1, 0, PMU_USB0_P);
>                 clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO);
>                 clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
>                 clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
> index 005cadb7a3f8..dbb450e3ba04 100644
> --- a/drivers/phy/Kconfig
> +++ b/drivers/phy/Kconfig
> @@ -488,6 +488,14 @@ config PHY_CYGNUS_PCIE
>           Enable this to support the Broadcom Cygnus PCIe PHY.
>           If unsure, say N.
>
> +config PHY_LANTIQ_RCU_USB2
> +       tristate "Lantiq XWAY SoC RCU based USB PHY"
> +       depends on SOC_TYPE_XWAY
> +       depends on OF
> +       select GENERIC_PHY
> +       help
> +         Support for the USB PHY(s) on the Lantiq XWAY family SoCs.
> +
>  source "drivers/phy/tegra/Kconfig"
>
>  config PHY_NS2_PCIE
> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> index dd8f3b5d2918..52631f5ac470 100644
> --- a/drivers/phy/Makefile
> +++ b/drivers/phy/Makefile
> @@ -59,6 +59,7 @@ obj-$(CONFIG_PHY_TUSB1210)            += phy-tusb1210.o
>  obj-$(CONFIG_PHY_BRCM_SATA)            += phy-brcm-sata.o
>  obj-$(CONFIG_PHY_PISTACHIO_USB)                += phy-pistachio-usb.o
>  obj-$(CONFIG_PHY_CYGNUS_PCIE)          += phy-bcm-cygnus-pcie.o
> +obj-$(CONFIG_PHY_LANTIQ_RCU_USB2)      += phy-lantiq-rcu-usb2.o
>  obj-$(CONFIG_ARCH_TEGRA) += tegra/
>  obj-$(CONFIG_PHY_NS2_PCIE)             += phy-bcm-ns2-pcie.o
>  obj-$(CONFIG_PHY_MESON8B_USB2)         += phy-meson8b-usb2.o
> diff --git a/drivers/phy/phy-lantiq-rcu-usb2.c b/drivers/phy/phy-lantiq-rcu-usb2.c
> new file mode 100644
> index 000000000000..9bff42afd256
> --- /dev/null
> +++ b/drivers/phy/phy-lantiq-rcu-usb2.c
> @@ -0,0 +1,325 @@
> +/*
> + * Lantiq XWAY SoC RCU module based USB 1.1/2.0 PHY driver
> + *
> + * Copyright (C) 2016 Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
> + * Copyright (C) 2017 Hauke Mehrtens <hauke-5/S+JYg5SzeELgA04lAiVw@public.gmane.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/gpio.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_gpio.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/reset.h>
> +
> +#define MAX_VBUS_GPIO          2
> +
> +/* Transmitter HS Pre-Emphasis Enable */
> +#define RCU_CFG1_TX_PEE                BIT(0)
> +/* Disconnect Threshold */
> +#define RCU_CFG1_DIS_THR_MASK  0x00038000
> +#define RCU_CFG1_DIS_THR_SHIFT 15
> +
> +struct ltq_rcu_usb2_bits {
> +       u8 hostmode;
> +       u8 slave_endianness;
> +       u8 host_endianness;
> +       bool have_ana_cfg;
> +};
> +
> +struct ltq_rcu_usb2_priv {
> +       struct regmap                   *regmap;
> +       u32                             phy_reg_offset;
> +       u32                             ana_cfg1_reg_offset;
> +       const struct ltq_rcu_usb2_bits  *reg_bits;
> +       struct device                   *dev;
> +       struct gpio_desc                *gpiod_vbus[MAX_VBUS_GPIO];
> +       struct phy                      *phy;
> +       struct clk                      *ctrl_gate_clk;
> +       struct clk                      *phy_gate_clk;
> +       struct reset_control            *ctrl_reset;
> +       struct reset_control            *phy_reset;
> +};
> +
> +static const struct ltq_rcu_usb2_bits xway_rcu_usb2_reg_bits = {
> +       .hostmode = 11,
> +       .slave_endianness = 9,
> +       .host_endianness = 10,
> +       .have_ana_cfg = false,
> +};
> +
> +static const struct ltq_rcu_usb2_bits xrx100_rcu_usb2_reg_bits = {
> +       .hostmode = 11,
> +       .slave_endianness = 17,
> +       .host_endianness = 10,
> +       .have_ana_cfg = false,
> +};
> +
> +static const struct ltq_rcu_usb2_bits xrx200_rcu_usb2_reg_bits = {
> +       .hostmode = 11,
> +       .slave_endianness = 9,
> +       .host_endianness = 10,
> +       .have_ana_cfg = true,
> +};
> +
> +static const struct of_device_id ltq_rcu_usb2_phy_of_match[] = {
> +       {
> +               .compatible = "lantiq,ase-rcu-usb2-phy",
> +               .data = &xway_rcu_usb2_reg_bits,
> +       },
> +       {
> +               .compatible = "lantiq,danube-rcu-usb2-phy",
> +               .data = &xway_rcu_usb2_reg_bits,
> +       },
> +       {
> +               .compatible = "lantiq,xrx100-rcu-usb2-phy",
> +               .data = &xrx100_rcu_usb2_reg_bits,
> +       },
> +       {
> +               .compatible = "lantiq,xrx200-rcu-usb2-phy",
> +               .data = &xrx200_rcu_usb2_reg_bits,
> +       },
> +       {
> +               .compatible = "lantiq,xrx300-rcu-usb2-phy",
> +               .data = &xrx200_rcu_usb2_reg_bits,
> +       },
> +       { },
> +};
> +MODULE_DEVICE_TABLE(of, ltq_rcu_usb2_phy_of_match);
> +
> +static void ltq_rcu_usb2_set_vbus_gpio_value(struct gpio_desc **gpiods,
> +                                               int value)
> +{
> +       int i;
> +
> +       for (i = 0; i < MAX_VBUS_GPIO; i++)
> +               if (!IS_ERR_OR_NULL(gpiods[i]))
> +                       gpiod_set_value(gpiods[i], value);
> +}
> +
> +static int ltq_rcu_usb2_phy_power_on(struct phy *phy)
> +{
> +       struct ltq_rcu_usb2_priv *priv = phy_get_drvdata(phy);
> +
> +       if (priv->phy_reset)
> +               reset_control_deassert(priv->phy_reset);
> +
> +       /* enable the port-specific VBUS GPIOs if available */
> +       ltq_rcu_usb2_set_vbus_gpio_value(priv->gpiod_vbus, 1);
as I mentioned in my previous mail, if you pass a fixed regulator then
the PHY framework handles this, see [1] (regulator_enable is called
right before .phy_power_on and regulator_disable is called right after
.phy_power_off)

> +       return 0;
> +}
> +
> +static int ltq_rcu_usb2_phy_power_off(struct phy *phy)
> +{
> +       struct ltq_rcu_usb2_priv *priv = phy_get_drvdata(phy);
> +
> +       /*
> +        * only disable the port-specific VBUS GPIO here (if available), the
> +        * shared VBUS GPIO might still be used by another port
> +        */
> +       ltq_rcu_usb2_set_vbus_gpio_value(priv->gpiod_vbus, 0);
> +
> +       if (priv->phy_reset)
> +               reset_control_assert(priv->phy_reset);
> +
> +       return 0;
> +}
> +
> +static struct phy_ops ltq_rcu_usb2_phy_ops = {
> +       .power_on       = ltq_rcu_usb2_phy_power_on,
> +       .power_off      = ltq_rcu_usb2_phy_power_off,
> +       .owner          = THIS_MODULE,
> +};
> +
> +static void ltq_rcu_usb2_start_cores(struct platform_device *pdev)
> +{
> +       struct device *dev = &pdev->dev;
> +       struct ltq_rcu_usb2_priv *priv = dev_get_drvdata(dev);
> +
> +       /* Power on the USB core. */
> +       if (clk_prepare_enable(priv->ctrl_gate_clk)) {
> +               dev_err(dev, "failed to enable CTRL gate\n");
> +               return;
> +       }
> +
> +       /*
> +        * Power on the USB PHY. We have to do it early because
> +        * otherwise the second core won't turn on properly.
> +        */
> +       if (clk_prepare_enable(priv->phy_gate_clk)) {
> +               dev_err(dev, "failed to enable PHY gate\n");
> +               return;
> +       }
> +
> +       if (priv->reg_bits->have_ana_cfg) {
> +               regmap_update_bits(priv->regmap, priv->ana_cfg1_reg_offset,
> +                       RCU_CFG1_TX_PEE, RCU_CFG1_TX_PEE);
> +               regmap_update_bits(priv->regmap, priv->ana_cfg1_reg_offset,
> +                       RCU_CFG1_DIS_THR_MASK, 7 << RCU_CFG1_DIS_THR_SHIFT);
> +       }
> +
> +       /* Configure core to host mode */
> +       regmap_update_bits(priv->regmap, priv->phy_reg_offset,
> +                          BIT(priv->reg_bits->hostmode), 0);
> +
> +       /* Select DMA endianness (Host-endian: big-endian) */
> +       regmap_update_bits(priv->regmap, priv->phy_reg_offset,
> +               BIT(priv->reg_bits->slave_endianness), 0);
> +       regmap_update_bits(priv->regmap, priv->phy_reg_offset,
> +               BIT(priv->reg_bits->host_endianness),
> +               BIT(priv->reg_bits->host_endianness));
> +
> +       /* Reset USB core throgh reset controller */
> +       reset_control_deassert(priv->ctrl_reset);
> +
> +       if (priv->phy_reset)
> +               reset_control_assert(priv->phy_reset);
> +}
> +
> +static int ltq_rcu_usb2_get_vbus_gpios(struct device *dev,
> +                                         struct gpio_desc **gpios)
> +{
> +       int i;
> +
> +       for (i = 0; i < MAX_VBUS_GPIO; i++) {
> +               gpios[i] = devm_gpiod_get_index_optional(dev, "vbus", i,
> +                                                        GPIOD_OUT_LOW);
> +               if (IS_ERR(gpios[i]))
> +                       return PTR_ERR(gpios[i]);
> +       }
> +
> +       return 0;
> +}
> +
> +static int ltq_rcu_usb2_of_probe(struct device_node *phynode,
> +                                   struct ltq_rcu_usb2_priv *priv)
> +{
> +       struct device *dev = priv->dev;
> +       const struct of_device_id *match =
> +               of_match_node(ltq_rcu_usb2_phy_of_match, phynode);
> +       int ret;
> +
> +       if (!match) {
> +               dev_err(dev, "Not a compatible Lantiq RCU USB PHY\n");
> +               return -EINVAL;
> +       }
> +
> +       priv->reg_bits = match->data;
> +
> +       priv->regmap = syscon_regmap_lookup_by_phandle(phynode,
> +                                                      "lantiq,rcu-syscon");
> +       if (IS_ERR(priv->regmap)) {
> +               dev_err(dev, "Failed to lookup RCU regmap\n");
> +               return PTR_ERR(priv->regmap);
> +       }
> +
> +       ret = ltq_rcu_usb2_get_vbus_gpios(dev, priv->gpiod_vbus);
> +       if (ret) {
> +               dev_err(dev, "failed to request shared USB VBUS GPIO\n");
> +               return ret;
> +       }
> +
> +       priv->ctrl_gate_clk = devm_clk_get(dev, "ctrl");
> +       if (IS_ERR(priv->ctrl_gate_clk)) {
> +               dev_err(dev, "Unable to get USB ctrl gate clk\n");
> +               return PTR_ERR(priv->ctrl_gate_clk);
> +       }
> +
> +       priv->phy_gate_clk = devm_clk_get(dev, "phy");
> +       if (IS_ERR(priv->phy_gate_clk)) {
> +               dev_err(dev, "Unable to get USB phy gate clk\n");
> +               return PTR_ERR(priv->phy_gate_clk);
> +       }
> +
> +       priv->ctrl_reset = devm_reset_control_get_shared(dev, "ctrl");
> +       if (IS_ERR(priv->ctrl_reset)) {
> +               dev_err(dev, "failed to get 'ctrl' reset\n");
> +               return PTR_ERR(priv->ctrl_reset);
> +       }
> +
> +       priv->phy_reset = devm_reset_control_get_optional(dev, "phy");
> +       if (IS_ERR(priv->phy_reset)) {
> +               if (PTR_ERR(priv->phy_reset) == -EPROBE_DEFER)
> +                       return PTR_ERR(priv->phy_reset);
> +               priv->phy_reset = NULL;
> +       }
a recent reset controller framework improvement allows us to make this
much easier as:
"As of commit bb475230b8e5 ("reset: make optional functions really
optional"), the reset framework API calls use NULL pointers to describe
optional, non-present reset controls." (see [0])
so we can basically turn this into IS_ERR() then return PTR_ERR()

> +       ret = of_property_read_u32_index(phynode, "lantiq,rcu-syscon", 1,
> +                                        &priv->phy_reg_offset);
> +       if (ret) {
> +               dev_err(dev, "Failed to get RCU PHY reg offset\n");
> +               return ret;
> +       }
> +
> +       if (priv->reg_bits->have_ana_cfg) {
> +               ret = of_property_read_u32_index(phynode, "lantiq,rcu-syscon",
> +                                                2, &priv->ana_cfg1_reg_offset);
> +               if (ret) {
> +                       dev_dbg(dev, "Failed to get RCU ANA CFG1 reg offset\n");
> +                       return ret;
> +               }
> +       }
> +
> +       return 0;
> +}
> +
> +static int ltq_rcu_usb2_phy_probe(struct platform_device *pdev)
> +{
> +       struct device_node *child, *np = pdev->dev.of_node;
> +       struct ltq_rcu_usb2_priv *priv;
> +       struct phy_provider *provider;
> +       int ret;
> +
> +       priv = devm_kzalloc(&pdev->dev, sizeof(*priv),
> +                                      GFP_KERNEL);
> +       if (!priv)
> +               return -ENOMEM;
> +
> +       priv->dev = &pdev->dev;
> +       dev_set_drvdata(priv->dev, priv);
> +
> +       ret = ltq_rcu_usb2_of_probe(np, priv);
> +       if (ret)
> +               return ret;
> +
> +       priv->phy = devm_phy_create(&pdev->dev, child,
> +                                        &ltq_rcu_usb2_phy_ops);
> +       if (IS_ERR(priv->phy)) {
> +               dev_err(&pdev->dev, "failed to create PHY\n");
> +               return PTR_ERR(priv->phy);
> +       }
> +
> +       phy_set_drvdata(priv->phy, priv);
> +
> +       ltq_rcu_usb2_start_cores(pdev);
> +
> +       provider = devm_of_phy_provider_register(&pdev->dev,
> +                                                of_phy_simple_xlate);
> +
> +       return PTR_ERR_OR_ZERO(provider);
> +}
> +
> +static struct platform_driver ltq_rcu_usb2_phy_driver = {
> +       .probe  = ltq_rcu_usb2_phy_probe,
> +       .driver = {
> +               .name   = "lantiq-rcu-usb2-phy",
> +               .of_match_table = ltq_rcu_usb2_phy_of_match,
> +       }
> +};
> +module_platform_driver(ltq_rcu_usb2_phy_driver);
> +
> +MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>");
> +MODULE_DESCRIPTION("Lantiq XWAY USB2 PHY driver");
> +MODULE_LICENSE("GPL v2");
> --
> 2.11.0
>

[0] https://patchwork.kernel.org/patch/9545031/
[1] http://lxr.free-electrons.com/source/drivers/phy/phy-core.c#L276
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" 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 RFC 7/7] ARM: dts: samsung: Switch to dedicated Odroid sound card binding
From: Krzysztof Kozlowski @ 2017-04-21 18:43 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: linux-samsung-soc, linux-clk, dri-devel, alsa-devel, devicetree,
	inki.dae, sw0312.kim, cw00.choi, javier, jy0922.shim, broonie,
	robh+dt, b.zolnierkie
In-Reply-To: <1492795191-31298-8-git-send-email-s.nawrocki@samsung.com>

On Fri, Apr 21, 2017 at 07:19:51PM +0200, Sylwester Nawrocki wrote:
> The new sound card DT binding is used for Odroid XU3 in order
> to properly support the HDMI audio path.
> Clocks configuration is changed so the I2S controller is now the bit
> and the frame clock master with EPLL as the root clock source.
> 
> Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
> ---
>  arch/arm/boot/dts/exynos4.dtsi                    |  1 +
>  arch/arm/boot/dts/exynos5420.dtsi                 |  1 +
>  arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi | 59 ++++++++++++++++++-----
>  3 files changed, 48 insertions(+), 13 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
> index 18def1c..f3dcb7f 100644
> --- a/arch/arm/boot/dts/exynos4.dtsi
> +++ b/arch/arm/boot/dts/exynos4.dtsi
> @@ -761,6 +761,7 @@
>  		phy = <&hdmi_i2c_phy>;
>  		power-domains = <&pd_tv>;
>  		samsung,syscon-phandle = <&pmu_system_controller>;
> +		#sound-dai-cells = <0>;
>  		status = "disabled";
>  	};
>  
> diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi
> index 7dc9dc8..c7d29b6 100644
> --- a/arch/arm/boot/dts/exynos5420.dtsi
> +++ b/arch/arm/boot/dts/exynos5420.dtsi
> @@ -618,6 +618,7 @@
>  			samsung,syscon-phandle = <&pmu_system_controller>;
>  			status = "disabled";
>  			power-domains = <&disp_pd>;
> +			#sound-dai-cells = <0>;
>  		};
>  
>  		hdmiphy: hdmiphy@145D0000 {
> diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi b/arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi
> index 9493923..84703f7 100644
> --- a/arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi
> +++ b/arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi
> @@ -11,15 +11,17 @@
>   * published by the Free Software Foundation.
>  */
>  
> +#include <dt-bindings/sound/samsung-i2s.h>
> +
>  / {
>  	sound: sound {
> -		compatible = "simple-audio-card";
> +		compatible = "samsung,odroid-xu3-audio";
> +		model = "Odroid-XU3";
>  
> -		simple-audio-card,name = "Odroid-XU3";
> -		simple-audio-card,widgets =
> +		samsung,audio-widgets =
>  			"Headphone", "Headphone Jack",
>  			"Speakers", "Speakers";
> -		simple-audio-card,routing =
> +		samsung,audio-routing =
>  			"Headphone Jack", "HPL",
>  			"Headphone Jack", "HPR",
>  			"Headphone Jack", "MICBIAS",
> @@ -27,22 +29,51 @@
>  			"Speakers", "SPKL",
>  			"Speakers", "SPKR";
>  
> -		simple-audio-card,format = "i2s";
> -		simple-audio-card,bitclock-master = <&link0_codec>;
> -		simple-audio-card,frame-master = <&link0_codec>;
> +		clocks = <&clock CLK_FOUT_EPLL>, <&i2s0 CLK_I2S_RCLK_SRC>;
> +		clock-names = "epll", "i2s_rclk";
>  
> -		simple-audio-card,cpu {
> +		cpu {
>  			sound-dai = <&i2s0 0>;
> -			system-clock-frequency = <19200000>;
>  		};
> -
> -		link0_codec: simple-audio-card,codec {
> -			sound-dai = <&max98090>;
> -			clocks = <&i2s0 CLK_I2S_CDCLK>;
> +		codec {
> +			sound-dai = <&hdmi>, <&max98090>;
>  		};
>  	};
>  };
>  
> +&clock_audss {
> +	assigned-clocks = <&clock_audss EXYNOS_DOUT_SRP>,
> +			  <&clock CLK_FOUT_EPLL>;
> +	assigned-clock-rates = <(196608000 / 256)>,
> +			       <196608000>;
> +};
> +
> +&sound {
> +	assigned-clocks = <&clock CLK_MOUT_EPLL>,
> +			<&clock CLK_MOUT_MAU_EPLL>,
> +			<&clock CLK_MOUT_USER_MAU_EPLL>,
> +			<&clock_audss EXYNOS_MOUT_AUDSS>,
> +			<&clock_audss EXYNOS_MOUT_I2S>,
> +			<&clock_audss EXYNOS_DOUT_SRP>,
> +			<&clock_audss EXYNOS_DOUT_AUD_BUS>,
> +			<&clock_audss EXYNOS_DOUT_I2S>;
> +
> +	assigned-clock-parents = <&clock CLK_FOUT_EPLL>,
> +			<&clock CLK_MOUT_EPLL>,
> +			<&clock CLK_MOUT_MAU_EPLL>,
> +			<&clock CLK_MAU_EPLL>,
> +			<&clock_audss EXYNOS_MOUT_AUDSS>;
> +
> +	assigned-clock-rates = <0>,
> +			<0>,
> +			<0>,
> +			<0>,
> +			<0>,
> +			<196608000>,
> +			<(196608000 / 2)>,
> +			<196608000>;
> +};

Unless there is clear reson not to, I would prefer to put nodes sorted
alphabetically. It helps avoiding conflicts and bring some logic.

Beside that, looks good for me.

You mentioned that DTS will be going in with next iteration. Sounds fine
with me.

Best regards,
Krzysztof


^ permalink raw reply

* [PATCH] streamline TLV320AIC23 drivers
From: Jens Rottmann @ 2017-04-21 19:22 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland, Jaroslav Kysela, Takashi Iwai
  Cc: alsa-devel, devicetree, linux-kernel, Liam Girdwood, Mark Brown

The iMX-TLV320AIC23 driver isn't from Freescale, but from a company named
Eukrea Electromatique, originally for their own boards. From the code I get
the impression it is a bit older, its DT options use a differing naming
scheme. Patch it up a bit:

- Remove Eukrea naming, i.MX is from Freescale, TLV320AIC23 is from TI,
  driver was written by Eukrea, but it's DT capable, so it's not exclusive:
  - Kconfig option title
  - 'model' option
  - driver 'compatible' string
- Other options just have changed over time, this driver remaining (one of)
  the last with the old semantics:
  - 'audio-codec' option (also moved from ssi node)
  - 'mux-int/ext-port' options
- All options stay backwards compatible, the DT binding documents new and
  old names.

CONFIG variable and files have not been renamed, though, so no need to
change old defconfigs.

Signed-off-by: Jens Rottmann <Jens.Rottmann@ADLINKtech.com>
---

--- a/Documentation/devicetree/bindings/sound/eukrea-tlv320.txt
+++ b/Documentation/devicetree/bindings/sound/eukrea-tlv320.txt
@@ -1,16 +1,23 @@
-Audio complex for Eukrea boards with tlv320aic23 codec.
+Audio complex for Freescale i.MX boards with TI TLV320AIC23 I2S codecs,
+like those from Eukrea Electromatique.
 
 Required properties:
 
-  - compatible		: "eukrea,asoc-tlv320"
+  - compatible		: "fsl,imx-audio-tlv320aic23" or
+			  "eukrea,asoc-tlv320" (deprecated)
 
-  - eukrea,model	: The user-visible name of this sound complex.
+  - model		: The user-visible name of this sound complex.
+  - eukrea,model	: Dito, deprecated.
 
   - ssi-controller	: The phandle of the SSI controller.
 
-  - fsl,mux-int-port	: The internal port of the i.MX audio muxer (AUDMUX).
+  - mux-int-port	: The internal port of the i.MX audio muxer (AUDMUX).
+  - fsl,mux-int-port	: Dito, deprecated.
 
-  - fsl,mux-ext-port	: The external port of the i.MX audio muxer.
+  - mux-ext-port	: The external port of the i.MX audio muxer.
+  - fsl,mux-ext-port	: Dito, deprecated.
+
+  - audio-codec		: The phandle of the audio codec.
 
 Note: The AUDMUX port numbering should start at 1, which is consistent with
 hardware manual.
@@ -18,9 +25,10 @@ hardware manual.
 Example:
 
 	sound {
-		compatible = "eukrea,asoc-tlv320";
-		eukrea,model = "imx51-eukrea-tlv320aic23";
+		compatible = "fsl,imx-audio-tlv320aic23";
+		model = "imx51-eukrea-tlv320aic23";
 		ssi-controller = <&ssi2>;
-		fsl,mux-int-port = <2>;
-		fsl,mux-ext-port = <3>;
+		mux-int-port = <2>;
+		mux-ext-port = <3>;
+		audio-codec = <&codec>;
 	};
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -220,7 +220,7 @@ config SND_SOC_PHYCORE_AC97
 	  and phyCARD boards in AC97 mode
 
 config SND_SOC_EUKREA_TLV320
-	tristate "Eukrea TLV320"
+	tristate "SoC Audio support for i.MX boards with TLV320AIC23"
 	depends on ARCH_MXC && I2C
 	select SND_SOC_TLV320AIC23_I2C
 	select SND_SOC_IMX_AUDMUX
--- a/sound/soc/fsl/eukrea-tlv320.c
+++ b/sound/soc/fsl/eukrea-tlv320.c
@@ -92,11 +92,13 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
 
 	eukrea_tlv320.dev = &pdev->dev;
 	if (np) {
-		ret = snd_soc_of_parse_card_name(&eukrea_tlv320,
-						 "eukrea,model");
+		ret = snd_soc_of_parse_card_name(&eukrea_tlv320, "model");
+		if (ret) /* backwards compatible */
+			ret = snd_soc_of_parse_card_name(&eukrea_tlv320,
+			                                 "eukrea,model");
 		if (ret) {
 			dev_err(&pdev->dev,
-				"eukrea,model node missing or invalid.\n");
+			        "model node missing or invalid.\n");
 			goto err;
 		}
 
@@ -109,22 +111,28 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
 			goto err;
 		}
 
-		codec_np = of_parse_phandle(ssi_np, "codec-handle", 0);
+		codec_np = of_parse_phandle(pdev->dev.of_node, "audio-codec", 0);
+		if (!codec_np) /* backwards compatible */
+			codec_np = of_parse_phandle(ssi_np, "codec-handle", 0);
 		if (codec_np)
 			eukrea_tlv320_dai.codec_of_node = codec_np;
 		else
-			dev_err(&pdev->dev, "codec-handle node missing or invalid.\n");
+			dev_err(&pdev->dev, "audio-codec node missing or invalid.\n");
 
-		ret = of_property_read_u32(np, "fsl,mux-int-port", &int_port);
+		ret = of_property_read_u32(np, "mux-int-port", &int_port);
+		if (ret) /* backwards compatible */
+			ret = of_property_read_u32(np, "fsl,mux-int-port", &int_port);
 		if (ret) {
 			dev_err(&pdev->dev,
-				"fsl,mux-int-port node missing or invalid.\n");
+			        "mux-int-port node missing or invalid.\n");
 			return ret;
 		}
-		ret = of_property_read_u32(np, "fsl,mux-ext-port", &ext_port);
+		ret = of_property_read_u32(np, "mux-ext-port", &ext_port);
+		if (ret) /* backwards compatible */
+			ret = of_property_read_u32(np, "fsl,mux-ext-port", &ext_port);
 		if (ret) {
 			dev_err(&pdev->dev,
-				"fsl,mux-ext-port node missing or invalid.\n");
+			        "mux-ext-port node missing or invalid.\n");
 			return ret;
 		}
 
@@ -213,7 +221,8 @@ static int eukrea_tlv320_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id imx_tlv320_dt_ids[] = {
-	{ .compatible = "eukrea,asoc-tlv320"},
+	{ .compatible = "eukrea,asoc-tlv320"}, /* backwards compatible */
+	{ .compatible = "fsl,imx-audio-tlv320aic23"},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, imx_tlv320_dt_ids);
_

^ permalink raw reply

* [PATCH] ARM: add DTS, defconfig for ADLINK LEC-iMX6
From: Jens Rottmann @ 2017-04-21 19:27 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland
  Cc: Russell King, Fancy Fang, Haibo Chen,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

These are SMARC form factor modules with NXP/Freescale i.MX6 Q/D/DL/S,
1-2 GB RAM, optional eMMC, optional PCIe switch. The DTS files support
the modules on ADLINK's LEC-Base R1 and LEC-Base Mini eval carriers.

Signed-off-by: Jens Rottmann <Jens.Rottmann-AbX7Xxim+f4qDJ6do+/SaQ@public.gmane.org>
---

--- /dev/null
+++ b/arch/arm/boot/dts/lec-imx6.dtsi
@@ -0,0 +1,1244 @@
+/*
+ * Copyright 2014-2016 LiPPERT ADLINK Technology GmbH
+ * Copyright 2012-2015 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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
+ */
+
+/* On-module multiplexer: 0 enables SMARC SPI0, !=0 enables I2S0 instead:
+ * 1=TI TLV320AIC23 on LEC-Base R1 carrier, 2=Freescale SGTL5000 on LEC-Base R2/Mini */
+#define CONFIG_I2S_AUDIO	0
+/* The LEC-Base carrier doesn't include cameras, but allows connecting some. */
+//#define CONFIG_SER_CAMERA	3c /* I2C addr of serial camera, hex without "0x" */
+//#define CONFIG_PAR_CAMERA	3c /* I2C addr of parallel camera */
+
+/* The on-module Freescale PF0100 PMIC provides VDD_ARM_IN, VDD_SOC_IN to the
+ * on-SoC Anatop LDOs, which then generate VDD_ARM (CPU cores), VDD_PU
+ * (GPU/VPU), VDD_SOC (the rest). To save power clock and voltage need to vary
+ * according to the workload.
+ * Normal: PMIC provides fixed voltage, internal LDO lowers voltage further to
+ *         required value, depending on clock frequency.
+ * LDO bypass: PMIC (switched!) provides variable voltage directly, controlled
+ *             via I2C; internal LDOs bridged (FETs permanently on).
+ * Bypassing saves power, but requires steady communication on i2c2 to work. */
+#define LDO_BYPASS	1
+
+/* Freescale defines 2 alternative DT nodes for the VPU: The one normally active
+ * loads a driver called 'mxc_vpu'. The other, disabled one, would invoke a
+ * different driver named 'coda'. I don't know what state it is in; none of
+ * Freescale's sample dts files enable it, but the code is there, appearently
+ * dormant, in imx6qdl.dtsi. 'Coda' requires a v4l-coda960-imx6*.bin firmware. */
+#define VPU_CODA	0
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#define __0x(X) 0x##X	/* prefix hex digits with "0x" */
+#define _0x(X) __0x(X)
+
+/ {
+	aliases {
+		mxcfb0 = &mxcfb1;
+		mxcfb1 = &mxcfb2;
+		mxcfb2 = &mxcfb3;
+	};
+
+	chosen {
+		/* U-Boot provides this via "console=..." in the 'params' variable. */
+		//stdout-path = &uart1;
+	};
+
+	/* The LEC-Base carriers don't have any LEDs, just show how it's done. */
+	//leds {
+	//	compatible = "gpio-leds";
+	//
+	//	example-led {
+	//		gpios = <&smarc_gpio 5 GPIO_ACTIVE_LOW>; /* SMARC GPIO5/PWM_OUT */
+	//		linux,default-trigger = "mmc1"; /* more triggers in menuconfig */
+	//	};
+	//};
+
+	memory: memory {
+		reg = <0x10000000 0x40000000>;	/* dummy size, overwritten by U-Boot */
+	};
+
+	regulators {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_regulators>;
+
+		reg_smarc_lcd_vdd: regulator@130 {
+			compatible = "regulator-fixed";
+			reg = <130>;
+			regulator-name = "smarc_lcd_vdd";
+			gpio = <&gpio1 30 GPIO_ACTIVE_HIGH>; /* SMARC LCD_VDD_EN */
+			enable-active-high;
+			regulator-always-on; /* Freescale's fb/lcd/ldb drivers can't control a regulator yet :-( */
+			regulator-state-mem { regulator-off-in-suspend; }; /* no effect? */
+		};
+
+		reg_smarc_usb0: regulator@127 {
+			compatible = "regulator-fixed";
+			reg = <127>;
+			regulator-name = "smarc_usb0";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			gpio = <&gpio1 27 GPIO_ACTIVE_HIGH>; /* SMARC USB0_EN_OC# */
+			enable-active-high;
+		};
+
+		reg_smarc_usb1: regulator@329 {
+			compatible = "regulator-fixed";
+			reg = <329>;
+			regulator-name = "smarc_usb1";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			gpio = <&gpio3 29 GPIO_ACTIVE_HIGH>; /* SMARC USB1_EN_OC# */
+			enable-active-high;
+			/* Before enabling Vbus on the carrier power up the host phy's Vbus. */
+			vin-supply = <&swbst_reg>;
+		};
+
+		reg_smarc_usb2: regulator@330 {
+			compatible = "regulator-fixed";
+			reg = <330>;
+			regulator-name = "smarc_usb2";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			gpio = <&gpio3 30 GPIO_ACTIVE_HIGH>; /* SMARC USB2_EN_OC# */
+			enable-active-high;
+			/* An on-module hub splits the i.MX6's usbh1 port into SMARC USB1 and 2.
+			 * Devices on both are powered independently, via reg_smarc_usb1 and 2.
+			 * But I've seen no way to model the hub in the device tree and usbh1
+			 * takes only 1 "vbus-supply" line. So by declaring one as vin-supply
+			 * for the other we trick usbh1 into enabling both. If someone needed to
+			 * enable them separately they'd have to do it manually in user mode. */
+			vin-supply = <&reg_smarc_usb1>;
+		};
+
+		reg_smarc_sdio_pwr: regulator@411 {
+			compatible = "regulator-fixed";
+			reg = <411>;
+			regulator-name = "smarc_sdio_pwr";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			gpio = <&gpio4 11 GPIO_ACTIVE_HIGH>; /* SMARC SDIO_PWR_EN */
+			enable-active-high;
+			regulator-boot-on;
+		};
+
+#if CONFIG_I2S_AUDIO == 2
+		/* Power supplies on the LEC-Base R2 carrier. They cannot be
+		 * controlled, but the SGTL5000 driver won't work without
+		 * regulator definitions. */
+		reg_base_1v8: regulator@18 {
+			compatible = "regulator-fixed";
+			reg = <18>;
+			regulator-name = "base_1v8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-boot-on;
+			regulator-always-on;
+		};
+
+		reg_base_3v3: regulator@33 {
+			compatible = "regulator-fixed";
+			reg = <33>;
+			regulator-name = "base_3v3";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-boot-on;
+			regulator-always-on;
+		};
+#endif
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_keys>;
+
+		lid {
+			label = "Lid switch";
+			gpios = <&gpio1 7 GPIO_ACTIVE_LOW>; /* SMARC LID# */
+			gpio-key,wakeup;
+			linux,input-type = <5>; /* EV_SW */
+			linux,code = <0>; /* SW_LID */
+		};
+
+		power {
+			label = "Power button";
+			gpios = <&gpio1 6 GPIO_ACTIVE_LOW>; /* SMARC POWER_BTN# */
+			gpio-key,wakeup;
+			linux,code = <KEY_POWER>;
+		};
+
+		sleep {
+			label = "Sleep button";
+			gpios = <&gpio2 7 GPIO_ACTIVE_LOW>; /* SMARC SLEEP# */
+			gpio-key,wakeup;
+			linux,code = <KEY_SLEEP>;
+		};
+
+		test {
+			label = "Test button"; /* LEC-Base R2 carrier provides a button */
+			gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; /* SMARC TEST# */
+			/* SMARC spec: "invoke module vendor specific test function(s)" */
+			linux,code = <KEY_PROG1>; /* adapt to your needs */
+		};
+
+		/* The PCIe driver doesn't implement a wakeup GPIO yet. For now,
+		 * this can serve as workaround. */
+		//pcie_wake {
+		//	label = "PCIe wake workaround";
+		//	gpios = <&gpio5 20 GPIO_ACTIVE_LOW>; /* PCIE_WAKE_B */
+		//	gpio-key,wakeup;
+		//	linux,code = <KEY_WAKEUP>;
+		//};
+	};
+
+#if CONFIG_I2S_AUDIO == 1
+	sound-i2s {	/* Audio codec on LEC-Base R1 carrier */
+		compatible = "fsl,imx-audio-tlv320aic23";
+		model = "imx-tlv320aic23";
+		ssi-controller = <&ssi2>;
+		mux-int-port = <2>;
+		mux-ext-port = <3>;
+		audio-codec = <&codec>;
+	};
+#elif CONFIG_I2S_AUDIO == 2
+	sound-i2s {	/* Audio codec on LEC-Base R2 carrier */
+		compatible = "fsl,imx-audio-sgtl5000";
+		model = "imx-sgtl5000";
+		ssi-controller = <&ssi2>;
+		mux-int-port = <2>;
+		mux-ext-port = <3>;
+		audio-codec = <&codec>;
+		asrc-controller = <&asrc>;
+		audio-routing =
+			"MIC_IN", "Mic Jack",
+			"Mic Jack", "Mic Bias",
+			"LINE_IN", "Line In Jack",
+		//	"Headphone Jack", "HP_OUT",
+			"Line Out Jack", "LINE_OUT";
+	};
+#endif
+
+	sound-hdmi {
+		compatible = "fsl,imx6q-audio-hdmi",
+			     "fsl,imx-audio-hdmi";
+		model = "imx-audio-hdmi";
+		hdmi-controller = <&hdmi_audio>;
+	};
+
+	sound-spdif {
+		compatible = "fsl,imx-audio-spdif";
+		model = "imx-spdif";
+		spdif-controller = <&spdif>;
+		spdif-in;
+		spdif-out;
+	};
+
+	mxcfb1: fb@0 {	/* IPU1 DI1: /dev/fb0=HDMI, fb1=IPU1's overlay */
+		compatible = "fsl,mxc_sdc_fb";
+		disp_dev = "hdmi";
+		interface_pix_fmt = "RGB24";
+		mode_str ="1920x1080M@60";
+		default_bpp = <24>;
+		int_clk = <0>;
+		late_init = <0>;
+		status = "okay";
+	};
+
+	mxcfb2: fb@1 {	/* IPU1 DI0: /dev/fb2=parallel RGB */
+		compatible = "fsl,mxc_sdc_fb";
+		disp_dev = "lcd";
+		interface_pix_fmt = "RGB24";
+		mode_str ="CLAA-WVGA";
+		default_bpp = <24>;
+		int_clk = <0>;
+		late_init = <0>;
+		status = "okay";
+	};
+
+	mxcfb3: fb@2 {	/* IPU2 DI0: /dev/fb3=LVDS, fb4=IPU2's overlay
+		         * Solo/DL: IPU1, fb2 competing with par. RGB, no overlay */
+		compatible = "fsl,mxc_sdc_fb";
+		disp_dev = "ldb";
+		interface_pix_fmt = "RGB24";
+		default_bpp = <24>;
+		int_clk = <0>;
+		late_init = <0>;
+		status = "okay";
+	};
+
+	rgb: lcd@0 {	/* parallel RGB (see fb above) */
+		compatible = "fsl,lcd";
+		ipu_id = <0>;
+		disp_id = <0>;
+		default_ifmt = "RGB24";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_ipu1>;
+		disp-power-on-supply = <&reg_smarc_lcd_vdd>; /* unsupported by driver */
+		status = "okay";
+	};
+
+	backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm1 0 5000000>;
+		brightness-levels = <0 4 8 16 32 64 128 255>;
+		default-brightness-level = <6>;
+		enable-gpios = <&gpio6 10 GPIO_ACTIVE_HIGH>; /* SMARC LCD_BKLT_EN */
+		status = "okay";
+	};
+
+#ifdef CONFIG_PAR_CAMERA
+	v4l2_cap_0 {
+		compatible = "fsl,imx6q-v4l2-capture";
+		ipu_id = <0>;
+		csi_id = <0>;
+		mclk_source = <0>;
+		status = "okay";
+	};
+#endif
+
+#ifdef CONFIG_SER_CAMERA
+	v4l2_cap_1 {
+		compatible = "fsl,imx6q-v4l2-capture";
+		ipu_id = <0>;
+		csi_id = <1>;
+		mclk_source = <0>;
+		status = "okay";
+	};
+#endif
+
+	v4l2_out {
+		compatible = "fsl,mxc_v4l2_output";
+		status = "okay";
+	};
+};
+
+#if VPU_CODA
+&vpu {
+	status = "okay";
+};
+&vpu_fsl {
+	status = "disabled";
+};
+#endif
+
+#if CONFIG_I2S_AUDIO
+&audmux {	/* SMARC I2S0 (instead of SPI0) */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_audmux>;
+	/* Freescale-specific; vanilla relies on U-Boot to set GPIO accordingly. */
+	//pinctrl-assert-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>; /* AEN# */
+	status = "okay";
+};
+#endif
+
+&cpu0 {
+#if LDO_BYPASS
+	arm-supply = <&sw1a_reg>;
+	soc-supply = <&sw1c_reg>;
+#else
+	arm-supply = <&reg_arm>;
+	soc-supply = <&reg_soc>;
+#endif
+};
+
+&clks {
+	fsl,ldb-di0-parent = <&clks IMX6QDL_CLK_PLL2_PFD0_352M>; /* LVDS */
+	fsl,ldb-di1-parent = <&clks IMX6QDL_CLK_PLL2_PFD0_352M>; /* unused */
+};
+
+#if !CONFIG_I2S_AUDIO
+&ecspi1 {	/* SMARC SPI0 (instead of I2S0) */
+	fsl,spi-num-chipselects = <2>;
+	cs-gpios = <&gpio5 25 GPIO_ACTIVE_LOW>, /* SMARC CS0 */
+	           <&gpio3 24 GPIO_ACTIVE_LOW>; /* SMARC CS1 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi1>;
+	/* Freescale-specific; vanilla relies on U-Boot to set GPIO accordingly. */
+	//pinctrl-assert-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>; /* AEN# */
+	status = "okay";
+
+	tsc2046@0 {		/* Touch screen controller on LEC-Base R1 carrier */
+		compatible = "ti,tsc2046";
+		reg = <0>;
+		vcc-supply = <&reg_smarc_lcd_vdd>;
+		spi-max-frequency = <2500000>;
+		interrupt-parent = <&smarc_gpio>;
+		interrupts = <10 IRQ_TYPE_EDGE_FALLING>; /* SMARC GPIO10 */
+		pendown-gpio = <&smarc_gpio 10 GPIO_ACTIVE_LOW>;
+		ti,vref-mv = /bits/ 16 <3300>;
+	};
+};
+#endif
+
+&ecspi2 {	/* SMARC SPI1 */
+	fsl,spi-num-chipselects = <2>;
+	cs-gpios = <&gpio2 27 GPIO_ACTIVE_LOW>, /* SMARC CS0 */
+	           <&gpio2 26 GPIO_ACTIVE_LOW>; /* SMARC CS1 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi2>;
+	status = "okay";
+};
+
+&ecspi4 {	/* on-module U-Boot SPI */
+	fsl,spi-num-chipselects = <1>;
+	cs-gpios = <&gpio3 25 GPIO_ACTIVE_LOW>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi4>;
+	status = "okay";
+
+	flash: m25p80@0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "winbond,w25q64";
+		spi-max-frequency = <66000000>; /* slowest we used was SST25VF032B; i.MX6 provides 60MHz max */
+		reg = <0>;
+		m25p,fast-read;
+	};
+};
+
+&fec {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_enet>;
+	phy-mode = "rgmii";
+	phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; /* RGMII_nRST */
+	/* Can't power off phy because sw2_reg is permanently needed. We could
+	 * turn off i.MX6's NVCC_RGMII (I/O voltage) only, but that's risky when
+	 * the phy remains powered. */
+	//phy-supply = <&vgen1_reg>;
+	fsl,magic-packet;
+	status = "okay";
+};
+
+&can1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_flexcan1>;
+	/* The next 2 options are documented, but not implemented by Freescale's
+	 * driver. Their recent DTs replace trx-stby-gpio and trx-en-gpio (also
+	 * missing) with 'xceiver-supply' regulators (is this really the same?),
+	 * however we won't bother, the GPIOs don't connect anyway. */
+	//trx-nerr-gpio = <&smarc_gpio 8 GPIO_ACTIVE_LOW>; /* SMARC GPIO8/CAN0_ERR#, unused on LEC-Base carrier */
+	//trx-stby-gpio = <&carrier_misc_control 1 GPIO_ACTIVE_HIGH>; /* CAN1_STB, solder jumper not populated */
+	status = "okay";
+};
+
+&can2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_flexcan2>;
+	//trx-nerr-gpio = <&smarc_gpio 9 GPIO_ACTIVE_LOW>; /* SMARC GPIO9/CAN1_ERR#, unused on LEC-Base carrier */
+	//trx-stby-gpio = <&carrier_misc_control 2 GPIO_ACTIVE_HIGH>; /* CAN2_STB, solder jumper not populated */
+	status = "okay";
+};
+
+&gpc {
+	fsl,ldo-bypass = <LDO_BYPASS>; /* U-Boot will check it and configure */
+};
+
+&dcic1 {
+	dcic_id = <0>;
+	dcic_mux = "dcic-hdmi";
+	status = "okay";
+};
+
+&dcic2 {
+	dcic_id = <1>;
+	dcic_mux = "dcic-lvds0";
+	status = "okay";
+};
+
+&hdmi_audio {
+	status = "okay";
+};
+
+&hdmi_cec {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_hdmi_cec>;
+	status = "okay";
+};
+
+&hdmi_core {		/* HDMI (see fb above) */
+	ipu_id = <0>;
+	disp_id = <1>;
+	status = "okay";
+};
+
+&hdmi_video {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_hdmi_hdcp>;
+	fsl,hdcp; /* also means we use the dedicated DDC function */
+	fsl,phy_reg_vlev = <0x03f4>;
+	fsl,phy_reg_cksymtx = <0x800f>;
+	status = "okay";
+};
+
+&i2c1 {		/* RTC, optional PCIe switch, SMARC I2C_CAM */
+	clock-frequency = <100000>; /* 66 MHz / 768 = 86 kHz */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c1>;
+	status = "okay";
+
+	pcf8563@51 {				/* Real Time Clock */
+		compatible = "nxp,pcf8563";
+		reg = <0x51>;
+	};
+
+	pex8605@58 {				/* optional PCIe switch */
+		compatible = "plx,pex8605"; /* guessing, no driver found */
+		reg = <0x58>;
+	};
+
+#if CONFIG_I2S_AUDIO == 2
+	codec: sgtl5000@0a {		/* Audio codec on LEC-Base R2 carrier */
+		compatible = "fsl,sgtl5000";
+		reg = <0x0a>;
+		clocks = <&clks IMX6QDL_CLK_CKO>; /* SMARC AUDIO_MCK, actually unused on carrier */
+		VDDA-supply = <&reg_base_3v3>;
+		VDDIO-supply = <&reg_base_1v8>;
+		VDDD-supply = <&reg_base_1v8>;
+		micbias-resistor-k-ohms = <4>;
+		micbias-voltage-m-volts = <1250>;
+	};
+#endif
+
+	carrier_misc_control: pcf8575@20 {	/* GPIO expander on LEC-Base R1 carrier */
+		compatible = "nxp,pcf8575";
+		reg = <0x20>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		/* 0: HUB1_RESET	 8: 3G1_DISABLE#
+		 * 1: CAN1_STB (NC)	 9: 3G1_DOWN#
+		 * 2: CAN2_STB (NC)	10: 3G2_DISABLE#
+		 * 3: LCD_RESET# (NC)	11: 3G2_DOWN#
+		 * 4: SUP_RESET# (NC)	12: HDMI_RESET#
+		 * 5: LVDS_VDD_EN	13: 3G_PW_EN
+		 * 6: CAM_PW_EN (NC)	14: PCAM_LE#
+		 * 7: GPS_VDD_EN	15: HUB2_RESET */
+		lines-initial-states = <0xc001>; /* bitmask: 0=high(!)/input, 1=pulled low */
+	};
+
+#ifdef CONFIG_PAR_CAMERA
+	ov564x@CONFIG_PAR_CAMERA {		/* Parallel camera connected to carrier */
+		compatible = "ovti,ov564x";
+		reg = <_0x(CONFIG_PAR_CAMERA)>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_ipu1_pcam>;
+		clocks = <&clks IMX6QDL_CLK_CKO>;
+		clock-names = "csi_mclk";
+		pwn-gpios = <&gpio6 14 GPIO_ACTIVE_HIGH>; /* SMARC GPIO1/CAM1_PWR# */
+		rst-gpios = <&gpio6 16 GPIO_ACTIVE_LOW>;  /* SMARC GPIO3/CAM1_RST# */
+		csi_id = <0>; /* but on SMARC CSI1_...! */
+		mclk = <24000000>;
+		mclk_source = <0>;
+	};
+#endif
+
+#ifdef CONFIG_SER_CAMERA
+	ov564x_mipi@CONFIG_SER_CAMERA {		/* Serial camera connected to carrier */
+		compatible = "ovti,ov564x_mipi";
+		reg = <_0x(CONFIG_SER_CAMERA)>;
+		clocks = <&clks IMX6QDL_CLK_CKO>;
+		clock-names = "csi_mclk";
+		pwn-gpios = <&gpio6 11 GPIO_ACTIVE_HIGH>; /* SMARC GPIO0/CAM0_PWR# */
+		rst-gpios = <&gpio6 15 GPIO_ACTIVE_LOW>;  /* SMARC GPIO2/CAM0_RST# */
+		csi_id = <1>; /* but on SMARC CSI0_...! */
+		mclk = <24000000>;
+		mclk_source = <0>;
+	};
+#endif
+};
+
+&i2c2 {		/* PFUZE100 PMIC, SMARC I2C_LCD, SMARC I2C_GP */
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c2>;
+	status = "okay";
+
+	pmic: pfuze100@08 {
+		compatible = "fsl,pfuze100";
+		reg = <0x08>;
+
+		regulators {
+			sw1a_reg: sw1ab { /* VDDCORE: VDDARM */
+				regulator-min-microvolt = <300000>;
+				regulator-max-microvolt = <1875000>;
+				regulator-boot-on;
+				regulator-always-on;
+				regulator-ramp-delay = <6250>;
+			};
+
+			sw1c_reg: sw1c { /* VDDSOC */
+				regulator-min-microvolt = <300000>;
+				regulator-max-microvolt = <1875000>;
+				regulator-boot-on;
+				regulator-always-on;
+				regulator-ramp-delay = <6250>;
+			};
+
+			sw2_reg: sw2 { /* GEN_3V3: NVCC_ENET (eth mac), eth phy, USB hub, eMMC, lots of misc stuff */
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-boot-on;
+				regulator-always-on;
+				regulator-ramp-delay = <6250>;
+			};
+
+			sw3a_reg: sw3a { /* DDR_1V5 */
+				regulator-min-microvolt = <400000>;
+				regulator-max-microvolt = <1975000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			sw3b_reg: sw3b { /* dito */
+				regulator-min-microvolt = <400000>;
+				regulator-max-microvolt = <1975000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			sw4_reg: sw4 { /* PMIC_1V8: VDD_IO and lots of stuff everywhere */
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			swbst_reg: swbst { /* PMIC_5V: USB h1 Vbus (for phy, rest is provided by carrier) */
+				regulator-min-microvolt = <5000000>;
+				regulator-max-microvolt = <5150000>;
+				regulator-boot-on;
+			};
+
+			snvs_reg: vsnvs { /* PMIC_VSNVS (3V) */
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			vref_reg: vrefddr { /* DDR_VREF */
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			vgen1_reg: vgen1 { /* VGEN1_1V5: NVCC_RGMII (i.MX6's I/O to external eth phy) */
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1550000>;
+				regulator-boot-on;
+				regulator-always-on; /* we can't power off phy itself */
+			};
+
+			vgen2_reg: vgen2 { /* unused */
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1550000>;
+			};
+
+			vgen3_reg: vgen3 { /* VGEN3_2V5: NVCC_LVDS (LVDS, DRAM, RGMII), SPI/I2S mux */
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-boot-on;
+				regulator-always-on; /* despite its name, NVCC_LVDS also supplies DRAM_IO */
+			};
+
+			vgen4_reg: vgen4 { /* VDDHIGH_IN (2.8V): SATA, PCIe, HDMI, MIPI, LVDS, USB, PLLs */
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+
+			vgen5_reg: vgen5 { /* dito, but unused per default (since LEC-iMX6 rev A4) */
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-boot-on;
+				//regulator-always-on; /* solder jumper */
+			};
+
+			vgen6_reg: vgen6 { /* VGEN6_3V3: PCIe switch, PCIe reset */
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-boot-on;
+				/* no driver for PCIe switch, no regulator in i.MX6 driver and we couldn't
+				   power down carrier devices or host, only PCIe switch in between */
+				regulator-always-on;
+			};
+		};
+	};
+
+#if CONFIG_I2S_AUDIO == 1
+	codec: tlv320aic23@1a {		/* Audio codec on LEC-Base R1 carrier */
+		compatible = "ti,tlv320aic23";
+		reg = <0x1a>;
+		clocks = <&clks IMX6QDL_CLK_CKO>; /* SMARC AUDIO_MCK, actually unused on carrier */
+	};
+#endif
+
+	/* Current driver depends on MXS framebuffer not present on i.MX6Q/D/DL/S.
+	 * Also assuming LEC-Base R1 JP3=1-2, JP15=2-3. */
+	sii902x@39 {			/* HDMI transmitter on LEC-Base R1 carrier */
+		compatible = "SiI,sii902x";
+		reg = <0x39>;
+		interrupt-parent = <&smarc_gpio>;
+		interrupts = <4 IRQ_TYPE_EDGE_FALLING>; /* SMARC GPIO4/HDA_RST# */
+		mode_str = "1280x720M@60";
+		bits-per-pixel = <32>;
+	};
+
+	mma7660@4c {			/* Accelerometer on LEC-Base R1 carrier */
+		compatible = "fsl,mma7660"; /* guessing, no driver mainlined */
+		reg = <0x4c>;
+		interrupt-parent = <&smarc_gpio>;
+		interrupts = <11 IRQ_TYPE_LEVEL_LOW>; /* SMARC GPIO11 */
+	};
+
+	at24c08@54 {			/* 1KB EEPROM on LEC-Base R1 carrier */
+		compatible = "atmel,24c08";
+		reg = <0x54>;
+		pagesize = <16>;
+	};
+
+	/* Driver disabled in defconfig, we have an on-module RTC already. */
+	ds1337@68 {			/* RTC on LEC-Base R1 carrier */
+		compatible = "maxim,ds1337";
+		reg = <0x68>;
+	};
+};
+
+&i2c3 {		/* GPIO expander, SEMA BMC, SMARC I2C_PM */
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c3>;
+	status = "okay";
+
+	smarc_gpio: pca9535@20 {	/* GPIO expander */
+		/* GPIOs 4-6, 8-11 map directly to the SMARC connector's GPIOx.
+		 * GPIOs 0-3, 7 are unused unless a solder jumper is changed, per default
+		 * SMARC GPIO0-3,7 are provided by the i.MX6 (CAM0/1_PWR/RST#,PCAM_FLD). */
+		compatible = "nxp,pca9535";
+		reg = <0x20>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <29 IRQ_TYPE_LEVEL_LOW>; /* GPIO_INT_B */
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	sema_bmc@28 {			/* SEMA Board Management Controller */
+		compatible = "adlink,sema_bmc"; /* no driver needed */
+		reg = <0x28>;
+	};
+
+	ltc1760@0a {			/* Battery charger on LEC-Base R1 carrier */
+		compatible = "linear,ltc1760"; /* guessing, no driver found */
+		reg = <0x0a>;
+	};
+};
+
+&iomuxc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_hog>;
+
+	lec-imx6 {
+		pinctrl_hog: hoggrp {
+			fsl,pins = <
+				/* Native pad functions */
+				MX6QDL_PAD_GPIO_0__CCM_CLKO1		0x130b0
+				/* Pads used for GPIOs */
+				MX6QDL_PAD_GPIO_3__GPIO1_IO03        0x80000000 /* AEN# (mux: 0=SPI0, 1=I2S0) */
+				MX6QDL_PAD_ENET_TXD1__GPIO1_IO29     0x80000000 /* GPIO_INT_B */
+				MX6QDL_PAD_NANDF_CS0__GPIO6_IO11     0x80000000 /* SMARC GPIO0/CAM0_PWR# */
+				MX6QDL_PAD_NANDF_CS1__GPIO6_IO14     0x80000000 /* SMARC GPIO1/CAM1_PWR# */
+				MX6QDL_PAD_NANDF_CS2__GPIO6_IO15     0x80000000 /* SMARC GPIO2/CAM0_RST# */
+				MX6QDL_PAD_NANDF_CS3__GPIO6_IO16     0x80000000 /* SMARC GPIO3/CAM1_RST# */
+				MX6QDL_PAD_NANDF_CLE__GPIO6_IO07     0x80000000 /* SMARC GPIO7/PCAM_FLD */
+			>;
+		};
+
+		pinctrl_regulators: regulatorsgrp {
+			fsl,pins = <
+				MX6QDL_PAD_ENET_TXD0__GPIO1_IO30     0x80000000 /* SMARC LCD_VDD_EN */
+				MX6QDL_PAD_ENET_RXD0__GPIO1_IO27	0x1a8b0 /* SMARC USB0_EN_OC# (open-drain) */
+				MX6QDL_PAD_EIM_D29__GPIO3_IO29		0x1a8b0 /* SMARC USB1_EN_OC# (open-drain) */
+				MX6QDL_PAD_EIM_D30__GPIO3_IO30		0x1a8b0 /* SMARC USB2_EN_OC# (open-drain) */
+				MX6QDL_PAD_KEY_ROW2__GPIO4_IO11      0x80000000 /* SMARC SDIO_PWR_EN */
+				//MX6QDL_PAD_GPIO_18__GPIO7_IO13     0x80000000 /* PMIC_INT_B */
+			>;
+		};
+
+#if CONFIG_I2S_AUDIO
+		pinctrl_audmux: audmuxgrp {
+			fsl,pins = <	/* SMARC I2S0 (instead of SPI0) */
+				MX6QDL_PAD_CSI0_DAT7__AUD3_RXD		0x130b0
+				MX6QDL_PAD_CSI0_DAT4__AUD3_TXC		0x130b0
+				MX6QDL_PAD_CSI0_DAT5__AUD3_TXD		0x110b0
+				MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS		0x130b0
+			>;
+		};
+#else
+		pinctrl_ecspi1: ecspi1grp {
+			fsl,pins = <	/* SMARC SPI0 (instead of I2S0) */
+				MX6QDL_PAD_CSI0_DAT6__ECSPI1_MISO	0x100b1
+				MX6QDL_PAD_CSI0_DAT5__ECSPI1_MOSI	0x100b1
+				MX6QDL_PAD_CSI0_DAT4__ECSPI1_SCLK	0x100b1
+				MX6QDL_PAD_CSI0_DAT7__GPIO5_IO25	0x1b0b0 /* SMARC CS0 */
+				MX6QDL_PAD_EIM_D24__GPIO3_IO24		0x1b0b0 /* SMARC CS1 */
+			>;
+		};
+#endif
+
+		pinctrl_ecspi2: ecspi2grp {
+			fsl,pins = <	/* SMARC SPI1 */
+				MX6QDL_PAD_EIM_OE__ECSPI2_MISO		0x100b1
+				MX6QDL_PAD_EIM_CS1__ECSPI2_MOSI		0x100b1
+				MX6QDL_PAD_EIM_CS0__ECSPI2_SCLK		0x100b1
+				MX6QDL_PAD_EIM_RW__GPIO2_IO26		0x1b0b0 /* SMARC CS1 */
+				MX6QDL_PAD_EIM_LBA__GPIO2_IO27		0x1b0b0 /* SMARC CS0 */
+			>;
+		};
+
+		pinctrl_ecspi4: ecspi4grp {
+			fsl,pins = <	/* on-module U-Boot SPI */
+				MX6QDL_PAD_EIM_D22__ECSPI4_MISO		0x100b1
+				MX6QDL_PAD_EIM_D28__ECSPI4_MOSI		0x100b1
+				MX6QDL_PAD_EIM_D21__ECSPI4_SCLK		0x100b1
+				MX6QDL_PAD_EIM_D25__GPIO3_IO25		0x1b0b0 /* CS3 */
+			>;
+		};
+
+		pinctrl_enet: enetgrp {
+			fsl,pins = <
+				MX6QDL_PAD_ENET_MDIO__ENET_MDIO		0x1b0b0
+				MX6QDL_PAD_ENET_MDC__ENET_MDC		0x1b0b0
+				MX6QDL_PAD_RGMII_TXC__RGMII_TXC		0x1b0b8 /* serial resistor added */
+				MX6QDL_PAD_RGMII_TD0__RGMII_TD0		0x1b0b0
+				MX6QDL_PAD_RGMII_TD1__RGMII_TD1		0x1b0b0
+				MX6QDL_PAD_RGMII_TD2__RGMII_TD2		0x1b0b0
+				MX6QDL_PAD_RGMII_TD3__RGMII_TD3		0x1b0b0
+				MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL	0x1b0b0
+				MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK	0x1b0b0
+				MX6QDL_PAD_RGMII_RXC__RGMII_RXC		0x1b0b0
+				MX6QDL_PAD_RGMII_RD0__RGMII_RD0		0x1b0b0
+				MX6QDL_PAD_RGMII_RD1__RGMII_RD1		0x1b0b0
+				MX6QDL_PAD_RGMII_RD2__RGMII_RD2		0x1b0b0
+				MX6QDL_PAD_RGMII_RD3__RGMII_RD3		0x1b0b0
+				MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL	0x1b0b0
+				MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25   0x80000000 /* RGMII_nRST */
+				//MX6QDL_PAD_ENET_RXD1__GPIO1_IO26   0x80000000 /* RGMII_INT */
+				/* For the workaround improving network latency described in i.MX6
+				 * erratum 6687 disable the power button, re-mux as follows and
+				 * add "interrupts-extended" as in imx6q-sabresd-enetirq.dts. */
+				//MX6QDL_PAD_GPIO_6__ENET_IRQ		0x000b1
+			>;
+		};
+
+		pinctrl_flexcan1: flexcan1grp {
+			fsl,pins = <	/* SMARC CAN0 */
+				MX6QDL_PAD_SD3_CMD__FLEXCAN1_TX		0x17059
+				MX6QDL_PAD_SD3_CLK__FLEXCAN1_RX		0x17059
+			>;
+		};
+
+		pinctrl_flexcan2: flexcan2grp {
+			fsl,pins = <	/* SMARC CAN1 */
+				MX6QDL_PAD_SD3_DAT0__FLEXCAN2_TX	0x17059
+				MX6QDL_PAD_SD3_DAT1__FLEXCAN2_RX	0x17059
+			>;
+		};
+
+		pinctrl_gpio_keys: gpio_keysgrp {
+			fsl,pins = <
+				MX6QDL_PAD_GPIO_7__GPIO1_IO07		0x1b0b0 /* SMARC LID# */
+				MX6QDL_PAD_GPIO_6__GPIO1_IO06		0x1b0b0 /* SMARC POWER_BTN# */
+				MX6QDL_PAD_NANDF_D7__GPIO2_IO07		0x1b0b0 /* SMARC SLEEP# */
+				MX6QDL_PAD_GPIO_8__GPIO1_IO08		0x1b0b0 /* SMARC TEST# */
+			>;
+		};
+
+		pinctrl_hdmi_cec: hdmicecgrp {
+			fsl,pins = <
+				MX6QDL_PAD_EIM_A25__HDMI_TX_CEC_LINE	0x108b0
+			>;
+		};
+
+		pinctrl_hdmi_hdcp: hdmihdcpgrp {
+			fsl,pins = <
+				MX6QDL_PAD_KEY_COL3__HDMI_TX_DDC_SCL 0x4001b8b1
+				MX6QDL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA 0x4001b8b1
+			>;
+		};
+
+		pinctrl_i2c1: i2c1grp {
+			fsl,pins = <
+				MX6QDL_PAD_CSI0_DAT8__I2C1_SDA		0x4001b8b1
+				MX6QDL_PAD_CSI0_DAT9__I2C1_SCL		0x4001b8b1
+			>;
+		};
+
+		pinctrl_i2c2: i2c2grp {
+			fsl,pins = <
+				MX6QDL_PAD_EIM_EB2__I2C2_SCL		0x4001b8b1
+				MX6QDL_PAD_EIM_D16__I2C2_SDA		0x4001b8b1
+			>;
+		};
+
+		pinctrl_i2c3: i2c3grp {
+			fsl,pins = <
+				MX6QDL_PAD_EIM_D17__I2C3_SCL		0x4001b8b1
+				MX6QDL_PAD_EIM_D18__I2C3_SDA		0x4001b8b1
+			>;
+		};
+
+		pinctrl_ipu1: ipu1grp {
+			fsl,pins = <
+				MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK       0xf1
+				MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15             0xf1
+				MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02              0xf1
+				MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03              0xf1
+				MX6QDL_PAD_DI0_PIN4__IPU1_DI0_PIN04        0x80000000
+				MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00         0xf1
+				MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01         0xf1
+				MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02         0xf1
+				MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03         0xf1
+				MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04         0xf1
+				MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05         0xf1
+				MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06         0xf1
+				MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07         0xf1
+				MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08         0xf1
+				MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09         0xf1
+				MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10        0xf1
+				MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11        0xf1
+				MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12        0xf1
+				MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13        0xf1
+				MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14        0xf1
+				MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15        0xf1
+				MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16        0xf1
+				MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17        0xf1
+				MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18        0xf1
+				MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19        0xf1
+				MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20        0xf1
+				MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21        0xf1
+				MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22        0xf1
+				MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23        0xf1
+			>;
+		};
+
+#ifdef CONFIG_PAR_CAMERA
+		pinctrl_ipu1_pcam: ipu1_pcamgrp {
+			fsl,pins = <	/* SMARC PCAM */
+				MX6QDL_PAD_CSI0_DAT10__IPU1_CSI0_DATA10    0x80000000
+				MX6QDL_PAD_CSI0_DAT11__IPU1_CSI0_DATA11    0x80000000
+				MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12    0x80000000
+				MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13    0x80000000
+				MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14    0x80000000
+				MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15    0x80000000
+				MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16    0x80000000
+				MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17    0x80000000
+				MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18    0x80000000
+				MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19    0x80000000
+				MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK   0x80000000
+				MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC      0x80000000
+				MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC     0x80000000
+			>;
+		};
+#endif
+
+		pinctrl_pcie: pciegrp {
+			fsl,pins = <
+				MX6QDL_PAD_GPIO_17__GPIO7_IO12		0x1b0b0 /* PCIE_RST_B */
+				MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20	0x1b0b0 /* PCIE_WAKE_B */
+			>;
+		};
+
+		pinctrl_pwm1: pwm1grp {
+			fsl,pins = <
+				MX6QDL_PAD_NANDF_RB0__GPIO6_IO10     0x80000000 /* SMARC LCD_BKLT_EN */
+				MX6QDL_PAD_GPIO_9__PWM1_OUT		0x1b0b1 /* SMARC LCD_BKLT_PWM */
+			>;
+		};
+
+		pinctrl_spdif: spdifgrp {
+			fsl,pins = <	/* SMARC SPDIF_IN/OUT */
+				MX6QDL_PAD_GPIO_16__SPDIF_IN		0x1b0b0
+				MX6QDL_PAD_GPIO_19__SPDIF_OUT		0x1b0b0
+			>;
+		};
+
+		pinctrl_uart1: uart1grp {
+			fsl,pins = <	/* SMARC SER0 */
+				MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA	0x1b0b1
+				MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA	0x1b0b1
+				MX6QDL_PAD_EIM_D19__UART1_CTS_B		0x1b0b1
+				MX6QDL_PAD_EIM_D20__UART1_RTS_B		0x1b0b1
+			>;
+		};
+
+		pinctrl_uart2: uart2grp {
+			fsl,pins = <	/* SMARC SER1 */
+				MX6QDL_PAD_EIM_D26__UART2_TX_DATA	0x1b0b1
+				MX6QDL_PAD_EIM_D27__UART2_RX_DATA	0x1b0b1
+			>;
+		};
+
+		pinctrl_uart4: uart4grp {
+			fsl,pins = <	/* SMARC SER3 */
+				MX6QDL_PAD_KEY_COL0__UART4_TX_DATA	0x1b0b1
+				MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA	0x1b0b1
+			>;
+		};
+
+		pinctrl_uart5: uart5grp {
+			fsl,pins = <	/* SMARC SER2 */
+				MX6QDL_PAD_KEY_COL1__UART5_TX_DATA	0x1b0b1
+				MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA	0x1b0b1
+				MX6QDL_PAD_KEY_COL4__UART5_RTS_B	0x1b0b1
+				MX6QDL_PAD_KEY_ROW4__UART5_CTS_B	0x1b0b1
+			>;
+		};
+
+		pinctrl_usbotg: usbotggrp {
+			fsl,pins = <	/* SMARC USB0 */
+				MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID	0x17059
+			>;
+		};
+
+		pinctrl_usdhc1: usdhc1grp {
+			fsl,pins = <	/* on-module eMMC */
+				MX6QDL_PAD_SD1_CMD__SD1_CMD		0x17059
+				MX6QDL_PAD_SD1_CLK__SD1_CLK		0x10059
+				MX6QDL_PAD_SD1_DAT0__SD1_DATA0		0x17059
+				MX6QDL_PAD_SD1_DAT1__SD1_DATA1		0x17059
+				MX6QDL_PAD_SD1_DAT2__SD1_DATA2		0x17059
+				MX6QDL_PAD_SD1_DAT3__SD1_DATA3		0x17059
+				MX6QDL_PAD_NANDF_D0__SD1_DATA4		0x17059
+				MX6QDL_PAD_NANDF_D1__SD1_DATA5		0x17059
+				MX6QDL_PAD_NANDF_D2__SD1_DATA6		0x17059
+				MX6QDL_PAD_NANDF_D3__SD1_DATA7		0x17059
+			>;
+		};
+
+		pinctrl_usdhc2: usdhc2grp {
+			fsl,pins = <	/* SMARC SDIO */
+				MX6QDL_PAD_SD2_CMD__SD2_CMD		0x17059
+				MX6QDL_PAD_SD2_CLK__SD2_CLK		0x10059
+				MX6QDL_PAD_SD2_DAT0__SD2_DATA0		0x17059
+				MX6QDL_PAD_SD2_DAT1__SD2_DATA1		0x17059
+				MX6QDL_PAD_SD2_DAT2__SD2_DATA2		0x17059
+				MX6QDL_PAD_SD2_DAT3__SD2_DATA3		0x17059
+				//MX6QDL_PAD_GPIO_4__SD2_CD_B	     0x80000000 /* controller internal CD doesn't work */
+				MX6QDL_PAD_GPIO_4__GPIO1_IO04	     0x80000000 /* SD2_CD_B: mux as GPIO instead */
+				MX6QDL_PAD_GPIO_2__SD2_WP	     0x80000000
+			>;
+		};
+
+		pinctrl_usdhc4: usdhc4grp {
+			fsl,pins = <	/* SMARC SDMMC */
+				MX6QDL_PAD_SD4_CMD__SD4_CMD		0x17059
+				MX6QDL_PAD_SD4_CLK__SD4_CLK		0x10059
+				MX6QDL_PAD_SD4_DAT0__SD4_DATA0		0x17059
+				MX6QDL_PAD_SD4_DAT1__SD4_DATA1		0x17059
+				MX6QDL_PAD_SD4_DAT2__SD4_DATA2		0x17059
+				MX6QDL_PAD_SD4_DAT3__SD4_DATA3		0x17059
+				MX6QDL_PAD_SD4_DAT4__SD4_DATA4		0x17059
+				MX6QDL_PAD_SD4_DAT5__SD4_DATA5		0x17059
+				MX6QDL_PAD_SD4_DAT6__SD4_DATA6		0x17059
+				MX6QDL_PAD_SD4_DAT7__SD4_DATA7		0x17059
+				MX6QDL_PAD_NANDF_ALE__SD4_RESET	     0x80000000
+			>;
+		};
+
+		pinctrl_wdog: wdoggrp {
+			fsl,pins = <
+				MX6QDL_PAD_GPIO_1__WDOG2_B 0x80000000
+			>;
+		};
+	};
+};
+
+&ldb {		/* LVDS (see fb above) */
+	disp-power-on-supply = <&reg_smarc_lcd_vdd>; /* unsupported by driver */
+	status = "okay";
+
+	lvds-channel@0 {
+		fsl,data-mapping = "spwg"; /* spwg or jeida (see chapter "Bit Mapping" in i.MX6 Reference Manual) */
+		fsl,data-width = <24>;
+		primary;
+		status = "okay";
+
+		display-timings {
+			native-mode = <&timing0>;
+			timing0: hsd100pxn1 {
+				clock-frequency = <65000000>;
+				hactive = <1024>;
+				vactive = <768>;
+				hback-porch = <220>;
+				hfront-porch = <40>;
+				vback-porch = <21>;
+				vfront-porch = <7>;
+				hsync-len = <60>;
+				vsync-len = <10>;
+			};
+		};
+	};
+};
+
+#ifdef CONFIG_SER_CAMERA
+&mipi_csi {
+	ipu_id = <0>;
+	csi_id = <1>;
+	v_channel = <0>;
+	lanes = <2>;
+	status = "okay";
+};
+#endif
+
+&mlb {		/* SMARC AFB_DIFF1-3 */
+	/* Driver doesn't seem to support differential (6-pin) mode. */
+	//status = "okay";
+};
+
+&pcie {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pcie>;
+	reset-gpio = <&gpio7 12 GPIO_ACTIVE_LOW>; /* PCIE_RST_B */
+	/* Next line has no effect: half-implemented in older kernels, Freescale
+	 * now removed code completely; gpio-key can serve as workaround. */
+	wake-up-gpio = <&gpio5 20 GPIO_ACTIVE_LOW>; /* PCIE_WAKE_B */
+	status = "okay";
+};
+
+&pwm1 {		/* SMARC LCD_BKLT_PWM */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm1>;
+	status = "okay";
+};
+
+&snvs_poweroff {
+	status = "okay";
+};
+
+&spdif {	/* SMARC SPDIF_IN/OUT */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_spdif>;
+	assigned-clocks = <&clks IMX6QDL_CLK_SPDIF_SEL>, <&clks IMX6QDL_CLK_SPDIF_PODF>;
+	assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_PFD3_454M>;
+	assigned-clock-rates = <0>, <227368421>;
+	status = "okay";
+};
+
+#if CONFIG_I2S_AUDIO
+&ssi2 {		/* SMARC I2S0 (instead of SPI0) */
+	status = "okay";
+};
+#endif
+
+&uart1 {	/* SMARC SER0 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart1>;
+	fsl,uart-has-rtscts;
+	status = "okay";
+};
+
+&uart2 {	/* SMARC SER1 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart2>;
+	status = "okay";
+};
+
+&uart4 {	/* SMARC SER3 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart4>;
+	status = "okay";
+};
+
+&uart5 {	/* SMARC SER2 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart5>;
+	fsl,uart-has-rtscts;
+	status = "okay";
+};
+
+&usbh1 {	/* SMARC USB1,2 */
+	vbus-supply = <&reg_smarc_usb2>; /* chained with usb1, see above */
+	disable-over-current; /* connects to SMARC USB2_EN_OC# but not USB1_ */
+	status = "okay";
+};
+
+&usbotg {	/* SMARC USB0 */
+	vbus-supply = <&reg_smarc_usb0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usbotg>;
+	//dr_mode = "peripheral"; /* default is "otg", override with "host" or "peripheral" to set fixed role */
+	disable-over-current;
+	srp-disable;
+	hnp-disable;
+	adp-disable;
+	status = "okay";
+};
+
+&usbphy1 {
+	tx-d-cal = <0x5>;
+};
+
+&usbphy2 {
+	tx-d-cal = <0x5>;
+};
+
+&usdhc1 {	/* on-module eMMC */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc1>;
+	bus-width = <8>;
+	non-removable;
+	status = "okay";
+};
+
+&usdhc2 {	/* SMARC SDIO */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc2>;
+	bus-width = <4>;
+	//fsl,cd-controller; /* using controller internal CD doesn't work properly */
+	cd-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; /* need to treat it as GPIO instead */
+	fsl,wp-controller;
+	vmmc-supply = <&reg_smarc_sdio_pwr>;
+	vqmmc-supply = <&reg_smarc_sdio_pwr>;
+	no-1-8-v; /* LEC-Base carriers have pull-ups (3.3V) on data lines */
+	//keep-power-in-suspend;
+	//enable-sdio-wakeup;
+	status = "okay";
+};
+
+&usdhc4 {	/* SMARC SDMMC */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usdhc4>;
+	bus-width = <8>;
+	//non-removable; /* eMMC: no polling saves power */
+	broken-cd; /* uSD slot on carrier: polling allows switching cards */
+	no-1-8-v; /* LEC-Base carriers have pull-ups (3.3V) on data lines */
+	status = "okay";
+};
+
+&wdog1 {
+	/* Contrary to other nodes Freescale's dtsi doesn't default to "disabled" here. */
+	status = "disabled";
+};
+
+&wdog2 {
+	/* This is the TrustZone watchdog, however pin mux leaves no other choice.
+	 * We don't need an SoC reset (wdog_rst_b), but WDOG2_B --> system wide POR. */
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_wdog>;
+	fsl,wdog_b;
+	status = "okay";
+};
--- /dev/null
+++ b/arch/arm/boot/dts/lec-imx6q.dts
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2014-2016 LiPPERT ADLINK Technology GmbH
+ * Copyright 2012-2015 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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 "imx6q.dtsi"
+#include "lec-imx6.dtsi"
+
+/ {
+	model = "ADLINK LEC-iMX6 (Quad/Dual) SMARC module";
+	compatible = "adlink,lec-imx6", "fsl,imx6q";
+};
+
+&ldb {		/* LVDS (see fb in lec-imx6.dtsi) */
+	lvds-channel@0 {
+		crtc = "ipu2-di0";
+	};
+};
+
+&sata {
+	/* Freescale's defaults */
+	fsl,transmit-level-mV = <1025>;
+	fsl,transmit-boost-mdB = <3330>;
+	fsl,transmit-atten-16ths = <9>;
+	fsl,receive-eq-mdB = <3000>;
+	status = "okay";
+};
--- /dev/null
+++ b/arch/arm/boot/dts/lec-imx6s.dts
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2014-2016 LiPPERT ADLINK Technology GmbH
+ * Copyright (C) 2013-2015 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/* The i.MX6 Solo/DualLite only has 1 IPU i.e. can only operate 2 of the 3
+ * display options at the same time. lec-imx6.dtsi assigns the IPU's 2 DIs such
+ * that HDMI always works, whereas parallel RGB and LVDS compete for the same
+ * DI. The following option leaves only one of them enabled. (The Quad/Dual DTS
+ * maps LVDS to the 2nd IPU, enabling all displays simultaneously.) */
+#define CONFIG_SOLO_LVDS	0
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "lec-imx6.dtsi"
+
+/ {
+	model = "ADLINK LEC-iMX6 (Solo/DualLite) SMARC module";
+	compatible = "adlink,lec-imx6", "fsl,imx6dl";
+};
+
+&ldb {		/* LVDS (see fb in lec-imx6.dtsi) */
+	lvds-channel@0 {
+		crtc = "ipu1-di0";
+	};
+};
+
+#if CONFIG_SOLO_LVDS
+&mxcfb2 {	/* parallel RGB */
+#else
+&mxcfb3 {	/* LVDS */
+#endif
+	status = "disabled";
+};
+
+#if CONFIG_SOLO_LVDS
+&rgb {		/* parallel RGB */
+#else
+&ldb {		/* LVDS */
+#endif
+	status = "disabled";
+};
+
+&pxp {
+	status = "okay";
+};
--- /dev/null
+++ b/arch/arm/configs/lec-imx6_defconfig
@@ -0,0 +1,309 @@
+CONFIG_CROSS_COMPILE="arm-linux-gnueabihf-"
+CONFIG_LOCALVERSION="-imx6"
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_KERNEL_XZ=y
+CONFIG_SYSVIPC=y
+CONFIG_FHANDLE=y
+# CONFIG_USELIB is not set
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_LOG_BUF_SHIFT=18
+CONFIG_CGROUPS=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_RD_GZIP is not set
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_RD_LZ4 is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_EXPERT=y
+# CONFIG_SYSFS_SYSCALL is not set
+CONFIG_PERF_EVENTS=y
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_JUMP_LABEL=y
+CONFIG_CC_STACKPROTECTOR_REGULAR=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_ARCH_MXC=y
+CONFIG_SOC_IMX6Q=y
+# CONFIG_SWP_EMULATE is not set
+# CONFIG_ARM_ERRATA_643719 is not set
+CONFIG_PCI=y
+CONFIG_PCI_IMX6=y
+# CONFIG_PCIEAER is not set
+CONFIG_PCIEASPM_POWERSAVE=y
+CONFIG_SMP=y
+CONFIG_VMSPLIT_2G=y
+CONFIG_PREEMPT_VOLUNTARY=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_CMA=y
+CONFIG_CMDLINE="console=ttymxc0,115200 rootwait"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT=m
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_ARM_IMX6Q_CPUFREQ=y
+CONFIG_CPU_IDLE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_IPV6_SIT is not set
+CONFIG_CAN=y
+# CONFIG_CAN_GW is not set
+CONFIG_CAN_FLEXCAN=y
+# CONFIG_WIRELESS is not set
+# CONFIG_UEVENT_HELPER is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set
+# CONFIG_ALLOW_DEV_COREDUMP is not set
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=0
+CONFIG_CONNECTOR=y
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_EEPROM_AT24=m
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_SCAN_ASYNC=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+# CONFIG_ATA_VERBOSE_ERROR is not set
+# CONFIG_SATA_PMP is not set
+CONFIG_AHCI_IMX=y
+# CONFIG_ATA_SFF is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_ADAPTEC is not set
+# CONFIG_NET_VENDOR_AGERE is not set
+# CONFIG_NET_VENDOR_ALTEON is not set
+# CONFIG_NET_VENDOR_AMD is not set
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_VENDOR_ATHEROS is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_BROCADE is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_CISCO is not set
+# CONFIG_NET_VENDOR_DEC is not set
+# CONFIG_NET_VENDOR_DLINK is not set
+# CONFIG_NET_VENDOR_EMULEX is not set
+# CONFIG_NET_VENDOR_EXAR is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_HISILICON is not set
+# CONFIG_NET_VENDOR_HP is not set
+CONFIG_IGB=m
+# CONFIG_IGB_HWMON is not set
+# CONFIG_NET_VENDOR_I825XX is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MELLANOX is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_MYRI is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NVIDIA is not set
+# CONFIG_NET_VENDOR_OKI is not set
+# CONFIG_NET_PACKET_ENGINE is not set
+# CONFIG_NET_VENDOR_QLOGIC is not set
+# CONFIG_NET_VENDOR_QUALCOMM is not set
+# CONFIG_NET_VENDOR_REALTEK is not set
+# CONFIG_NET_VENDOR_RDC is not set
+# CONFIG_NET_VENDOR_ROCKER is not set
+# CONFIG_NET_VENDOR_SAMSUNG is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SILAN is not set
+# CONFIG_NET_VENDOR_SIS is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SUN is not set
+# CONFIG_NET_VENDOR_TEHUTI is not set
+# CONFIG_NET_VENDOR_TI is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_AT803X_PHY=y
+# CONFIG_USB_NET_DRIVERS is not set
+# CONFIG_WLAN is not set
+CONFIG_INPUT_MOUSEDEV=m
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_EVDEV=m
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=m
+# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+CONFIG_FSL_OTP=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_IMX=y
+CONFIG_SPI=y
+CONFIG_SPI_IMX=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_GPIO_PCA953X_IRQ=y
+CONFIG_GPIO_PCF857X=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_SYSCON_POWEROFF=y
+# CONFIG_MXC_MMA8451 is not set
+CONFIG_THERMAL=y
+CONFIG_CPU_THERMAL=y
+CONFIG_IMX_THERMAL=y
+CONFIG_DEVICE_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_IMX2_WDT=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_ANATOP=y
+CONFIG_REGULATOR_PFUZE100=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_VIDEO_MXC_OUTPUT=y
+CONFIG_VIDEO_MXC_CAPTURE=m
+CONFIG_MXC_CAMERA_OV5640=m
+CONFIG_MXC_CAMERA_OV5642=m
+CONFIG_MXC_CAMERA_OV5640_MIPI=m
+CONFIG_MXC_IPU_DEVICE_QUEUE_SDC=m
+CONFIG_VIDEO_MXC_IPU_OUTPUT=y
+CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_VIDEO_CODA=m
+# CONFIG_VGA_ARB is not set
+CONFIG_DRM=y
+CONFIG_DRM_VGEM=m
+CONFIG_DRM_VIVANTE=y
+CONFIG_FB=y
+CONFIG_FB_MXC_SYNC_PANEL=y
+CONFIG_FB_MXC_LDB=y
+CONFIG_FB_MXC_HDMI=y
+CONFIG_FB_MXC_DCIC=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_PCI is not set
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_FSL_ASRC=y
+CONFIG_SND_IMX_SOC=y
+CONFIG_SND_SOC_EUKREA_TLV320=m
+CONFIG_SND_SOC_IMX_SGTL5000=m
+CONFIG_SND_SOC_IMX_SPDIF=y
+CONFIG_SND_SOC_IMX_HDMI=y
+CONFIG_HID_MULTITOUCH=m
+CONFIG_USB=y
+CONFIG_USB_OTG=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_ACM=m
+CONFIG_USB_STORAGE=y
+CONFIG_USB_CHIPIDEA=y
+CONFIG_USB_CHIPIDEA_UDC=y
+CONFIG_USB_CHIPIDEA_HOST=y
+CONFIG_USB_MXS_PHY=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_MMC=y
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=y
+CONFIG_MXC_IPU=y
+CONFIG_MXC_GPU_VIV=y
+CONFIG_MXC_MIPI_CSI2=y
+CONFIG_MXC_HDMI_CEC=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_SYSTOHC is not set
+CONFIG_RTC_DRV_PCF8563=y
+CONFIG_RTC_DRV_SNVS=m
+CONFIG_DMADEVICES=y
+CONFIG_MXC_PXP_V2=y
+# CONFIG_MX3_IPU is not set
+CONFIG_IMX_SDMA=y
+CONFIG_MXS_DMA=y
+CONFIG_STAGING=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_PWM=y
+CONFIG_PWM_IMX=y
+# CONFIG_RESET_GPIO is not set
+CONFIG_EXT4_FS=y
+CONFIG_FANOTIFY=y
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_VFAT_FS=y
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+# CONFIG_JFFS2_FS_WRITEBUFFER is not set
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V2 is not set
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_UTF8=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_RCU_CPU_STALL_INFO is not set
+# CONFIG_FTRACE is not set
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_DEV_FSL_CAAM=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SM=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=y
+# CONFIG_XZ_DEC_X86 is not set
+# CONFIG_XZ_DEC_POWERPC is not set
+# CONFIG_XZ_DEC_IA64 is not set
+# CONFIG_XZ_DEC_SPARC is not set
_
--
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] iio: adc: add driver for the ti-adc084s021 chip
From: Peter Meerwald-Stadler @ 2017-04-21 20:19 UTC (permalink / raw)
  To: Mårten Lindahl
  Cc: jic23-DgEjT+Ai2ygdnm+yROfE0A, lars-Qo5EllUWu/uELgA04lAiVw,
	linux-iio-u79uwXL29TY76Z2rM5mHXA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	mark.rutland-5wv7dgnIgG8, devicetree-u79uwXL29TY76Z2rM5mHXA,
	Mårten Lindahl
In-Reply-To: <1492786703-5149-1-git-send-email-marten.lindahl-VrBV9hrLPhE@public.gmane.org>

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


> From: Mårten Lindahl <martenli-VrBV9hrLPhE@public.gmane.org>

comments below
 
> This adds support for the Texas Instruments ADC084S021 ADC chip.
> 
> Signed-off-by: Mårten Lindahl <martenli-VrBV9hrLPhE@public.gmane.org>
> ---
>  .../devicetree/bindings/iio/adc/ti-adc084s021.txt  |  25 ++
>  drivers/iio/adc/Kconfig                            |  12 +
>  drivers/iio/adc/Makefile                           |   1 +
>  drivers/iio/adc/ti-adc084s021.c                    | 342 +++++++++++++++++++++
>  4 files changed, 380 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/iio/adc/ti-adc084s021.txt
>  create mode 100644 drivers/iio/adc/ti-adc084s021.c
> 
> diff --git a/Documentation/devicetree/bindings/iio/adc/ti-adc084s021.txt b/Documentation/devicetree/bindings/iio/adc/ti-adc084s021.txt
> new file mode 100644
> index 0000000..921eb46
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/iio/adc/ti-adc084s021.txt
> @@ -0,0 +1,25 @@
> +* Texas Instruments' ADC084S021
> +
> +Required properties:
> + - compatible        : Must be "ti,adc084s021"
> + - reg               : SPI chip select number for the device
> + - vref-supply       : The regulator supply for ADC reference voltage
> + - spi-max-frequency : Definition as per Documentation/devicetree/bindings/spi/spi-bus.txt
> +
> +Optional properties:
> + - spi-cpol          : SPI inverse clock polarity, as per spi-bus bindings
> + - spi-cpha          : SPI shifted clock phase (CPHA), as per spi-bus bindings
> + - spi-cs-high       : SPI chip select active high, as per spi-bus bindings
> +
> +
> +Example:
> +adc@0 {
> +	compatible = "ti,adc084s021";
> +	reg = <0>;
> +	vref-supply = <&adc_vref>;
> +	spi-cpol;
> +	spi-cpha;
> +	spi-cs-high;
> +	spi-max-frequency = <16000000>;
> +	pl022,com-mode = <0x2>; /* DMA */

what is this?

> +};
> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> index dedae7a..13141e5 100644
> --- a/drivers/iio/adc/Kconfig
> +++ b/drivers/iio/adc/Kconfig
> @@ -560,6 +560,18 @@ config TI_ADC0832
>  	  This driver can also be built as a module. If so, the module will be
>  	  called ti-adc0832.
>  
> +config TI_ADC084S021
> +	tristate "Texas Instruments ADC084S021"
> +	depends on SPI
> +	select IIO_BUFFER
> +	select IIO_TRIGGERED_BUFFER
> +	help
> +	  If you say yes here you get support for Texas Instruments ADC084S021
> +	  chips.
> +
> +	  This driver can also be built as a module. If so, the module will be
> +	  called ti-adc084s021.
> +
>  config TI_ADC12138
>  	tristate "Texas Instruments ADC12130/ADC12132/ADC12138"
>  	depends on SPI
> diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
> index d001262..b1a6158 100644
> --- a/drivers/iio/adc/Makefile
> +++ b/drivers/iio/adc/Makefile
> @@ -51,6 +51,7 @@ obj-$(CONFIG_STM32_ADC_CORE) += stm32-adc-core.o
>  obj-$(CONFIG_STM32_ADC) += stm32-adc.o
>  obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
>  obj-$(CONFIG_TI_ADC0832) += ti-adc0832.o
> +obj-$(CONFIG_TI_ADC084S021) += ti-adc084s021.o
>  obj-$(CONFIG_TI_ADC12138) += ti-adc12138.o
>  obj-$(CONFIG_TI_ADC128S052) += ti-adc128s052.o
>  obj-$(CONFIG_TI_ADC161S626) += ti-adc161s626.o
> diff --git a/drivers/iio/adc/ti-adc084s021.c b/drivers/iio/adc/ti-adc084s021.c
> new file mode 100644
> index 0000000..4f33b91
> --- /dev/null
> +++ b/drivers/iio/adc/ti-adc084s021.c
> @@ -0,0 +1,342 @@
> +/**
> + * Copyright (C) 2017 Axis Communications AB
> + *
> + * Driver for Texas Instruments' ADC084S021 ADC chip.
> + * Datasheets can be found here:
> + * http://www.ti.com/lit/ds/symlink/adc084s021.pdf
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/err.h>
> +#include <linux/spi/spi.h>
> +#include <linux/module.h>
> +#include <linux/interrupt.h>
> +#include <linux/iio/iio.h>
> +#include <linux/iio/buffer.h>
> +#include <linux/iio/events.h>
> +#include <linux/iio/triggered_buffer.h>
> +#include <linux/iio/trigger_consumer.h>
> +#include <linux/regulator/consumer.h>
> +
> +#define MODULE_NAME     "adc084s021"
> +#define DRIVER_VERSION  "1.0"

is only used once at the very end...

> +#define ADC_RESOLUTION  8
> +#define ADC_N_CHANNELS  4

we want a consistent prefix, such as ADC084S021_

> +
> +struct adc084s021_configuration {
> +	const struct iio_chan_spec *channels;
> +	u8 num_channels;

no need for u8, perhaps unsigned?

> +};
> +
> +struct adc084s021 {
> +	struct spi_device *spi;
> +	struct spi_message message;
> +	struct spi_transfer spi_trans[2];
> +	struct regulator *reg;
> +	struct mutex lock;
> +	/*
> +	 * DMA (thus cache coherency maintenance) requires the
> +	 * transfer buffers to live in their own cache lines.
> +	 */
> +	union {
> +		u8 tx_buf[2];
> +		u8 rx_buf[2];
> +	} ____cacheline_aligned;
> +	u8 cur_adc_values[ADC_N_CHANNELS];
> +};
> +
> +/**
> + * Event triggered when value changes on a channel
> + */
> +static const struct iio_event_spec adc084s021_event = {
> +	.type = IIO_EV_TYPE_CHANGE,
> +	.dir = IIO_EV_DIR_NONE,
> +};
> +
> +/**
> + * Channel specification
> + */
> +#define ADC084S021_VOLTAGE_CHANNEL(num)                  \
> +	{                                                      \
> +		.type = IIO_VOLTAGE,                                 \
> +		.channel = (num),                                    \
> +		.address = (num << 3),                               \

parenthesis should be around (num)

> +		.indexed = 1,                                        \
> +		.scan_index = num,                                   \

parenthesis?

> +		.scan_type = {                                       \
> +			.sign = 'u',                                       \
> +			.realbits = 8,                                     \
> +			.storagebits = 32,                                 \
> +			.shift = 24 - ((num << 3)),                        \

no need for (( )) around the expression, parenthesis should be around num

the shift doesn't make sense, you are shifting in 

adc084s021_adc_conversion() already and return just 8 bits (so storagebits 
should be 8)?

you could/should use realbits = 8, storagebits = 16, shift = 4 and 
endianness = IIO_BE if I read Figure 1 of the datasheet correctly

> +		},                                                   \
> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),        \

likely this is missing _SCALE
IIO expects data to be returned in millivolt, see 
Documentation/ABI/testing/sysfs-bus-iio

> +		.event_spec = &adc084s021_event,                     \
> +		.num_event_specs = 1,                                \

ARRAY_SIZE(&adc084s021_event) to be extensible?

> +	}
> +
> +static const struct iio_chan_spec adc084s021_channels[] = {
> +	ADC084S021_VOLTAGE_CHANNEL(0),
> +	ADC084S021_VOLTAGE_CHANNEL(1),
> +	ADC084S021_VOLTAGE_CHANNEL(2),
> +	ADC084S021_VOLTAGE_CHANNEL(3),
> +	IIO_CHAN_SOFT_TIMESTAMP(4),
> +};
> +
> +static const struct adc084s021_configuration adc084s021_config[] = {
> +	{ adc084s021_channels, ARRAY_SIZE(adc084s021_channels) },

for just one configuration, this is not really needed; so you plan/forsee 
more chips being added soonish?

> +};
> +
> +/**
> + * Read an ADC channel and return its value.
> + *
> + * @adc: The ADC SPI data.
> + * @channel: The IIO channel data structure.
> + */
> +static int adc084s021_adc_conversion(struct adc084s021 *adc,
> +			   struct iio_chan_spec const *channel)
> +{
> +	u16 value;

value should be u8, but is not really needed

> +	int ret;
> +
> +	mutex_lock(&adc->lock);
> +	adc->tx_buf[0] = channel->address;
> +
> +	/* Do the transfer */
> +	ret = spi_sync(adc->spi, &adc->message);
> +

no newline here please

> +	if (ret < 0) {
> +		mutex_unlock(&adc->lock);
> +		return ret;
> +	}
> +
> +	value = (adc->rx_buf[0] << 4) | (adc->rx_buf[1] >> 4);

I recommend using __be16 for rx_buf and
ret = (be16_to_cpu(adc->rx_buf) >> 4) & 0xff;

> +	mutex_unlock(&adc->lock);
> +
> +	dev_dbg(&adc->spi->dev, "value 0x%02X on channel %d\n",
> +			     value, channel->channel);
> +	return value;
> +}
> +
> +/**
> + * Make a readout of requested IIO channel info.

no need to document this, it is found in every IIO driver...

> + *
> + * @indio_dev: The industrial I/O device.
> + * @channel: The IIO channel data structure.
> + * @val: First element of value (integer).
> + * @val2: Second element of value (fractional).
> + * @mask: The info_mask to read.
> + */
> +static int adc084s021_read_raw(struct iio_dev *indio_dev,
> +			   struct iio_chan_spec const *channel, int *val,
> +			   int *val2, long mask)
> +{
> +	struct adc084s021 *adc = iio_priv(indio_dev);
> +	int retval;

how about using ret everywhere?

> +
> +	switch (mask) {
> +	case IIO_CHAN_INFO_RAW:

probably want iio_device_claim_direct_mode() so to not interfere with 
buffered access

> +		retval = adc084s021_adc_conversion(adc, channel);
> +		if (retval < 0)
> +			return retval;
> +
> +		*val = retval;
> +		return IIO_VAL_INT;
> +
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +/**
> + * Read enabled ADC channels and push data to the buffer.
> + *
> + * @irq: The interrupt number (not used).
> + * @pollfunc: Pointer to the poll func.
> + */
> +static irqreturn_t adc084s021_trigger_handler(int irq, void *pollfunc)
> +{
> +	struct iio_poll_func *pf = pollfunc;
> +	struct iio_dev *indio_dev = pf->indio_dev;
> +	struct adc084s021 *adc = iio_priv(indio_dev);
> +	u8 *data;
> +	s64 timestamp;
> +	int value, scan_index;
> +
> +	data = kzalloc(indio_dev->scan_bytes, GFP_KERNEL);

pre-allocate buffer with maximum size statically; allocation is 
potentially expensive; don't forget space for the timestamp and padding...

> +	if (!data) {
> +		iio_trigger_notify_done(indio_dev->trig);
> +		return IRQ_NONE;
> +	}
> +
> +	timestamp = iio_get_time_ns(indio_dev);
> +
> +	for_each_set_bit(scan_index, indio_dev->active_scan_mask,
> +			 indio_dev->masklength) {
> +		const struct iio_chan_spec *channel =
> +			&indio_dev->channels[scan_index];
> +		value = adc084s021_adc_conversion(adc, channel);

lock is taken and released for each channel, probably want to do it just 
once?

> +		data[scan_index] = value;
> +
> +		/*
> +		 * Compare read data to previous read. If it differs send
> +		 * event notification for affected channel.
> +		 */
> +		if (adc->cur_adc_values[scan_index] != (u8)value) {

cur_adc_values is not initialized (probably set to 0);
so on first read, should the notification be sent?

> +			adc->cur_adc_values[scan_index] = (u8)value;
> +			iio_push_event(indio_dev,
> +						  IIO_EVENT_CODE(IIO_VOLTAGE, 0,
> +						    IIO_NO_MOD, IIO_EV_DIR_NONE,
> +						    IIO_EV_TYPE_CHANGE,
> +						    channel->channel, 0, 0),
> +						  timestamp);
> +			dev_dbg(&indio_dev->dev,
> +					    "new value on ch%d: 0x%02X (ts %llu)\n",
> +					    channel->channel, value, timestamp);
> +		}
> +	}
> +
> +	iio_push_to_buffers_with_timestamp(indio_dev, data, timestamp);
> +	iio_trigger_notify_done(indio_dev->trig);
> +	kfree(data);
> +	return IRQ_HANDLED;
> +}
> +
> +static const struct iio_info adc084s021_info = {
> +	.read_raw = adc084s021_read_raw,
> +	.driver_module = THIS_MODULE,
> +};
> +
> +/**
> + * Create and register ADC IIO device for SPI.

comment is rather pointless

> + */
> +static int adc084s021_probe(struct spi_device *spi)
> +{
> +	struct iio_dev *indio_dev;
> +	struct adc084s021 *adc;
> +	int config = spi_get_device_id(spi)->driver_data;
> +	int retval;

ret maybe

> +
> +	/* Allocate an Industrial I/O device */

obviously...

> +	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc));
> +	if (!indio_dev) {
> +		dev_err(&spi->dev, "Failed to allocate IIO device\n");
> +		return -ENOMEM;
> +	}
> +
> +	adc = iio_priv(indio_dev);
> +	adc->spi = spi;
> +	spi->bits_per_word = ADC_RESOLUTION;
> +
> +	/* Update the SPI device with config and connect the iio dev */
> +	retval = spi_setup(spi);
> +	if (retval) {
> +		dev_err(&spi->dev, "Failed to update SPI device\n");
> +		return retval;
> +	}
> +	spi_set_drvdata(spi, indio_dev);
> +
> +	/* Initiate the Industrial I/O device */
> +	indio_dev->dev.parent = &spi->dev;
> +	indio_dev->dev.of_node = spi->dev.of_node;
> +	indio_dev->name = spi_get_device_id(spi)->name;
> +	indio_dev->modes = INDIO_DIRECT_MODE;
> +	indio_dev->info = &adc084s021_info;
> +	indio_dev->channels = adc084s021_config[config].channels;
> +	indio_dev->num_channels = adc084s021_config[config].num_channels;

could do it directly as long there is just one configuration

> +
> +	/* Create SPI transfer for channel reads */
> +	adc->spi_trans[0].tx_buf = &adc->tx_buf[0];
> +	adc->spi_trans[0].len = 2;
> +	adc->spi_trans[0].speed_hz = spi->max_speed_hz;
> +	adc->spi_trans[0].bits_per_word = spi->bits_per_word;
> +	adc->spi_trans[1].rx_buf = &adc->rx_buf[0];
> +	adc->spi_trans[1].len = 2;
> +	adc->spi_trans[1].speed_hz = spi->max_speed_hz;
> +	adc->spi_trans[1].bits_per_word = spi->bits_per_word;
> +
> +	/* Setup SPI message for channel reads */
> +	spi_message_init(&adc->message);
> +	spi_message_add_tail(&adc->spi_trans[0], &adc->message);
> +	spi_message_add_tail(&adc->spi_trans[1], &adc->message);
> +
> +	adc->reg = devm_regulator_get(&spi->dev, "vref");
> +	if (IS_ERR(adc->reg))
> +		return PTR_ERR(adc->reg);
> +
> +	retval = regulator_enable(adc->reg);
> +	if (retval < 0)
> +		return retval;
> +
> +	mutex_init(&adc->lock);
> +
> +	/* Setup triggered buffer with pollfunction */
> +	retval = iio_triggered_buffer_setup(indio_dev, NULL,

devm_()

> +					    adc084s021_trigger_handler, NULL);
> +	if (retval) {
> +		dev_err(&spi->dev, "Failed to setup triggered buffer\n");
> +		goto buffer_setup_failed;
> +	}
> +
> +	retval = iio_device_register(indio_dev);
> +	if (retval) {
> +		dev_err(&spi->dev, "Failed to register IIO device\n");
> +		goto device_register_failed;
> +	}
> +
> +	dev_info(&spi->dev, "probed!\n");

no logging please, just outputs clutter

> +	return 0;
> +
> +device_register_failed:
> +	iio_triggered_buffer_cleanup(indio_dev);
> +buffer_setup_failed:
> +	regulator_disable(adc->reg);
> +	return retval;
> +}
> +
> +/**
> + * Unregister ADC IIO device for SPI.
> + */
> +static int adc084s021_remove(struct spi_device *spi)
> +{
> +	struct iio_dev *indio_dev = spi_get_drvdata(spi);
> +	struct adc084s021 *adc = iio_priv(indio_dev);
> +
> +	iio_device_unregister(indio_dev);
> +	iio_triggered_buffer_cleanup(indio_dev);
> +	regulator_disable(adc->reg);
> +	return 0;
> +}
> +
> +static const struct of_device_id adc084s021_of_match[] = {
> +	{ .compatible = "ti,adc084s021", },
> +	{},
> +};
> +
> +MODULE_DEVICE_TABLE(of, adc084s021_of_match);
> +
> +static const struct spi_device_id adc084s021_id[] = {
> +	{ MODULE_NAME, 0},
> +	{}
> +};
> +
> +MODULE_DEVICE_TABLE(spi, adc084s021_id);
> +
> +static struct spi_driver adc084s021_driver = {
> +	.driver = {
> +		.name = MODULE_NAME,
> +		.of_match_table = of_match_ptr(adc084s021_of_match),
> +	},
> +	.probe = adc084s021_probe,
> +	.remove = adc084s021_remove,
> +	.id_table = adc084s021_id,
> +};
> +
> +module_spi_driver(adc084s021_driver);
> +
> +MODULE_AUTHOR("Mårten Lindahl <martenli-VrBV9hrLPhE@public.gmane.org>");
> +MODULE_DESCRIPTION("Texas Instruments ADC084S021");
> +MODULE_LICENSE("GPL v2");
> +MODULE_VERSION(DRIVER_VERSION);
> 

-- 

Peter Meerwald-Stadler
Mobile: +43 664 24 44 418

^ permalink raw reply

* [PATCH 1/5 v3] usb: host: add DT bindings for faraday fotg2
From: Linus Walleij @ 2017-04-21 20:40 UTC (permalink / raw)
  To: Hans Ulli Kroll, Florian Fainelli,
	linux-usb-u79uwXL29TY76Z2rM5mHXA, Greg Kroah-Hartman
  Cc: Janos Laube, Paulius Zaleckas,
	openwrt-devel-p3rKhJxN3npAfugRpC6u6w,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Linus Walleij

From: Hans Ulli Kroll <ulli.kroll-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>

This adds device tree bindings for the Faraday FOTG2
dual-mode host controller.

Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Signed-off-by: Hans Ulli Kroll <ulli.kroll-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
Signed-off-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
ChangeLog v1->v3:
- Change compatible to "faraday,fotg210" as the name of the
  hardware block.
- Add an elaborate SoC-specific compatible string for the
  Cortina Systems Gemini so that SoC-specific features can
  be enabled.
- Add cortina,gemini-mini-b to indicate a Gemini PHY with
  a Mini-B adapter connected.
- Indicated that the Gemini version can handle "wakeup-source".
- Add optional IP block clock.
---
 .../devicetree/bindings/usb/faraday,fotg210.txt    | 35 ++++++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/faraday,fotg210.txt

diff --git a/Documentation/devicetree/bindings/usb/faraday,fotg210.txt b/Documentation/devicetree/bindings/usb/faraday,fotg210.txt
new file mode 100644
index 000000000000..cf06808303e2
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/faraday,fotg210.txt
@@ -0,0 +1,35 @@
+Faraday FOTG Host controller
+
+This OTG-capable USB host controller is found in Cortina Systems
+Gemini and other SoC products.
+
+Required properties:
+- compatible: should be one of:
+  "faraday,fotg210"
+  "cortina,gemini-usb", "faraday,fotg210"
+- reg: should contain one register range i.e. start and length
+- interrupts: description of the interrupt line
+
+Optional properties:
+- clocks: should contain the IP block clock
+- clock-names: should be "PCLK" for the IP block clock
+
+Required properties for "cortina,gemini-usb" compatible:
+- syscon: a phandle to the system controller to access PHY registers
+
+Optional properties for "cortina,gemini-usb" compatible:
+- cortina,gemini-mini-b: boolean property that indicates that a Mini-B
+  OTH connector is in use
+- wakeup-source: see power/wakeup-source.txt
+
+Example for Gemini:
+
+usb@68000000 {
+	compatible = "cortina,gemini-usb", "faraday,fotg210";
+	reg = <0x68000000 0x1000>;
+	interrupts = <10 IRQ_TYPE_LEVEL_HIGH>;
+	clocks = <&cc 12>;
+	clock-names = "PCLK";
+	syscon = <&syscon>;
+	wakeup-source;
+};
-- 
2.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" 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 2/3] drm/vc4: Don't try to initialize FBDEV if we're only bound to V3D.
From: Eric Anholt @ 2017-04-21 22:53 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: dri-devel, Rob Herring, Mark Rutland, devicetree@vger.kernel.org,
	Linux Kernel Mailing List
In-Reply-To: <CAKMK7uHBE1Qtjr2dM3U9edEfZ0mXVEjcw+hs8mF9ZkRP4Vcm=A@mail.gmail.com>

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

Daniel Vetter <daniel-/w4YWyX8dFk@public.gmane.org> writes:

> On Wed, Apr 19, 2017 at 7:55 PM, Eric Anholt <eric-WhKQ6XTQaPysTnJN9+BGXg@public.gmane.org> wrote:
>> Daniel Vetter <daniel-/w4YWyX8dFk@public.gmane.org> writes:
>>> On Tue, Apr 18, 2017 at 9:11 PM, Eric Anholt <eric-WhKQ6XTQaPysTnJN9+BGXg@public.gmane.org> wrote:
>>>> The FBDEV initialization would throw an error in dmesg, when we just
>>>> want to silently not initialize fbdev on a V3D-only VC4 instance.
>>>>
>>>> Signed-off-by: Eric Anholt <eric-WhKQ6XTQaPysTnJN9+BGXg@public.gmane.org>
>>>
>>> Hm, this shouldn't be an error really, you might want to hotplug more
>>> connectors later on. What exactly complains?
>>
>> drm_fb_helper_init() throws an error if the passed in connector count is
>> 0, so drm_fb_cma_helper() printks an error.
>
> Oh, _that_ thing. The error in there is correct, but (almost) everyone
> gets this parameter wrong. This isn't the max number of connectors the
> fb helper will light up, but just the max number of connectors _per_
> crtc when driving in hw clone mode. There's two problems with that:
> - fb helpers don't support hw clone mode, we select 1:1 crtcs for each
> active connector
> - I mentioned that everyone gets this wrong?
>
> If you're moderately bored it'd be great to nuke the max_connector
> argument from drm_fb_helper_init, and hard-code it to 1 (with a big
> comment explaining that this needs to be changed, probably with
> dynamic reallocation, once someone gets around to implementing hw
> clone mode).
>
> If you're less bored, just hardcode this to 1 in vc4 and done. Plus a
> TODO.rst entry would be great in that case.

If I'm driving a GPU with no display subsystem at all, it seems like I
shouldn't initialize fbdev for it, right?

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

^ permalink raw reply

* [PATCH 0/4] RTL8211E-specified hacks
From: Icenowy Zheng @ 2017-04-21 23:24 UTC (permalink / raw)
  To: Andrew Lunn, Florian Fainelli, Rob Herring
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng

Some Pine64 boards are reported to have broken RTL8211E PHYs, which will fail
to work at 1000BASE-T mode if not workarounded.

The workaround is retrieved from Pine64, and is said to be from Realtek
engineer. It's undocumented but effective. (Tested on my Pine64 with GbE
broken)

The first patch is a small tweak for Realtek PHY driver, which removed the
"F" in page select register name, as RTL8211E also uses the same register
as page select (although with some different difinition).

The second patch adds a binding for the PHY, specified for this hack.

The third patch is the real driver part of this hack, which contains
some magic numbers from Pine64/Realtek.

The fourth patch is for reference only and should not be merged -- to
use it you will need sun8i-emac or dwmac-sun8i patchset applied.

Icenowy Zheng (4):
  net: phy: realtek: change macro name for page select register
  dt-bindings: add binding for RTL8211E Ethernet PHY
  net: phy: realtek: add disable RX delay hack for RTL8211E
  [DO NOT MERGE] arm64: allwinner: a64: enable RTL8211E PHY workaround

 .../devicetree/bindings/net/realtek,rtl8211e.txt   | 22 ++++++++++
 .../boot/dts/allwinner/sun50i-a64-pine64-plus.dts  |  4 ++
 drivers/net/phy/realtek.c                          | 48 +++++++++++++++++++---
 3 files changed, 69 insertions(+), 5 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/realtek,rtl8211e.txt

-- 
2.12.2

--
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 1/4] net: phy: realtek: change macro name for page select register
From: Icenowy Zheng @ 2017-04-21 23:24 UTC (permalink / raw)
  To: Andrew Lunn, Florian Fainelli, Rob Herring
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
In-Reply-To: <20170421232436.10924-1-icenowy-h8G6r0blFSE@public.gmane.org>

From: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>

The page select register also exists on RTL8211E PHY (although it
behaves slightly differently).

Change the register macro name to remove the F.

Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
---
 drivers/net/phy/realtek.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index 9cbe645e3d89..d820d00addf6 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -22,11 +22,13 @@
 #define RTL821x_INER		0x12
 #define RTL821x_INER_INIT	0x6400
 #define RTL821x_INSR		0x13
+
+#define RTL8211_PAGE_SELECT	0x1f
+
 #define RTL8211E_INER_LINK_STATUS 0x400
 
 #define RTL8211F_INER_LINK_STATUS 0x0010
 #define RTL8211F_INSR		0x1d
-#define RTL8211F_PAGE_SELECT	0x1f
 #define RTL8211F_TX_DELAY	0x100
 
 MODULE_DESCRIPTION("Realtek PHY driver");
@@ -46,10 +48,10 @@ static int rtl8211f_ack_interrupt(struct phy_device *phydev)
 {
 	int err;
 
-	phy_write(phydev, RTL8211F_PAGE_SELECT, 0xa43);
+	phy_write(phydev, RTL8211_PAGE_SELECT, 0xa43);
 	err = phy_read(phydev, RTL8211F_INSR);
 	/* restore to default page 0 */
-	phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0);
+	phy_write(phydev, RTL8211_PAGE_SELECT, 0x0);
 
 	return (err < 0) ? err : 0;
 }
@@ -102,7 +104,7 @@ static int rtl8211f_config_init(struct phy_device *phydev)
 	if (ret < 0)
 		return ret;
 
-	phy_write(phydev, RTL8211F_PAGE_SELECT, 0xd08);
+	phy_write(phydev, RTL8211_PAGE_SELECT, 0xd08);
 	reg = phy_read(phydev, 0x11);
 
 	/* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */
@@ -114,7 +116,7 @@ static int rtl8211f_config_init(struct phy_device *phydev)
 
 	phy_write(phydev, 0x11, reg);
 	/* restore to default page 0 */
-	phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0);
+	phy_write(phydev, RTL8211_PAGE_SELECT, 0x0);
 
 	return 0;
 }
-- 
2.12.2

^ permalink raw reply related

* [PATCH 2/4] dt-bindings: add binding for RTL8211E Ethernet PHY
From: Icenowy Zheng @ 2017-04-21 23:24 UTC (permalink / raw)
  To: Andrew Lunn, Florian Fainelli, Rob Herring
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
In-Reply-To: <20170421232436.10924-1-icenowy-h8G6r0blFSE@public.gmane.org>

From: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>

Some RTL8211E Ethernet PHY have an issue that needs a workaround
indicated with device tree.

Add the binding for a property that indicates this workaround.

Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
---
 .../devicetree/bindings/net/realtek,rtl8211e.txt   | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/realtek,rtl8211e.txt

diff --git a/Documentation/devicetree/bindings/net/realtek,rtl8211e.txt b/Documentation/devicetree/bindings/net/realtek,rtl8211e.txt
new file mode 100644
index 000000000000..c1913301bfe8
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/realtek,rtl8211e.txt
@@ -0,0 +1,22 @@
+Realtek RTL8211E Ethernet PHY
+
+One batch of RTL8211E is slight broken, that needs some special (and
+full of magic numbers) tweaking in order to make GbE to operate properly.
+The only well-known board that used the broken batch is Pine64+.
+Configure it through an Ethernet OF device node.
+
+Optional properties:
+
+- realtek,disable-rx-delay:
+  If set, RX delay will be completely disabled (according to Realtek). This
+  will affect the performance on non-broken boards.
+  default: do not disable RX delay.
+
+Examples:
+Pine64+ with broken RTL8211E:
+&mdio {
+	ext_phy: ethernet-phy@0 {
+		reg = <0>;
+		realtek,disable-rx-delay;
+	};
+};
-- 
2.12.2

^ permalink raw reply related

* [PATCH 3/4] net: phy: realtek: add disable RX delay hack for RTL8211E
From: Icenowy Zheng @ 2017-04-21 23:24 UTC (permalink / raw)
  To: Andrew Lunn, Florian Fainelli, Rob Herring
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
In-Reply-To: <20170421232436.10924-1-icenowy-h8G6r0blFSE@public.gmane.org>

From: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>

Some RTL8211E chips have broken GbE function, which needs a hack to
fix. It's said that this fix will affect the performance on not-buggy
PHYs, so it should only be enabled on boards with the broken PHY.
Currently only some Pine64+ boards are known to have this issue.

This hack is said to disable RX relay for RTL8211E according to Realtek.

Enable this hack when a certain device tree property is set.

As this hack is not documented on the datasheet at all, it contains
magic numbers, and could not be revealed. These magic numbers are
received from Realtek via Pine64.

Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
---
 drivers/net/phy/realtek.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index d820d00addf6..880022160cd2 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -13,6 +13,7 @@
  * option) any later version.
  *
  */
+#include <linux/of.h>
 #include <linux/phy.h>
 #include <linux/module.h>
 
@@ -26,6 +27,8 @@
 #define RTL8211_PAGE_SELECT	0x1f
 
 #define RTL8211E_INER_LINK_STATUS 0x400
+#define RTL8211E_EXT_PAGE_SELECT 0x1e
+#define RTL8211E_EXT_PAGE	0x7
 
 #define RTL8211F_INER_LINK_STATUS 0x0010
 #define RTL8211F_INSR		0x1d
@@ -121,6 +124,38 @@ static int rtl8211f_config_init(struct phy_device *phydev)
 	return 0;
 }
 
+static int rtl8211e_config_init(struct phy_device *phydev)
+{
+	struct device *dev = &phydev->mdio.dev;
+	struct device_node *of_node = dev->of_node;
+	int ret;
+
+	ret = genphy_config_init(phydev);
+	if (ret < 0)
+		return ret;
+
+	if (of_node &&
+	    of_property_read_bool(of_node, "realtek,disable-rx-delay")) {
+		/* All these magic numbers are retrieved from Pine64, and
+		 * they're said to be originated from Realtek.
+		 *
+		 * The datasheet of RTL8211E didn't cover this ext page.
+		 *
+		 * Select extension page 0xa4 here.
+		 */
+		phy_write(phydev, RTL8211_PAGE_SELECT, RTL8211E_EXT_PAGE)
+		phy_write(phydev, RTL8211E_EXT_PAGE_SELECT, 0xa4);
+
+		/* Write the magic number */
+		phy_write(phydev, 0x1c, 0xb591);
+
+		/* Restore to default page 0 */
+		phy_write(phydev, RTL8211_PAGE_SELECT, 0);
+	}
+
+	return 0;
+}
+
 static struct phy_driver realtek_drvs[] = {
 	{
 		.phy_id         = 0x00008201,
@@ -159,6 +194,7 @@ static struct phy_driver realtek_drvs[] = {
 		.features	= PHY_GBIT_FEATURES,
 		.flags		= PHY_HAS_INTERRUPT,
 		.config_aneg	= &genphy_config_aneg,
+		.config_init	= rtl8211e_config_init,
 		.read_status	= &genphy_read_status,
 		.ack_interrupt	= &rtl821x_ack_interrupt,
 		.config_intr	= &rtl8211e_config_intr,
-- 
2.12.2

^ permalink raw reply related

* [PATCH 4/4] [DO NOT MERGE] arm64: allwinner: a64: enable RTL8211E PHY workaround
From: Icenowy Zheng @ 2017-04-21 23:24 UTC (permalink / raw)
  To: Andrew Lunn, Florian Fainelli, Rob Herring
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
In-Reply-To: <20170421232436.10924-1-icenowy-h8G6r0blFSE@public.gmane.org>

From: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>

Some Pine64+ boards are said to have broken RTL8211E PHY.

Enable the workaround in Pine64+ device tree file.

Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
---
 arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts
index 790d14daaa6a..1f59ee4f8b45 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts
@@ -48,3 +48,7 @@
 
 	/* TODO: Camera, Ethernet PHY, touchscreen, etc. */
 };
+
+&ext_phy {
+	realtek,disable-rx-delay;
+};
-- 
2.12.2

^ permalink raw reply related

* Re: [PATCH v13 03/10] mux: minimal mux subsystem and gpio-based mux controller
From: Peter Rosin @ 2017-04-21 23:28 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-kernel, Wolfram Sang, Rob Herring, Mark Rutland,
	Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald-Stadler, Jonathan Corbet, linux-i2c, devicetree,
	linux-iio, linux-doc, Andrew Morton, Colin Ian King,
	Paul Gortmaker, Philipp Zabel, kernel
In-Reply-To: <0f605429-afa2-2818-96d5-5da0bad122d6@axentia.se>

On 2017-04-20 23:53, Peter Rosin wrote:
> On 2017-04-18 23:53, Peter Rosin wrote:
>> On 2017-04-18 13:44, Greg Kroah-Hartman wrote:
>>> On Tue, Apr 18, 2017 at 12:59:50PM +0200, Peter Rosin wrote:
>>>> On 2017-04-18 10:51, Greg Kroah-Hartman wrote:
>>>>> On Thu, Apr 13, 2017 at 06:43:07PM +0200, Peter Rosin wrote:
> 
> *snip*
> 
>>>>>> +	if (mux->idle_state != MUX_IDLE_AS_IS &&
>>>>>> +	    mux->idle_state != mux->cached_state)
>>>>>> +		ret = mux_control_set(mux, mux->idle_state);
>>>>>> +
>>>>>> +	up_read(&mux->lock);
>>>>>
>>>>> You require a lock to be held for a "global" function?  Without
>>>>> documentation?  Or even a sparse marking?  That's asking for trouble...
>>>>
>>>> Documentation I can handle, but where should I look to understand how I
>>>> should add sparse markings?
>>>
>>> Run sparse on the code and see what it says :)
>>
>> Will do.
> 
> I just did, and even went through the trouble of getting the bleeding
> edge sparse from the git repo when sparse 0.5.0 came up empty, but it's
> all silence for me. So, how do I add sparse markings?

I looked some more into this, and the markings I find that seem related
are __acquire() and __release(). But neither mutex_lock() nor up_read()
has markings like that, so adding them when using those kinds of locks
in an imbalanced way seems like a sure way of *getting* sparse messages
about context imbalance...

So, either that, or you are talking about __must_check markings?

I feel like I'm missing something, please advise further.

Cheers,
peda


^ permalink raw reply

* Re: [PATCH 2/3] usb: add DT bindings for farady fotg2 host controller
From: Linus Walleij @ 2017-04-22  0:22 UTC (permalink / raw)
  To: Hans Ulli Kroll
  Cc: Rob Herring, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Linux USB List, Greg Kroah-Hartman, Mark Rutland
In-Reply-To: <alpine.LNX.2.00.1703302023250.17971@T420s>

On Thu, Mar 30, 2017 at 8:31 PM, Hans Ulli Kroll
<ulli.kroll-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> wrote:
>> On Tue, Feb 21, 2017 at 3:43 PM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
>> > On Fri, Feb 17, 2017 at 4:07 AM, Hans Ulli Kroll
>> > <ulli.kroll-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> wrote:
>> >> Hi Rob,
>> >>
>> >> On Wed, 15 Feb 2017, Rob Herring wrote:
>> >>
>> >>> On Wed, Feb 08, 2017 at 09:00:09PM +0100, Hans Ulli Kroll wrote:
>> >>> > This adds DT bindings for the Faraday FOTG2 host controller.
>> >>> >
>> >>> > Signed-off-by: Hans Ulli Kroll <ulli.kroll-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
>> >>> > ---
>> >>> >  Documentation/devicetree/bindings/usb/fotg2-host.txt | 15 +++++++++++++++
>> >>> >  1 file changed, 15 insertions(+)
>> >>> >  create mode 100644 Documentation/devicetree/bindings/usb/fotg2-host.txt
>> >>> >
>> >>> > diff --git a/Documentation/devicetree/bindings/usb/fotg2-host.txt b/Documentation/devicetree/bindings/usb/fotg2-host.txt
>> >>> > new file mode 100644
>> >>> > index 000000000000..4c07566a4bf5
>> >>> > --- /dev/null
>> >>> > +++ b/Documentation/devicetree/bindings/usb/fotg2-host.txt
>> >>> > @@ -0,0 +1,15 @@
>> >>> > +Faraday FOTG Host controller
>> >>> > +
>> >>> > +Required properties:
>> >>> > +
>> >>> > +- compatible: should be "faraday,fotg210-hcd"
>> >>>
>> >>> hcd as in "host controller driver"? Bindings describe h/w not drivers.
>> >>>
>> >>> It's an OTG controller or host controller?
>> >>>
>> >>
>> >> here only the host controller part used.
>> >>
>> >> faraday fotg2 is a dual role hcd/otg device and here is only the
>> >> host part used.
>> >
>> > Because you don't care about device mode or restricted by the IP
>> > configuration or SoC integration? The former is a user choice and
>> > shouldn't be part of DT. The latter should be implied by an SoC
>> > specific compatible string. Using only a compatible string for a
>> > licensed IP is not specific enough as vendors use differing versions
>> > and integrate them in different ways.
>>
>> Hans can you add:
>>
>> compatible = "cortina,gemini-fotg", "faraday,fotg210-hcd" or something
>> as composite compatible for our controller?

I hacked on it a bit and sent out. Hope you don't hate it too much.

> I prefer
> "faraday,fotg210-usb2"

I simply named it after the IP core name, which is just "faraday,fotg210".

> I've got rejected by Rob due the fact this is an dual role controller,
> which supports both host and device mode. And DT must reflect this desgn
> pattern.
>
> Currently I'm wrappingt my head around the design of the fsl-mph-dr-of.c
> driver to use this as a blueprint for the Faraday driver.

I don't know how much more of the dual-mode we need to reflect,
I guess it comes up in OTG mode since we don't parse the
host-only or device-only attributes (yet).

Yours,
Linus Walleij
--
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 2/4] dt-bindings: add binding for RTL8211E Ethernet PHY
From: Florian Fainelli @ 2017-04-22  0:22 UTC (permalink / raw)
  To: Icenowy Zheng, Andrew Lunn, Rob Herring
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
In-Reply-To: <20170421232436.10924-3-icenowy-h8G6r0blFSE@public.gmane.org>

On 04/21/2017 04:24 PM, Icenowy Zheng wrote:
> From: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
> 
> Some RTL8211E Ethernet PHY have an issue that needs a workaround
> indicated with device tree.
> 
> Add the binding for a property that indicates this workaround.
> 
> Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
> ---
>  .../devicetree/bindings/net/realtek,rtl8211e.txt   | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/realtek,rtl8211e.txt
> 
> diff --git a/Documentation/devicetree/bindings/net/realtek,rtl8211e.txt b/Documentation/devicetree/bindings/net/realtek,rtl8211e.txt
> new file mode 100644
> index 000000000000..c1913301bfe8
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/realtek,rtl8211e.txt
> @@ -0,0 +1,22 @@
> +Realtek RTL8211E Ethernet PHY
> +
> +One batch of RTL8211E is slight broken, that needs some special (and
> +full of magic numbers) tweaking in order to make GbE to operate properly.
> +The only well-known board that used the broken batch is Pine64+.
> +Configure it through an Ethernet OF device node.
> +
> +Optional properties:
> +
> +- realtek,disable-rx-delay:
> +  If set, RX delay will be completely disabled (according to Realtek). This
> +  will affect the performance on non-broken boards.
> +  default: do not disable RX delay.

Please don't introduce custom properties to do that, instead correct
specify the "phy-mode" such that it is e.g: "rgmii-txid" which indicates
that there should be no RX internal delay, but a TX internal delay added
by the PHY.
-- 
Florian

^ permalink raw reply

* Re: [PATCH 3/4] net: phy: realtek: add disable RX delay hack for RTL8211E
From: Florian Fainelli @ 2017-04-22  0:35 UTC (permalink / raw)
  To: Icenowy Zheng, Andrew Lunn, Rob Herring
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
In-Reply-To: <20170421232436.10924-4-icenowy-h8G6r0blFSE@public.gmane.org>

On 04/21/2017 04:24 PM, Icenowy Zheng wrote:
> From: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
> 
> Some RTL8211E chips have broken GbE function, which needs a hack to
> fix. It's said that this fix will affect the performance on not-buggy
> PHYs, so it should only be enabled on boards with the broken PHY.
> Currently only some Pine64+ boards are known to have this issue.
> 
> This hack is said to disable RX relay for RTL8211E according to Realtek.
> 
> Enable this hack when a certain device tree property is set.
> 
> As this hack is not documented on the datasheet at all, it contains
> magic numbers, and could not be revealed. These magic numbers are
> received from Realtek via Pine64.
> 
> Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
> ---
>  drivers/net/phy/realtek.c | 36 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 36 insertions(+)
> 
> diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
> index d820d00addf6..880022160cd2 100644
> --- a/drivers/net/phy/realtek.c
> +++ b/drivers/net/phy/realtek.c
> @@ -13,6 +13,7 @@
>   * option) any later version.
>   *
>   */
> +#include <linux/of.h>
>  #include <linux/phy.h>
>  #include <linux/module.h>
>  
> @@ -26,6 +27,8 @@
>  #define RTL8211_PAGE_SELECT	0x1f
>  
>  #define RTL8211E_INER_LINK_STATUS 0x400
> +#define RTL8211E_EXT_PAGE_SELECT 0x1e
> +#define RTL8211E_EXT_PAGE	0x7
>  
>  #define RTL8211F_INER_LINK_STATUS 0x0010
>  #define RTL8211F_INSR		0x1d
> @@ -121,6 +124,38 @@ static int rtl8211f_config_init(struct phy_device *phydev)
>  	return 0;
>  }
>  
> +static int rtl8211e_config_init(struct phy_device *phydev)
> +{
> +	struct device *dev = &phydev->mdio.dev;
> +	struct device_node *of_node = dev->of_node;
> +	int ret;
> +
> +	ret = genphy_config_init(phydev);
> +	if (ret < 0)
> +		return ret;
> +
> +	if (of_node &&
> +	    of_property_read_bool(of_node, "realtek,disable-rx-delay")) {
> +		/* All these magic numbers are retrieved from Pine64, and
> +		 * they're said to be originated from Realtek.
> +		 *
> +		 * The datasheet of RTL8211E didn't cover this ext page.
> +		 *
> +		 * Select extension page 0xa4 here.
> +		 */
> +		phy_write(phydev, RTL8211_PAGE_SELECT, RTL8211E_EXT_PAGE)
> +		phy_write(phydev, RTL8211E_EXT_PAGE_SELECT, 0xa4);
> +
> +		/* Write the magic number */
> +		phy_write(phydev, 0x1c, 0xb591);
> +
> +		/* Restore to default page 0 */
> +		phy_write(phydev, RTL8211_PAGE_SELECT, 0);
> +	}

The code itself is probably fine, but the way you are checking whether
the RX delay should be disabled is not. As mentioned in patch 2, using
the correct "phy-mode" property would translate in the proper
phydev->interface value here (presumably PHY_INTERFACE_MODE_RGMII_TXID)
is that you want here that would allow you to check whether the RX delay
should, or should not be disabled.

Thank you
-- 
Florian

^ permalink raw reply

* Re: [PATCH 2/4] dt-bindings: add binding for RTL8211E Ethernet PHY
From: icenowy-h8G6r0blFSE @ 2017-04-22  1:12 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Andrew Lunn, Rob Herring, netdev-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Icenowy Zheng
In-Reply-To: <c7aa9d7a-5e97-0e7f-2b1c-584a4de00837-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

在 2017-04-22 08:22,Florian Fainelli 写道:
> On 04/21/2017 04:24 PM, Icenowy Zheng wrote:
>> From: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
>> 
>> Some RTL8211E Ethernet PHY have an issue that needs a workaround
>> indicated with device tree.
>> 
>> Add the binding for a property that indicates this workaround.
>> 
>> Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
>> ---
>>  .../devicetree/bindings/net/realtek,rtl8211e.txt   | 22 
>> ++++++++++++++++++++++
>>  1 file changed, 22 insertions(+)
>>  create mode 100644 
>> Documentation/devicetree/bindings/net/realtek,rtl8211e.txt
>> 
>> diff --git 
>> a/Documentation/devicetree/bindings/net/realtek,rtl8211e.txt 
>> b/Documentation/devicetree/bindings/net/realtek,rtl8211e.txt
>> new file mode 100644
>> index 000000000000..c1913301bfe8
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/net/realtek,rtl8211e.txt
>> @@ -0,0 +1,22 @@
>> +Realtek RTL8211E Ethernet PHY
>> +
>> +One batch of RTL8211E is slight broken, that needs some special (and
>> +full of magic numbers) tweaking in order to make GbE to operate 
>> properly.
>> +The only well-known board that used the broken batch is Pine64+.
>> +Configure it through an Ethernet OF device node.
>> +
>> +Optional properties:
>> +
>> +- realtek,disable-rx-delay:
>> +  If set, RX delay will be completely disabled (according to 
>> Realtek). This
>> +  will affect the performance on non-broken boards.
>> +  default: do not disable RX delay.
> 
> Please don't introduce custom properties to do that, instead correct
> specify the "phy-mode" such that it is e.g: "rgmii-txid" which 
> indicates
> that there should be no RX internal delay, but a TX internal delay 
> added
> by the PHY.

According to Realtek and Pine64 people, set that register is equal to
hardwire RDDLY line to low.

Is it the standard definition of RGMII-TXID?

(P.S. as it's only provided as a workaround, there's no implementation
known for RGMII-RXID and RGMII-ID)

Thanks,
Icenowy

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

^ permalink raw reply

* [PATCH v2 0/5] mtd: nand: gpmi: add i.MX 7 support
From: Stefan Agner @ 2017-04-22  1:23 UTC (permalink / raw)
  To: dwmw2, computersforpeace, boris.brezillon, marek.vasut, richard,
	cyrille.pitchen
  Cc: robh+dt, mark.rutland, shawnguo, kernel, han.xu, fabio.estevam,
	LW, linux-mtd, devicetree, linux-arm-kernel, linux-kernel,
	Stefan Agner

This patchset adds support for i.MX 7 SoC for the GPMI NAND controller.
There have been similar patchsets already:
https://lkml.org/lkml/2016/2/23/912

However, this patchset does not make use of any of the new features.
The current feature set seems to work fine, I successfully run the MTD
tests on a Colibri iMX7.

--
Stefan

Changes since v1:
- Make clks_count const
- Introduce IS_IMX7D for i.MX 7 SoC's and make it part of GPMI_IS_MX6

Stefan Agner (5):
  mtd: nand: gpmi: unify clock handling
  mtd: nand: gpmi: add i.MX 7 SoC support
  mtd: gpmi: document current clock requirements
  ARM: dts: imx7: add GPMI NAND
  ARM: dts: imx7-colibri: add NAND support

 .../devicetree/bindings/mtd/gpmi-nand.txt          | 14 +++++-
 arch/arm/boot/dts/imx7-colibri.dtsi                |  9 ++++
 arch/arm/boot/dts/imx7s.dtsi                       | 31 ++++++++++++
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c             | 56 +++++++++++++---------
 drivers/mtd/nand/gpmi-nand/gpmi-nand.h             |  9 +++-
 5 files changed, 93 insertions(+), 26 deletions(-)

-- 
2.12.2

^ permalink raw reply

* [PATCH v2 1/5] mtd: nand: gpmi: unify clock handling
From: Stefan Agner @ 2017-04-22  1:23 UTC (permalink / raw)
  To: dwmw2, computersforpeace, boris.brezillon, marek.vasut, richard,
	cyrille.pitchen
  Cc: mark.rutland, fabio.estevam, devicetree, linux-kernel,
	Stefan Agner, robh+dt, linux-mtd, kernel, han.xu, shawnguo,
	linux-arm-kernel, LW
In-Reply-To: <20170422012338.4635-1-stefan@agner.ch>

Add device specific list of clocks required, and handle all clocks
in a single for loop. This avoids further code duplication when
adding i.MX 7 support.

Signed-off-by: Stefan Agner <stefan@agner.ch>
Reviewed-by: Marek Vasut <marek.vasut@gmail.com>
---
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 41 +++++++++++++++-------------------
 drivers/mtd/nand/gpmi-nand/gpmi-nand.h |  2 ++
 2 files changed, 20 insertions(+), 23 deletions(-)

diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index d52139635b67..c8bbf5da2ab8 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -82,6 +82,10 @@ static int gpmi_ooblayout_free(struct mtd_info *mtd, int section,
 	return 0;
 }
 
+static const char * const gpmi_clks_for_mx2x[] = {
+	"gpmi_io",
+};
+
 static const struct mtd_ooblayout_ops gpmi_ooblayout_ops = {
 	.ecc = gpmi_ooblayout_ecc,
 	.free = gpmi_ooblayout_free,
@@ -91,24 +95,36 @@ static const struct gpmi_devdata gpmi_devdata_imx23 = {
 	.type = IS_MX23,
 	.bch_max_ecc_strength = 20,
 	.max_chain_delay = 16,
+	.clks = gpmi_clks_for_mx2x,
+	.clks_count = ARRAY_SIZE(gpmi_clks_for_mx2x),
 };
 
 static const struct gpmi_devdata gpmi_devdata_imx28 = {
 	.type = IS_MX28,
 	.bch_max_ecc_strength = 20,
 	.max_chain_delay = 16,
+	.clks = gpmi_clks_for_mx2x,
+	.clks_count = ARRAY_SIZE(gpmi_clks_for_mx2x),
+};
+
+static const char * const gpmi_clks_for_mx6[] = {
+	"gpmi_io", "gpmi_apb", "gpmi_bch", "gpmi_bch_apb", "per1_bch",
 };
 
 static const struct gpmi_devdata gpmi_devdata_imx6q = {
 	.type = IS_MX6Q,
 	.bch_max_ecc_strength = 40,
 	.max_chain_delay = 12,
+	.clks = gpmi_clks_for_mx6,
+	.clks_count = ARRAY_SIZE(gpmi_clks_for_mx6),
 };
 
 static const struct gpmi_devdata gpmi_devdata_imx6sx = {
 	.type = IS_MX6SX,
 	.bch_max_ecc_strength = 62,
 	.max_chain_delay = 12,
+	.clks = gpmi_clks_for_mx6,
+	.clks_count = ARRAY_SIZE(gpmi_clks_for_mx6),
 };
 
 static irqreturn_t bch_irq(int irq, void *cookie)
@@ -599,35 +615,14 @@ static int acquire_dma_channels(struct gpmi_nand_data *this)
 	return -EINVAL;
 }
 
-static char *extra_clks_for_mx6q[GPMI_CLK_MAX] = {
-	"gpmi_apb", "gpmi_bch", "gpmi_bch_apb", "per1_bch",
-};
-
 static int gpmi_get_clks(struct gpmi_nand_data *this)
 {
 	struct resources *r = &this->resources;
-	char **extra_clks = NULL;
 	struct clk *clk;
 	int err, i;
 
-	/* The main clock is stored in the first. */
-	r->clock[0] = devm_clk_get(this->dev, "gpmi_io");
-	if (IS_ERR(r->clock[0])) {
-		err = PTR_ERR(r->clock[0]);
-		goto err_clock;
-	}
-
-	/* Get extra clocks */
-	if (GPMI_IS_MX6(this))
-		extra_clks = extra_clks_for_mx6q;
-	if (!extra_clks)
-		return 0;
-
-	for (i = 1; i < GPMI_CLK_MAX; i++) {
-		if (extra_clks[i - 1] == NULL)
-			break;
-
-		clk = devm_clk_get(this->dev, extra_clks[i - 1]);
+	for (i = 0; i < this->devdata->clks_count; i++) {
+		clk = devm_clk_get(this->dev, this->devdata->clks[i]);
 		if (IS_ERR(clk)) {
 			err = PTR_ERR(clk);
 			goto err_clock;
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
index 4e49a1f5fa27..8879c4eff25e 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
@@ -130,6 +130,8 @@ struct gpmi_devdata {
 	enum gpmi_type type;
 	int bch_max_ecc_strength;
 	int max_chain_delay; /* See the async EDO mode */
+	const char * const *clks;
+	const int clks_count;
 };
 
 struct gpmi_nand_data {
-- 
2.12.2

^ permalink raw reply related

* [PATCH v2 2/5] mtd: nand: gpmi: add i.MX 7 SoC support
From: Stefan Agner @ 2017-04-22  1:23 UTC (permalink / raw)
  To: dwmw2, computersforpeace, boris.brezillon, marek.vasut, richard,
	cyrille.pitchen
  Cc: robh+dt, mark.rutland, shawnguo, kernel, han.xu, fabio.estevam,
	LW, linux-mtd, devicetree, linux-arm-kernel, linux-kernel,
	Stefan Agner
In-Reply-To: <20170422012338.4635-1-stefan@agner.ch>

Add support for i.MX 7 SoC. The i.MX 7 has a slightly different
clock architecture requiring only two clocks to be referenced.
The IP is slightly different compared to i.MX 6, but currently none
of this differences are in use, therefore reuse GPMI_IS_MX6.

Signed-off-by: Stefan Agner <stefan@agner.ch>
Reviewed-by: Marek Vasut <marek.vasut@gmail.com>
---
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 15 +++++++++++++++
 drivers/mtd/nand/gpmi-nand/gpmi-nand.h |  7 +++++--
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index c8bbf5da2ab8..9b777be633a9 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -127,6 +127,18 @@ static const struct gpmi_devdata gpmi_devdata_imx6sx = {
 	.clks_count = ARRAY_SIZE(gpmi_clks_for_mx6),
 };
 
+static const char * const gpmi_clks_for_mx7d[] = {
+	"gpmi_io", "gpmi_bch_apb",
+};
+
+static const struct gpmi_devdata gpmi_devdata_imx7d = {
+	.type = IS_MX7D,
+	.bch_max_ecc_strength = 62,
+	.max_chain_delay = 12,
+	.clks = gpmi_clks_for_mx7d,
+	.clks_count = ARRAY_SIZE(gpmi_clks_for_mx7d),
+};
+
 static irqreturn_t bch_irq(int irq, void *cookie)
 {
 	struct gpmi_nand_data *this = cookie;
@@ -2071,6 +2083,9 @@ static const struct of_device_id gpmi_nand_id_table[] = {
 	}, {
 		.compatible = "fsl,imx6sx-gpmi-nand",
 		.data = &gpmi_devdata_imx6sx,
+	}, {
+		.compatible = "fsl,imx7d-gpmi-nand",
+		.data = &gpmi_devdata_imx7d,
 	}, {}
 };
 MODULE_DEVICE_TABLE(of, gpmi_nand_id_table);
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
index 8879c4eff25e..e88a45a62ab6 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
@@ -123,7 +123,8 @@ enum gpmi_type {
 	IS_MX23,
 	IS_MX28,
 	IS_MX6Q,
-	IS_MX6SX
+	IS_MX6SX,
+	IS_MX7D,
 };
 
 struct gpmi_devdata {
@@ -307,6 +308,8 @@ void gpmi_copy_bits(u8 *dst, size_t dst_bit_off,
 #define GPMI_IS_MX28(x)		((x)->devdata->type == IS_MX28)
 #define GPMI_IS_MX6Q(x)		((x)->devdata->type == IS_MX6Q)
 #define GPMI_IS_MX6SX(x)	((x)->devdata->type == IS_MX6SX)
+#define GPMI_IS_MX7D(x)		((x)->devdata->type == IS_MX7D)
 
-#define GPMI_IS_MX6(x)		(GPMI_IS_MX6Q(x) || GPMI_IS_MX6SX(x))
+#define GPMI_IS_MX6(x)		(GPMI_IS_MX6Q(x) || GPMI_IS_MX6SX(x) || \
+				 GPMI_IS_MX7D(x))
 #endif
-- 
2.12.2

^ permalink raw reply related

* [PATCH v2 3/5] mtd: gpmi: document current clock requirements
From: Stefan Agner @ 2017-04-22  1:23 UTC (permalink / raw)
  To: dwmw2, computersforpeace, boris.brezillon, marek.vasut, richard,
	cyrille.pitchen
  Cc: robh+dt, mark.rutland, shawnguo, kernel, han.xu, fabio.estevam,
	LW, linux-mtd, devicetree, linux-arm-kernel, linux-kernel,
	Stefan Agner
In-Reply-To: <20170422012338.4635-1-stefan@agner.ch>

The clock requirements are completely missing, add the clocks
currently required by the driver.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 Documentation/devicetree/bindings/mtd/gpmi-nand.txt | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mtd/gpmi-nand.txt b/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
index d02acaff3c35..b289ef3c1b7e 100644
--- a/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
@@ -4,7 +4,12 @@ The GPMI nand controller provides an interface to control the
 NAND flash chips.
 
 Required properties:
-  - compatible : should be "fsl,<chip>-gpmi-nand"
+  - compatible : should be "fsl,<chip>-gpmi-nand", chip can be:
+    * imx23
+    * imx28
+    * imx6q
+    * imx6sx
+    * imx7d
   - reg : should contain registers location and length for gpmi and bch.
   - reg-names: Should contain the reg names "gpmi-nand" and "bch"
   - interrupts : BCH interrupt number.
@@ -13,6 +18,13 @@ Required properties:
     and GPMI DMA channel ID.
     Refer to dma.txt and fsl-mxs-dma.txt for details.
   - dma-names: Must be "rx-tx".
+  - clocks : clocks phandle and clock specifier corresponding to each clock
+    specified in clock-names.
+  - clock-names : The "gpmi_io" clock is always required. Which clocks are
+    exactly required depends on chip:
+    * imx23/imx28 : "gpmi_io"
+    * imx6q/sx : "gpmi_io", "gpmi_apb", "gpmi_bch", "gpmi_bch_apb", "per1_bch"
+    * imx7d : "gpmi_io", "gpmi_bch_apb"
 
 Optional properties:
   - nand-on-flash-bbt: boolean to enable on flash bbt option if not
-- 
2.12.2

^ permalink raw reply related

* [PATCH v2 4/5] ARM: dts: imx7: add GPMI NAND
From: Stefan Agner @ 2017-04-22  1:23 UTC (permalink / raw)
  To: dwmw2-wEGCiKHe2LqWVfeAwA7xHQ,
	computersforpeace-Re5JQEeQqe8AvxtiuMwx3w,
	boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	marek.vasut-Re5JQEeQqe8AvxtiuMwx3w, richard-/L3Ra7n9ekc,
	cyrille.pitchen-AIFe0yeh4nAAvxtiuMwx3w
  Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	shawnguo-DgEjT+Ai2ygdnm+yROfE0A, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
	han.xu-3arQi8VN3Tc, fabio.estevam-KZfg59tc24xl57MIdRCFDg,
	LW-bxm8fMRDkQLDiMYJYoSAnRvVK+yQ3ZXh,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Stefan Agner
In-Reply-To: <20170422012338.4635-1-stefan-XLVq0VzYD2Y@public.gmane.org>

Add i.MX 7 GPMI NAND module.

Signed-off-by: Stefan Agner <stefan-XLVq0VzYD2Y@public.gmane.org>
---
 arch/arm/boot/dts/imx7s.dtsi | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
index 843eb379e1ea..9645257638d4 100644
--- a/arch/arm/boot/dts/imx7s.dtsi
+++ b/arch/arm/boot/dts/imx7s.dtsi
@@ -995,5 +995,36 @@
 				status = "disabled";
 			};
 		};
+
+		dma_apbh: dma-apbh@33000000 {
+			compatible = "fsl,imx7d-dma-apbh", "fsl,imx28-dma-apbh";
+			reg = <0x33000000 0x2000>;
+			interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "gpmi0", "gpmi1", "gpmi2", "gpmi3";
+			#dma-cells = <1>;
+			dma-channels = <4>;
+			clocks = <&clks IMX7D_NAND_USDHC_BUS_ROOT_CLK>,
+				<&clks IMX7D_NAND_ROOT_CLK>;
+			clock-names = "dma_apbh_bch", "dma_apbh_io";
+		};
+
+		gpmi: gpmi-nand@33002000{
+			compatible = "fsl,imx7d-gpmi-nand";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <0x33002000 0x2000>, <0x33004000 0x4000>;
+			reg-names = "gpmi-nand", "bch";
+			interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "bch";
+			clocks = <&clks IMX7D_NAND_ROOT_CLK>,
+				<&clks IMX7D_NAND_USDHC_BUS_ROOT_CLK>;
+			clock-names = "gpmi_io", "gpmi_bch_apb";
+			dmas = <&dma_apbh 0>;
+			dma-names = "rx-tx";
+			status = "disabled";
+		};
 	};
 };
-- 
2.12.2

--
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 5/5] ARM: dts: imx7-colibri: add NAND support
From: Stefan Agner @ 2017-04-22  1:23 UTC (permalink / raw)
  To: dwmw2-wEGCiKHe2LqWVfeAwA7xHQ,
	computersforpeace-Re5JQEeQqe8AvxtiuMwx3w,
	boris.brezillon-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	marek.vasut-Re5JQEeQqe8AvxtiuMwx3w, richard-/L3Ra7n9ekc,
	cyrille.pitchen-AIFe0yeh4nAAvxtiuMwx3w
  Cc: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	shawnguo-DgEjT+Ai2ygdnm+yROfE0A, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
	han.xu-3arQi8VN3Tc, fabio.estevam-KZfg59tc24xl57MIdRCFDg,
	LW-bxm8fMRDkQLDiMYJYoSAnRvVK+yQ3ZXh,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Stefan Agner
In-Reply-To: <20170422012338.4635-1-stefan-XLVq0VzYD2Y@public.gmane.org>

The Colibri iMX7 modules come with 512MB on-module SLC NAND flash
populated. Make use of it by enabling the GPMI controller.

Signed-off-by: Stefan Agner <stefan-XLVq0VzYD2Y@public.gmane.org>
---
 arch/arm/boot/dts/imx7-colibri.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi b/arch/arm/boot/dts/imx7-colibri.dtsi
index 2d87489f9105..ad4ce19d455b 100644
--- a/arch/arm/boot/dts/imx7-colibri.dtsi
+++ b/arch/arm/boot/dts/imx7-colibri.dtsi
@@ -106,6 +106,15 @@
 	fsl,magic-packet;
 };
 
+&gpmi {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_gpmi_nand>;
+	fsl,use-minimum-ecc;
+	nand-on-flash-bbt;
+	nand-ecc-mode = "hw";
+	status = "okay";
+};
+
 &i2c1 {
 	clock-frequency = <100000>;
 	pinctrl-names = "default";
-- 
2.12.2

--
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