// 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 = kcalloc(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);
}
