162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Marvell Dove pinctrl driver based on mvebu pinctrl core
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Author: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <linux/err.h>
962306a36Sopenharmony_ci#include <linux/init.h>
1062306a36Sopenharmony_ci#include <linux/io.h>
1162306a36Sopenharmony_ci#include <linux/bitops.h>
1262306a36Sopenharmony_ci#include <linux/platform_device.h>
1362306a36Sopenharmony_ci#include <linux/clk.h>
1462306a36Sopenharmony_ci#include <linux/of.h>
1562306a36Sopenharmony_ci#include <linux/of_device.h>
1662306a36Sopenharmony_ci#include <linux/mfd/syscon.h>
1762306a36Sopenharmony_ci#include <linux/pinctrl/pinctrl.h>
1862306a36Sopenharmony_ci#include <linux/regmap.h>
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci#include "pinctrl-mvebu.h"
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci/* Internal registers can be configured at any 1 MiB aligned address */
2362306a36Sopenharmony_ci#define INT_REGS_MASK		~(SZ_1M - 1)
2462306a36Sopenharmony_ci#define MPP4_REGS_OFFS		0xd0440
2562306a36Sopenharmony_ci#define PMU_REGS_OFFS		0xd802c
2662306a36Sopenharmony_ci#define GC_REGS_OFFS		0xe802c
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci/* MPP Base registers */
2962306a36Sopenharmony_ci#define PMU_MPP_GENERAL_CTRL	0x10
3062306a36Sopenharmony_ci#define  AU0_AC97_SEL		BIT(16)
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci/* MPP Control 4 register */
3362306a36Sopenharmony_ci#define SPI_GPIO_SEL		BIT(5)
3462306a36Sopenharmony_ci#define UART1_GPIO_SEL		BIT(4)
3562306a36Sopenharmony_ci#define AU1_GPIO_SEL		BIT(3)
3662306a36Sopenharmony_ci#define CAM_GPIO_SEL		BIT(2)
3762306a36Sopenharmony_ci#define SD1_GPIO_SEL		BIT(1)
3862306a36Sopenharmony_ci#define SD0_GPIO_SEL		BIT(0)
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci/* PMU Signal Select registers */
4162306a36Sopenharmony_ci#define PMU_SIGNAL_SELECT_0	0x00
4262306a36Sopenharmony_ci#define PMU_SIGNAL_SELECT_1	0x04
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci/* Global Config regmap registers */
4562306a36Sopenharmony_ci#define GLOBAL_CONFIG_1		0x00
4662306a36Sopenharmony_ci#define  TWSI_ENABLE_OPTION1	BIT(7)
4762306a36Sopenharmony_ci#define GLOBAL_CONFIG_2		0x04
4862306a36Sopenharmony_ci#define  TWSI_ENABLE_OPTION2	BIT(20)
4962306a36Sopenharmony_ci#define  TWSI_ENABLE_OPTION3	BIT(21)
5062306a36Sopenharmony_ci#define  TWSI_OPTION3_GPIO	BIT(22)
5162306a36Sopenharmony_ci#define SSP_CTRL_STATUS_1	0x08
5262306a36Sopenharmony_ci#define  SSP_ON_AU1		BIT(0)
5362306a36Sopenharmony_ci#define MPP_GENERAL_CONFIG	0x10
5462306a36Sopenharmony_ci#define  AU1_SPDIFO_GPIO_EN	BIT(1)
5562306a36Sopenharmony_ci#define  NAND_GPIO_EN		BIT(0)
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci#define CONFIG_PMU	BIT(4)
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_cistatic void __iomem *mpp4_base;
6062306a36Sopenharmony_cistatic void __iomem *pmu_base;
6162306a36Sopenharmony_cistatic struct regmap *gconfmap;
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_cistatic int dove_pmu_mpp_ctrl_get(struct mvebu_mpp_ctrl_data *data,
6462306a36Sopenharmony_ci				 unsigned pid, unsigned long *config)
6562306a36Sopenharmony_ci{
6662306a36Sopenharmony_ci	unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
6762306a36Sopenharmony_ci	unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
6862306a36Sopenharmony_ci	unsigned long pmu = readl(data->base + PMU_MPP_GENERAL_CTRL);
6962306a36Sopenharmony_ci	unsigned long func;
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	if ((pmu & BIT(pid)) == 0)
7262306a36Sopenharmony_ci		return mvebu_mmio_mpp_ctrl_get(data, pid, config);
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci	func = readl(pmu_base + PMU_SIGNAL_SELECT_0 + off);
7562306a36Sopenharmony_ci	*config = (func >> shift) & MVEBU_MPP_MASK;
7662306a36Sopenharmony_ci	*config |= CONFIG_PMU;
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci	return 0;
7962306a36Sopenharmony_ci}
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_cistatic int dove_pmu_mpp_ctrl_set(struct mvebu_mpp_ctrl_data *data,
8262306a36Sopenharmony_ci				 unsigned pid, unsigned long config)
8362306a36Sopenharmony_ci{
8462306a36Sopenharmony_ci	unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
8562306a36Sopenharmony_ci	unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
8662306a36Sopenharmony_ci	unsigned long pmu = readl(data->base + PMU_MPP_GENERAL_CTRL);
8762306a36Sopenharmony_ci	unsigned long func;
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci	if ((config & CONFIG_PMU) == 0) {
9062306a36Sopenharmony_ci		writel(pmu & ~BIT(pid), data->base + PMU_MPP_GENERAL_CTRL);
9162306a36Sopenharmony_ci		return mvebu_mmio_mpp_ctrl_set(data, pid, config);
9262306a36Sopenharmony_ci	}
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci	writel(pmu | BIT(pid), data->base + PMU_MPP_GENERAL_CTRL);
9562306a36Sopenharmony_ci	func = readl(pmu_base + PMU_SIGNAL_SELECT_0 + off);
9662306a36Sopenharmony_ci	func &= ~(MVEBU_MPP_MASK << shift);
9762306a36Sopenharmony_ci	func |= (config & MVEBU_MPP_MASK) << shift;
9862306a36Sopenharmony_ci	writel(func, pmu_base + PMU_SIGNAL_SELECT_0 + off);
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci	return 0;
10162306a36Sopenharmony_ci}
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_cistatic int dove_mpp4_ctrl_get(struct mvebu_mpp_ctrl_data *data, unsigned pid,
10462306a36Sopenharmony_ci			      unsigned long *config)
10562306a36Sopenharmony_ci{
10662306a36Sopenharmony_ci	unsigned long mpp4 = readl(mpp4_base);
10762306a36Sopenharmony_ci	unsigned long mask;
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci	switch (pid) {
11062306a36Sopenharmony_ci	case 24: /* mpp_camera */
11162306a36Sopenharmony_ci		mask = CAM_GPIO_SEL;
11262306a36Sopenharmony_ci		break;
11362306a36Sopenharmony_ci	case 40: /* mpp_sdio0 */
11462306a36Sopenharmony_ci		mask = SD0_GPIO_SEL;
11562306a36Sopenharmony_ci		break;
11662306a36Sopenharmony_ci	case 46: /* mpp_sdio1 */
11762306a36Sopenharmony_ci		mask = SD1_GPIO_SEL;
11862306a36Sopenharmony_ci		break;
11962306a36Sopenharmony_ci	case 58: /* mpp_spi0 */
12062306a36Sopenharmony_ci		mask = SPI_GPIO_SEL;
12162306a36Sopenharmony_ci		break;
12262306a36Sopenharmony_ci	case 62: /* mpp_uart1 */
12362306a36Sopenharmony_ci		mask = UART1_GPIO_SEL;
12462306a36Sopenharmony_ci		break;
12562306a36Sopenharmony_ci	default:
12662306a36Sopenharmony_ci		return -EINVAL;
12762306a36Sopenharmony_ci	}
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci	*config = ((mpp4 & mask) != 0);
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci	return 0;
13262306a36Sopenharmony_ci}
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_cistatic int dove_mpp4_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid,
13562306a36Sopenharmony_ci			      unsigned long config)
13662306a36Sopenharmony_ci{
13762306a36Sopenharmony_ci	unsigned long mpp4 = readl(mpp4_base);
13862306a36Sopenharmony_ci	unsigned long mask;
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci	switch (pid) {
14162306a36Sopenharmony_ci	case 24: /* mpp_camera */
14262306a36Sopenharmony_ci		mask = CAM_GPIO_SEL;
14362306a36Sopenharmony_ci		break;
14462306a36Sopenharmony_ci	case 40: /* mpp_sdio0 */
14562306a36Sopenharmony_ci		mask = SD0_GPIO_SEL;
14662306a36Sopenharmony_ci		break;
14762306a36Sopenharmony_ci	case 46: /* mpp_sdio1 */
14862306a36Sopenharmony_ci		mask = SD1_GPIO_SEL;
14962306a36Sopenharmony_ci		break;
15062306a36Sopenharmony_ci	case 58: /* mpp_spi0 */
15162306a36Sopenharmony_ci		mask = SPI_GPIO_SEL;
15262306a36Sopenharmony_ci		break;
15362306a36Sopenharmony_ci	case 62: /* mpp_uart1 */
15462306a36Sopenharmony_ci		mask = UART1_GPIO_SEL;
15562306a36Sopenharmony_ci		break;
15662306a36Sopenharmony_ci	default:
15762306a36Sopenharmony_ci		return -EINVAL;
15862306a36Sopenharmony_ci	}
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci	mpp4 &= ~mask;
16162306a36Sopenharmony_ci	if (config)
16262306a36Sopenharmony_ci		mpp4 |= mask;
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci	writel(mpp4, mpp4_base);
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci	return 0;
16762306a36Sopenharmony_ci}
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_cistatic int dove_nand_ctrl_get(struct mvebu_mpp_ctrl_data *data, unsigned pid,
17062306a36Sopenharmony_ci			      unsigned long *config)
17162306a36Sopenharmony_ci{
17262306a36Sopenharmony_ci	unsigned int gmpp;
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci	regmap_read(gconfmap, MPP_GENERAL_CONFIG, &gmpp);
17562306a36Sopenharmony_ci	*config = ((gmpp & NAND_GPIO_EN) != 0);
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci	return 0;
17862306a36Sopenharmony_ci}
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_cistatic int dove_nand_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid,
18162306a36Sopenharmony_ci			      unsigned long config)
18262306a36Sopenharmony_ci{
18362306a36Sopenharmony_ci	regmap_update_bits(gconfmap, MPP_GENERAL_CONFIG,
18462306a36Sopenharmony_ci			   NAND_GPIO_EN,
18562306a36Sopenharmony_ci			   (config) ? NAND_GPIO_EN : 0);
18662306a36Sopenharmony_ci	return 0;
18762306a36Sopenharmony_ci}
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_cistatic int dove_audio0_ctrl_get(struct mvebu_mpp_ctrl_data *data, unsigned pid,
19062306a36Sopenharmony_ci				unsigned long *config)
19162306a36Sopenharmony_ci{
19262306a36Sopenharmony_ci	unsigned long pmu = readl(data->base + PMU_MPP_GENERAL_CTRL);
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci	*config = ((pmu & AU0_AC97_SEL) != 0);
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci	return 0;
19762306a36Sopenharmony_ci}
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_cistatic int dove_audio0_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid,
20062306a36Sopenharmony_ci				unsigned long config)
20162306a36Sopenharmony_ci{
20262306a36Sopenharmony_ci	unsigned long pmu = readl(data->base + PMU_MPP_GENERAL_CTRL);
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci	pmu &= ~AU0_AC97_SEL;
20562306a36Sopenharmony_ci	if (config)
20662306a36Sopenharmony_ci		pmu |= AU0_AC97_SEL;
20762306a36Sopenharmony_ci	writel(pmu, data->base + PMU_MPP_GENERAL_CTRL);
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci	return 0;
21062306a36Sopenharmony_ci}
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_cistatic int dove_audio1_ctrl_get(struct mvebu_mpp_ctrl_data *data, unsigned pid,
21362306a36Sopenharmony_ci				unsigned long *config)
21462306a36Sopenharmony_ci{
21562306a36Sopenharmony_ci	unsigned int mpp4 = readl(mpp4_base);
21662306a36Sopenharmony_ci	unsigned int sspc1;
21762306a36Sopenharmony_ci	unsigned int gmpp;
21862306a36Sopenharmony_ci	unsigned int gcfg2;
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci	regmap_read(gconfmap, SSP_CTRL_STATUS_1, &sspc1);
22162306a36Sopenharmony_ci	regmap_read(gconfmap, MPP_GENERAL_CONFIG, &gmpp);
22262306a36Sopenharmony_ci	regmap_read(gconfmap, GLOBAL_CONFIG_2, &gcfg2);
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci	*config = 0;
22562306a36Sopenharmony_ci	if (mpp4 & AU1_GPIO_SEL)
22662306a36Sopenharmony_ci		*config |= BIT(3);
22762306a36Sopenharmony_ci	if (sspc1 & SSP_ON_AU1)
22862306a36Sopenharmony_ci		*config |= BIT(2);
22962306a36Sopenharmony_ci	if (gmpp & AU1_SPDIFO_GPIO_EN)
23062306a36Sopenharmony_ci		*config |= BIT(1);
23162306a36Sopenharmony_ci	if (gcfg2 & TWSI_OPTION3_GPIO)
23262306a36Sopenharmony_ci		*config |= BIT(0);
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_ci	/* SSP/TWSI only if I2S1 not set*/
23562306a36Sopenharmony_ci	if ((*config & BIT(3)) == 0)
23662306a36Sopenharmony_ci		*config &= ~(BIT(2) | BIT(0));
23762306a36Sopenharmony_ci	/* TWSI only if SPDIFO not set*/
23862306a36Sopenharmony_ci	if ((*config & BIT(1)) == 0)
23962306a36Sopenharmony_ci		*config &= ~BIT(0);
24062306a36Sopenharmony_ci	return 0;
24162306a36Sopenharmony_ci}
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_cistatic int dove_audio1_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid,
24462306a36Sopenharmony_ci				unsigned long config)
24562306a36Sopenharmony_ci{
24662306a36Sopenharmony_ci	unsigned int mpp4 = readl(mpp4_base);
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ci	mpp4 &= ~AU1_GPIO_SEL;
24962306a36Sopenharmony_ci	if (config & BIT(3))
25062306a36Sopenharmony_ci		mpp4 |= AU1_GPIO_SEL;
25162306a36Sopenharmony_ci	writel(mpp4, mpp4_base);
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_ci	regmap_update_bits(gconfmap, SSP_CTRL_STATUS_1,
25462306a36Sopenharmony_ci			   SSP_ON_AU1,
25562306a36Sopenharmony_ci			   (config & BIT(2)) ? SSP_ON_AU1 : 0);
25662306a36Sopenharmony_ci	regmap_update_bits(gconfmap, MPP_GENERAL_CONFIG,
25762306a36Sopenharmony_ci			   AU1_SPDIFO_GPIO_EN,
25862306a36Sopenharmony_ci			   (config & BIT(1)) ? AU1_SPDIFO_GPIO_EN : 0);
25962306a36Sopenharmony_ci	regmap_update_bits(gconfmap, GLOBAL_CONFIG_2,
26062306a36Sopenharmony_ci			   TWSI_OPTION3_GPIO,
26162306a36Sopenharmony_ci			   (config & BIT(0)) ? TWSI_OPTION3_GPIO : 0);
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ci	return 0;
26462306a36Sopenharmony_ci}
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ci/* mpp[52:57] gpio pins depend heavily on current config;
26762306a36Sopenharmony_ci * gpio_req does not try to mux in gpio capabilities to not
26862306a36Sopenharmony_ci * break other functions. If you require all mpps as gpio
26962306a36Sopenharmony_ci * enforce gpio setting by pinctrl mapping.
27062306a36Sopenharmony_ci */
27162306a36Sopenharmony_cistatic int dove_audio1_ctrl_gpio_req(struct mvebu_mpp_ctrl_data *data,
27262306a36Sopenharmony_ci				     unsigned pid)
27362306a36Sopenharmony_ci{
27462306a36Sopenharmony_ci	unsigned long config;
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_ci	dove_audio1_ctrl_get(data, pid, &config);
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_ci	switch (config) {
27962306a36Sopenharmony_ci	case 0x02: /* i2s1 : gpio[56:57] */
28062306a36Sopenharmony_ci	case 0x0e: /* ssp  : gpio[56:57] */
28162306a36Sopenharmony_ci		if (pid >= 56)
28262306a36Sopenharmony_ci			return 0;
28362306a36Sopenharmony_ci		return -ENOTSUPP;
28462306a36Sopenharmony_ci	case 0x08: /* spdifo : gpio[52:55] */
28562306a36Sopenharmony_ci	case 0x0b: /* twsi   : gpio[52:55] */
28662306a36Sopenharmony_ci		if (pid <= 55)
28762306a36Sopenharmony_ci			return 0;
28862306a36Sopenharmony_ci		return -ENOTSUPP;
28962306a36Sopenharmony_ci	case 0x0a: /* all gpio */
29062306a36Sopenharmony_ci		return 0;
29162306a36Sopenharmony_ci	/* 0x00 : i2s1/spdifo : no gpio */
29262306a36Sopenharmony_ci	/* 0x0c : ssp/spdifo  : no gpio */
29362306a36Sopenharmony_ci	/* 0x0f : ssp/twsi    : no gpio */
29462306a36Sopenharmony_ci	}
29562306a36Sopenharmony_ci	return -ENOTSUPP;
29662306a36Sopenharmony_ci}
29762306a36Sopenharmony_ci
29862306a36Sopenharmony_ci/* mpp[52:57] has gpio pins capable of in and out */
29962306a36Sopenharmony_cistatic int dove_audio1_ctrl_gpio_dir(struct mvebu_mpp_ctrl_data *data,
30062306a36Sopenharmony_ci				     unsigned pid, bool input)
30162306a36Sopenharmony_ci{
30262306a36Sopenharmony_ci	if (pid < 52 || pid > 57)
30362306a36Sopenharmony_ci		return -ENOTSUPP;
30462306a36Sopenharmony_ci	return 0;
30562306a36Sopenharmony_ci}
30662306a36Sopenharmony_ci
30762306a36Sopenharmony_cistatic int dove_twsi_ctrl_get(struct mvebu_mpp_ctrl_data *data, unsigned pid,
30862306a36Sopenharmony_ci			      unsigned long *config)
30962306a36Sopenharmony_ci{
31062306a36Sopenharmony_ci	unsigned int gcfg1;
31162306a36Sopenharmony_ci	unsigned int gcfg2;
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci	regmap_read(gconfmap, GLOBAL_CONFIG_1, &gcfg1);
31462306a36Sopenharmony_ci	regmap_read(gconfmap, GLOBAL_CONFIG_2, &gcfg2);
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_ci	*config = 0;
31762306a36Sopenharmony_ci	if (gcfg1 & TWSI_ENABLE_OPTION1)
31862306a36Sopenharmony_ci		*config = 1;
31962306a36Sopenharmony_ci	else if (gcfg2 & TWSI_ENABLE_OPTION2)
32062306a36Sopenharmony_ci		*config = 2;
32162306a36Sopenharmony_ci	else if (gcfg2 & TWSI_ENABLE_OPTION3)
32262306a36Sopenharmony_ci		*config = 3;
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ci	return 0;
32562306a36Sopenharmony_ci}
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_cistatic int dove_twsi_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid,
32862306a36Sopenharmony_ci			      unsigned long config)
32962306a36Sopenharmony_ci{
33062306a36Sopenharmony_ci	unsigned int gcfg1 = 0;
33162306a36Sopenharmony_ci	unsigned int gcfg2 = 0;
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ci	switch (config) {
33462306a36Sopenharmony_ci	case 1:
33562306a36Sopenharmony_ci		gcfg1 = TWSI_ENABLE_OPTION1;
33662306a36Sopenharmony_ci		break;
33762306a36Sopenharmony_ci	case 2:
33862306a36Sopenharmony_ci		gcfg2 = TWSI_ENABLE_OPTION2;
33962306a36Sopenharmony_ci		break;
34062306a36Sopenharmony_ci	case 3:
34162306a36Sopenharmony_ci		gcfg2 = TWSI_ENABLE_OPTION3;
34262306a36Sopenharmony_ci		break;
34362306a36Sopenharmony_ci	}
34462306a36Sopenharmony_ci
34562306a36Sopenharmony_ci	regmap_update_bits(gconfmap, GLOBAL_CONFIG_1,
34662306a36Sopenharmony_ci			   TWSI_ENABLE_OPTION1,
34762306a36Sopenharmony_ci			   gcfg1);
34862306a36Sopenharmony_ci	regmap_update_bits(gconfmap, GLOBAL_CONFIG_2,
34962306a36Sopenharmony_ci			   TWSI_ENABLE_OPTION2 | TWSI_ENABLE_OPTION3,
35062306a36Sopenharmony_ci			   gcfg2);
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ci	return 0;
35362306a36Sopenharmony_ci}
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_cistatic const struct mvebu_mpp_ctrl dove_mpp_controls[] = {
35662306a36Sopenharmony_ci	MPP_FUNC_CTRL(0, 15, NULL, dove_pmu_mpp_ctrl),
35762306a36Sopenharmony_ci	MPP_FUNC_CTRL(16, 23, NULL, mvebu_mmio_mpp_ctrl),
35862306a36Sopenharmony_ci	MPP_FUNC_CTRL(24, 39, "mpp_camera", dove_mpp4_ctrl),
35962306a36Sopenharmony_ci	MPP_FUNC_CTRL(40, 45, "mpp_sdio0", dove_mpp4_ctrl),
36062306a36Sopenharmony_ci	MPP_FUNC_CTRL(46, 51, "mpp_sdio1", dove_mpp4_ctrl),
36162306a36Sopenharmony_ci	MPP_FUNC_GPIO_CTRL(52, 57, "mpp_audio1", dove_audio1_ctrl),
36262306a36Sopenharmony_ci	MPP_FUNC_CTRL(58, 61, "mpp_spi0", dove_mpp4_ctrl),
36362306a36Sopenharmony_ci	MPP_FUNC_CTRL(62, 63, "mpp_uart1", dove_mpp4_ctrl),
36462306a36Sopenharmony_ci	MPP_FUNC_CTRL(64, 71, "mpp_nand", dove_nand_ctrl),
36562306a36Sopenharmony_ci	MPP_FUNC_CTRL(72, 72, "audio0", dove_audio0_ctrl),
36662306a36Sopenharmony_ci	MPP_FUNC_CTRL(73, 73, "twsi", dove_twsi_ctrl),
36762306a36Sopenharmony_ci};
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_cistatic struct mvebu_mpp_mode dove_mpp_modes[] = {
37062306a36Sopenharmony_ci	MPP_MODE(0,
37162306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "gpio", NULL),
37262306a36Sopenharmony_ci		MPP_FUNCTION(0x02, "uart2", "rts"),
37362306a36Sopenharmony_ci		MPP_FUNCTION(0x03, "sdio0", "cd"),
37462306a36Sopenharmony_ci		MPP_FUNCTION(0x0f, "lcd0", "pwm"),
37562306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
37662306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
37762306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
37862306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
37962306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
38062306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
38162306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),
38262306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
38362306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
38462306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
38562306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
38662306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
38762306a36Sopenharmony_ci	MPP_MODE(1,
38862306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "gpio", NULL),
38962306a36Sopenharmony_ci		MPP_FUNCTION(0x02, "uart2", "cts"),
39062306a36Sopenharmony_ci		MPP_FUNCTION(0x03, "sdio0", "wp"),
39162306a36Sopenharmony_ci		MPP_FUNCTION(0x0f, "lcd1", "pwm"),
39262306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
39362306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
39462306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
39562306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
39662306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
39762306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
39862306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),
39962306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
40062306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
40162306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
40262306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
40362306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
40462306a36Sopenharmony_ci	MPP_MODE(2,
40562306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "gpio", NULL),
40662306a36Sopenharmony_ci		MPP_FUNCTION(0x01, "sata", "prsnt"),
40762306a36Sopenharmony_ci		MPP_FUNCTION(0x02, "uart2", "txd"),
40862306a36Sopenharmony_ci		MPP_FUNCTION(0x03, "sdio0", "buspwr"),
40962306a36Sopenharmony_ci		MPP_FUNCTION(0x04, "uart1", "rts"),
41062306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
41162306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
41262306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
41362306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
41462306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
41562306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
41662306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),
41762306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
41862306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
41962306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
42062306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
42162306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
42262306a36Sopenharmony_ci	MPP_MODE(3,
42362306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "gpio", NULL),
42462306a36Sopenharmony_ci		MPP_FUNCTION(0x01, "sata", "act"),
42562306a36Sopenharmony_ci		MPP_FUNCTION(0x02, "uart2", "rxd"),
42662306a36Sopenharmony_ci		MPP_FUNCTION(0x03, "sdio0", "ledctrl"),
42762306a36Sopenharmony_ci		MPP_FUNCTION(0x04, "uart1", "cts"),
42862306a36Sopenharmony_ci		MPP_FUNCTION(0x0f, "lcd-spi", "cs1"),
42962306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
43062306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
43162306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
43262306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
43362306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
43462306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
43562306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),
43662306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
43762306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
43862306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
43962306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
44062306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
44162306a36Sopenharmony_ci	MPP_MODE(4,
44262306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "gpio", NULL),
44362306a36Sopenharmony_ci		MPP_FUNCTION(0x02, "uart3", "rts"),
44462306a36Sopenharmony_ci		MPP_FUNCTION(0x03, "sdio1", "cd"),
44562306a36Sopenharmony_ci		MPP_FUNCTION(0x04, "spi1", "miso"),
44662306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
44762306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
44862306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
44962306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
45062306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
45162306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
45262306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),
45362306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
45462306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
45562306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
45662306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
45762306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
45862306a36Sopenharmony_ci	MPP_MODE(5,
45962306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "gpio", NULL),
46062306a36Sopenharmony_ci		MPP_FUNCTION(0x02, "uart3", "cts"),
46162306a36Sopenharmony_ci		MPP_FUNCTION(0x03, "sdio1", "wp"),
46262306a36Sopenharmony_ci		MPP_FUNCTION(0x04, "spi1", "cs"),
46362306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
46462306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
46562306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
46662306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
46762306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
46862306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
46962306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),
47062306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
47162306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
47262306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
47362306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
47462306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
47562306a36Sopenharmony_ci	MPP_MODE(6,
47662306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "gpio", NULL),
47762306a36Sopenharmony_ci		MPP_FUNCTION(0x02, "uart3", "txd"),
47862306a36Sopenharmony_ci		MPP_FUNCTION(0x03, "sdio1", "buspwr"),
47962306a36Sopenharmony_ci		MPP_FUNCTION(0x04, "spi1", "mosi"),
48062306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
48162306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
48262306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
48362306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
48462306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
48562306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
48662306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),
48762306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
48862306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
48962306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
49062306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
49162306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
49262306a36Sopenharmony_ci	MPP_MODE(7,
49362306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "gpio", NULL),
49462306a36Sopenharmony_ci		MPP_FUNCTION(0x02, "uart3", "rxd"),
49562306a36Sopenharmony_ci		MPP_FUNCTION(0x03, "sdio1", "ledctrl"),
49662306a36Sopenharmony_ci		MPP_FUNCTION(0x04, "spi1", "sck"),
49762306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
49862306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
49962306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
50062306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
50162306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
50262306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
50362306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x8, "core-pwr-good", NULL),
50462306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
50562306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
50662306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
50762306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
50862306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
50962306a36Sopenharmony_ci	MPP_MODE(8,
51062306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "gpio", NULL),
51162306a36Sopenharmony_ci		MPP_FUNCTION(0x01, "watchdog", "rstout"),
51262306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
51362306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
51462306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
51562306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
51662306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
51762306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
51862306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),
51962306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
52062306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
52162306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
52262306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
52362306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
52462306a36Sopenharmony_ci	MPP_MODE(9,
52562306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "gpio", NULL),
52662306a36Sopenharmony_ci		MPP_FUNCTION(0x05, "pex1", "clkreq"),
52762306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
52862306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
52962306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
53062306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
53162306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
53262306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
53362306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),
53462306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
53562306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
53662306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
53762306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
53862306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
53962306a36Sopenharmony_ci	MPP_MODE(10,
54062306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "gpio", NULL),
54162306a36Sopenharmony_ci		MPP_FUNCTION(0x05, "ssp", "sclk"),
54262306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
54362306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
54462306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
54562306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
54662306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
54762306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
54862306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),
54962306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
55062306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
55162306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
55262306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
55362306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
55462306a36Sopenharmony_ci	MPP_MODE(11,
55562306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "gpio", NULL),
55662306a36Sopenharmony_ci		MPP_FUNCTION(0x01, "sata", "prsnt"),
55762306a36Sopenharmony_ci		MPP_FUNCTION(0x02, "sata-1", "act"),
55862306a36Sopenharmony_ci		MPP_FUNCTION(0x03, "sdio0", "ledctrl"),
55962306a36Sopenharmony_ci		MPP_FUNCTION(0x04, "sdio1", "ledctrl"),
56062306a36Sopenharmony_ci		MPP_FUNCTION(0x05, "pex0", "clkreq"),
56162306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
56262306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
56362306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
56462306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
56562306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
56662306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
56762306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),
56862306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
56962306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
57062306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
57162306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
57262306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
57362306a36Sopenharmony_ci	MPP_MODE(12,
57462306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "gpio", NULL),
57562306a36Sopenharmony_ci		MPP_FUNCTION(0x01, "sata", "act"),
57662306a36Sopenharmony_ci		MPP_FUNCTION(0x02, "uart2", "rts"),
57762306a36Sopenharmony_ci		MPP_FUNCTION(0x03, "audio0", "extclk"),
57862306a36Sopenharmony_ci		MPP_FUNCTION(0x04, "sdio1", "cd"),
57962306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
58062306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
58162306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
58262306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
58362306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
58462306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
58562306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),
58662306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
58762306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
58862306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
58962306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
59062306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
59162306a36Sopenharmony_ci	MPP_MODE(13,
59262306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "gpio", NULL),
59362306a36Sopenharmony_ci		MPP_FUNCTION(0x02, "uart2", "cts"),
59462306a36Sopenharmony_ci		MPP_FUNCTION(0x03, "audio1", "extclk"),
59562306a36Sopenharmony_ci		MPP_FUNCTION(0x04, "sdio1", "wp"),
59662306a36Sopenharmony_ci		MPP_FUNCTION(0x05, "ssp", "extclk"),
59762306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
59862306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
59962306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
60062306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
60162306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
60262306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
60362306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),
60462306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
60562306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
60662306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
60762306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
60862306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
60962306a36Sopenharmony_ci	MPP_MODE(14,
61062306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "gpio", NULL),
61162306a36Sopenharmony_ci		MPP_FUNCTION(0x02, "uart2", "txd"),
61262306a36Sopenharmony_ci		MPP_FUNCTION(0x04, "sdio1", "buspwr"),
61362306a36Sopenharmony_ci		MPP_FUNCTION(0x05, "ssp", "rxd"),
61462306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
61562306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
61662306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
61762306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
61862306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
61962306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
62062306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),
62162306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
62262306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
62362306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
62462306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
62562306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
62662306a36Sopenharmony_ci	MPP_MODE(15,
62762306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "gpio", NULL),
62862306a36Sopenharmony_ci		MPP_FUNCTION(0x02, "uart2", "rxd"),
62962306a36Sopenharmony_ci		MPP_FUNCTION(0x04, "sdio1", "ledctrl"),
63062306a36Sopenharmony_ci		MPP_FUNCTION(0x05, "ssp", "sfrm"),
63162306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x0, "pmu-nc", NULL),
63262306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x1, "pmu-low", NULL),
63362306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x2, "pmu-high", NULL),
63462306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x3, "pmic", "sdi"),
63562306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x4, "cpu-pwr-down", NULL),
63662306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x5, "standby-pwr-down", NULL),
63762306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0x8, "cpu-pwr-good", NULL),
63862306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xa, "bat-fault", NULL),
63962306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xb, "ext0-wakeup", NULL),
64062306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xc, "ext1-wakeup", NULL),
64162306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xd, "ext2-wakeup", NULL),
64262306a36Sopenharmony_ci		MPP_FUNCTION(CONFIG_PMU | 0xe, "pmu-blink", NULL)),
64362306a36Sopenharmony_ci	MPP_MODE(16,
64462306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "gpio", NULL),
64562306a36Sopenharmony_ci		MPP_FUNCTION(0x02, "uart3", "rts"),
64662306a36Sopenharmony_ci		MPP_FUNCTION(0x03, "sdio0", "cd"),
64762306a36Sopenharmony_ci		MPP_FUNCTION(0x04, "lcd-spi", "cs1"),
64862306a36Sopenharmony_ci		MPP_FUNCTION(0x05, "ac97", "sdi1")),
64962306a36Sopenharmony_ci	MPP_MODE(17,
65062306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "gpio", NULL),
65162306a36Sopenharmony_ci		MPP_FUNCTION(0x01, "ac97-1", "sysclko"),
65262306a36Sopenharmony_ci		MPP_FUNCTION(0x02, "uart3", "cts"),
65362306a36Sopenharmony_ci		MPP_FUNCTION(0x03, "sdio0", "wp"),
65462306a36Sopenharmony_ci		MPP_FUNCTION(0x04, "twsi", "sda"),
65562306a36Sopenharmony_ci		MPP_FUNCTION(0x05, "ac97", "sdi2")),
65662306a36Sopenharmony_ci	MPP_MODE(18,
65762306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "gpio", NULL),
65862306a36Sopenharmony_ci		MPP_FUNCTION(0x02, "uart3", "txd"),
65962306a36Sopenharmony_ci		MPP_FUNCTION(0x03, "sdio0", "buspwr"),
66062306a36Sopenharmony_ci		MPP_FUNCTION(0x04, "lcd0", "pwm"),
66162306a36Sopenharmony_ci		MPP_FUNCTION(0x05, "ac97", "sdi3")),
66262306a36Sopenharmony_ci	MPP_MODE(19,
66362306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "gpio", NULL),
66462306a36Sopenharmony_ci		MPP_FUNCTION(0x02, "uart3", "rxd"),
66562306a36Sopenharmony_ci		MPP_FUNCTION(0x03, "sdio0", "ledctrl"),
66662306a36Sopenharmony_ci		MPP_FUNCTION(0x04, "twsi", "sck")),
66762306a36Sopenharmony_ci	MPP_MODE(20,
66862306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "gpio", NULL),
66962306a36Sopenharmony_ci		MPP_FUNCTION(0x01, "ac97", "sysclko"),
67062306a36Sopenharmony_ci		MPP_FUNCTION(0x02, "lcd-spi", "miso"),
67162306a36Sopenharmony_ci		MPP_FUNCTION(0x03, "sdio1", "cd"),
67262306a36Sopenharmony_ci		MPP_FUNCTION(0x05, "sdio0", "cd"),
67362306a36Sopenharmony_ci		MPP_FUNCTION(0x06, "spi1", "miso")),
67462306a36Sopenharmony_ci	MPP_MODE(21,
67562306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "gpio", NULL),
67662306a36Sopenharmony_ci		MPP_FUNCTION(0x01, "uart1", "rts"),
67762306a36Sopenharmony_ci		MPP_FUNCTION(0x02, "lcd-spi", "cs0"),
67862306a36Sopenharmony_ci		MPP_FUNCTION(0x03, "sdio1", "wp"),
67962306a36Sopenharmony_ci		MPP_FUNCTION(0x04, "ssp", "sfrm"),
68062306a36Sopenharmony_ci		MPP_FUNCTION(0x05, "sdio0", "wp"),
68162306a36Sopenharmony_ci		MPP_FUNCTION(0x06, "spi1", "cs")),
68262306a36Sopenharmony_ci	MPP_MODE(22,
68362306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "gpio", NULL),
68462306a36Sopenharmony_ci		MPP_FUNCTION(0x01, "uart1", "cts"),
68562306a36Sopenharmony_ci		MPP_FUNCTION(0x02, "lcd-spi", "mosi"),
68662306a36Sopenharmony_ci		MPP_FUNCTION(0x03, "sdio1", "buspwr"),
68762306a36Sopenharmony_ci		MPP_FUNCTION(0x04, "ssp", "txd"),
68862306a36Sopenharmony_ci		MPP_FUNCTION(0x05, "sdio0", "buspwr"),
68962306a36Sopenharmony_ci		MPP_FUNCTION(0x06, "spi1", "mosi")),
69062306a36Sopenharmony_ci	MPP_MODE(23,
69162306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "gpio", NULL),
69262306a36Sopenharmony_ci		MPP_FUNCTION(0x02, "lcd-spi", "sck"),
69362306a36Sopenharmony_ci		MPP_FUNCTION(0x03, "sdio1", "ledctrl"),
69462306a36Sopenharmony_ci		MPP_FUNCTION(0x04, "ssp", "sclk"),
69562306a36Sopenharmony_ci		MPP_FUNCTION(0x05, "sdio0", "ledctrl"),
69662306a36Sopenharmony_ci		MPP_FUNCTION(0x06, "spi1", "sck")),
69762306a36Sopenharmony_ci	MPP_MODE(24,
69862306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "camera", NULL),
69962306a36Sopenharmony_ci		MPP_FUNCTION(0x01, "gpio", NULL)),
70062306a36Sopenharmony_ci	MPP_MODE(40,
70162306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "sdio0", NULL),
70262306a36Sopenharmony_ci		MPP_FUNCTION(0x01, "gpio", NULL)),
70362306a36Sopenharmony_ci	MPP_MODE(46,
70462306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "sdio1", NULL),
70562306a36Sopenharmony_ci		MPP_FUNCTION(0x01, "gpio", NULL)),
70662306a36Sopenharmony_ci	MPP_MODE(52,
70762306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "i2s1/spdifo", NULL),
70862306a36Sopenharmony_ci		MPP_FUNCTION(0x02, "i2s1", NULL),
70962306a36Sopenharmony_ci		MPP_FUNCTION(0x08, "spdifo", NULL),
71062306a36Sopenharmony_ci		MPP_FUNCTION(0x0a, "gpio", NULL),
71162306a36Sopenharmony_ci		MPP_FUNCTION(0x0b, "twsi", NULL),
71262306a36Sopenharmony_ci		MPP_FUNCTION(0x0c, "ssp/spdifo", NULL),
71362306a36Sopenharmony_ci		MPP_FUNCTION(0x0e, "ssp", NULL),
71462306a36Sopenharmony_ci		MPP_FUNCTION(0x0f, "ssp/twsi", NULL)),
71562306a36Sopenharmony_ci	MPP_MODE(58,
71662306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "spi0", NULL),
71762306a36Sopenharmony_ci		MPP_FUNCTION(0x01, "gpio", NULL)),
71862306a36Sopenharmony_ci	MPP_MODE(62,
71962306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "uart1", NULL),
72062306a36Sopenharmony_ci		MPP_FUNCTION(0x01, "gpio", NULL)),
72162306a36Sopenharmony_ci	MPP_MODE(64,
72262306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "nand", NULL),
72362306a36Sopenharmony_ci		MPP_FUNCTION(0x01, "gpo", NULL)),
72462306a36Sopenharmony_ci	MPP_MODE(72,
72562306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "i2s", NULL),
72662306a36Sopenharmony_ci		MPP_FUNCTION(0x01, "ac97", NULL)),
72762306a36Sopenharmony_ci	MPP_MODE(73,
72862306a36Sopenharmony_ci		MPP_FUNCTION(0x00, "twsi-none", NULL),
72962306a36Sopenharmony_ci		MPP_FUNCTION(0x01, "twsi-opt1", NULL),
73062306a36Sopenharmony_ci		MPP_FUNCTION(0x02, "twsi-opt2", NULL),
73162306a36Sopenharmony_ci		MPP_FUNCTION(0x03, "twsi-opt3", NULL)),
73262306a36Sopenharmony_ci};
73362306a36Sopenharmony_ci
73462306a36Sopenharmony_cistatic struct pinctrl_gpio_range dove_mpp_gpio_ranges[] = {
73562306a36Sopenharmony_ci	MPP_GPIO_RANGE(0,  0,  0, 32),
73662306a36Sopenharmony_ci	MPP_GPIO_RANGE(1, 32, 32, 32),
73762306a36Sopenharmony_ci	MPP_GPIO_RANGE(2, 64, 64,  8),
73862306a36Sopenharmony_ci};
73962306a36Sopenharmony_ci
74062306a36Sopenharmony_cistatic struct mvebu_pinctrl_soc_info dove_pinctrl_info = {
74162306a36Sopenharmony_ci	.controls = dove_mpp_controls,
74262306a36Sopenharmony_ci	.ncontrols = ARRAY_SIZE(dove_mpp_controls),
74362306a36Sopenharmony_ci	.modes = dove_mpp_modes,
74462306a36Sopenharmony_ci	.nmodes = ARRAY_SIZE(dove_mpp_modes),
74562306a36Sopenharmony_ci	.gpioranges = dove_mpp_gpio_ranges,
74662306a36Sopenharmony_ci	.ngpioranges = ARRAY_SIZE(dove_mpp_gpio_ranges),
74762306a36Sopenharmony_ci	.variant = 0,
74862306a36Sopenharmony_ci};
74962306a36Sopenharmony_ci
75062306a36Sopenharmony_cistatic struct clk *clk;
75162306a36Sopenharmony_ci
75262306a36Sopenharmony_cistatic const struct of_device_id dove_pinctrl_of_match[] = {
75362306a36Sopenharmony_ci	{ .compatible = "marvell,dove-pinctrl", .data = &dove_pinctrl_info },
75462306a36Sopenharmony_ci	{ }
75562306a36Sopenharmony_ci};
75662306a36Sopenharmony_ci
75762306a36Sopenharmony_cistatic const struct regmap_config gc_regmap_config = {
75862306a36Sopenharmony_ci	.reg_bits = 32,
75962306a36Sopenharmony_ci	.val_bits = 32,
76062306a36Sopenharmony_ci	.reg_stride = 4,
76162306a36Sopenharmony_ci	.max_register = 5,
76262306a36Sopenharmony_ci};
76362306a36Sopenharmony_ci
76462306a36Sopenharmony_cistatic int dove_pinctrl_probe(struct platform_device *pdev)
76562306a36Sopenharmony_ci{
76662306a36Sopenharmony_ci	struct resource *res, *mpp_res;
76762306a36Sopenharmony_ci	struct resource fb_res;
76862306a36Sopenharmony_ci	const struct of_device_id *match =
76962306a36Sopenharmony_ci		of_match_device(dove_pinctrl_of_match, &pdev->dev);
77062306a36Sopenharmony_ci	struct mvebu_mpp_ctrl_data *mpp_data;
77162306a36Sopenharmony_ci	void __iomem *base;
77262306a36Sopenharmony_ci	int i;
77362306a36Sopenharmony_ci
77462306a36Sopenharmony_ci	pdev->dev.platform_data = (void *)match->data;
77562306a36Sopenharmony_ci
77662306a36Sopenharmony_ci	/*
77762306a36Sopenharmony_ci	 * General MPP Configuration Register is part of pdma registers.
77862306a36Sopenharmony_ci	 * grab clk to make sure it is ticking.
77962306a36Sopenharmony_ci	 */
78062306a36Sopenharmony_ci	clk = devm_clk_get(&pdev->dev, NULL);
78162306a36Sopenharmony_ci	if (IS_ERR(clk)) {
78262306a36Sopenharmony_ci		dev_err(&pdev->dev, "Unable to get pdma clock");
78362306a36Sopenharmony_ci		return PTR_ERR(clk);
78462306a36Sopenharmony_ci	}
78562306a36Sopenharmony_ci	clk_prepare_enable(clk);
78662306a36Sopenharmony_ci
78762306a36Sopenharmony_ci	base = devm_platform_get_and_ioremap_resource(pdev, 0, &mpp_res);
78862306a36Sopenharmony_ci	if (IS_ERR(base))
78962306a36Sopenharmony_ci		return PTR_ERR(base);
79062306a36Sopenharmony_ci
79162306a36Sopenharmony_ci	mpp_data = devm_kcalloc(&pdev->dev, dove_pinctrl_info.ncontrols,
79262306a36Sopenharmony_ci				sizeof(*mpp_data), GFP_KERNEL);
79362306a36Sopenharmony_ci	if (!mpp_data)
79462306a36Sopenharmony_ci		return -ENOMEM;
79562306a36Sopenharmony_ci
79662306a36Sopenharmony_ci	dove_pinctrl_info.control_data = mpp_data;
79762306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(dove_mpp_controls); i++)
79862306a36Sopenharmony_ci		mpp_data[i].base = base;
79962306a36Sopenharmony_ci
80062306a36Sopenharmony_ci	/* prepare fallback resource */
80162306a36Sopenharmony_ci	memcpy(&fb_res, mpp_res, sizeof(struct resource));
80262306a36Sopenharmony_ci	fb_res.start = 0;
80362306a36Sopenharmony_ci
80462306a36Sopenharmony_ci	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
80562306a36Sopenharmony_ci	if (!res) {
80662306a36Sopenharmony_ci		dev_warn(&pdev->dev, "falling back to hardcoded MPP4 resource\n");
80762306a36Sopenharmony_ci		adjust_resource(&fb_res,
80862306a36Sopenharmony_ci			(mpp_res->start & INT_REGS_MASK) + MPP4_REGS_OFFS, 0x4);
80962306a36Sopenharmony_ci		res = &fb_res;
81062306a36Sopenharmony_ci	}
81162306a36Sopenharmony_ci
81262306a36Sopenharmony_ci	mpp4_base = devm_ioremap_resource(&pdev->dev, res);
81362306a36Sopenharmony_ci	if (IS_ERR(mpp4_base))
81462306a36Sopenharmony_ci		return PTR_ERR(mpp4_base);
81562306a36Sopenharmony_ci
81662306a36Sopenharmony_ci	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
81762306a36Sopenharmony_ci	if (!res) {
81862306a36Sopenharmony_ci		dev_warn(&pdev->dev, "falling back to hardcoded PMU resource\n");
81962306a36Sopenharmony_ci		adjust_resource(&fb_res,
82062306a36Sopenharmony_ci			(mpp_res->start & INT_REGS_MASK) + PMU_REGS_OFFS, 0x8);
82162306a36Sopenharmony_ci		res = &fb_res;
82262306a36Sopenharmony_ci	}
82362306a36Sopenharmony_ci
82462306a36Sopenharmony_ci	pmu_base = devm_ioremap_resource(&pdev->dev, res);
82562306a36Sopenharmony_ci	if (IS_ERR(pmu_base))
82662306a36Sopenharmony_ci		return PTR_ERR(pmu_base);
82762306a36Sopenharmony_ci
82862306a36Sopenharmony_ci	gconfmap = syscon_regmap_lookup_by_compatible("marvell,dove-global-config");
82962306a36Sopenharmony_ci	if (IS_ERR(gconfmap)) {
83062306a36Sopenharmony_ci		void __iomem *gc_base;
83162306a36Sopenharmony_ci
83262306a36Sopenharmony_ci		dev_warn(&pdev->dev, "falling back to hardcoded global registers\n");
83362306a36Sopenharmony_ci		adjust_resource(&fb_res,
83462306a36Sopenharmony_ci			(mpp_res->start & INT_REGS_MASK) + GC_REGS_OFFS, 0x14);
83562306a36Sopenharmony_ci		gc_base = devm_ioremap_resource(&pdev->dev, &fb_res);
83662306a36Sopenharmony_ci		if (IS_ERR(gc_base))
83762306a36Sopenharmony_ci			return PTR_ERR(gc_base);
83862306a36Sopenharmony_ci		gconfmap = devm_regmap_init_mmio(&pdev->dev,
83962306a36Sopenharmony_ci						 gc_base, &gc_regmap_config);
84062306a36Sopenharmony_ci		if (IS_ERR(gconfmap))
84162306a36Sopenharmony_ci			return PTR_ERR(gconfmap);
84262306a36Sopenharmony_ci	}
84362306a36Sopenharmony_ci
84462306a36Sopenharmony_ci	/* Warn on any missing DT resource */
84562306a36Sopenharmony_ci	if (fb_res.start)
84662306a36Sopenharmony_ci		dev_warn(&pdev->dev, FW_BUG "Missing pinctrl regs in DTB. Please update your firmware.\n");
84762306a36Sopenharmony_ci
84862306a36Sopenharmony_ci	return mvebu_pinctrl_probe(pdev);
84962306a36Sopenharmony_ci}
85062306a36Sopenharmony_ci
85162306a36Sopenharmony_cistatic struct platform_driver dove_pinctrl_driver = {
85262306a36Sopenharmony_ci	.driver = {
85362306a36Sopenharmony_ci		.name = "dove-pinctrl",
85462306a36Sopenharmony_ci		.suppress_bind_attrs = true,
85562306a36Sopenharmony_ci		.of_match_table = dove_pinctrl_of_match,
85662306a36Sopenharmony_ci	},
85762306a36Sopenharmony_ci	.probe = dove_pinctrl_probe,
85862306a36Sopenharmony_ci};
85962306a36Sopenharmony_cibuiltin_platform_driver(dove_pinctrl_driver);
860