// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2024 Nuvoton Technology Corp.
 *
 * Author: Shan-Chun Hung <schung@nuvoton.com>
 * *       Jacky Huang <ychuang3@nuvoton.com>
 */

#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/cleanup.h>
#include <linux/clk.h>
#include <linux/gpio/driver.h>
#include <linux/mfd/syscon.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h>

#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinctrl.h>
#include "../core.h"
#include "../pinconf.h"
#include "pinctrl-ma35.h"

#define MA35_MFP_REG_BASE		0x80
#define MA35_MFP_REG_SZ_PER_BANK	8
#define MA35_MFP_BITS_PER_PORT		4

#define MA35_GPIO_BANK_MAX		14
#define MA35_GPIO_PORT_MAX		16

/* GPIO control registers */
#define MA35_GP_REG_MODE		0x00
#define MA35_GP_REG_DINOFF		0x04
#define MA35_GP_REG_DOUT		0x08
#define MA35_GP_REG_DATMSK		0x0c
#define MA35_GP_REG_PIN			0x10
#define MA35_GP_REG_DBEN		0x14
#define MA35_GP_REG_INTTYPE		0x18
#define MA35_GP_REG_INTEN		0x1c
#define MA35_GP_REG_INTSRC		0x20
#define MA35_GP_REG_SMTEN		0x24
#define MA35_GP_REG_SLEWCTL		0x28
#define MA35_GP_REG_SPW			0x2c
#define MA35_GP_REG_PUSEL		0x30
#define MA35_GP_REG_DSL			0x38
#define MA35_GP_REG_DSH			0x3c

/* GPIO mode control */
#define MA35_GP_MODE_INPUT		0x0
#define MA35_GP_MODE_OUTPUT		0x1
#define MA35_GP_MODE_OPEN_DRAIN		0x2
#define MA35_GP_MODE_QUASI		0x3
#define MA35_GP_MODE_MASK(n)		GENMASK(n * 2 + 1, n * 2)

#define MA35_GP_SLEWCTL_MASK(n)		GENMASK(n * 2 + 1, n * 2)

/* GPIO pull-up and pull-down selection control */
#define MA35_GP_PUSEL_DISABLE		0x0
#define MA35_GP_PUSEL_PULL_UP		0x1
#define MA35_GP_PUSEL_PULL_DOWN		0x2
#define MA35_GP_PUSEL_MASK(n)		GENMASK(n * 2 + 1, n * 2)

/*
 * The MA35_GP_REG_INTEN bits 0 ~ 15 control low-level or falling edge trigger,
 * while bits 16 ~ 31 control high-level or rising edge trigger.
 */
#define MA35_GP_INTEN_L(n)		BIT(n)
#define MA35_GP_INTEN_H(n)		BIT(n + 16)
#define MA35_GP_INTEN_BOTH(n)		(MA35_GP_INTEN_H(n) | MA35_GP_INTEN_L(n))

/*
 * The MA35_GP_REG_DSL register controls ports 0 to 7, while the MA35_GP_REG_DSH
 * register controls ports 8 to 15. Each port occupies a width of 4 bits, with 3
 * bits being effective.
 */
#define MA35_GP_DS_REG(n)		(n < 8 ? MA35_GP_REG_DSL : MA35_GP_REG_DSH)
#define MA35_GP_DS_MASK(n)		GENMASK((n % 8) * 4 + 3, (n % 8) * 4)

#define MVOLT_1800			0
#define MVOLT_3300			1

/* Non-constant mask variant of FIELD_GET() and FIELD_PREP() */
#define field_get(_mask, _reg)	(((_reg) & (_mask)) >> (ffs(_mask) - 1))
#define field_prep(_mask, _val)	(((_val) << (ffs(_mask) - 1)) & (_mask))

static const char * const gpio_group_name[] = {
	"gpioa", "gpiob", "gpioc", "gpiod", "gpioe", "gpiof", "gpiog",
	"gpioh", "gpioi", "gpioj", "gpiok", "gpiol", "gpiom", "gpion",
};

static const u32 ds_1800mv_tbl[] = {
	2900, 4400, 5800, 7300, 8600, 10100, 11500, 13000,
};

static const u32 ds_3300mv_tbl[] = {
	17100, 25600, 34100, 42800, 48000, 56000, 77000, 82000,
};

struct ma35_pin_func {
	const char		*name;
	const char		**groups;
	u32			ngroups;
};

struct ma35_pin_setting {
	u32			offset;
	u32			shift;
	u32			muxval;
	unsigned long		*configs;
	unsigned int		nconfigs;
};

struct ma35_pin_group {
	const char		*name;
	unsigned int		npins;
	unsigned int		*pins;
	struct ma35_pin_setting	*settings;
};

struct ma35_pin_bank {
	void __iomem		*reg_base;
	struct clk		*clk;
	int			irq;
	u8			bank_num;
	u8			nr_pins;
	bool			valid;
	const char		*name;
	struct fwnode_handle	*fwnode;
	struct gpio_chip	chip;
	u32			irqtype;
	u32			irqinten;
	struct regmap		*regmap;
	struct device		*dev;
};

struct ma35_pin_ctrl {
	struct ma35_pin_bank	*pin_banks;
	u32			nr_banks;
	u32			nr_pins;
};

struct ma35_pinctrl {
	struct device		*dev;
	struct ma35_pin_ctrl	*ctrl;
	struct pinctrl_dev	*pctl;
	const struct ma35_pinctrl_soc_info *info;
	struct regmap		*regmap;
	struct ma35_pin_group	*groups;
	unsigned int		ngroups;
	struct ma35_pin_func	*functions;
	unsigned int		nfunctions;
};

static DEFINE_RAW_SPINLOCK(ma35_lock);

static int ma35_get_groups_count(struct pinctrl_dev *pctldev)
{
	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);

	return npctl->ngroups;
}

static const char *ma35_get_group_name(struct pinctrl_dev *pctldev, unsigned int selector)
{
	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);

	return npctl->groups[selector].name;
}

static int ma35_get_group_pins(struct pinctrl_dev *pctldev, unsigned int selector,
			       const unsigned int **pins, unsigned int *npins)
{
	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);

	if (selector >= npctl->ngroups)
		return -EINVAL;

	*pins = npctl->groups[selector].pins;
	*npins = npctl->groups[selector].npins;

	return 0;
}

static struct ma35_pin_group *ma35_pinctrl_find_group_by_name(
			      const struct ma35_pinctrl *npctl, const char *name)
{
	int i;

	for (i = 0; i < npctl->ngroups; i++) {
		if (!strcmp(npctl->groups[i].name, name))
			return &npctl->groups[i];
	}
	return NULL;
}

static int ma35_pinctrl_dt_node_to_map_func(struct pinctrl_dev *pctldev,
					    struct device_node *np,
					    struct pinctrl_map **map,
					    unsigned int *num_maps)
{
	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);
	struct ma35_pin_group *grp;
	struct pinctrl_map *new_map;
	struct device_node *parent;
	int map_num = 1;
	int i;

	/*
	 * first find the group of this node and check if we need create
	 * config maps for pins
	 */
	grp = ma35_pinctrl_find_group_by_name(npctl, np->name);
	if (!grp) {
		dev_err(npctl->dev, "unable to find group for node %s\n", np->name);
		return -EINVAL;
	}

	map_num += grp->npins;
	new_map = devm_kcalloc(pctldev->dev, map_num, sizeof(*new_map), GFP_KERNEL);
	if (!new_map)
		return -ENOMEM;

	*map = new_map;
	*num_maps = map_num;
	/* create mux map */
	parent = of_get_parent(np);
	if (!parent)
		return -EINVAL;

	new_map[0].type = PIN_MAP_TYPE_MUX_GROUP;
	new_map[0].data.mux.function = parent->name;
	new_map[0].data.mux.group = np->name;
	of_node_put(parent);

	new_map++;
	for (i = 0; i < grp->npins; i++) {
		new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN;
		new_map[i].data.configs.group_or_pin = pin_get_name(pctldev, grp->pins[i]);
		new_map[i].data.configs.configs = grp->settings[i].configs;
		new_map[i].data.configs.num_configs = grp->settings[i].nconfigs;
	}
	dev_dbg(pctldev->dev, "maps: function %s group %s num %d\n",
		(*map)->data.mux.function, (*map)->data.mux.group, map_num);

	return 0;
}

static const struct pinctrl_ops ma35_pctrl_ops = {
	.get_groups_count = ma35_get_groups_count,
	.get_group_name = ma35_get_group_name,
	.get_group_pins = ma35_get_group_pins,
	.dt_node_to_map = ma35_pinctrl_dt_node_to_map_func,
	.dt_free_map = pinconf_generic_dt_free_map,
};

static int ma35_pinmux_get_func_count(struct pinctrl_dev *pctldev)
{
	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);

	return npctl->nfunctions;
}

static const char *ma35_pinmux_get_func_name(struct pinctrl_dev *pctldev,
					     unsigned int selector)
{
	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);

	return npctl->functions[selector].name;
}

static int ma35_pinmux_get_func_groups(struct pinctrl_dev *pctldev,
				       unsigned int function,
				       const char *const **groups,
				       unsigned int *const num_groups)
{
	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);

	*groups = npctl->functions[function].groups;
	*num_groups = npctl->functions[function].ngroups;

	return 0;
}

static int ma35_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int selector,
			       unsigned int group)
{
	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);
	struct ma35_pin_group *grp = &npctl->groups[group];
	struct ma35_pin_setting *setting = grp->settings;
	u32 i, regval;

	dev_dbg(npctl->dev, "enable function %s group %s\n",
		npctl->functions[selector].name, npctl->groups[group].name);

	for (i = 0; i < grp->npins; i++) {
		regmap_read(npctl->regmap, setting->offset, &regval);
		regval &= ~GENMASK(setting->shift + MA35_MFP_BITS_PER_PORT - 1,
				   setting->shift);
		regval |= setting->muxval << setting->shift;
		regmap_write(npctl->regmap, setting->offset, regval);
		setting++;
	}
	return 0;
}

static const struct pinmux_ops ma35_pmx_ops = {
	.get_functions_count = ma35_pinmux_get_func_count,
	.get_function_name = ma35_pinmux_get_func_name,
	.get_function_groups = ma35_pinmux_get_func_groups,
	.set_mux = ma35_pinmux_set_mux,
	.strict = true,
};

static void ma35_gpio_set_mode(void __iomem *reg_mode, unsigned int gpio, u32 mode)
{
	u32 regval = readl(reg_mode);

	regval &= ~MA35_GP_MODE_MASK(gpio);
	regval |= field_prep(MA35_GP_MODE_MASK(gpio), mode);

	writel(regval, reg_mode);
}

static u32 ma35_gpio_get_mode(void __iomem *reg_mode, unsigned int gpio)
{
	u32 regval = readl(reg_mode);

	return field_get(MA35_GP_MODE_MASK(gpio), regval);
}

static int ma35_gpio_core_direction_in(struct gpio_chip *gc, unsigned int gpio)
{
	struct ma35_pin_bank *bank = gpiochip_get_data(gc);
	void __iomem *reg_mode = bank->reg_base + MA35_GP_REG_MODE;

	guard(raw_spinlock_irqsave)(&ma35_lock);

	ma35_gpio_set_mode(reg_mode, gpio, MA35_GP_MODE_INPUT);

	return 0;
}

static int ma35_gpio_core_direction_out(struct gpio_chip *gc, unsigned int gpio, int val)
{
	struct ma35_pin_bank *bank = gpiochip_get_data(gc);
	void __iomem *reg_dout = bank->reg_base + MA35_GP_REG_DOUT;
	void __iomem *reg_mode = bank->reg_base + MA35_GP_REG_MODE;
	unsigned int regval;

	guard(raw_spinlock_irqsave)(&ma35_lock);

	regval = readl(reg_dout);
	if (val)
		regval |= BIT(gpio);
	else
		regval &= ~BIT(gpio);
	writel(regval, reg_dout);

	ma35_gpio_set_mode(reg_mode, gpio, MA35_GP_MODE_OUTPUT);

	return 0;
}

static int ma35_gpio_core_get(struct gpio_chip *gc, unsigned int gpio)
{
	struct ma35_pin_bank *bank = gpiochip_get_data(gc);
	void __iomem *reg_pin = bank->reg_base + MA35_GP_REG_PIN;

	return !!(readl(reg_pin) & BIT(gpio));
}

static void ma35_gpio_core_set(struct gpio_chip *gc, unsigned int gpio, int val)
{
	struct ma35_pin_bank *bank = gpiochip_get_data(gc);
	void __iomem *reg_dout = bank->reg_base + MA35_GP_REG_DOUT;
	u32 regval;

	if (val)
		regval = readl(reg_dout) | BIT(gpio);
	else
		regval = readl(reg_dout) & ~BIT(gpio);

	writel(regval, reg_dout);
}

static int ma35_gpio_core_to_request(struct gpio_chip *gc, unsigned int gpio)
{
	struct ma35_pin_bank *bank = gpiochip_get_data(gc);
	u32 reg_offs, bit_offs, regval;

	if (gpio < 8) {
		/* The MFP low register controls port 0 ~ 7 */
		reg_offs = bank->bank_num * MA35_MFP_REG_SZ_PER_BANK;
		bit_offs = gpio * MA35_MFP_BITS_PER_PORT;
	} else {
		/* The MFP high register controls port 8 ~ 15 */
		reg_offs = bank->bank_num * MA35_MFP_REG_SZ_PER_BANK + 4;
		bit_offs = (gpio - 8) * MA35_MFP_BITS_PER_PORT;
	}

	regmap_read(bank->regmap, MA35_MFP_REG_BASE + reg_offs, &regval);
	regval &= ~GENMASK(bit_offs + MA35_MFP_BITS_PER_PORT - 1, bit_offs);
	regmap_write(bank->regmap, MA35_MFP_REG_BASE + reg_offs, regval);

	return 0;
}

static void ma35_irq_gpio_ack(struct irq_data *d)
{
	struct ma35_pin_bank *bank = gpiochip_get_data(irq_data_get_irq_chip_data(d));
	void __iomem *reg_intsrc = bank->reg_base + MA35_GP_REG_INTSRC;
	irq_hw_number_t hwirq = irqd_to_hwirq(d);

	writel(BIT(hwirq), reg_intsrc);
}

static void ma35_irq_gpio_mask(struct irq_data *d)
{
	struct ma35_pin_bank *bank = gpiochip_get_data(irq_data_get_irq_chip_data(d));
	void __iomem *reg_ien = bank->reg_base + MA35_GP_REG_INTEN;
	irq_hw_number_t hwirq = irqd_to_hwirq(d);
	u32 regval;

	regval = readl(reg_ien);

	regval &= ~MA35_GP_INTEN_BOTH(hwirq);

	writel(regval, reg_ien);
}

static void ma35_irq_gpio_unmask(struct irq_data *d)
{
	struct ma35_pin_bank *bank = gpiochip_get_data(irq_data_get_irq_chip_data(d));
	void __iomem *reg_itype = bank->reg_base + MA35_GP_REG_INTTYPE;
	void __iomem *reg_ien = bank->reg_base + MA35_GP_REG_INTEN;
	irq_hw_number_t hwirq = irqd_to_hwirq(d);
	u32 bval, regval;

	bval = bank->irqtype & BIT(hwirq);
	regval = readl(reg_itype);
	regval &= ~BIT(hwirq);
	writel(regval | bval, reg_itype);

	bval = bank->irqinten & MA35_GP_INTEN_BOTH(hwirq);
	regval = readl(reg_ien);
	regval &= ~MA35_GP_INTEN_BOTH(hwirq);
	writel(regval | bval, reg_ien);
}

static int ma35_irq_irqtype(struct irq_data *d, unsigned int type)
{
	struct ma35_pin_bank *bank = gpiochip_get_data(irq_data_get_irq_chip_data(d));
	irq_hw_number_t hwirq = irqd_to_hwirq(d);

	switch (type) {
	case IRQ_TYPE_EDGE_BOTH:
		irq_set_handler_locked(d, handle_edge_irq);
		bank->irqtype &= ~BIT(hwirq);
		bank->irqinten |= MA35_GP_INTEN_BOTH(hwirq);
		break;
	case IRQ_TYPE_EDGE_RISING:
	case IRQ_TYPE_LEVEL_HIGH:
		irq_set_handler_locked(d, handle_edge_irq);
		bank->irqtype &= ~BIT(hwirq);
		bank->irqinten |= MA35_GP_INTEN_H(hwirq);
		bank->irqinten &= ~MA35_GP_INTEN_L(hwirq);
		break;
	case IRQ_TYPE_EDGE_FALLING:
	case IRQ_TYPE_LEVEL_LOW:
		irq_set_handler_locked(d, handle_edge_irq);
		bank->irqtype &= ~BIT(hwirq);
		bank->irqinten |= MA35_GP_INTEN_L(hwirq);
		bank->irqinten &= ~MA35_GP_INTEN_H(hwirq);
		break;
	default:
		return -EINVAL;
	}

	writel(bank->irqtype, bank->reg_base + MA35_GP_REG_INTTYPE);
	writel(bank->irqinten, bank->reg_base + MA35_GP_REG_INTEN);

	return 0;
}

static struct irq_chip ma35_gpio_irqchip = {
	.name = "MA35-GPIO-IRQ",
	.irq_disable = ma35_irq_gpio_mask,
	.irq_enable = ma35_irq_gpio_unmask,
	.irq_ack = ma35_irq_gpio_ack,
	.irq_mask = ma35_irq_gpio_mask,
	.irq_unmask = ma35_irq_gpio_unmask,
	.irq_set_type = ma35_irq_irqtype,
	.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_IMMUTABLE,
	GPIOCHIP_IRQ_RESOURCE_HELPERS,
};

static void ma35_irq_demux_intgroup(struct irq_desc *desc)
{
	struct ma35_pin_bank *bank = gpiochip_get_data(irq_desc_get_handler_data(desc));
	struct irq_domain *irqdomain = bank->chip.irq.domain;
	struct irq_chip *irqchip = irq_desc_get_chip(desc);
	unsigned long isr;
	int offset;

	chained_irq_enter(irqchip, desc);

	isr = readl(bank->reg_base + MA35_GP_REG_INTSRC);

	for_each_set_bit(offset, &isr, bank->nr_pins)
		generic_handle_irq(irq_find_mapping(irqdomain, offset));

	chained_irq_exit(irqchip, desc);
}

static int ma35_gpiolib_register(struct platform_device *pdev, struct ma35_pinctrl *npctl)
{
	struct ma35_pin_ctrl *ctrl = npctl->ctrl;
	struct ma35_pin_bank *bank = ctrl->pin_banks;
	int ret;
	int i;

	for (i = 0; i < ctrl->nr_banks; i++, bank++) {
		if (!bank->valid) {
			dev_warn(&pdev->dev, "%pfw: bank is not valid\n", bank->fwnode);
			continue;
		}
		bank->irqtype = 0;
		bank->irqinten = 0;
		bank->chip.label = bank->name;
		bank->chip.of_gpio_n_cells = 2;
		bank->chip.parent = &pdev->dev;
		bank->chip.request = ma35_gpio_core_to_request;
		bank->chip.direction_input = ma35_gpio_core_direction_in;
		bank->chip.direction_output = ma35_gpio_core_direction_out;
		bank->chip.get = ma35_gpio_core_get;
		bank->chip.set = ma35_gpio_core_set;
		bank->chip.base = -1;
		bank->chip.ngpio = bank->nr_pins;
		bank->chip.can_sleep = false;

		if (bank->irq > 0) {
			struct gpio_irq_chip *girq;

			girq = &bank->chip.irq;
			gpio_irq_chip_set_chip(girq, &ma35_gpio_irqchip);
			girq->parent_handler = ma35_irq_demux_intgroup;
			girq->num_parents = 1;

			girq->parents = devm_kcalloc(&pdev->dev, girq->num_parents,
						     sizeof(*girq->parents), GFP_KERNEL);
			if (!girq->parents)
				return -ENOMEM;

			girq->parents[0] = bank->irq;
			girq->default_type = IRQ_TYPE_NONE;
			girq->handler = handle_bad_irq;
		}

		ret = devm_gpiochip_add_data(&pdev->dev, &bank->chip, bank);
		if (ret) {
			dev_err(&pdev->dev, "failed to register gpio_chip %s, error code: %d\n",
				bank->chip.label, ret);
			return ret;
		}
	}
	return 0;
}

static int ma35_get_bank_data(struct ma35_pin_bank *bank)
{
	bank->reg_base = fwnode_iomap(bank->fwnode, 0);
	if (!bank->reg_base)
		return -ENOMEM;

	bank->irq = fwnode_irq_get(bank->fwnode, 0);

	bank->nr_pins = MA35_GPIO_PORT_MAX;

	bank->clk = of_clk_get(to_of_node(bank->fwnode), 0);
	if (IS_ERR(bank->clk))
		return PTR_ERR(bank->clk);

	return clk_prepare_enable(bank->clk);
}

static int ma35_pinctrl_get_soc_data(struct ma35_pinctrl *pctl, struct platform_device *pdev)
{
	struct fwnode_handle *child;
	struct ma35_pin_ctrl *ctrl;
	struct ma35_pin_bank *bank;
	int i, id = 0;

	ctrl = pctl->ctrl;
	ctrl->nr_banks = MA35_GPIO_BANK_MAX;

	ctrl->pin_banks = devm_kcalloc(&pdev->dev, ctrl->nr_banks,
				       sizeof(*ctrl->pin_banks), GFP_KERNEL);
	if (!ctrl->pin_banks)
		return -ENOMEM;

	for (i = 0; i < ctrl->nr_banks; i++) {
		ctrl->pin_banks[i].bank_num = i;
		ctrl->pin_banks[i].name = gpio_group_name[i];
	}

	for_each_gpiochip_node(&pdev->dev, child) {
		bank = &ctrl->pin_banks[id];
		bank->fwnode = child;
		bank->regmap = pctl->regmap;
		bank->dev = &pdev->dev;
		if (!ma35_get_bank_data(bank))
			bank->valid = true;
		id++;
	}
	return 0;
}

static void ma35_gpio_cla_port(unsigned int gpio_num, unsigned int *group,
			       unsigned int *num)
{
	*group = gpio_num / MA35_GPIO_PORT_MAX;
	*num = gpio_num % MA35_GPIO_PORT_MAX;
}

static int ma35_pinconf_set_pull(struct ma35_pinctrl *npctl, unsigned int pin,
				 int pull_up)
{
	unsigned int port, group_num;
	void __iomem *base;
	u32 regval, pull_sel = MA35_GP_PUSEL_DISABLE;

	ma35_gpio_cla_port(pin, &group_num, &port);
	base = npctl->ctrl->pin_banks[group_num].reg_base;

	regval = readl(base + MA35_GP_REG_PUSEL);
	regval &= ~MA35_GP_PUSEL_MASK(port);

	switch (pull_up) {
	case PIN_CONFIG_BIAS_PULL_UP:
		pull_sel = MA35_GP_PUSEL_PULL_UP;
		break;

	case PIN_CONFIG_BIAS_PULL_DOWN:
		pull_sel = MA35_GP_PUSEL_PULL_DOWN;
		break;

	case PIN_CONFIG_BIAS_DISABLE:
		pull_sel = MA35_GP_PUSEL_DISABLE;
		break;
	}

	regval |= field_prep(MA35_GP_PUSEL_MASK(port), pull_sel);
	writel(regval, base + MA35_GP_REG_PUSEL);

	return 0;
}

static int ma35_pinconf_get_output(struct ma35_pinctrl *npctl, unsigned int pin)
{
	unsigned int port, group_num;
	void __iomem *base;
	u32 mode;

	ma35_gpio_cla_port(pin, &group_num, &port);
	base = npctl->ctrl->pin_banks[group_num].reg_base;

	mode = ma35_gpio_get_mode(base + MA35_GP_REG_MODE, port);
	if (mode == MA35_GP_MODE_OUTPUT)
		return 1;

	return 0;
}

static int ma35_pinconf_get_pull(struct ma35_pinctrl *npctl, unsigned int pin)
{
	unsigned int port, group_num;
	void __iomem *base;
	u32 regval, pull_sel;

	ma35_gpio_cla_port(pin, &group_num, &port);
	base = npctl->ctrl->pin_banks[group_num].reg_base;

	regval = readl(base + MA35_GP_REG_PUSEL);

	pull_sel = field_get(MA35_GP_PUSEL_MASK(port), regval);

	switch (pull_sel) {
	case MA35_GP_PUSEL_PULL_UP:
		return PIN_CONFIG_BIAS_PULL_UP;

	case MA35_GP_PUSEL_PULL_DOWN:
		return PIN_CONFIG_BIAS_PULL_DOWN;

	case MA35_GP_PUSEL_DISABLE:
		return PIN_CONFIG_BIAS_DISABLE;
	}

	return PIN_CONFIG_BIAS_DISABLE;
}

static int ma35_pinconf_set_output(struct ma35_pinctrl *npctl, unsigned int pin, bool out)
{
	unsigned int port, group_num;
	void __iomem *base;

	ma35_gpio_cla_port(pin, &group_num, &port);
	base = npctl->ctrl->pin_banks[group_num].reg_base;

	ma35_gpio_set_mode(base + MA35_GP_REG_MODE, port, MA35_GP_MODE_OUTPUT);

	return 0;
}

static int ma35_pinconf_get_power_source(struct ma35_pinctrl *npctl, unsigned int pin)
{
	unsigned int port, group_num;
	void __iomem *base;
	u32 regval;

	ma35_gpio_cla_port(pin, &group_num, &port);
	base = npctl->ctrl->pin_banks[group_num].reg_base;

	regval = readl(base + MA35_GP_REG_SPW);

	if (regval & BIT(port))
		return MVOLT_3300;
	else
		return MVOLT_1800;
}

static int ma35_pinconf_set_power_source(struct ma35_pinctrl *npctl,
					 unsigned int pin, int arg)
{
	unsigned int port, group_num;
	void __iomem *base;
	u32 regval;

	if ((arg != MVOLT_1800) && (arg != MVOLT_3300))
		return -EINVAL;

	ma35_gpio_cla_port(pin, &group_num, &port);
	base = npctl->ctrl->pin_banks[group_num].reg_base;

	regval = readl(base + MA35_GP_REG_SPW);

	if (arg == MVOLT_1800)
		regval &= ~BIT(port);
	else
		regval |= BIT(port);

	writel(regval, base + MA35_GP_REG_SPW);

	return 0;
}

static int ma35_pinconf_get_drive_strength(struct ma35_pinctrl *npctl, unsigned int pin,
					   u32 *strength)
{
	unsigned int port, group_num;
	void __iomem *base;
	u32 regval, ds_val;

	ma35_gpio_cla_port(pin, &group_num, &port);
	base = npctl->ctrl->pin_banks[group_num].reg_base;

	regval = readl(base + MA35_GP_DS_REG(port));
	ds_val = field_get(MA35_GP_DS_MASK(port), regval);

	if (ma35_pinconf_get_power_source(npctl, pin) == MVOLT_1800)
		*strength = ds_1800mv_tbl[ds_val];
	else
		*strength = ds_3300mv_tbl[ds_val];

	return 0;
}

static int ma35_pinconf_set_drive_strength(struct ma35_pinctrl *npctl, unsigned int pin,
					   int strength)
{
	unsigned int port, group_num;
	void __iomem *base;
	int i, ds_val = -1;
	u32 regval;

	if (ma35_pinconf_get_power_source(npctl, pin) == MVOLT_1800) {
		for (i = 0; i < ARRAY_SIZE(ds_1800mv_tbl); i++) {
			if (ds_1800mv_tbl[i] == strength) {
				ds_val = i;
				break;
			}
		}
	} else {
		for (i = 0; i < ARRAY_SIZE(ds_3300mv_tbl); i++) {
			if (ds_3300mv_tbl[i] == strength) {
				ds_val = i;
				break;
			}
		}
	}
	if (ds_val == -1)
		return -EINVAL;

	ma35_gpio_cla_port(pin, &group_num, &port);
	base = npctl->ctrl->pin_banks[group_num].reg_base;

	regval = readl(base + MA35_GP_DS_REG(port));
	regval &= ~MA35_GP_DS_MASK(port);
	regval |= field_prep(MA35_GP_DS_MASK(port), ds_val);

	writel(regval, base + MA35_GP_DS_REG(port));

	return 0;
}

static int ma35_pinconf_get_schmitt_enable(struct ma35_pinctrl *npctl, unsigned int pin)
{
	unsigned int port, group_num;
	void __iomem *base;
	u32 regval;

	ma35_gpio_cla_port(pin, &group_num, &port);
	base = npctl->ctrl->pin_banks[group_num].reg_base;

	regval = readl(base + MA35_GP_REG_SMTEN);

	return !!(regval & BIT(port));
}

static int ma35_pinconf_set_schmitt(struct ma35_pinctrl *npctl, unsigned int pin, int enable)
{
	unsigned int port, group_num;
	void __iomem *base;
	u32 regval;

	ma35_gpio_cla_port(pin, &group_num, &port);
	base = npctl->ctrl->pin_banks[group_num].reg_base;

	regval = readl(base + MA35_GP_REG_SMTEN);

	if (enable)
		regval |= BIT(port);
	else
		regval &= ~BIT(port);

	writel(regval, base + MA35_GP_REG_SMTEN);

	return 0;
}

static int ma35_pinconf_get_slew_rate(struct ma35_pinctrl *npctl, unsigned int pin)
{
	unsigned int port, group_num;
	void __iomem *base;
	u32 regval;

	ma35_gpio_cla_port(pin, &group_num, &port);
	base = npctl->ctrl->pin_banks[group_num].reg_base;

	regval = readl(base + MA35_GP_REG_SLEWCTL);

	return field_get(MA35_GP_SLEWCTL_MASK(port), regval);
}

static int ma35_pinconf_set_slew_rate(struct ma35_pinctrl *npctl, unsigned int pin, int rate)
{
	unsigned int port, group_num;
	void __iomem *base;
	u32 regval;

	ma35_gpio_cla_port(pin, &group_num, &port);
	base = npctl->ctrl->pin_banks[group_num].reg_base;

	regval = readl(base + MA35_GP_REG_SLEWCTL);
	regval &= ~MA35_GP_SLEWCTL_MASK(port);
	regval |= field_prep(MA35_GP_SLEWCTL_MASK(port), rate);

	writel(regval, base + MA35_GP_REG_SLEWCTL);

	return 0;
}

static int ma35_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, unsigned long *config)
{
	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);
	enum pin_config_param param = pinconf_to_config_param(*config);
	u32 arg;
	int ret;

	switch (param) {
	case PIN_CONFIG_BIAS_DISABLE:
	case PIN_CONFIG_BIAS_PULL_DOWN:
	case PIN_CONFIG_BIAS_PULL_UP:
		if (ma35_pinconf_get_pull(npctl, pin) != param)
			return -EINVAL;
		arg = 1;
		break;

	case PIN_CONFIG_DRIVE_STRENGTH:
		ret = ma35_pinconf_get_drive_strength(npctl, pin, &arg);
		if (ret)
			return ret;
		break;

	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
		arg = ma35_pinconf_get_schmitt_enable(npctl, pin);
		break;

	case PIN_CONFIG_SLEW_RATE:
		arg = ma35_pinconf_get_slew_rate(npctl, pin);
		break;

	case PIN_CONFIG_OUTPUT_ENABLE:
		arg = ma35_pinconf_get_output(npctl, pin);
		break;

	case PIN_CONFIG_POWER_SOURCE:
		arg = ma35_pinconf_get_power_source(npctl, pin);
		break;

	default:
		return -EINVAL;
	}
	*config = pinconf_to_config_packed(param, arg);

	return 0;
}

static int ma35_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
			    unsigned long *configs, unsigned int num_configs)
{
	struct ma35_pinctrl *npctl = pinctrl_dev_get_drvdata(pctldev);
	enum pin_config_param param;
	unsigned int arg = 0;
	int i, ret = 0;

	for (i = 0; i < num_configs; i++) {
		param = pinconf_to_config_param(configs[i]);
		arg = pinconf_to_config_argument(configs[i]);

		switch (param) {
		case PIN_CONFIG_BIAS_DISABLE:
		case PIN_CONFIG_BIAS_PULL_UP:
		case PIN_CONFIG_BIAS_PULL_DOWN:
			ret = ma35_pinconf_set_pull(npctl, pin, param);
			break;

		case PIN_CONFIG_DRIVE_STRENGTH:
			ret = ma35_pinconf_set_drive_strength(npctl, pin, arg);
			break;

		case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
			ret = ma35_pinconf_set_schmitt(npctl, pin, 1);
			break;

		case PIN_CONFIG_INPUT_SCHMITT:
			ret = ma35_pinconf_set_schmitt(npctl, pin, arg);
			break;

		case PIN_CONFIG_SLEW_RATE:
			ret = ma35_pinconf_set_slew_rate(npctl, pin, arg);
			break;

		case PIN_CONFIG_OUTPUT_ENABLE:
			ret = ma35_pinconf_set_output(npctl, pin, arg);
			break;

		case PIN_CONFIG_POWER_SOURCE:
			ret = ma35_pinconf_set_power_source(npctl, pin, arg);
			break;

		default:
			return -EINVAL;
		}

		if (ret)
			break;
	}
	return ret;
}

static const struct pinconf_ops ma35_pinconf_ops = {
	.pin_config_get = ma35_pinconf_get,
	.pin_config_set = ma35_pinconf_set,
	.is_generic = true,
};

static int ma35_pinctrl_parse_groups(struct device_node *np, struct ma35_pin_group *grp,
				     struct ma35_pinctrl *npctl, u32 index)
{
	struct ma35_pin_setting *pin;
	unsigned long *configs;
	unsigned int nconfigs;
	int i, j, count, ret;
	u32 *elems;

	grp->name = np->name;

	ret = pinconf_generic_parse_dt_config(np, NULL, &configs, &nconfigs);
	if (ret)
		return ret;

	count = of_property_count_elems_of_size(np, "nuvoton,pins", sizeof(u32));
	if (!count || count % 3)
		return -EINVAL;

	elems = devm_kmalloc_array(npctl->dev, count, sizeof(u32), GFP_KERNEL);
	if (!elems)
		return -ENOMEM;

	ret = of_property_read_u32_array(np, "nuvoton,pins", elems, count);
	if (ret)
		return -EINVAL;

	grp->npins = count / 3;

	grp->pins = devm_kcalloc(npctl->dev, grp->npins, sizeof(*grp->pins), GFP_KERNEL);
	if (!grp->pins)
		return -ENOMEM;

	grp->settings = devm_kcalloc(npctl->dev, grp->npins, sizeof(*grp->settings), GFP_KERNEL);
	if (!grp->settings)
		return -ENOMEM;

	pin = grp->settings;

	for (i = 0, j = 0; i < count; i += 3, j++) {
		pin->offset = elems[i] * MA35_MFP_REG_SZ_PER_BANK + MA35_MFP_REG_BASE;
		pin->shift = (elems[i + 1] * MA35_MFP_BITS_PER_PORT) % 32;
		pin->muxval = elems[i + 2];
		pin->configs = configs;
		pin->nconfigs = nconfigs;
		grp->pins[j] = npctl->info->get_pin_num(pin->offset, pin->shift);
		pin++;
	}
	return 0;
}

static int ma35_pinctrl_parse_functions(struct device_node *np, struct ma35_pinctrl *npctl,
					u32 index)
{
	struct device_node *child;
	struct ma35_pin_func *func;
	struct ma35_pin_group *grp;
	static u32 grp_index;
	u32 ret, i = 0;

	dev_dbg(npctl->dev, "parse function(%d): %s\n", index, np->name);

	func = &npctl->functions[index];
	func->name = np->name;
	func->ngroups = of_get_child_count(np);

	if (func->ngroups <= 0)
		return 0;

	func->groups = devm_kcalloc(npctl->dev, func->ngroups, sizeof(char *), GFP_KERNEL);
	if (!func->groups)
		return -ENOMEM;

	for_each_child_of_node(np, child) {
		func->groups[i] = child->name;
		grp = &npctl->groups[grp_index++];
		ret = ma35_pinctrl_parse_groups(child, grp, npctl, i++);
		if (ret) {
			of_node_put(child);
			return ret;
		}
	}
	return 0;
}

static int ma35_pinctrl_probe_dt(struct platform_device *pdev, struct ma35_pinctrl *npctl)
{
	struct fwnode_handle *child;
	u32 idx = 0;
	int ret;

	device_for_each_child_node(&pdev->dev, child) {
		if (fwnode_property_present(child, "gpio-controller"))
			continue;
		npctl->nfunctions++;
		npctl->ngroups += of_get_child_count(to_of_node(child));
	}

	if (!npctl->nfunctions)
		return -EINVAL;

	npctl->functions = devm_kcalloc(&pdev->dev, npctl->nfunctions,
					sizeof(*npctl->functions), GFP_KERNEL);
	if (!npctl->functions)
		return -ENOMEM;

	npctl->groups = devm_kcalloc(&pdev->dev, npctl->ngroups,
				     sizeof(*npctl->groups), GFP_KERNEL);
	if (!npctl->groups)
		return -ENOMEM;

	device_for_each_child_node(&pdev->dev, child) {
		if (fwnode_property_present(child, "gpio-controller"))
			continue;

		ret = ma35_pinctrl_parse_functions(to_of_node(child), npctl, idx++);
		if (ret) {
			fwnode_handle_put(child);
			dev_err(&pdev->dev, "failed to parse function\n");
			return ret;
		}
	}
	return 0;
}

int ma35_pinctrl_probe(struct platform_device *pdev, const struct ma35_pinctrl_soc_info *info)
{
	struct pinctrl_desc *ma35_pinctrl_desc;
	struct device *dev = &pdev->dev;
	struct ma35_pinctrl *npctl;
	int ret;

	if (!info || !info->pins || !info->npins) {
		dev_err(&pdev->dev, "wrong pinctrl info\n");
		return -EINVAL;
	}

	npctl = devm_kzalloc(&pdev->dev, sizeof(*npctl), GFP_KERNEL);
	if (!npctl)
		return -ENOMEM;

	ma35_pinctrl_desc = devm_kzalloc(&pdev->dev, sizeof(*ma35_pinctrl_desc), GFP_KERNEL);
	if (!ma35_pinctrl_desc)
		return -ENOMEM;

	npctl->ctrl = devm_kzalloc(&pdev->dev, sizeof(*npctl->ctrl), GFP_KERNEL);
	if (!npctl->ctrl)
		return -ENOMEM;

	ma35_pinctrl_desc->name = dev_name(&pdev->dev);
	ma35_pinctrl_desc->pins = info->pins;
	ma35_pinctrl_desc->npins = info->npins;
	ma35_pinctrl_desc->pctlops = &ma35_pctrl_ops;
	ma35_pinctrl_desc->pmxops = &ma35_pmx_ops;
	ma35_pinctrl_desc->confops = &ma35_pinconf_ops;
	ma35_pinctrl_desc->owner = THIS_MODULE;

	npctl->info = info;
	npctl->dev = &pdev->dev;

	npctl->regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "nuvoton,sys");
	if (IS_ERR(npctl->regmap))
		return dev_err_probe(&pdev->dev, PTR_ERR(npctl->regmap),
				     "No syscfg phandle specified\n");

	ret = ma35_pinctrl_get_soc_data(npctl, pdev);
	if (ret)
		return dev_err_probe(&pdev->dev, ret, "fail to get soc data\n");

	platform_set_drvdata(pdev, npctl);

	ret = ma35_pinctrl_probe_dt(pdev, npctl);
	if (ret)
		return dev_err_probe(&pdev->dev, ret, "fail to probe MA35 pinctrl dt\n");

	ret = devm_pinctrl_register_and_init(dev, ma35_pinctrl_desc, npctl, &npctl->pctl);
	if (ret)
		return dev_err_probe(&pdev->dev, ret, "fail to register MA35 pinctrl\n");

	ret = pinctrl_enable(npctl->pctl);
	if (ret)
		return dev_err_probe(&pdev->dev, ret, "fail to enable MA35 pinctrl\n");

	return ma35_gpiolib_register(pdev, npctl);
}

int ma35_pinctrl_suspend(struct device *dev)
{
	struct ma35_pinctrl *npctl = dev_get_drvdata(dev);

	return pinctrl_force_sleep(npctl->pctl);
}

int ma35_pinctrl_resume(struct device *dev)
{
	struct ma35_pinctrl *npctl = dev_get_drvdata(dev);

	return pinctrl_force_default(npctl->pctl);
}
