root/drivers/pinctrl/mvebu/pinctrl-armada-cp110.c
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Marvell Armada CP110 pinctrl driver based on mvebu pinctrl core
 *
 * Copyright (C) 2017 Marvell
 *
 * Hanna Hawa <hannah@marvell.com>
 */

#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/of.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/platform_device.h>
#include <linux/property.h>

#include "pinctrl-mvebu.h"

/*
 * Even if the pin controller is the same the MMP available depend on the SoC
 * integration.
 *  - In Armada7K (single CP) almost all the MPPs are available (except the
 *    MMP 39 to 43)
 *  - In Armada8K (dual CP) the MPPs are split into 2 parts, MPPs 0-31 from
 *    CPS, and MPPs 32-62 from CPM, the below flags (V_ARMADA_8K_CPM,
 *    V_ARMADA_8K_CPS) set which MPP is available to the CPx.
 * The x_PLUS enum mean that the MPP available for CPx and for Armada70x0
 */
enum {
        V_ARMADA_7K = BIT(0),
        V_ARMADA_8K_CPM = BIT(1),
        V_ARMADA_8K_CPS = BIT(2),
        V_CP115_STANDALONE = BIT(3),
        V_ARMADA_7K_8K_CPM = (V_ARMADA_7K | V_ARMADA_8K_CPM),
        V_ARMADA_7K_8K_CPS = (V_ARMADA_7K | V_ARMADA_8K_CPS),
};

static struct mvebu_mpp_mode armada_cp110_mpp_modes[] = {
        MPP_MODE(0,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "ale1"),
                 MPP_FUNCTION(2,        "au",           "i2smclk"),
                 MPP_FUNCTION(3,        "ge0",          "rxd3"),
                 MPP_FUNCTION(4,        "tdm",          "pclk"),
                 MPP_FUNCTION(6,        "ptp",          "pulse"),
                 MPP_FUNCTION(7,        "mss_i2c",      "sda"),
                 MPP_FUNCTION(8,        "uart0",        "rxd"),
                 MPP_FUNCTION(9,        "sata0",        "present_act"),
                 MPP_FUNCTION(10,       "ge",           "mdio")),
        MPP_MODE(1,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "ale0"),
                 MPP_FUNCTION(2,        "au",           "i2sdo_spdifo"),
                 MPP_FUNCTION(3,        "ge0",          "rxd2"),
                 MPP_FUNCTION(4,        "tdm",          "drx"),
                 MPP_FUNCTION(6,        "ptp",          "clk"),
                 MPP_FUNCTION(7,        "mss_i2c",      "sck"),
                 MPP_FUNCTION(8,        "uart0",        "txd"),
                 MPP_FUNCTION(9,        "sata1",        "present_act"),
                 MPP_FUNCTION(10,       "ge",           "mdc")),
        MPP_MODE(2,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "ad15"),
                 MPP_FUNCTION(2,        "au",           "i2sextclk"),
                 MPP_FUNCTION(3,        "ge0",          "rxd1"),
                 MPP_FUNCTION(4,        "tdm",          "dtx"),
                 MPP_FUNCTION(5,        "mss_uart",     "rxd"),
                 MPP_FUNCTION(6,        "ptp",          "pclk_out"),
                 MPP_FUNCTION(7,        "i2c1",         "sck"),
                 MPP_FUNCTION(8,        "uart1",        "rxd"),
                 MPP_FUNCTION(9,        "sata0",        "present_act"),
                 MPP_FUNCTION(10,       "xg",           "mdc")),
        MPP_MODE(3,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "ad14"),
                 MPP_FUNCTION(2,        "au",           "i2slrclk"),
                 MPP_FUNCTION(3,        "ge0",          "rxd0"),
                 MPP_FUNCTION(4,        "tdm",          "fsync"),
                 MPP_FUNCTION(5,        "mss_uart",     "txd"),
                 MPP_FUNCTION(6,        "pcie",         "rstoutn"),
                 MPP_FUNCTION(7,        "i2c1",         "sda"),
                 MPP_FUNCTION(8,        "uart1",        "txd"),
                 MPP_FUNCTION(9,        "sata1",        "present_act"),
                 MPP_FUNCTION(10,       "xg",           "mdio")),
        MPP_MODE(4,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "ad13"),
                 MPP_FUNCTION(2,        "au",           "i2sbclk"),
                 MPP_FUNCTION(3,        "ge0",          "rxctl"),
                 MPP_FUNCTION(4,        "tdm",          "rstn"),
                 MPP_FUNCTION(5,        "mss_uart",     "rxd"),
                 MPP_FUNCTION(6,        "uart1",        "cts"),
                 MPP_FUNCTION(7,        "pcie0",        "clkreq"),
                 MPP_FUNCTION(8,        "uart3",        "rxd"),
                 MPP_FUNCTION(10,       "ge",           "mdc")),
        MPP_MODE(5,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "ad12"),
                 MPP_FUNCTION(2,        "au",           "i2sdi"),
                 MPP_FUNCTION(3,        "ge0",          "rxclk"),
                 MPP_FUNCTION(4,        "tdm",          "intn"),
                 MPP_FUNCTION(5,        "mss_uart",     "txd"),
                 MPP_FUNCTION(6,        "uart1",        "rts"),
                 MPP_FUNCTION(7,        "pcie1",        "clkreq"),
                 MPP_FUNCTION(8,        "uart3",        "txd"),
                 MPP_FUNCTION(10,       "ge",           "mdio")),
        MPP_MODE(6,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "ad11"),
                 MPP_FUNCTION(3,        "ge0",          "txd3"),
                 MPP_FUNCTION(4,        "spi0",         "csn2"),
                 MPP_FUNCTION(5,        "au",           "i2sextclk"),
                 MPP_FUNCTION(6,        "sata1",        "present_act"),
                 MPP_FUNCTION(7,        "pcie2",        "clkreq"),
                 MPP_FUNCTION(8,        "uart0",        "rxd"),
                 MPP_FUNCTION(9,        "ptp",          "pulse")),
        MPP_MODE(7,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "ad10"),
                 MPP_FUNCTION(3,        "ge0",          "txd2"),
                 MPP_FUNCTION(4,        "spi0",         "csn1"),
                 MPP_FUNCTION(5,        "spi1",         "csn1"),
                 MPP_FUNCTION(6,        "sata0",        "present_act"),
                 MPP_FUNCTION(7,        "led",          "data"),
                 MPP_FUNCTION(8,        "uart0",        "txd"),
                 MPP_FUNCTION(9,        "ptp",          "clk")),
        MPP_MODE(8,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "ad9"),
                 MPP_FUNCTION(3,        "ge0",          "txd1"),
                 MPP_FUNCTION(4,        "spi0",         "csn0"),
                 MPP_FUNCTION(5,        "spi1",         "csn0"),
                 MPP_FUNCTION(6,        "uart0",        "cts"),
                 MPP_FUNCTION(7,        "led",          "stb"),
                 MPP_FUNCTION(8,        "uart2",        "rxd"),
                 MPP_FUNCTION(9,        "ptp",          "pclk_out"),
                 MPP_FUNCTION(10,       "synce1",       "clk")),
        MPP_MODE(9,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "ad8"),
                 MPP_FUNCTION(3,        "ge0",          "txd0"),
                 MPP_FUNCTION(4,        "spi0",         "mosi"),
                 MPP_FUNCTION(5,        "spi1",         "mosi"),
                 MPP_FUNCTION(7,        "pcie",         "rstoutn"),
                 MPP_FUNCTION(10,       "synce2",       "clk")),
        MPP_MODE(10,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "readyn"),
                 MPP_FUNCTION(3,        "ge0",          "txctl"),
                 MPP_FUNCTION(4,        "spi0",         "miso"),
                 MPP_FUNCTION(5,        "spi1",         "miso"),
                 MPP_FUNCTION(6,        "uart0",        "cts"),
                 MPP_FUNCTION(7,        "sata1",        "present_act")),
        MPP_MODE(11,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "wen1"),
                 MPP_FUNCTION(3,        "ge0",          "txclkout"),
                 MPP_FUNCTION(4,        "spi0",         "clk"),
                 MPP_FUNCTION(5,        "spi1",         "clk"),
                 MPP_FUNCTION(6,        "uart0",        "rts"),
                 MPP_FUNCTION(7,        "led",          "clk"),
                 MPP_FUNCTION(8,        "uart2",        "txd"),
                 MPP_FUNCTION(9,        "sata0",        "present_act")),
        MPP_MODE(12,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "clk_out"),
                 MPP_FUNCTION(2,        "nf",           "rbn1"),
                 MPP_FUNCTION(3,        "spi1",         "csn1"),
                 MPP_FUNCTION(4,        "ge0",          "rxclk")),
        MPP_MODE(13,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "burstn"),
                 MPP_FUNCTION(2,        "nf",           "rbn0"),
                 MPP_FUNCTION(3,        "spi1",         "miso"),
                 MPP_FUNCTION(4,        "ge0",          "rxctl"),
                 MPP_FUNCTION(8,        "mss_spi",      "miso")),
        MPP_MODE(14,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "bootcsn"),
                 MPP_FUNCTION(2,        "dev",          "csn0"),
                 MPP_FUNCTION(3,        "spi1",         "csn0"),
                 MPP_FUNCTION(4,        "spi0",         "csn3"),
                 MPP_FUNCTION(5,        "au",           "i2sextclk"),
                 MPP_FUNCTION(6,        "spi0",         "miso"),
                 MPP_FUNCTION(7,        "sata0",        "present_act"),
                 MPP_FUNCTION(8,        "mss_spi",      "csn")),
        MPP_MODE(15,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "ad7"),
                 MPP_FUNCTION(3,        "spi1",         "mosi"),
                 MPP_FUNCTION(6,        "spi0",         "mosi"),
                 MPP_FUNCTION(8,        "mss_spi",      "mosi"),
                 MPP_FUNCTION(11,       "ptp",          "pulse_cp2cp")),
        MPP_MODE(16,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "ad6"),
                 MPP_FUNCTION(3,        "spi1",         "clk"),
                 MPP_FUNCTION(8,        "mss_spi",      "clk")),
        MPP_MODE(17,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "ad5"),
                 MPP_FUNCTION(4,        "ge0",          "txd3")),
        MPP_MODE(18,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "ad4"),
                 MPP_FUNCTION(4,        "ge0",          "txd2"),
                 MPP_FUNCTION(11,       "ptp",          "clk_cp2cp")),
        MPP_MODE(19,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "ad3"),
                 MPP_FUNCTION(4,        "ge0",          "txd1"),
                 MPP_FUNCTION(11,       "wakeup",       "out_cp2cp")),
        MPP_MODE(20,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "ad2"),
                 MPP_FUNCTION(4,        "ge0",          "txd0")),
        MPP_MODE(21,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "ad1"),
                 MPP_FUNCTION(4,        "ge0",          "txctl"),
                 MPP_FUNCTION(11,       "sei",          "in_cp2cp")),
        MPP_MODE(22,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "ad0"),
                 MPP_FUNCTION(4,        "ge0",          "txclkout"),
                 MPP_FUNCTION(11,       "wakeup",       "in_cp2cp")),
        MPP_MODE(23,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "a1"),
                 MPP_FUNCTION(5,        "au",           "i2smclk"),
                 MPP_FUNCTION(11,       "link",         "rd_in_cp2cp")),
        MPP_MODE(24,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "a0"),
                 MPP_FUNCTION(5,        "au",           "i2slrclk")),
        MPP_MODE(25,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "oen"),
                 MPP_FUNCTION(5,        "au",           "i2sdo_spdifo")),
        MPP_MODE(26,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "wen0"),
                 MPP_FUNCTION(5,        "au",           "i2sbclk")),
        MPP_MODE(27,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "csn0"),
                 MPP_FUNCTION(2,        "spi1",         "miso"),
                 MPP_FUNCTION(3,        "mss_gpio4",    NULL),
                 MPP_FUNCTION(4,        "ge0",          "rxd3"),
                 MPP_FUNCTION(5,        "spi0",         "csn4"),
                 MPP_FUNCTION(8,        "ge",           "mdio"),
                 MPP_FUNCTION(9,        "sata0",        "present_act"),
                 MPP_FUNCTION(10,       "uart0",        "rts"),
                 MPP_FUNCTION(11,       "rei",          "in_cp2cp")),
        MPP_MODE(28,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "csn1"),
                 MPP_FUNCTION(2,        "spi1",         "csn0"),
                 MPP_FUNCTION(3,        "mss_gpio5",    NULL),
                 MPP_FUNCTION(4,        "ge0",          "rxd2"),
                 MPP_FUNCTION(5,        "spi0",         "csn5"),
                 MPP_FUNCTION(6,        "pcie2",        "clkreq"),
                 MPP_FUNCTION(7,        "ptp",          "pulse"),
                 MPP_FUNCTION(8,        "ge",           "mdc"),
                 MPP_FUNCTION(9,        "sata1",        "present_act"),
                 MPP_FUNCTION(10,       "uart0",        "cts"),
                 MPP_FUNCTION(11,       "led",          "data")),
        MPP_MODE(29,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "csn2"),
                 MPP_FUNCTION(2,        "spi1",         "mosi"),
                 MPP_FUNCTION(3,        "mss_gpio6",    NULL),
                 MPP_FUNCTION(4,        "ge0",          "rxd1"),
                 MPP_FUNCTION(5,        "spi0",         "csn6"),
                 MPP_FUNCTION(6,        "pcie1",        "clkreq"),
                 MPP_FUNCTION(7,        "ptp",          "clk"),
                 MPP_FUNCTION(8,        "mss_i2c",      "sda"),
                 MPP_FUNCTION(9,        "sata0",        "present_act"),
                 MPP_FUNCTION(10,       "uart0",        "rxd"),
                 MPP_FUNCTION(11,       "led",          "stb")),
        MPP_MODE(30,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "csn3"),
                 MPP_FUNCTION(2,        "spi1",         "clk"),
                 MPP_FUNCTION(3,        "mss_gpio7",    NULL),
                 MPP_FUNCTION(4,        "ge0",          "rxd0"),
                 MPP_FUNCTION(5,        "spi0",         "csn7"),
                 MPP_FUNCTION(6,        "pcie0",        "clkreq"),
                 MPP_FUNCTION(7,        "ptp",          "pclk_out"),
                 MPP_FUNCTION(8,        "mss_i2c",      "sck"),
                 MPP_FUNCTION(9,        "sata1",        "present_act"),
                 MPP_FUNCTION(10,       "uart0",        "txd"),
                 MPP_FUNCTION(11,       "led",          "clk")),
        MPP_MODE(31,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "dev",          "a2"),
                 MPP_FUNCTION(3,        "mss_gpio4",    NULL),
                 MPP_FUNCTION(6,        "pcie",         "rstoutn"),
                 MPP_FUNCTION(8,        "ge",           "mdc")),
        MPP_MODE(32,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "mii",          "col"),
                 MPP_FUNCTION(2,        "mii",          "txerr"),
                 MPP_FUNCTION(3,        "mss_spi",      "miso"),
                 MPP_FUNCTION(4,        "tdm",          "drx"),
                 MPP_FUNCTION(5,        "au",           "i2sextclk"),
                 MPP_FUNCTION(6,        "au",           "i2sdi"),
                 MPP_FUNCTION(7,        "ge",           "mdio"),
                 MPP_FUNCTION(8,        "sdio",         "v18_en"),
                 MPP_FUNCTION(9,        "pcie1",        "clkreq"),
                 MPP_FUNCTION(10,       "mss_gpio0",    NULL)),
        MPP_MODE(33,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "mii",          "txclk"),
                 MPP_FUNCTION(2,        "sdio",         "pwr10"),
                 MPP_FUNCTION(3,        "mss_spi",      "csn"),
                 MPP_FUNCTION(4,        "tdm",          "fsync"),
                 MPP_FUNCTION(5,        "au",           "i2smclk"),
                 MPP_FUNCTION(6,        "sdio",         "bus_pwr"),
                 MPP_FUNCTION(8,        "xg",           "mdio"),
                 MPP_FUNCTION(9,        "pcie2",        "clkreq"),
                 MPP_FUNCTION(10,       "mss_gpio1",    NULL)),
        MPP_MODE(34,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "mii",          "rxerr"),
                 MPP_FUNCTION(2,        "sdio",         "pwr11"),
                 MPP_FUNCTION(3,        "mss_spi",      "mosi"),
                 MPP_FUNCTION(4,        "tdm",          "dtx"),
                 MPP_FUNCTION(5,        "au",           "i2slrclk"),
                 MPP_FUNCTION(6,        "sdio",         "wr_protect"),
                 MPP_FUNCTION(7,        "ge",           "mdc"),
                 MPP_FUNCTION(9,        "pcie0",        "clkreq"),
                 MPP_FUNCTION(10,       "mss_gpio2",    NULL)),
        MPP_MODE(35,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "sata1",        "present_act"),
                 MPP_FUNCTION(2,        "i2c1",         "sda"),
                 MPP_FUNCTION(3,        "mss_spi",      "clk"),
                 MPP_FUNCTION(4,        "tdm",          "pclk"),
                 MPP_FUNCTION(5,        "au",           "i2sdo_spdifo"),
                 MPP_FUNCTION(6,        "sdio",         "card_detect"),
                 MPP_FUNCTION(7,        "xg",           "mdio"),
                 MPP_FUNCTION(8,        "ge",           "mdio"),
                 MPP_FUNCTION(9,        "pcie",         "rstoutn"),
                 MPP_FUNCTION(10,       "mss_gpio3",    NULL)),
        MPP_MODE(36,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "synce2",       "clk"),
                 MPP_FUNCTION(2,        "i2c1",         "sck"),
                 MPP_FUNCTION(3,        "ptp",          "clk"),
                 MPP_FUNCTION(4,        "synce1",       "clk"),
                 MPP_FUNCTION(5,        "au",           "i2sbclk"),
                 MPP_FUNCTION(6,        "sata0",        "present_act"),
                 MPP_FUNCTION(7,        "xg",           "mdc"),
                 MPP_FUNCTION(8,        "ge",           "mdc"),
                 MPP_FUNCTION(9,        "pcie2",        "clkreq"),
                 MPP_FUNCTION(10,       "mss_gpio5",    NULL)),
        MPP_MODE(37,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "uart2",        "rxd"),
                 MPP_FUNCTION(2,        "i2c0",         "sck"),
                 MPP_FUNCTION(3,        "ptp",          "pclk_out"),
                 MPP_FUNCTION(4,        "tdm",          "intn"),
                 MPP_FUNCTION(5,        "mss_i2c",      "sck"),
                 MPP_FUNCTION(6,        "sata1",        "present_act"),
                 MPP_FUNCTION(7,        "ge",           "mdc"),
                 MPP_FUNCTION(8,        "xg",           "mdc"),
                 MPP_FUNCTION(9,        "pcie1",        "clkreq"),
                 MPP_FUNCTION(10,       "mss_gpio6",    NULL),
                 MPP_FUNCTION(11,       "link",         "rd_out_cp2cp")),
        MPP_MODE(38,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "uart2",        "txd"),
                 MPP_FUNCTION(2,        "i2c0",         "sda"),
                 MPP_FUNCTION(3,        "ptp",          "pulse"),
                 MPP_FUNCTION(4,        "tdm",          "rstn"),
                 MPP_FUNCTION(5,        "mss_i2c",      "sda"),
                 MPP_FUNCTION(6,        "sata0",        "present_act"),
                 MPP_FUNCTION(7,        "ge",           "mdio"),
                 MPP_FUNCTION(8,        "xg",           "mdio"),
                 MPP_FUNCTION(9,        "au",           "i2sextclk"),
                 MPP_FUNCTION(10,       "mss_gpio7",    NULL),
                 MPP_FUNCTION(11,       "ptp",          "pulse_cp2cp")),
        MPP_MODE(39,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "sdio",         "wr_protect"),
                 MPP_FUNCTION(4,        "au",           "i2sbclk"),
                 MPP_FUNCTION(5,        "ptp",          "clk"),
                 MPP_FUNCTION(6,        "spi0",         "csn1"),
                 MPP_FUNCTION(9,        "sata1",        "present_act"),
                 MPP_FUNCTION(10,       "mss_gpio0",    NULL)),
        MPP_MODE(40,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "sdio",         "pwr11"),
                 MPP_FUNCTION(2,        "synce1",       "clk"),
                 MPP_FUNCTION(3,        "mss_i2c",      "sda"),
                 MPP_FUNCTION(4,        "au",           "i2sdo_spdifo"),
                 MPP_FUNCTION(5,        "ptp",          "pclk_out"),
                 MPP_FUNCTION(6,        "spi0",         "clk"),
                 MPP_FUNCTION(7,        "uart1",        "txd"),
                 MPP_FUNCTION(8,        "ge",           "mdio"),
                 MPP_FUNCTION(9,        "sata0",        "present_act"),
                 MPP_FUNCTION(10,       "mss_gpio1",    NULL)),
        MPP_MODE(41,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "sdio",         "pwr10"),
                 MPP_FUNCTION(2,        "sdio",         "bus_pwr"),
                 MPP_FUNCTION(3,        "mss_i2c",      "sck"),
                 MPP_FUNCTION(4,        "au",           "i2slrclk"),
                 MPP_FUNCTION(5,        "ptp",          "pulse"),
                 MPP_FUNCTION(6,        "spi0",         "mosi"),
                 MPP_FUNCTION(7,        "uart1",        "rxd"),
                 MPP_FUNCTION(8,        "ge",           "mdc"),
                 MPP_FUNCTION(9,        "sata1",        "present_act"),
                 MPP_FUNCTION(10,       "mss_gpio2",    NULL),
                 MPP_FUNCTION(11,       "rei",          "out_cp2cp")),
        MPP_MODE(42,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "sdio",         "v18_en"),
                 MPP_FUNCTION(2,        "sdio",         "wr_protect"),
                 MPP_FUNCTION(3,        "synce2",       "clk"),
                 MPP_FUNCTION(4,        "au",           "i2smclk"),
                 MPP_FUNCTION(5,        "mss_uart",     "txd"),
                 MPP_FUNCTION(6,        "spi0",         "miso"),
                 MPP_FUNCTION(7,        "uart1",        "cts"),
                 MPP_FUNCTION(8,        "xg",           "mdc"),
                 MPP_FUNCTION(9,        "sata0",        "present_act"),
                 MPP_FUNCTION(10,       "mss_gpio4",    NULL)),
        MPP_MODE(43,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "sdio",         "card_detect"),
                 MPP_FUNCTION(3,        "synce1",       "clk"),
                 MPP_FUNCTION(4,        "au",           "i2sextclk"),
                 MPP_FUNCTION(5,        "mss_uart",     "rxd"),
                 MPP_FUNCTION(6,        "spi0",         "csn0"),
                 MPP_FUNCTION(7,        "uart1",        "rts"),
                 MPP_FUNCTION(8,        "xg",           "mdio"),
                 MPP_FUNCTION(9,        "sata1",        "present_act"),
                 MPP_FUNCTION(10,       "mss_gpio5",    NULL),
                 MPP_FUNCTION(11,       "wakeup",       "out_cp2cp")),
        MPP_MODE(44,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "ge1",          "txd2"),
                 MPP_FUNCTION(7,        "uart0",        "rts"),
                 MPP_FUNCTION(11,       "ptp",          "clk_cp2cp")),
        MPP_MODE(45,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "ge1",          "txd3"),
                 MPP_FUNCTION(7,        "uart0",        "txd"),
                 MPP_FUNCTION(9,        "pcie",         "rstoutn")),
        MPP_MODE(46,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "ge1",          "txd1"),
                 MPP_FUNCTION(7,        "uart1",        "rts")),
        MPP_MODE(47,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "ge1",          "txd0"),
                 MPP_FUNCTION(5,        "spi1",         "clk"),
                 MPP_FUNCTION(7,        "uart1",        "txd"),
                 MPP_FUNCTION(8,        "ge",           "mdc")),
        MPP_MODE(48,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "ge1",          "txctl_txen"),
                 MPP_FUNCTION(5,        "spi1",         "mosi"),
                 MPP_FUNCTION(8,        "xg",           "mdc"),
                 MPP_FUNCTION(11,       "wakeup",       "in_cp2cp")),
        MPP_MODE(49,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "ge1",          "txclkout"),
                 MPP_FUNCTION(2,        "mii",          "crs"),
                 MPP_FUNCTION(5,        "spi1",         "miso"),
                 MPP_FUNCTION(7,        "uart1",        "rxd"),
                 MPP_FUNCTION(8,        "ge",           "mdio"),
                 MPP_FUNCTION(9,        "pcie0",        "clkreq"),
                 MPP_FUNCTION(10,       "sdio",         "v18_en"),
                 MPP_FUNCTION(11,       "sei",          "out_cp2cp")),
        MPP_MODE(50,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "ge1",          "rxclk"),
                 MPP_FUNCTION(2,        "mss_i2c",      "sda"),
                 MPP_FUNCTION(5,        "spi1",         "csn0"),
                 MPP_FUNCTION(6,        "uart2",        "txd"),
                 MPP_FUNCTION(7,        "uart0",        "rxd"),
                 MPP_FUNCTION(8,        "xg",           "mdio"),
                 MPP_FUNCTION(10,       "sdio",         "pwr11")),
        MPP_MODE(51,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "ge1",          "rxd0"),
                 MPP_FUNCTION(2,        "mss_i2c",      "sck"),
                 MPP_FUNCTION(5,        "spi1",         "csn1"),
                 MPP_FUNCTION(6,        "uart2",        "rxd"),
                 MPP_FUNCTION(7,        "uart0",        "cts"),
                 MPP_FUNCTION(10,       "sdio",         "pwr10")),
        MPP_MODE(52,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "ge1",          "rxd1"),
                 MPP_FUNCTION(2,        "synce1",       "clk"),
                 MPP_FUNCTION(4,        "synce2",       "clk"),
                 MPP_FUNCTION(5,        "spi1",         "csn2"),
                 MPP_FUNCTION(7,        "uart1",        "cts"),
                 MPP_FUNCTION(8,        "led",          "clk"),
                 MPP_FUNCTION(9,        "pcie",         "rstoutn"),
                 MPP_FUNCTION(10,       "pcie0",        "clkreq")),
        MPP_MODE(53,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "ge1",          "rxd2"),
                 MPP_FUNCTION(3,        "ptp",          "clk"),
                 MPP_FUNCTION(5,        "spi1",         "csn3"),
                 MPP_FUNCTION(7,        "uart1",        "rxd"),
                 MPP_FUNCTION(8,        "led",          "stb"),
                 MPP_FUNCTION(11,       "sdio",         "led")),
        MPP_MODE(54,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "ge1",          "rxd3"),
                 MPP_FUNCTION(2,        "synce2",       "clk"),
                 MPP_FUNCTION(3,        "ptp",          "pclk_out"),
                 MPP_FUNCTION(4,        "synce1",       "clk"),
                 MPP_FUNCTION(8,        "led",          "data"),
                 MPP_FUNCTION(10,       "sdio",         "hw_rst"),
                 MPP_FUNCTION(11,       "sdio_wp",      "wr_protect")),
        MPP_MODE(55,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "ge1",          "rxctl_rxdv"),
                 MPP_FUNCTION(3,        "ptp",          "pulse"),
                 MPP_FUNCTION(10,       "sdio",         "led"),
                 MPP_FUNCTION(11,       "sdio_cd",      "card_detect")),
        MPP_MODE(56,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(4,        "tdm",          "drx"),
                 MPP_FUNCTION(5,        "au",           "i2sdo_spdifo"),
                 MPP_FUNCTION(6,        "spi0",         "clk"),
                 MPP_FUNCTION(7,        "uart1",        "rxd"),
                 MPP_FUNCTION(9,        "sata1",        "present_act"),
                 MPP_FUNCTION(14,       "sdio",         "clk")),
        MPP_MODE(57,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(2,        "mss_i2c",      "sda"),
                 MPP_FUNCTION(3,        "ptp",          "pclk_out"),
                 MPP_FUNCTION(4,        "tdm",          "intn"),
                 MPP_FUNCTION(5,        "au",           "i2sbclk"),
                 MPP_FUNCTION(6,        "spi0",         "mosi"),
                 MPP_FUNCTION(7,        "uart1",        "txd"),
                 MPP_FUNCTION(9,        "sata0",        "present_act"),
                 MPP_FUNCTION(14,       "sdio",         "cmd")),
        MPP_MODE(58,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(2,        "mss_i2c",      "sck"),
                 MPP_FUNCTION(3,        "ptp",          "clk"),
                 MPP_FUNCTION(4,        "tdm",          "rstn"),
                 MPP_FUNCTION(5,        "au",           "i2sdi"),
                 MPP_FUNCTION(6,        "spi0",         "miso"),
                 MPP_FUNCTION(7,        "uart1",        "cts"),
                 MPP_FUNCTION(8,        "led",          "clk"),
                 MPP_FUNCTION(14,       "sdio",         "d0")),
        MPP_MODE(59,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "mss_gpio7",    NULL),
                 MPP_FUNCTION(2,        "synce2",       "clk"),
                 MPP_FUNCTION(4,        "tdm",          "fsync"),
                 MPP_FUNCTION(5,        "au",           "i2slrclk"),
                 MPP_FUNCTION(6,        "spi0",         "csn0"),
                 MPP_FUNCTION(7,        "uart0",        "cts"),
                 MPP_FUNCTION(8,        "led",          "stb"),
                 MPP_FUNCTION(9,        "uart1",        "txd"),
                 MPP_FUNCTION(14,       "sdio",         "d1")),
        MPP_MODE(60,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "mss_gpio6",    NULL),
                 MPP_FUNCTION(3,        "ptp",          "pulse"),
                 MPP_FUNCTION(4,        "tdm",          "dtx"),
                 MPP_FUNCTION(5,        "au",           "i2smclk"),
                 MPP_FUNCTION(6,        "spi0",         "csn1"),
                 MPP_FUNCTION(7,        "uart0",        "rts"),
                 MPP_FUNCTION(8,        "led",          "data"),
                 MPP_FUNCTION(9,        "uart1",        "rxd"),
                 MPP_FUNCTION(14,       "sdio",         "d2")),
        MPP_MODE(61,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "mss_gpio5",    NULL),
                 MPP_FUNCTION(3,        "ptp",          "clk"),
                 MPP_FUNCTION(4,        "tdm",          "pclk"),
                 MPP_FUNCTION(5,        "au",           "i2sextclk"),
                 MPP_FUNCTION(6,        "spi0",         "csn2"),
                 MPP_FUNCTION(7,        "uart0",        "txd"),
                 MPP_FUNCTION(8,        "uart2",        "txd"),
                 MPP_FUNCTION(9,        "sata1",        "present_act"),
                 MPP_FUNCTION(10,       "ge",           "mdio"),
                 MPP_FUNCTION(14,       "sdio",         "d3")),
        MPP_MODE(62,
                 MPP_FUNCTION(0,        "gpio",         NULL),
                 MPP_FUNCTION(1,        "mss_gpio4",    NULL),
                 MPP_FUNCTION(2,        "synce1",       "clk"),
                 MPP_FUNCTION(3,        "ptp",          "pclk_out"),
                 MPP_FUNCTION(5,        "sata1",        "present_act"),
                 MPP_FUNCTION(6,        "spi0",         "csn3"),
                 MPP_FUNCTION(7,        "uart0",        "rxd"),
                 MPP_FUNCTION(8,        "uart2",        "rxd"),
                 MPP_FUNCTION(9,        "sata0",        "present_act"),
                 MPP_FUNCTION(10,       "ge",           "mdc"),
                 MPP_FUNCTION(14,       "sdio",         "ds")),
};

static const struct of_device_id armada_cp110_pinctrl_of_match[] = {
        {
                .compatible     = "marvell,armada-7k-pinctrl",
                .data           = (void *) V_ARMADA_7K,
        },
        {
                .compatible     = "marvell,armada-8k-cpm-pinctrl",
                .data           = (void *) V_ARMADA_8K_CPM,
        },
        {
                .compatible     = "marvell,armada-8k-cps-pinctrl",
                .data           = (void *) V_ARMADA_8K_CPS,
        },
        {
                .compatible     = "marvell,cp115-standalone-pinctrl",
                .data           = (void *) V_CP115_STANDALONE,
        },
        { },
};

static const struct mvebu_mpp_ctrl armada_cp110_mpp_controls[] = {
        MPP_FUNC_CTRL(0, 62, NULL, mvebu_regmap_mpp_ctrl),
};

static void mvebu_pinctrl_assign_variant(struct mvebu_mpp_mode *m,
                                         u8 variant)
{
        struct mvebu_mpp_ctrl_setting *s;

        for (s = m->settings ; s->name ; s++)
                s->variant = variant;
}

static int armada_cp110_pinctrl_probe(struct platform_device *pdev)
{
        struct mvebu_pinctrl_soc_info *soc;
        int i;

        if (!pdev->dev.parent)
                return -ENODEV;

        soc = devm_kzalloc(&pdev->dev,
                           sizeof(struct mvebu_pinctrl_soc_info), GFP_KERNEL);
        if (!soc)
                return -ENOMEM;

        soc->variant = (unsigned long)device_get_match_data(&pdev->dev) & 0xff;
        soc->controls = armada_cp110_mpp_controls;
        soc->ncontrols = ARRAY_SIZE(armada_cp110_mpp_controls);
        soc->modes = armada_cp110_mpp_modes;
        soc->nmodes = ARRAY_SIZE(armada_cp110_mpp_modes);
        for (i = 0; i < ARRAY_SIZE(armada_cp110_mpp_modes); i++) {
                struct mvebu_mpp_mode *m = &armada_cp110_mpp_modes[i];

                switch (i) {
                case 0 ... 31:
                        mvebu_pinctrl_assign_variant(m, (V_ARMADA_7K_8K_CPS |
                                                         V_CP115_STANDALONE));
                        break;
                case 32 ... 38:
                        mvebu_pinctrl_assign_variant(m, (V_ARMADA_7K_8K_CPM |
                                                         V_CP115_STANDALONE));
                        break;
                case 39 ... 43:
                        mvebu_pinctrl_assign_variant(m, (V_ARMADA_8K_CPM |
                                                         V_CP115_STANDALONE));
                        break;
                case 44 ... 62:
                        mvebu_pinctrl_assign_variant(m, (V_ARMADA_7K_8K_CPM |
                                                         V_CP115_STANDALONE));
                        break;
                }
        }
        pdev->dev.platform_data = soc;

        return mvebu_pinctrl_simple_regmap_probe(pdev, pdev->dev.parent, 0);
}

static struct platform_driver armada_cp110_pinctrl_driver = {
        .driver = {
                .name = "armada-cp110-pinctrl",
                .of_match_table = of_match_ptr(armada_cp110_pinctrl_of_match),
        },
        .probe = armada_cp110_pinctrl_probe,
};

builtin_platform_driver(armada_cp110_pinctrl_driver);