diff mbox

[RFC] drivers: pinctrl: add driver for Allwinner A64 SoC

Message ID 1451582246-32373-1-git-send-email-andre.przywara@arm.com
State New
Headers show

Commit Message

Andre Przywara Dec. 31, 2015, 5:17 p.m. UTC
Based on the Allwinner A64 user manual and on the previous sunxi
pinctrl drivers this introduces the pin multiplex assignments for
the ARMv8 Allwinner A64 SoC.
Port A is apparently used for the fixed function DRAM controller, so
the ports start at B here (the manual mentions "n from 1 to 7", so
not starting at 0).

Signed-off-by: Andre Przywara <andre.przywara@arm.com>

---
Hi,

this work is based on an Allwinner A64 manual that was sent to me via
email by the pine64.com guys. I am not sure about the status of the
manual linked on the linux-sunxi wiki, though, but I am trying to
clarify this.
As I am not really knowledgable about the details of the pinctrl
subsystem, please correct me in case there are any stupidities in
this drop. I couldn't make out all the mappings between Allwinner's
peripherals naming and the corresponding Linux lingo, so if someone
with more experience in this could have a look it would be much
appreciated.
Due to the lack of hardware at the moment this is only compile-tested
(for arm and arm64).

Cheers,
Andre.

 arch/arm64/Kconfig.platforms        |   6 +
 drivers/pinctrl/sunxi/Kconfig       |   4 +
 drivers/pinctrl/sunxi/Makefile      |   1 +
 drivers/pinctrl/sunxi/pinctrl-a64.c | 606 ++++++++++++++++++++++++++++++++++++
 4 files changed, 617 insertions(+)
 create mode 100644 drivers/pinctrl/sunxi/pinctrl-a64.c

Comments

vishnupatekar Jan. 4, 2016, 6:34 a.m. UTC | #1
Hello Andre,

On Fri, Jan 1, 2016 at 1:17 AM, Andre Przywara <andre.przywara@arm.com> wrote:
> Based on the Allwinner A64 user manual and on the previous sunxi
> pinctrl drivers this introduces the pin multiplex assignments for
> the ARMv8 Allwinner A64 SoC.
> Port A is apparently used for the fixed function DRAM controller, so
> the ports start at B here (the manual mentions "n from 1 to 7", so
> not starting at 0).
>
> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
>
> ---
> Hi,
>
> this work is based on an Allwinner A64 manual that was sent to me via
> email by the pine64.com guys. I am not sure about the status of the
> manual linked on the linux-sunxi wiki, though, but I am trying to
> clarify this.
> As I am not really knowledgable about the details of the pinctrl
> subsystem, please correct me in case there are any stupidities in
> this drop. I couldn't make out all the mappings between Allwinner's
> peripherals naming and the corresponding Linux lingo, so if someone
> with more experience in this could have a look it would be much
> appreciated.
> Due to the lack of hardware at the moment this is only compile-tested
> (for arm and arm64).
>
> Cheers,
> Andre.
>
>  arch/arm64/Kconfig.platforms        |   6 +
>  drivers/pinctrl/sunxi/Kconfig       |   4 +
>  drivers/pinctrl/sunxi/Makefile      |   1 +
>  drivers/pinctrl/sunxi/pinctrl-a64.c | 606 ++++++++++++++++++++++++++++++++++++
>  4 files changed, 617 insertions(+)
>  create mode 100644 drivers/pinctrl/sunxi/pinctrl-a64.c
>
> diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
> index 4043c35..4dbec84 100644
> --- a/arch/arm64/Kconfig.platforms
> +++ b/arch/arm64/Kconfig.platforms
> @@ -1,5 +1,11 @@
>  menu "Platform selection"
>
> +config ARCH_SUNXI
> +       bool "Allwinner sunxi 64-bit SoC Family"
> +       select PINCTRL_A64
> +       help
> +         This enables support for Allwinner sunxi based SoCs like the A64.
> +
>  config ARCH_BCM_IPROC
>         bool "Broadcom iProc SoC Family"
>         help
> diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
> index e68fd95..ac47b5d 100644
> --- a/drivers/pinctrl/sunxi/Kconfig
> +++ b/drivers/pinctrl/sunxi/Kconfig
> @@ -55,4 +55,8 @@ config PINCTRL_SUN9I_A80
>         def_bool MACH_SUN9I
>         select PINCTRL_SUNXI_COMMON
>
> +config PINCTRL_A64
> +       bool
> +       select PINCTRL_SUNXI_COMMON
> +
>  endif
> diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile
> index e080290..130e7bc 100644
> --- a/drivers/pinctrl/sunxi/Makefile
> +++ b/drivers/pinctrl/sunxi/Makefile
> @@ -12,5 +12,6 @@ obj-$(CONFIG_PINCTRL_SUN7I_A20)               += pinctrl-sun7i-a20.o
>  obj-$(CONFIG_PINCTRL_SUN8I_A23)                += pinctrl-sun8i-a23.o
>  obj-$(CONFIG_PINCTRL_SUN8I_A23_R)      += pinctrl-sun8i-a23-r.o
>  obj-$(CONFIG_PINCTRL_SUN8I_A33)                += pinctrl-sun8i-a33.o
> +obj-$(CONFIG_PINCTRL_A64)              += pinctrl-a64.o

Shouldn't this follow pinctrl config name like other sunXi SOCs?
This should be PINCTRL_SUN??_A64.

First, we should find family name for A64. I remember, on IRC Maxime
refering A64 to family named sun10i.


>  obj-$(CONFIG_PINCTRL_SUN8I_A83T)       += pinctrl-sun8i-a83t.o
>  obj-$(CONFIG_PINCTRL_SUN9I_A80)                += pinctrl-sun9i-a80.o
> diff --git a/drivers/pinctrl/sunxi/pinctrl-a64.c b/drivers/pinctrl/sunxi/pinctrl-a64.c
> new file mode 100644
> index 0000000..00746d0
> --- /dev/null
> +++ b/drivers/pinctrl/sunxi/pinctrl-a64.c
> @@ -0,0 +1,606 @@
> +/*
> + * Allwinner A64 SoCs pinctrl driver.
> + *
> + * Copyright (C) 2016 - ARM Ltd.
> + * Author: Andre Przywara <andre.przywara@arm.com>
> + *
> + * Based on pinctrl-sun7i-a20.c, which is:
> + * Copyright (C) 2014 Maxime Ripard <maxime.ripard@free-electrons.com>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/pinctrl/pinctrl.h>
> +
> +#include "pinctrl-sunxi.h"
> +
> +static const struct sunxi_desc_pin a64_pins[] = {
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 0),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "uart2"),         /* TX */
> +                 SUNXI_FUNCTION(0x4, "jtag"),          /* MS0 */
> +                 SUNXI_FUNCTION_IRQ(0x6, 0)),          /* EINT0 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 1),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "uart2"),         /* RX */
> +                 SUNXI_FUNCTION(0x4, "jtag"),          /* CK0 */
> +                 SUNXI_FUNCTION(0x5, "sim"),           /* VCCEN */
> +                 SUNXI_FUNCTION_IRQ(0x6, 1)),          /* EINT1 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 2),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "uart2"),         /* RTS */
> +                 SUNXI_FUNCTION(0x4, "jtag"),          /* DO0 */
> +                 SUNXI_FUNCTION(0x5, "sim"),           /* VPPEN */
> +                 SUNXI_FUNCTION_IRQ(0x6, 2)),          /* EINT2 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "uart2"),         /* CTS */
> +                 SUNXI_FUNCTION(0x3, "i2s0"),          /* MCLK */
> +                 SUNXI_FUNCTION(0x4, "jtag"),          /* DI0 */
> +                 SUNXI_FUNCTION(0x5, "sim"),           /* VPPPP */
> +                 SUNXI_FUNCTION_IRQ(0x6, 3)),          /* EINT3 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "aif2"),          /* SYNC */
> +                 SUNXI_FUNCTION(0x3, "ac97"),          /* SYNC */
This bit is reffered as PCM in A64 user manual. you've named PCM1 as
i2s1 in PG pins.
It will be great if we follow same here, it should be i2s0; same for
PB5, PB6, PB7 pins.
In fact, PB3 above is i2s0 MCLK pin.

> +                 SUNXI_FUNCTION(0x5, "sim"),           /* CLK */
> +                 SUNXI_FUNCTION_IRQ(0x6, 4)),          /* EINT4 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 5),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "aif2"),          /* BCLK */
> +                 SUNXI_FUNCTION(0x3, "ac97"),          /* BCLK */
> +                 SUNXI_FUNCTION(0x5, "sim"),           /* DATA */
> +                 SUNXI_FUNCTION_IRQ(0x6, 5)),          /* EINT5 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 6),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "aif2"),          /* DOUT */
> +                 SUNXI_FUNCTION(0x3, "ac97"),          /* DOUT */
> +                 SUNXI_FUNCTION(0x5, "sim"),           /* RST */
> +                 SUNXI_FUNCTION_IRQ(0x6, 6)),          /* EINT6 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 7),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "aif2"),          /* DIN */
> +                 SUNXI_FUNCTION(0x3, "ac97"),          /* DIN */
> +                 SUNXI_FUNCTION(0x5, "sim"),           /* DET */
> +                 SUNXI_FUNCTION_IRQ(0x6, 7)),          /* EINT7 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 8),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x4, "uart0"),         /* TX */
> +                 SUNXI_FUNCTION_IRQ(0x6, 8)),          /* EINT8 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 9),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x4, "uart0"),         /* RX */
> +                 SUNXI_FUNCTION_IRQ(0x6, 9)),          /* EINT9 */
> +       /* Hole */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NWE */
> +                 SUNXI_FUNCTION(0x4, "spi0")),         /* MOSI */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 1),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NALE */
> +                 SUNXI_FUNCTION(0x3, "mmc2"),          /* DS */
> +                 SUNXI_FUNCTION(0x4, "spi0")),         /* MISO */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 2),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NCLE */
> +                 SUNXI_FUNCTION(0x4, "spi0")),         /* SCK */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 3),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NCE1 */
> +                 SUNXI_FUNCTION(0x4, "spi0")),         /* CS */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 4),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "nand0")),        /* NCE0 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 5),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NRE# */
> +                 SUNXI_FUNCTION(0x3, "mmc2")),         /* CLK */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 6),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NRB0 */
> +                 SUNXI_FUNCTION(0x3, "mmc2")),         /* CMD */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 7),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "nand0")),        /* NRB1 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 8),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NDQ0 */
> +                 SUNXI_FUNCTION(0x3, "mmc2")),         /* D0 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 9),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NDQ1 */
> +                 SUNXI_FUNCTION(0x3, "mmc2")),         /* D1 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 10),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NDQ2 */
> +                 SUNXI_FUNCTION(0x3, "mmc2")),         /* D2 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 11),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NDQ3 */
> +                 SUNXI_FUNCTION(0x3, "mmc2")),         /* D3 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 12),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NDQ4 */
> +                 SUNXI_FUNCTION(0x3, "mmc2")),         /* D4 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 13),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NDQ5 */
> +                 SUNXI_FUNCTION(0x3, "mmc2")),         /* D5 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NDQ6 */
> +                 SUNXI_FUNCTION(0x3, "mmc2")),         /* D6 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NDQ7 */
> +                 SUNXI_FUNCTION(0x3, "mmc2")),         /* D7 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NDQS */
> +                 SUNXI_FUNCTION(0x3, "mmc2")),         /* RST */
> +       /* Hole */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 0),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D2 */
> +                 SUNXI_FUNCTION(0x3, "uart3"),         /* TX */
> +                 SUNXI_FUNCTION(0x4, "spi1"),          /* CS */
> +                 SUNXI_FUNCTION(0x5, "ccir")),         /* CLK */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 1),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D3 */
> +                 SUNXI_FUNCTION(0x3, "uart3"),         /* RX */
> +                 SUNXI_FUNCTION(0x4, "spi1"),          /* CLK */
> +                 SUNXI_FUNCTION(0x5, "ccir")),         /* DE */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 2),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D4 */
> +                 SUNXI_FUNCTION(0x3, "uart4"),         /* TX */
> +                 SUNXI_FUNCTION(0x4, "spi1"),          /* MOSI */
> +                 SUNXI_FUNCTION(0x5, "ccir")),         /* HSYNC */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 3),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D5 */
> +                 SUNXI_FUNCTION(0x3, "uart4"),         /* RX */
> +                 SUNXI_FUNCTION(0x4, "spi1"),          /* MISO */
> +                 SUNXI_FUNCTION(0x5, "ccir")),         /* VSYNC */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 4),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D6 */
> +                 SUNXI_FUNCTION(0x3, "uart4"),         /* RTS */
> +                 SUNXI_FUNCTION(0x5, "ccir")),         /* D0 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 5),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D7 */
> +                 SUNXI_FUNCTION(0x3, "uart4"),         /* CTS */
> +                 SUNXI_FUNCTION(0x5, "ccir")),         /* D1 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 6),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D10 */
> +                 SUNXI_FUNCTION(0x5, "ccir")),         /* D2 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 7),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D11 */
> +                 SUNXI_FUNCTION(0x5, "ccir")),         /* D3 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 8),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D12 */
> +                 SUNXI_FUNCTION(0x4, "emac"),          /* ERXD3 */
> +                 SUNXI_FUNCTION(0x5, "ccir")),         /* D4 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 9),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D13 */
> +                 SUNXI_FUNCTION(0x4, "emac"),          /* ERXD2 */
> +                 SUNXI_FUNCTION(0x5, "ccir")),         /* D5 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 10),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D14 */
> +                 SUNXI_FUNCTION(0x4, "emac")),         /* ERXD1 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 11),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D15 */
> +                 SUNXI_FUNCTION(0x4, "emac")),         /* ERXD0 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 12),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D18 */
> +                 SUNXI_FUNCTION(0x3, "lvds0"),         /* VP0 */
> +                 SUNXI_FUNCTION(0x4, "emac")),         /* ERXCK */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 13),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D19 */
> +                 SUNXI_FUNCTION(0x3, "lvds0"),         /* VN0 */
> +                 SUNXI_FUNCTION(0x4, "emac")),         /* ERXCTL */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 14),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D20 */
> +                 SUNXI_FUNCTION(0x3, "lvds0"),         /* VP1 */
> +                 SUNXI_FUNCTION(0x4, "emac")),         /* ENULL */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 15),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D21 */
> +                 SUNXI_FUNCTION(0x3, "lvds0"),         /* VN1 */
> +                 SUNXI_FUNCTION(0x4, "emac"),          /* ETXD3 */
> +                 SUNXI_FUNCTION(0x5, "ccir")),         /* D6 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 16),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D22 */
> +                 SUNXI_FUNCTION(0x3, "lvds0"),         /* VP2 */
> +                 SUNXI_FUNCTION(0x4, "emac"),          /* ETXD2 */
> +                 SUNXI_FUNCTION(0x5, "ccir")),         /* D7 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 17),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D23 */
> +                 SUNXI_FUNCTION(0x3, "lvds0"),         /* VN2 */
> +                 SUNXI_FUNCTION(0x4, "emac")),         /* ETXD1 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 18),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* CLK */
> +                 SUNXI_FUNCTION(0x3, "lvds0"),         /* VPC */
> +                 SUNXI_FUNCTION(0x4, "emac")),         /* ETXD0 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 19),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* DE */
> +                 SUNXI_FUNCTION(0x3, "lvds0"),         /* VNC */
> +                 SUNXI_FUNCTION(0x4, "emac")),         /* ETXCK */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 20),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* HSYNC */
> +                 SUNXI_FUNCTION(0x3, "lvds0"),         /* VP3 */
> +                 SUNXI_FUNCTION(0x4, "emac")),         /* ETXCTL */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 21),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* VSYNC */
> +                 SUNXI_FUNCTION(0x3, "lvds0"),         /* VN3 */
> +                 SUNXI_FUNCTION(0x4, "emac")),         /* ECLKIN */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 22),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "pwm"),           /* PWM0 */
> +                 SUNXI_FUNCTION(0x4, "emac")),         /* EMDC */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 23),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x4, "emac")),         /* EMDIO */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 24),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out")),
> +       /* Hole */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 0),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "csi0"),          /* PCK */
> +                 SUNXI_FUNCTION(0x4, "ts0")),          /* CLK */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 1),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "csi0"),          /* CK */
> +                 SUNXI_FUNCTION(0x4, "ts0")),          /* ERR */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 2),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "csi0"),          /* HSYNC */
> +                 SUNXI_FUNCTION(0x4, "ts0")),          /* SYNC */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 3),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "csi0"),          /* VSYNC */
> +                 SUNXI_FUNCTION(0x4, "ts0")),          /* DVLD */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 4),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "csi0"),          /* D0 */
> +                 SUNXI_FUNCTION(0x4, "ts0")),          /* D0 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 5),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "csi0"),          /* D1 */
> +                 SUNXI_FUNCTION(0x4, "ts0")),          /* D1 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 6),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "csi0"),          /* D2 */
> +                 SUNXI_FUNCTION(0x4, "ts0")),          /* D2 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 7),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "csi0"),          /* D3 */
> +                 SUNXI_FUNCTION(0x4, "ts0")),          /* D3 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 8),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "csi0"),          /* D4 */
> +                 SUNXI_FUNCTION(0x4, "ts0")),          /* D4 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 9),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "csi0"),          /* D5 */
> +                 SUNXI_FUNCTION(0x4, "ts0")),          /* D5 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 10),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "csi0"),          /* D6 */
> +                 SUNXI_FUNCTION(0x4, "ts0")),          /* D6 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 11),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "csi0"),          /* D7 */
> +                 SUNXI_FUNCTION(0x4, "ts0")),          /* D7 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 12),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "csi0")),         /* SCK */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 13),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "csi0")),         /* SDA */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 14),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "pll"),           /* LOCK_DBG */
> +                 SUNXI_FUNCTION(0x3, "i2c2")),         /* SCK */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 15),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x3, "i2c2")),         /* SDA */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 16),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out")),
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 17),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out")),
> +       /* Hole */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "mmc0"),          /* D1 */
> +                 SUNXI_FUNCTION(0x3, "jtag")),         /* MSI */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 1),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "mmc0"),          /* D0 */
> +                 SUNXI_FUNCTION(0x3, "jtag")),         /* DI1 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 2),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "mmc0"),          /* CLK */
> +                 SUNXI_FUNCTION(0x3, "uart0")),        /* TX */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 3),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "mmc0"),          /* CMD */
> +                 SUNXI_FUNCTION(0x3, "jtag")),         /* DO1 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 4),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "mmc0"),          /* D3 */
> +                 SUNXI_FUNCTION(0x4, "uart0")),        /* RX */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 5),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "mmc0"),          /* D2 */
> +                 SUNXI_FUNCTION(0x3, "jtag")),         /* CK1 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 6),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out")),
> +       /* Hole */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "mmc1"),          /* CLK */
> +                 SUNXI_FUNCTION_IRQ(0x6, 0)),          /* EINT0 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "mmc1"),          /* CMD */
> +                 SUNXI_FUNCTION_IRQ(0x6, 1)),          /* EINT1 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "mmc1"),          /* D0 */
> +                 SUNXI_FUNCTION_IRQ(0x6, 2)),          /* EINT2 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "mmc1"),          /* D1 */
> +                 SUNXI_FUNCTION_IRQ(0x6, 3)),          /* EINT3 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 4),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "mmc1"),          /* D2 */
> +                 SUNXI_FUNCTION_IRQ(0x6, 4)),          /* EINT4 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "mmc1"),          /* D3 */
> +                 SUNXI_FUNCTION_IRQ(0x6, 5)),          /* EINT5 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 6),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "uart1"),         /* TX */
> +                 SUNXI_FUNCTION_IRQ(0x6, 6)),          /* EINT6 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 7),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "uart1"),         /* RX */
> +                 SUNXI_FUNCTION_IRQ(0x6, 7)),          /* EINT7 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "uart1"),         /* RTS */
> +                 SUNXI_FUNCTION_IRQ(0x6, 8)),          /* EINT8 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "uart1"),         /* CTS */
> +                 SUNXI_FUNCTION_IRQ(0x6, 9)),          /* EINT9 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "aif3"),          /* SYNC */
> +                 SUNXI_FUNCTION(0x3, "i2s1"),          /* SYNC */
> +                 SUNXI_FUNCTION_IRQ(0x6, 10)),         /* EINT10 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 11),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "aif3"),          /* BCLK */
> +                 SUNXI_FUNCTION(0x3, "i2s1"),          /* BCLK */
> +                 SUNXI_FUNCTION_IRQ(0x6, 11)),         /* EINT11 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 12),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "aif3"),          /* DOUT */
> +                 SUNXI_FUNCTION(0x3, "i2s1"),          /* DOUT */
> +                 SUNXI_FUNCTION_IRQ(0x6, 12)),         /* EINT12 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 13),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "aif3"),          /* DIN */
> +                 SUNXI_FUNCTION(0x3, "i2s1"),          /* DIN */
> +                 SUNXI_FUNCTION_IRQ(0x6, 13)),         /* EINT13 */
> +       /* Hole */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 0),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "i2c0"),          /* SCK */
> +                 SUNXI_FUNCTION_IRQ(0x6, 0)),          /* EINT0 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 1),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "i2c0"),          /* SDA */
> +                 SUNXI_FUNCTION_IRQ(0x6, 1)),          /* EINT1 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 2),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "i2c1"),          /* SCK */
> +                 SUNXI_FUNCTION_IRQ(0x6, 2)),          /* EINT2 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 3),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "i2c1"),          /* SDA */
> +                 SUNXI_FUNCTION_IRQ(0x6, 3)),          /* EINT3 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 4),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "uart3"),         /* TX */
> +                 SUNXI_FUNCTION_IRQ(0x6, 4)),          /* EINT4 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 5),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "uart3"),         /* RX */
> +                 SUNXI_FUNCTION_IRQ(0x6, 5)),          /* EINT5 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 6),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "uart3"),         /* RTS */
> +                 SUNXI_FUNCTION_IRQ(0x6, 6)),          /* EINT6 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 7),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "uart3"),         /* CTS */
> +                 SUNXI_FUNCTION_IRQ(0x6, 7)),          /* EINT7 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 8),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "owa"),           /* OUT */
> +                 SUNXI_FUNCTION_IRQ(0x6, 8)),          /* EINT8 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 9),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION_IRQ(0x6, 9)),          /* EINT9 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 10),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "mic"),           /* CLK */
> +                 SUNXI_FUNCTION_IRQ(0x6, 10)),         /* EINT10 */
> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 11),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "mic"),           /* DATA */
> +                 SUNXI_FUNCTION_IRQ(0x6, 11)),         /* EINT11 */
> +};
> +
> +static const struct sunxi_pinctrl_desc a64_pinctrl_data = {
> +       .pins = a64_pins,
> +       .npins = ARRAY_SIZE(a64_pins),
> +       .irq_banks = 1,
> +};
> +
> +static int a64_pinctrl_probe(struct platform_device *pdev)
> +{
> +       return sunxi_pinctrl_init(pdev,
> +                                 &a64_pinctrl_data);
> +}
> +
> +static const struct of_device_id a64_pinctrl_match[] = {
> +       { .compatible = "allwinner,a64-pinctrl", },
> +       {}
> +};
> +MODULE_DEVICE_TABLE(of, a64_pinctrl_match);
> +
> +static struct platform_driver a64_pinctrl_driver = {
> +       .probe  = a64_pinctrl_probe,
> +       .driver = {
> +               .name           = "a64-pinctrl",
> +               .of_match_table = a64_pinctrl_match,
> +       },
> +};
> +module_platform_driver(a64_pinctrl_driver);
> +
> +MODULE_AUTHOR("Andre Przywara <andre.przywara@arm.com>");
> +MODULE_DESCRIPTION("Allwinner A64 pinctrl driver");
> +MODULE_LICENSE("GPL");

I've verified that all the bit configurations are correct as per A64
user manual.

Regards,
Vishnu Patekar
> --
> 1.8.4
>
> --
> 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@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Maxime Ripard Jan. 4, 2016, 8:43 a.m. UTC | #2
Hi,

On Mon, Jan 04, 2016 at 02:34:52PM +0800, Vishnu Patekar wrote:
> > diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile
> > index e080290..130e7bc 100644
> > --- a/drivers/pinctrl/sunxi/Makefile
> > +++ b/drivers/pinctrl/sunxi/Makefile
> > @@ -12,5 +12,6 @@ obj-$(CONFIG_PINCTRL_SUN7I_A20)               += pinctrl-sun7i-a20.o
> >  obj-$(CONFIG_PINCTRL_SUN8I_A23)                += pinctrl-sun8i-a23.o
> >  obj-$(CONFIG_PINCTRL_SUN8I_A23_R)      += pinctrl-sun8i-a23-r.o
> >  obj-$(CONFIG_PINCTRL_SUN8I_A33)                += pinctrl-sun8i-a33.o
> > +obj-$(CONFIG_PINCTRL_A64)              += pinctrl-a64.o
> 
> Shouldn't this follow pinctrl config name like other sunXi SOCs?
> This should be PINCTRL_SUN??_A64.
> 
> First, we should find family name for A64. I remember, on IRC Maxime
> refering A64 to family named sun10i.

It's called sun50i in the BSP, so I guess we can go with that.

Thanks!
Maxime
Andre Przywara Jan. 4, 2016, 10:29 a.m. UTC | #3
Hi Vishnu,

thanks for going through the pain of actually reading this patch!

On 04/01/16 06:34, Vishnu Patekar wrote:
> Hello Andre,
> 
> On Fri, Jan 1, 2016 at 1:17 AM, Andre Przywara <andre.przywara@arm.com> wrote:
>> Based on the Allwinner A64 user manual and on the previous sunxi
>> pinctrl drivers this introduces the pin multiplex assignments for
>> the ARMv8 Allwinner A64 SoC.
>> Port A is apparently used for the fixed function DRAM controller, so
>> the ports start at B here (the manual mentions "n from 1 to 7", so
>> not starting at 0).
>>
>> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
>>
>> ---
>> Hi,
>>
>> this work is based on an Allwinner A64 manual that was sent to me via
>> email by the pine64.com guys. I am not sure about the status of the
>> manual linked on the linux-sunxi wiki, though, but I am trying to
>> clarify this.
>> As I am not really knowledgable about the details of the pinctrl
>> subsystem, please correct me in case there are any stupidities in
>> this drop. I couldn't make out all the mappings between Allwinner's
>> peripherals naming and the corresponding Linux lingo, so if someone
>> with more experience in this could have a look it would be much
>> appreciated.
>> Due to the lack of hardware at the moment this is only compile-tested
>> (for arm and arm64).
>>
>> Cheers,
>> Andre.
>>
>>  arch/arm64/Kconfig.platforms        |   6 +
>>  drivers/pinctrl/sunxi/Kconfig       |   4 +
>>  drivers/pinctrl/sunxi/Makefile      |   1 +
>>  drivers/pinctrl/sunxi/pinctrl-a64.c | 606 ++++++++++++++++++++++++++++++++++++
>>  4 files changed, 617 insertions(+)
>>  create mode 100644 drivers/pinctrl/sunxi/pinctrl-a64.c
>>
>> diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
>> index 4043c35..4dbec84 100644
>> --- a/arch/arm64/Kconfig.platforms
>> +++ b/arch/arm64/Kconfig.platforms
>> @@ -1,5 +1,11 @@
>>  menu "Platform selection"
>>
>> +config ARCH_SUNXI
>> +       bool "Allwinner sunxi 64-bit SoC Family"
>> +       select PINCTRL_A64
>> +       help
>> +         This enables support for Allwinner sunxi based SoCs like the A64.
>> +
>>  config ARCH_BCM_IPROC
>>         bool "Broadcom iProc SoC Family"
>>         help
>> diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
>> index e68fd95..ac47b5d 100644
>> --- a/drivers/pinctrl/sunxi/Kconfig
>> +++ b/drivers/pinctrl/sunxi/Kconfig
>> @@ -55,4 +55,8 @@ config PINCTRL_SUN9I_A80
>>         def_bool MACH_SUN9I
>>         select PINCTRL_SUNXI_COMMON
>>
>> +config PINCTRL_A64
>> +       bool
>> +       select PINCTRL_SUNXI_COMMON
>> +
>>  endif
>> diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile
>> index e080290..130e7bc 100644
>> --- a/drivers/pinctrl/sunxi/Makefile
>> +++ b/drivers/pinctrl/sunxi/Makefile
>> @@ -12,5 +12,6 @@ obj-$(CONFIG_PINCTRL_SUN7I_A20)               += pinctrl-sun7i-a20.o
>>  obj-$(CONFIG_PINCTRL_SUN8I_A23)                += pinctrl-sun8i-a23.o
>>  obj-$(CONFIG_PINCTRL_SUN8I_A23_R)      += pinctrl-sun8i-a23-r.o
>>  obj-$(CONFIG_PINCTRL_SUN8I_A33)                += pinctrl-sun8i-a33.o
>> +obj-$(CONFIG_PINCTRL_A64)              += pinctrl-a64.o
> 
> Shouldn't this follow pinctrl config name like other sunXi SOCs?
> This should be PINCTRL_SUN??_A64.

I never really got the reason we use those sunxi names in addition to
the SoC name in the first place, maybe apart from copying from some
Allwinner code.
Since I decided to not look at Allwinner's BSP at all (if avoidable), I
also thought it would be time to drop that sunxi naming, which looks
redundant to me.
Is there any reason why we would need this (beside having a rather
unique identifier prefix)?

> First, we should find family name for A64. I remember, on IRC Maxime
> refering A64 to family named sun10i.

If people insist, I can of course add the "sun50i" prefix (as Maxime
stated).

>>  obj-$(CONFIG_PINCTRL_SUN8I_A83T)       += pinctrl-sun8i-a83t.o
>>  obj-$(CONFIG_PINCTRL_SUN9I_A80)                += pinctrl-sun9i-a80.o
>> diff --git a/drivers/pinctrl/sunxi/pinctrl-a64.c b/drivers/pinctrl/sunxi/pinctrl-a64.c
>> new file mode 100644
>> index 0000000..00746d0
>> --- /dev/null
>> +++ b/drivers/pinctrl/sunxi/pinctrl-a64.c
>> @@ -0,0 +1,606 @@
>> +/*
>> + * Allwinner A64 SoCs pinctrl driver.
>> + *
>> + * Copyright (C) 2016 - ARM Ltd.
>> + * Author: Andre Przywara <andre.przywara@arm.com>
>> + *
>> + * Based on pinctrl-sun7i-a20.c, which is:
>> + * Copyright (C) 2014 Maxime Ripard <maxime.ripard@free-electrons.com>
>> + *
>> + * This file is licensed under the terms of the GNU General Public
>> + * License version 2.  This program is licensed "as is" without any
>> + * warranty of any kind, whether express or implied.
>> + */
>> +
>> +#include <linux/module.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/of.h>
>> +#include <linux/of_device.h>
>> +#include <linux/pinctrl/pinctrl.h>
>> +
>> +#include "pinctrl-sunxi.h"
>> +
>> +static const struct sunxi_desc_pin a64_pins[] = {
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 0),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "uart2"),         /* TX */
>> +                 SUNXI_FUNCTION(0x4, "jtag"),          /* MS0 */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 0)),          /* EINT0 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 1),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "uart2"),         /* RX */
>> +                 SUNXI_FUNCTION(0x4, "jtag"),          /* CK0 */
>> +                 SUNXI_FUNCTION(0x5, "sim"),           /* VCCEN */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 1)),          /* EINT1 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 2),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "uart2"),         /* RTS */
>> +                 SUNXI_FUNCTION(0x4, "jtag"),          /* DO0 */
>> +                 SUNXI_FUNCTION(0x5, "sim"),           /* VPPEN */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 2)),          /* EINT2 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "uart2"),         /* CTS */
>> +                 SUNXI_FUNCTION(0x3, "i2s0"),          /* MCLK */
>> +                 SUNXI_FUNCTION(0x4, "jtag"),          /* DI0 */
>> +                 SUNXI_FUNCTION(0x5, "sim"),           /* VPPPP */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 3)),          /* EINT3 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "aif2"),          /* SYNC */
>> +                 SUNXI_FUNCTION(0x3, "ac97"),          /* SYNC */
> This bit is reffered as PCM in A64 user manual. you've named PCM1 as
> i2s1 in PG pins.

You are right, thanks for catching that.
Looks like I changed my mind later on and forgot to amend these earlier
references.

> It will be great if we follow same here, it should be i2s0; same for
> PB5, PB6, PB7 pins.

Sure, will fix this in the next drop.

> In fact, PB3 above is i2s0 MCLK pin.

Yeah, this is actually called I2S0 in the manual, in contrast to the
other pins in this very same port register, which use the PCM0 prefix.
I think the reason is that there seems to be only one I2S MCLK signal,
probably shared between the two I2S controllers.

Let's go with is20 and see where this takes us. I guess most boards will
only connect one I2S controller anyway.

>> +                 SUNXI_FUNCTION(0x5, "sim"),           /* CLK */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 4)),          /* EINT4 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 5),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "aif2"),          /* BCLK */
>> +                 SUNXI_FUNCTION(0x3, "ac97"),          /* BCLK */
>> +                 SUNXI_FUNCTION(0x5, "sim"),           /* DATA */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 5)),          /* EINT5 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 6),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "aif2"),          /* DOUT */
>> +                 SUNXI_FUNCTION(0x3, "ac97"),          /* DOUT */
>> +                 SUNXI_FUNCTION(0x5, "sim"),           /* RST */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 6)),          /* EINT6 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 7),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "aif2"),          /* DIN */
>> +                 SUNXI_FUNCTION(0x3, "ac97"),          /* DIN */
>> +                 SUNXI_FUNCTION(0x5, "sim"),           /* DET */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 7)),          /* EINT7 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 8),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x4, "uart0"),         /* TX */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 8)),          /* EINT8 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 9),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x4, "uart0"),         /* RX */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 9)),          /* EINT9 */
>> +       /* Hole */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NWE */
>> +                 SUNXI_FUNCTION(0x4, "spi0")),         /* MOSI */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 1),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NALE */
>> +                 SUNXI_FUNCTION(0x3, "mmc2"),          /* DS */
>> +                 SUNXI_FUNCTION(0x4, "spi0")),         /* MISO */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 2),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NCLE */
>> +                 SUNXI_FUNCTION(0x4, "spi0")),         /* SCK */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 3),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NCE1 */
>> +                 SUNXI_FUNCTION(0x4, "spi0")),         /* CS */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 4),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "nand0")),        /* NCE0 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 5),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NRE# */
>> +                 SUNXI_FUNCTION(0x3, "mmc2")),         /* CLK */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 6),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NRB0 */
>> +                 SUNXI_FUNCTION(0x3, "mmc2")),         /* CMD */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 7),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "nand0")),        /* NRB1 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 8),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NDQ0 */
>> +                 SUNXI_FUNCTION(0x3, "mmc2")),         /* D0 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 9),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NDQ1 */
>> +                 SUNXI_FUNCTION(0x3, "mmc2")),         /* D1 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 10),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NDQ2 */
>> +                 SUNXI_FUNCTION(0x3, "mmc2")),         /* D2 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 11),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NDQ3 */
>> +                 SUNXI_FUNCTION(0x3, "mmc2")),         /* D3 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 12),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NDQ4 */
>> +                 SUNXI_FUNCTION(0x3, "mmc2")),         /* D4 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 13),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NDQ5 */
>> +                 SUNXI_FUNCTION(0x3, "mmc2")),         /* D5 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NDQ6 */
>> +                 SUNXI_FUNCTION(0x3, "mmc2")),         /* D6 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NDQ7 */
>> +                 SUNXI_FUNCTION(0x3, "mmc2")),         /* D7 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "nand0"),         /* NDQS */
>> +                 SUNXI_FUNCTION(0x3, "mmc2")),         /* RST */
>> +       /* Hole */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 0),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D2 */
>> +                 SUNXI_FUNCTION(0x3, "uart3"),         /* TX */
>> +                 SUNXI_FUNCTION(0x4, "spi1"),          /* CS */
>> +                 SUNXI_FUNCTION(0x5, "ccir")),         /* CLK */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 1),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D3 */
>> +                 SUNXI_FUNCTION(0x3, "uart3"),         /* RX */
>> +                 SUNXI_FUNCTION(0x4, "spi1"),          /* CLK */
>> +                 SUNXI_FUNCTION(0x5, "ccir")),         /* DE */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 2),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D4 */
>> +                 SUNXI_FUNCTION(0x3, "uart4"),         /* TX */
>> +                 SUNXI_FUNCTION(0x4, "spi1"),          /* MOSI */
>> +                 SUNXI_FUNCTION(0x5, "ccir")),         /* HSYNC */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 3),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D5 */
>> +                 SUNXI_FUNCTION(0x3, "uart4"),         /* RX */
>> +                 SUNXI_FUNCTION(0x4, "spi1"),          /* MISO */
>> +                 SUNXI_FUNCTION(0x5, "ccir")),         /* VSYNC */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 4),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D6 */
>> +                 SUNXI_FUNCTION(0x3, "uart4"),         /* RTS */
>> +                 SUNXI_FUNCTION(0x5, "ccir")),         /* D0 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 5),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D7 */
>> +                 SUNXI_FUNCTION(0x3, "uart4"),         /* CTS */
>> +                 SUNXI_FUNCTION(0x5, "ccir")),         /* D1 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 6),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D10 */
>> +                 SUNXI_FUNCTION(0x5, "ccir")),         /* D2 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 7),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D11 */
>> +                 SUNXI_FUNCTION(0x5, "ccir")),         /* D3 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 8),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D12 */
>> +                 SUNXI_FUNCTION(0x4, "emac"),          /* ERXD3 */
>> +                 SUNXI_FUNCTION(0x5, "ccir")),         /* D4 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 9),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D13 */
>> +                 SUNXI_FUNCTION(0x4, "emac"),          /* ERXD2 */
>> +                 SUNXI_FUNCTION(0x5, "ccir")),         /* D5 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 10),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D14 */
>> +                 SUNXI_FUNCTION(0x4, "emac")),         /* ERXD1 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 11),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D15 */
>> +                 SUNXI_FUNCTION(0x4, "emac")),         /* ERXD0 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 12),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D18 */
>> +                 SUNXI_FUNCTION(0x3, "lvds0"),         /* VP0 */
>> +                 SUNXI_FUNCTION(0x4, "emac")),         /* ERXCK */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 13),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D19 */
>> +                 SUNXI_FUNCTION(0x3, "lvds0"),         /* VN0 */
>> +                 SUNXI_FUNCTION(0x4, "emac")),         /* ERXCTL */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 14),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D20 */
>> +                 SUNXI_FUNCTION(0x3, "lvds0"),         /* VP1 */
>> +                 SUNXI_FUNCTION(0x4, "emac")),         /* ENULL */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 15),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D21 */
>> +                 SUNXI_FUNCTION(0x3, "lvds0"),         /* VN1 */
>> +                 SUNXI_FUNCTION(0x4, "emac"),          /* ETXD3 */
>> +                 SUNXI_FUNCTION(0x5, "ccir")),         /* D6 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 16),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D22 */
>> +                 SUNXI_FUNCTION(0x3, "lvds0"),         /* VP2 */
>> +                 SUNXI_FUNCTION(0x4, "emac"),          /* ETXD2 */
>> +                 SUNXI_FUNCTION(0x5, "ccir")),         /* D7 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 17),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* D23 */
>> +                 SUNXI_FUNCTION(0x3, "lvds0"),         /* VN2 */
>> +                 SUNXI_FUNCTION(0x4, "emac")),         /* ETXD1 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 18),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* CLK */
>> +                 SUNXI_FUNCTION(0x3, "lvds0"),         /* VPC */
>> +                 SUNXI_FUNCTION(0x4, "emac")),         /* ETXD0 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 19),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* DE */
>> +                 SUNXI_FUNCTION(0x3, "lvds0"),         /* VNC */
>> +                 SUNXI_FUNCTION(0x4, "emac")),         /* ETXCK */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 20),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* HSYNC */
>> +                 SUNXI_FUNCTION(0x3, "lvds0"),         /* VP3 */
>> +                 SUNXI_FUNCTION(0x4, "emac")),         /* ETXCTL */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 21),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "lcd0"),          /* VSYNC */
>> +                 SUNXI_FUNCTION(0x3, "lvds0"),         /* VN3 */
>> +                 SUNXI_FUNCTION(0x4, "emac")),         /* ECLKIN */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 22),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "pwm"),           /* PWM0 */
>> +                 SUNXI_FUNCTION(0x4, "emac")),         /* EMDC */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 23),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x4, "emac")),         /* EMDIO */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 24),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out")),
>> +       /* Hole */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 0),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "csi0"),          /* PCK */
>> +                 SUNXI_FUNCTION(0x4, "ts0")),          /* CLK */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 1),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "csi0"),          /* CK */
>> +                 SUNXI_FUNCTION(0x4, "ts0")),          /* ERR */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 2),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "csi0"),          /* HSYNC */
>> +                 SUNXI_FUNCTION(0x4, "ts0")),          /* SYNC */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 3),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "csi0"),          /* VSYNC */
>> +                 SUNXI_FUNCTION(0x4, "ts0")),          /* DVLD */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 4),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "csi0"),          /* D0 */
>> +                 SUNXI_FUNCTION(0x4, "ts0")),          /* D0 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 5),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "csi0"),          /* D1 */
>> +                 SUNXI_FUNCTION(0x4, "ts0")),          /* D1 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 6),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "csi0"),          /* D2 */
>> +                 SUNXI_FUNCTION(0x4, "ts0")),          /* D2 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 7),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "csi0"),          /* D3 */
>> +                 SUNXI_FUNCTION(0x4, "ts0")),          /* D3 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 8),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "csi0"),          /* D4 */
>> +                 SUNXI_FUNCTION(0x4, "ts0")),          /* D4 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 9),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "csi0"),          /* D5 */
>> +                 SUNXI_FUNCTION(0x4, "ts0")),          /* D5 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 10),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "csi0"),          /* D6 */
>> +                 SUNXI_FUNCTION(0x4, "ts0")),          /* D6 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 11),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "csi0"),          /* D7 */
>> +                 SUNXI_FUNCTION(0x4, "ts0")),          /* D7 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 12),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "csi0")),         /* SCK */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 13),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "csi0")),         /* SDA */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 14),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "pll"),           /* LOCK_DBG */
>> +                 SUNXI_FUNCTION(0x3, "i2c2")),         /* SCK */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 15),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x3, "i2c2")),         /* SDA */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 16),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out")),
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 17),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out")),
>> +       /* Hole */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "mmc0"),          /* D1 */
>> +                 SUNXI_FUNCTION(0x3, "jtag")),         /* MSI */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 1),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "mmc0"),          /* D0 */
>> +                 SUNXI_FUNCTION(0x3, "jtag")),         /* DI1 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 2),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "mmc0"),          /* CLK */
>> +                 SUNXI_FUNCTION(0x3, "uart0")),        /* TX */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 3),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "mmc0"),          /* CMD */
>> +                 SUNXI_FUNCTION(0x3, "jtag")),         /* DO1 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 4),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "mmc0"),          /* D3 */
>> +                 SUNXI_FUNCTION(0x4, "uart0")),        /* RX */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 5),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "mmc0"),          /* D2 */
>> +                 SUNXI_FUNCTION(0x3, "jtag")),         /* CK1 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 6),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out")),
>> +       /* Hole */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "mmc1"),          /* CLK */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 0)),          /* EINT0 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "mmc1"),          /* CMD */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 1)),          /* EINT1 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "mmc1"),          /* D0 */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 2)),          /* EINT2 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "mmc1"),          /* D1 */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 3)),          /* EINT3 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 4),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "mmc1"),          /* D2 */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 4)),          /* EINT4 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "mmc1"),          /* D3 */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 5)),          /* EINT5 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 6),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "uart1"),         /* TX */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 6)),          /* EINT6 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 7),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "uart1"),         /* RX */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 7)),          /* EINT7 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "uart1"),         /* RTS */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 8)),          /* EINT8 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "uart1"),         /* CTS */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 9)),          /* EINT9 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "aif3"),          /* SYNC */
>> +                 SUNXI_FUNCTION(0x3, "i2s1"),          /* SYNC */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 10)),         /* EINT10 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 11),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "aif3"),          /* BCLK */
>> +                 SUNXI_FUNCTION(0x3, "i2s1"),          /* BCLK */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 11)),         /* EINT11 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 12),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "aif3"),          /* DOUT */
>> +                 SUNXI_FUNCTION(0x3, "i2s1"),          /* DOUT */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 12)),         /* EINT12 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 13),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "aif3"),          /* DIN */
>> +                 SUNXI_FUNCTION(0x3, "i2s1"),          /* DIN */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 13)),         /* EINT13 */
>> +       /* Hole */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 0),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "i2c0"),          /* SCK */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 0)),          /* EINT0 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 1),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "i2c0"),          /* SDA */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 1)),          /* EINT1 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 2),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "i2c1"),          /* SCK */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 2)),          /* EINT2 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 3),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "i2c1"),          /* SDA */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 3)),          /* EINT3 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 4),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "uart3"),         /* TX */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 4)),          /* EINT4 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 5),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "uart3"),         /* RX */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 5)),          /* EINT5 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 6),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "uart3"),         /* RTS */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 6)),          /* EINT6 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 7),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "uart3"),         /* CTS */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 7)),          /* EINT7 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 8),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "owa"),           /* OUT */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 8)),          /* EINT8 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 9),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION_IRQ(0x6, 9)),          /* EINT9 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 10),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "mic"),           /* CLK */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 10)),         /* EINT10 */
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 11),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "mic"),           /* DATA */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 11)),         /* EINT11 */
>> +};
>> +
>> +static const struct sunxi_pinctrl_desc a64_pinctrl_data = {
>> +       .pins = a64_pins,
>> +       .npins = ARRAY_SIZE(a64_pins),
>> +       .irq_banks = 1,
>> +};
>> +
>> +static int a64_pinctrl_probe(struct platform_device *pdev)
>> +{
>> +       return sunxi_pinctrl_init(pdev,
>> +                                 &a64_pinctrl_data);
>> +}
>> +
>> +static const struct of_device_id a64_pinctrl_match[] = {
>> +       { .compatible = "allwinner,a64-pinctrl", },
>> +       {}
>> +};
>> +MODULE_DEVICE_TABLE(of, a64_pinctrl_match);
>> +
>> +static struct platform_driver a64_pinctrl_driver = {
>> +       .probe  = a64_pinctrl_probe,
>> +       .driver = {
>> +               .name           = "a64-pinctrl",
>> +               .of_match_table = a64_pinctrl_match,
>> +       },
>> +};
>> +module_platform_driver(a64_pinctrl_driver);
>> +
>> +MODULE_AUTHOR("Andre Przywara <andre.przywara@arm.com>");
>> +MODULE_DESCRIPTION("Allwinner A64 pinctrl driver");
>> +MODULE_LICENSE("GPL");
> 
> I've verified that all the bit configurations are correct as per A64
> user manual.

Wow, great! Thanks a lot for this!

Cheers,
Andre.
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Maxime Ripard Jan. 4, 2016, 8:30 p.m. UTC | #4
Hi Andre,

On Mon, Jan 04, 2016 at 10:29:06AM +0000, Andre Przywara wrote:
> >> diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile
> >> index e080290..130e7bc 100644
> >> --- a/drivers/pinctrl/sunxi/Makefile
> >> +++ b/drivers/pinctrl/sunxi/Makefile
> >> @@ -12,5 +12,6 @@ obj-$(CONFIG_PINCTRL_SUN7I_A20)               += pinctrl-sun7i-a20.o
> >>  obj-$(CONFIG_PINCTRL_SUN8I_A23)                += pinctrl-sun8i-a23.o
> >>  obj-$(CONFIG_PINCTRL_SUN8I_A23_R)      += pinctrl-sun8i-a23-r.o
> >>  obj-$(CONFIG_PINCTRL_SUN8I_A33)                += pinctrl-sun8i-a33.o
> >> +obj-$(CONFIG_PINCTRL_A64)              += pinctrl-a64.o
> > 
> > Shouldn't this follow pinctrl config name like other sunXi SOCs?
> > This should be PINCTRL_SUN??_A64.
> 
> I never really got the reason we use those sunxi names in addition to
> the SoC name in the first place, maybe apart from copying from some
> Allwinner code.
> Since I decided to not look at Allwinner's BSP at all (if avoidable), I
> also thought it would be time to drop that sunxi naming, which looks
> redundant to me.
> Is there any reason why we would need this (beside having a rather
> unique identifier prefix)?

It's mostly historical.


Back when we started this, There was a few SoCs already out: A10,
A10s, A12 and A13, which was very similar to the Cortex-A naming
scheme (and I think the Cortex-A12 was also announced at the time).

We couldn't really use the SoC family either, since there was already
multiple SoCs that were part of the same family (the A10s, A12 and
A13, part of the sun5i family).

In order to avoid any confusion, we chose to go with both to uniquely
and without any confusion possible, and we just went on with that
naming scheme for consistency.

Maxime
Andre Przywara Jan. 5, 2016, noon UTC | #5
Hi Maxime,

On 04/01/16 20:30, Maxime Ripard wrote:
> Hi Andre,
> 
> On Mon, Jan 04, 2016 at 10:29:06AM +0000, Andre Przywara wrote:
>>>> diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile
>>>> index e080290..130e7bc 100644
>>>> --- a/drivers/pinctrl/sunxi/Makefile
>>>> +++ b/drivers/pinctrl/sunxi/Makefile
>>>> @@ -12,5 +12,6 @@ obj-$(CONFIG_PINCTRL_SUN7I_A20)               += pinctrl-sun7i-a20.o
>>>>  obj-$(CONFIG_PINCTRL_SUN8I_A23)                += pinctrl-sun8i-a23.o
>>>>  obj-$(CONFIG_PINCTRL_SUN8I_A23_R)      += pinctrl-sun8i-a23-r.o
>>>>  obj-$(CONFIG_PINCTRL_SUN8I_A33)                += pinctrl-sun8i-a33.o
>>>> +obj-$(CONFIG_PINCTRL_A64)              += pinctrl-a64.o
>>>
>>> Shouldn't this follow pinctrl config name like other sunXi SOCs?
>>> This should be PINCTRL_SUN??_A64.
>>
>> I never really got the reason we use those sunxi names in addition to
>> the SoC name in the first place, maybe apart from copying from some
>> Allwinner code.
>> Since I decided to not look at Allwinner's BSP at all (if avoidable), I
>> also thought it would be time to drop that sunxi naming, which looks
>> redundant to me.
>> Is there any reason why we would need this (beside having a rather
>> unique identifier prefix)?
> 
> It's mostly historical.
> 
> 
> Back when we started this, There was a few SoCs already out: A10,
> A10s, A12 and A13, which was very similar to the Cortex-A naming
> scheme (and I think the Cortex-A12 was also announced at the time).
> 
> We couldn't really use the SoC family either, since there was already
> multiple SoCs that were part of the same family (the A10s, A12 and
> A13, part of the sun5i family).
> 
> In order to avoid any confusion, we chose to go with both to uniquely
> and without any confusion possible, and we just went on with that
> naming scheme for consistency.

I see, thanks for the explanation.
I was wondering since we now move to a new architecture as well to avoid
this historic "ballast", but I have no problems with adding "_sun50i_"
to the identifiers and file names.
To me as only a casual sunxi user I found it mostly hard to memorize the
connections between the sunxi numbering and the SoC names (I just know
that the A20 is sun7i ;-). So for finding a specific dts for instance,
you have to start with the sunxi number to get it TAB completed ...

With that being said: Would you prefer to have a sun50i prefix? I see
that having just "a64" on itself is not very specific.

Please let me know so that I can amend the code for the next post.

Cheers,
Andre.
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Maxime Ripard Jan. 6, 2016, 9:12 p.m. UTC | #6
Hi Andre,

On Tue, Jan 05, 2016 at 12:00:11PM +0000, Andre Przywara wrote:
> Hi Maxime,
> 
> On 04/01/16 20:30, Maxime Ripard wrote:
> > Hi Andre,
> > 
> > On Mon, Jan 04, 2016 at 10:29:06AM +0000, Andre Przywara wrote:
> >>>> diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile
> >>>> index e080290..130e7bc 100644
> >>>> --- a/drivers/pinctrl/sunxi/Makefile
> >>>> +++ b/drivers/pinctrl/sunxi/Makefile
> >>>> @@ -12,5 +12,6 @@ obj-$(CONFIG_PINCTRL_SUN7I_A20)               += pinctrl-sun7i-a20.o
> >>>>  obj-$(CONFIG_PINCTRL_SUN8I_A23)                += pinctrl-sun8i-a23.o
> >>>>  obj-$(CONFIG_PINCTRL_SUN8I_A23_R)      += pinctrl-sun8i-a23-r.o
> >>>>  obj-$(CONFIG_PINCTRL_SUN8I_A33)                += pinctrl-sun8i-a33.o
> >>>> +obj-$(CONFIG_PINCTRL_A64)              += pinctrl-a64.o
> >>>
> >>> Shouldn't this follow pinctrl config name like other sunXi SOCs?
> >>> This should be PINCTRL_SUN??_A64.
> >>
> >> I never really got the reason we use those sunxi names in addition to
> >> the SoC name in the first place, maybe apart from copying from some
> >> Allwinner code.
> >> Since I decided to not look at Allwinner's BSP at all (if avoidable), I
> >> also thought it would be time to drop that sunxi naming, which looks
> >> redundant to me.
> >> Is there any reason why we would need this (beside having a rather
> >> unique identifier prefix)?
> > 
> > It's mostly historical.
> > 
> > 
> > Back when we started this, There was a few SoCs already out: A10,
> > A10s, A12 and A13, which was very similar to the Cortex-A naming
> > scheme (and I think the Cortex-A12 was also announced at the time).
> > 
> > We couldn't really use the SoC family either, since there was already
> > multiple SoCs that were part of the same family (the A10s, A12 and
> > A13, part of the sun5i family).
> > 
> > In order to avoid any confusion, we chose to go with both to uniquely
> > and without any confusion possible, and we just went on with that
> > naming scheme for consistency.
> 
> I see, thanks for the explanation.
> I was wondering since we now move to a new architecture as well to avoid
> this historic "ballast", but I have no problems with adding "_sun50i_"
> to the identifiers and file names.
> To me as only a casual sunxi user I found it mostly hard to memorize the
> connections between the sunxi numbering and the SoC names (I just know
> that the A20 is sun7i ;-). So for finding a specific dts for instance,
> you have to start with the sunxi number to get it TAB completed ...

I guess it doesn't really matter for arm64, since it seems like
there's a sub-folder per SoC family.

However, having an a12.dtsi in arch/arm/boot/dts will probably bring a
lot of confusion :)

I still think that we should maintain the current compatible scheme
though, in order to keep consistency.

> With that being said: Would you prefer to have a sun50i prefix? I see
> that having just "a64" on itself is not very specific.

I'd say that having a DTSI in arch/arm64/boot/dts/sunxi/a64.dtsi would
not bring a lot of confusion. If you're there, you know what you're
dealing with already.

If you feel like it makes the life easier to new or casual users, go
ahead.

Maxime
Amit Tomer March 28, 2016, 4:15 p.m. UTC | #7
Hello ,

> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 11),
> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
> +                 SUNXI_FUNCTION(0x2, "mic"),           /* DATA */
> +                 SUNXI_FUNCTION_IRQ(0x6, 11)),         /* EINT11 */
> +};
> +

Sorry to intervene here but is there any specific reason for not
covering Bank from PL0 - PL12(as it is mentioned in Datasheet) ?

Thanks,
Amit
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Chen-Yu Tsai March 28, 2016, 4:19 p.m. UTC | #8
On Tue, Mar 29, 2016 at 12:15 AM, Amit Tomer <amittomer25@gmail.com> wrote:
> Hello ,
>
>> +       SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 11),
>> +                 SUNXI_FUNCTION(0x0, "gpio_in"),
>> +                 SUNXI_FUNCTION(0x1, "gpio_out"),
>> +                 SUNXI_FUNCTION(0x2, "mic"),           /* DATA */
>> +                 SUNXI_FUNCTION_IRQ(0x6, 11)),         /* EINT11 */
>> +};
>> +
>
> Sorry to intervene here but is there any specific reason for not
> covering Bank from PL0 - PL12(as it is mentioned in Datasheet) ?


The PL bank is a separate controller (R_PIO), and would be covered by
a separate driver.
See the other sunxi drivers.

ChenYu
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Amit Tomer March 28, 2016, 4:52 p.m. UTC | #9
> The PL bank is a separate controller (R_PIO), and would be covered by
> a separate driver.
> See the other sunxi drivers.

Ok, Thanks for the clarification.
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 4043c35..4dbec84 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -1,5 +1,11 @@ 
 menu "Platform selection"
 
+config ARCH_SUNXI
+	bool "Allwinner sunxi 64-bit SoC Family"
+	select PINCTRL_A64
+	help
+	  This enables support for Allwinner sunxi based SoCs like the A64.
+
 config ARCH_BCM_IPROC
 	bool "Broadcom iProc SoC Family"
 	help
diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig
index e68fd95..ac47b5d 100644
--- a/drivers/pinctrl/sunxi/Kconfig
+++ b/drivers/pinctrl/sunxi/Kconfig
@@ -55,4 +55,8 @@  config PINCTRL_SUN9I_A80
 	def_bool MACH_SUN9I
 	select PINCTRL_SUNXI_COMMON
 
+config PINCTRL_A64
+	bool
+	select PINCTRL_SUNXI_COMMON
+
 endif
diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile
index e080290..130e7bc 100644
--- a/drivers/pinctrl/sunxi/Makefile
+++ b/drivers/pinctrl/sunxi/Makefile
@@ -12,5 +12,6 @@  obj-$(CONFIG_PINCTRL_SUN7I_A20)		+= pinctrl-sun7i-a20.o
 obj-$(CONFIG_PINCTRL_SUN8I_A23)		+= pinctrl-sun8i-a23.o
 obj-$(CONFIG_PINCTRL_SUN8I_A23_R)	+= pinctrl-sun8i-a23-r.o
 obj-$(CONFIG_PINCTRL_SUN8I_A33)		+= pinctrl-sun8i-a33.o
+obj-$(CONFIG_PINCTRL_A64)		+= pinctrl-a64.o
 obj-$(CONFIG_PINCTRL_SUN8I_A83T)	+= pinctrl-sun8i-a83t.o
 obj-$(CONFIG_PINCTRL_SUN9I_A80)		+= pinctrl-sun9i-a80.o
diff --git a/drivers/pinctrl/sunxi/pinctrl-a64.c b/drivers/pinctrl/sunxi/pinctrl-a64.c
new file mode 100644
index 0000000..00746d0
--- /dev/null
+++ b/drivers/pinctrl/sunxi/pinctrl-a64.c
@@ -0,0 +1,606 @@ 
+/*
+ * Allwinner A64 SoCs pinctrl driver.
+ *
+ * Copyright (C) 2016 - ARM Ltd.
+ * Author: Andre Przywara <andre.przywara@arm.com>
+ *
+ * Based on pinctrl-sun7i-a20.c, which is:
+ * Copyright (C) 2014 Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-sunxi.h"
+
+static const struct sunxi_desc_pin a64_pins[] = {
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 0),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart2"),		/* TX */
+		  SUNXI_FUNCTION(0x4, "jtag"),		/* MS0 */
+		  SUNXI_FUNCTION_IRQ(0x6, 0)),		/* EINT0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 1),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart2"),		/* RX */
+		  SUNXI_FUNCTION(0x4, "jtag"),		/* CK0 */
+		  SUNXI_FUNCTION(0x5, "sim"),		/* VCCEN */
+		  SUNXI_FUNCTION_IRQ(0x6, 1)),		/* EINT1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 2),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart2"),		/* RTS */
+		  SUNXI_FUNCTION(0x4, "jtag"),		/* DO0 */
+		  SUNXI_FUNCTION(0x5, "sim"),		/* VPPEN */
+		  SUNXI_FUNCTION_IRQ(0x6, 2)),		/* EINT2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart2"),		/* CTS */
+		  SUNXI_FUNCTION(0x3, "i2s0"),		/* MCLK */
+		  SUNXI_FUNCTION(0x4, "jtag"),		/* DI0 */
+		  SUNXI_FUNCTION(0x5, "sim"),		/* VPPPP */
+		  SUNXI_FUNCTION_IRQ(0x6, 3)),		/* EINT3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "aif2"),		/* SYNC */
+		  SUNXI_FUNCTION(0x3, "ac97"),		/* SYNC */
+		  SUNXI_FUNCTION(0x5, "sim"),		/* CLK */
+		  SUNXI_FUNCTION_IRQ(0x6, 4)),		/* EINT4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 5),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "aif2"),		/* BCLK */
+		  SUNXI_FUNCTION(0x3, "ac97"),		/* BCLK */
+		  SUNXI_FUNCTION(0x5, "sim"),		/* DATA */
+		  SUNXI_FUNCTION_IRQ(0x6, 5)),		/* EINT5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 6),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "aif2"),		/* DOUT */
+		  SUNXI_FUNCTION(0x3, "ac97"),		/* DOUT */
+		  SUNXI_FUNCTION(0x5, "sim"),		/* RST */
+		  SUNXI_FUNCTION_IRQ(0x6, 6)),		/* EINT6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 7),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "aif2"),		/* DIN */
+		  SUNXI_FUNCTION(0x3, "ac97"),		/* DIN */
+		  SUNXI_FUNCTION(0x5, "sim"),		/* DET */
+		  SUNXI_FUNCTION_IRQ(0x6, 7)),		/* EINT7 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 8),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x4, "uart0"),		/* TX */
+		  SUNXI_FUNCTION_IRQ(0x6, 8)),		/* EINT8 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 9),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x4, "uart0"),		/* RX */
+		  SUNXI_FUNCTION_IRQ(0x6, 9)),		/* EINT9 */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NWE */
+		  SUNXI_FUNCTION(0x4, "spi0")),		/* MOSI */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 1),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NALE */
+		  SUNXI_FUNCTION(0x3, "mmc2"),		/* DS */
+		  SUNXI_FUNCTION(0x4, "spi0")),		/* MISO */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 2),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NCLE */
+		  SUNXI_FUNCTION(0x4, "spi0")),		/* SCK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 3),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NCE1 */
+		  SUNXI_FUNCTION(0x4, "spi0")),		/* CS */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 4),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0")),	/* NCE0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 5),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NRE# */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* CLK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 6),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NRB0 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* CMD */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 7),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0")),	/* NRB1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 8),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ0 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 9),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ1 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 10),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ2 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 11),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ3 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 12),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ4 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 13),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ5 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ6 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQ7 */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D7 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* NDQS */
+		  SUNXI_FUNCTION(0x3, "mmc2")),		/* RST */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 0),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D2 */
+		  SUNXI_FUNCTION(0x3, "uart3"),		/* TX */
+		  SUNXI_FUNCTION(0x4, "spi1"),		/* CS */
+		  SUNXI_FUNCTION(0x5, "ccir")),		/* CLK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 1),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D3 */
+		  SUNXI_FUNCTION(0x3, "uart3"),		/* RX */
+		  SUNXI_FUNCTION(0x4, "spi1"),		/* CLK */
+		  SUNXI_FUNCTION(0x5, "ccir")),		/* DE */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 2),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D4 */
+		  SUNXI_FUNCTION(0x3, "uart4"),		/* TX */
+		  SUNXI_FUNCTION(0x4, "spi1"),		/* MOSI */
+		  SUNXI_FUNCTION(0x5, "ccir")),		/* HSYNC */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 3),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D5 */
+		  SUNXI_FUNCTION(0x3, "uart4"),		/* RX */
+		  SUNXI_FUNCTION(0x4, "spi1"),		/* MISO */
+		  SUNXI_FUNCTION(0x5, "ccir")),		/* VSYNC */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 4),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D6 */
+		  SUNXI_FUNCTION(0x3, "uart4"),		/* RTS */
+		  SUNXI_FUNCTION(0x5, "ccir")),		/* D0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 5),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D7 */
+		  SUNXI_FUNCTION(0x3, "uart4"),		/* CTS */
+		  SUNXI_FUNCTION(0x5, "ccir")),		/* D1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 6),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D10 */
+		  SUNXI_FUNCTION(0x5, "ccir")),		/* D2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 7),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D11 */
+		  SUNXI_FUNCTION(0x5, "ccir")),		/* D3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 8),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D12 */
+		  SUNXI_FUNCTION(0x4, "emac"),		/* ERXD3 */
+		  SUNXI_FUNCTION(0x5, "ccir")),		/* D4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 9),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D13 */
+		  SUNXI_FUNCTION(0x4, "emac"),		/* ERXD2 */
+		  SUNXI_FUNCTION(0x5, "ccir")),		/* D5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 10),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D14 */
+		  SUNXI_FUNCTION(0x4, "emac")),		/* ERXD1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 11),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D15 */
+		  SUNXI_FUNCTION(0x4, "emac")),		/* ERXD0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 12),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D18 */
+		  SUNXI_FUNCTION(0x3, "lvds0"),		/* VP0 */
+		  SUNXI_FUNCTION(0x4, "emac")),		/* ERXCK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 13),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D19 */
+		  SUNXI_FUNCTION(0x3, "lvds0"),		/* VN0 */
+		  SUNXI_FUNCTION(0x4, "emac")),		/* ERXCTL */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 14),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D20 */
+		  SUNXI_FUNCTION(0x3, "lvds0"),		/* VP1 */
+		  SUNXI_FUNCTION(0x4, "emac")),		/* ENULL */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 15),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D21 */
+		  SUNXI_FUNCTION(0x3, "lvds0"),		/* VN1 */
+		  SUNXI_FUNCTION(0x4, "emac"),		/* ETXD3 */
+		  SUNXI_FUNCTION(0x5, "ccir")),		/* D6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 16),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D22 */
+		  SUNXI_FUNCTION(0x3, "lvds0"),		/* VP2 */
+		  SUNXI_FUNCTION(0x4, "emac"),		/* ETXD2 */
+		  SUNXI_FUNCTION(0x5, "ccir")),		/* D7 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 17),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* D23 */
+		  SUNXI_FUNCTION(0x3, "lvds0"),		/* VN2 */
+		  SUNXI_FUNCTION(0x4, "emac")),		/* ETXD1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 18),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* CLK */
+		  SUNXI_FUNCTION(0x3, "lvds0"),		/* VPC */
+		  SUNXI_FUNCTION(0x4, "emac")),		/* ETXD0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 19),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* DE */
+		  SUNXI_FUNCTION(0x3, "lvds0"),		/* VNC */
+		  SUNXI_FUNCTION(0x4, "emac")),		/* ETXCK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 20),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* HSYNC */
+		  SUNXI_FUNCTION(0x3, "lvds0"),		/* VP3 */
+		  SUNXI_FUNCTION(0x4, "emac")),		/* ETXCTL */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 21),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "lcd0"),		/* VSYNC */
+		  SUNXI_FUNCTION(0x3, "lvds0"),		/* VN3 */
+		  SUNXI_FUNCTION(0x4, "emac")),		/* ECLKIN */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 22),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "pwm"),		/* PWM0 */
+		  SUNXI_FUNCTION(0x4, "emac")),		/* EMDC */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 23),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x4, "emac")),		/* EMDIO */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 24),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out")),
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 0),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi0"),		/* PCK */
+		  SUNXI_FUNCTION(0x4, "ts0")),		/* CLK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 1),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi0"),		/* CK */
+		  SUNXI_FUNCTION(0x4, "ts0")),		/* ERR */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 2),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi0"),		/* HSYNC */
+		  SUNXI_FUNCTION(0x4, "ts0")),		/* SYNC */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 3),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi0"),		/* VSYNC */
+		  SUNXI_FUNCTION(0x4, "ts0")),		/* DVLD */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 4),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi0"),		/* D0 */
+		  SUNXI_FUNCTION(0x4, "ts0")),		/* D0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 5),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi0"),		/* D1 */
+		  SUNXI_FUNCTION(0x4, "ts0")),		/* D1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 6),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi0"),		/* D2 */
+		  SUNXI_FUNCTION(0x4, "ts0")),		/* D2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 7),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi0"),		/* D3 */
+		  SUNXI_FUNCTION(0x4, "ts0")),		/* D3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 8),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi0"),		/* D4 */
+		  SUNXI_FUNCTION(0x4, "ts0")),		/* D4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 9),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi0"),		/* D5 */
+		  SUNXI_FUNCTION(0x4, "ts0")),		/* D5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 10),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi0"),		/* D6 */
+		  SUNXI_FUNCTION(0x4, "ts0")),		/* D6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 11),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi0"),		/* D7 */
+		  SUNXI_FUNCTION(0x4, "ts0")),		/* D7 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 12),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi0")),		/* SCK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 13),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "csi0")),		/* SDA */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 14),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "pll"),		/* LOCK_DBG */
+		  SUNXI_FUNCTION(0x3, "i2c2")),		/* SCK */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 15),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x3, "i2c2")),		/* SDA */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 16),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out")),
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 17),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out")),
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc0"),		/* D1 */
+		  SUNXI_FUNCTION(0x3, "jtag")),		/* MSI */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 1),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc0"),		/* D0 */
+		  SUNXI_FUNCTION(0x3, "jtag")),		/* DI1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 2),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc0"),		/* CLK */
+		  SUNXI_FUNCTION(0x3, "uart0")),	/* TX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 3),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc0"),		/* CMD */
+		  SUNXI_FUNCTION(0x3, "jtag")),		/* DO1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 4),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc0"),		/* D3 */
+		  SUNXI_FUNCTION(0x4, "uart0")),	/* RX */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 5),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc0"),		/* D2 */
+		  SUNXI_FUNCTION(0x3, "jtag")),		/* CK1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 6),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out")),
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1"),		/* CLK */
+		  SUNXI_FUNCTION_IRQ(0x6, 0)),		/* EINT0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1"),		/* CMD */
+		  SUNXI_FUNCTION_IRQ(0x6, 1)),		/* EINT1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1"),		/* D0 */
+		  SUNXI_FUNCTION_IRQ(0x6, 2)),		/* EINT2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1"),		/* D1 */
+		  SUNXI_FUNCTION_IRQ(0x6, 3)),		/* EINT3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 4),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1"),		/* D2 */
+		  SUNXI_FUNCTION_IRQ(0x6, 4)),		/* EINT4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mmc1"),		/* D3 */
+		  SUNXI_FUNCTION_IRQ(0x6, 5)),		/* EINT5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 6),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart1"),		/* TX */
+		  SUNXI_FUNCTION_IRQ(0x6, 6)),		/* EINT6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 7),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart1"),		/* RX */
+		  SUNXI_FUNCTION_IRQ(0x6, 7)),		/* EINT7 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 8),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart1"),		/* RTS */
+		  SUNXI_FUNCTION_IRQ(0x6, 8)),		/* EINT8 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 9),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart1"),		/* CTS */
+		  SUNXI_FUNCTION_IRQ(0x6, 9)),		/* EINT9 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 10),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "aif3"),		/* SYNC */
+		  SUNXI_FUNCTION(0x3, "i2s1"),		/* SYNC */
+		  SUNXI_FUNCTION_IRQ(0x6, 10)),		/* EINT10 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 11),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "aif3"),		/* BCLK */
+		  SUNXI_FUNCTION(0x3, "i2s1"),		/* BCLK */
+		  SUNXI_FUNCTION_IRQ(0x6, 11)),		/* EINT11 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 12),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "aif3"),		/* DOUT */
+		  SUNXI_FUNCTION(0x3, "i2s1"),		/* DOUT */
+		  SUNXI_FUNCTION_IRQ(0x6, 12)),		/* EINT12 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 13),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "aif3"),		/* DIN */
+		  SUNXI_FUNCTION(0x3, "i2s1"),		/* DIN */
+		  SUNXI_FUNCTION_IRQ(0x6, 13)),		/* EINT13 */
+	/* Hole */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 0),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c0"),		/* SCK */
+		  SUNXI_FUNCTION_IRQ(0x6, 0)),		/* EINT0 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 1),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c0"),		/* SDA */
+		  SUNXI_FUNCTION_IRQ(0x6, 1)),		/* EINT1 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 2),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c1"),		/* SCK */
+		  SUNXI_FUNCTION_IRQ(0x6, 2)),		/* EINT2 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 3),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "i2c1"),		/* SDA */
+		  SUNXI_FUNCTION_IRQ(0x6, 3)),		/* EINT3 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 4),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart3"),		/* TX */
+		  SUNXI_FUNCTION_IRQ(0x6, 4)),		/* EINT4 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 5),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart3"),		/* RX */
+		  SUNXI_FUNCTION_IRQ(0x6, 5)),		/* EINT5 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 6),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart3"),		/* RTS */
+		  SUNXI_FUNCTION_IRQ(0x6, 6)),		/* EINT6 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 7),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "uart3"),		/* CTS */
+		  SUNXI_FUNCTION_IRQ(0x6, 7)),		/* EINT7 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 8),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "owa"),		/* OUT */
+		  SUNXI_FUNCTION_IRQ(0x6, 8)),		/* EINT8 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 9),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION_IRQ(0x6, 9)),		/* EINT9 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 10),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mic"),		/* CLK */
+		  SUNXI_FUNCTION_IRQ(0x6, 10)),		/* EINT10 */
+	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 11),
+		  SUNXI_FUNCTION(0x0, "gpio_in"),
+		  SUNXI_FUNCTION(0x1, "gpio_out"),
+		  SUNXI_FUNCTION(0x2, "mic"),		/* DATA */
+		  SUNXI_FUNCTION_IRQ(0x6, 11)),		/* EINT11 */
+};
+
+static const struct sunxi_pinctrl_desc a64_pinctrl_data = {
+	.pins = a64_pins,
+	.npins = ARRAY_SIZE(a64_pins),
+	.irq_banks = 1,
+};
+
+static int a64_pinctrl_probe(struct platform_device *pdev)
+{
+	return sunxi_pinctrl_init(pdev,
+				  &a64_pinctrl_data);
+}
+
+static const struct of_device_id a64_pinctrl_match[] = {
+	{ .compatible = "allwinner,a64-pinctrl", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, a64_pinctrl_match);
+
+static struct platform_driver a64_pinctrl_driver = {
+	.probe	= a64_pinctrl_probe,
+	.driver	= {
+		.name		= "a64-pinctrl",
+		.of_match_table	= a64_pinctrl_match,
+	},
+};
+module_platform_driver(a64_pinctrl_driver);
+
+MODULE_AUTHOR("Andre Przywara <andre.przywara@arm.com>");
+MODULE_DESCRIPTION("Allwinner A64 pinctrl driver");
+MODULE_LICENSE("GPL");