// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * AXP20x pinctrl and GPIO driver
 *
 * Copyright (C) 2016 Maxime Ripard <maxime.ripard@free-electrons.com>
 * Copyright (C) 2017 Quentin Schulz <quentin.schulz@free-electrons.com>
 */

#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/gpio/driver.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mfd/axp20x.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>

#include <linux/pinctrl/consumer.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>

#define AXP20X_GPIO_FUNCTIONS		0x7
#define AXP20X_GPIO_FUNCTION_OUT_LOW	0
#define AXP20X_GPIO_FUNCTION_OUT_HIGH	1
#define AXP20X_GPIO_FUNCTION_INPUT	2

#define AXP20X_GPIO3_FUNCTIONS		GENMASK(2, 1)
#define AXP20X_GPIO3_FUNCTION_OUT_LOW	0
#define AXP20X_GPIO3_FUNCTION_OUT_HIGH	2
#define AXP20X_GPIO3_FUNCTION_INPUT	4

#define AXP20X_FUNC_GPIO_OUT		0
#define AXP20X_FUNC_GPIO_IN		1
#define AXP20X_FUNC_LDO			2
#define AXP20X_FUNC_ADC			3
#define AXP20X_FUNCS_NB			4

#define AXP20X_MUX_GPIO_OUT		0
#define AXP20X_MUX_GPIO_IN		BIT(1)
#define AXP20X_MUX_ADC			BIT(2)

#define AXP813_MUX_ADC			(BIT(2) | BIT(0))

struct axp20x_pctrl_desc {
	const struct pinctrl_pin_desc	*pins;
	unsigned int			npins;
	/* Stores the pins supporting LDO function. Bit offset is pin number. */
	u8				ldo_mask;
	/* Stores the pins supporting ADC function. Bit offset is pin number. */
	u8				adc_mask;
	u8				gpio_status_offset;
	u8				adc_mux;
};

struct axp20x_pinctrl_function {
	const char	*name;
	unsigned int	muxval;
	const char	**groups;
	unsigned int	ngroups;
};

struct axp20x_pctl {
	struct gpio_chip	chip;
	struct regmap		*regmap;
	struct pinctrl_dev			*pctl_dev;
	struct device				*dev;
	const struct axp20x_pctrl_desc		*desc;
	struct axp20x_pinctrl_function		funcs[AXP20X_FUNCS_NB];
};

static const struct pinctrl_pin_desc axp209_pins[] = {
	PINCTRL_PIN(0, "GPIO0"),
	PINCTRL_PIN(1, "GPIO1"),
	PINCTRL_PIN(2, "GPIO2"),
	PINCTRL_PIN(3, "GPIO3"),
};

static const struct pinctrl_pin_desc axp22x_pins[] = {
	PINCTRL_PIN(0, "GPIO0"),
	PINCTRL_PIN(1, "GPIO1"),
};

static const struct axp20x_pctrl_desc axp20x_data = {
	.pins	= axp209_pins,
	.npins	= ARRAY_SIZE(axp209_pins),
	.ldo_mask = BIT(0) | BIT(1),
	.adc_mask = BIT(0) | BIT(1),
	.gpio_status_offset = 4,
	.adc_mux = AXP20X_MUX_ADC,
};

static const struct axp20x_pctrl_desc axp22x_data = {
	.pins	= axp22x_pins,
	.npins	= ARRAY_SIZE(axp22x_pins),
	.ldo_mask = BIT(0) | BIT(1),
	.gpio_status_offset = 0,
};

static const struct axp20x_pctrl_desc axp813_data = {
	.pins	= axp22x_pins,
	.npins	= ARRAY_SIZE(axp22x_pins),
	.ldo_mask = BIT(0) | BIT(1),
	.adc_mask = BIT(0),
	.gpio_status_offset = 0,
	.adc_mux = AXP813_MUX_ADC,
};

static int axp20x_gpio_get_reg(unsigned int offset)
{
	switch (offset) {
	case 0:
		return AXP20X_GPIO0_CTRL;
	case 1:
		return AXP20X_GPIO1_CTRL;
	case 2:
		return AXP20X_GPIO2_CTRL;
	}

	return -EINVAL;
}

static int axp20x_gpio_get(struct gpio_chip *chip, unsigned int offset)
{
	struct axp20x_pctl *pctl = gpiochip_get_data(chip);
	unsigned int val;
	int ret;

	/* AXP209 has GPIO3 status sharing the settings register */
	if (offset == 3) {
		ret = regmap_read(pctl->regmap, AXP20X_GPIO3_CTRL, &val);
		if (ret)
			return ret;
		return !!(val & BIT(0));
	}

	ret = regmap_read(pctl->regmap, AXP20X_GPIO20_SS, &val);
	if (ret)
		return ret;

	return !!(val & BIT(offset + pctl->desc->gpio_status_offset));
}

static int axp20x_gpio_get_direction(struct gpio_chip *chip,
				     unsigned int offset)
{
	struct axp20x_pctl *pctl = gpiochip_get_data(chip);
	unsigned int val;
	int reg, ret;

	/* AXP209 GPIO3 settings have a different layout */
	if (offset == 3) {
		ret = regmap_read(pctl->regmap, AXP20X_GPIO3_CTRL, &val);
		if (ret)
			return ret;
		if (val & AXP20X_GPIO3_FUNCTION_INPUT)
			return GPIO_LINE_DIRECTION_IN;

		return GPIO_LINE_DIRECTION_OUT;
	}

	reg = axp20x_gpio_get_reg(offset);
	if (reg < 0)
		return reg;

	ret = regmap_read(pctl->regmap, reg, &val);
	if (ret)
		return ret;

	/*
	 * This shouldn't really happen if the pin is in use already,
	 * or if it's not in use yet, it doesn't matter since we're
	 * going to change the value soon anyway. Default to output.
	 */
	if ((val & AXP20X_GPIO_FUNCTIONS) > 2)
		return GPIO_LINE_DIRECTION_OUT;

	/*
	 * The GPIO directions are the three lowest values.
	 * 2 is input, 0 and 1 are output
	 */
	if (val & 2)
		return GPIO_LINE_DIRECTION_IN;

	return GPIO_LINE_DIRECTION_OUT;
}

static int axp20x_gpio_output(struct gpio_chip *chip, unsigned int offset,
			      int value)
{
	chip->set(chip, offset, value);

	return 0;
}

static void axp20x_gpio_set(struct gpio_chip *chip, unsigned int offset,
			    int value)
{
	struct axp20x_pctl *pctl = gpiochip_get_data(chip);
	int reg;

	/* AXP209 has GPIO3 status sharing the settings register */
	if (offset == 3) {
		regmap_update_bits(pctl->regmap, AXP20X_GPIO3_CTRL,
				   AXP20X_GPIO3_FUNCTIONS,
				   value ? AXP20X_GPIO3_FUNCTION_OUT_HIGH :
				   AXP20X_GPIO3_FUNCTION_OUT_LOW);
		return;
	}

	reg = axp20x_gpio_get_reg(offset);
	if (reg < 0)
		return;

	regmap_update_bits(pctl->regmap, reg,
			   AXP20X_GPIO_FUNCTIONS,
			   value ? AXP20X_GPIO_FUNCTION_OUT_HIGH :
			   AXP20X_GPIO_FUNCTION_OUT_LOW);
}

static int axp20x_pmx_set(struct pinctrl_dev *pctldev, unsigned int offset,
			  u8 config)
{
	struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
	int reg;

	/* AXP209 GPIO3 settings have a different layout */
	if (offset == 3) {
		return regmap_update_bits(pctl->regmap, AXP20X_GPIO3_CTRL,
				   AXP20X_GPIO3_FUNCTIONS,
				   config == AXP20X_MUX_GPIO_OUT ? AXP20X_GPIO3_FUNCTION_OUT_LOW :
				   AXP20X_GPIO3_FUNCTION_INPUT);
	}

	reg = axp20x_gpio_get_reg(offset);
	if (reg < 0)
		return reg;

	return regmap_update_bits(pctl->regmap, reg, AXP20X_GPIO_FUNCTIONS,
				  config);
}

static int axp20x_pmx_func_cnt(struct pinctrl_dev *pctldev)
{
	struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);

	return ARRAY_SIZE(pctl->funcs);
}

static const char *axp20x_pmx_func_name(struct pinctrl_dev *pctldev,
					unsigned int selector)
{
	struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);

	return pctl->funcs[selector].name;
}

static int axp20x_pmx_func_groups(struct pinctrl_dev *pctldev,
				  unsigned int selector,
				  const char * const **groups,
				  unsigned int *num_groups)
{
	struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);

	*groups = pctl->funcs[selector].groups;
	*num_groups = pctl->funcs[selector].ngroups;

	return 0;
}

static int axp20x_pmx_set_mux(struct pinctrl_dev *pctldev,
			      unsigned int function, unsigned int group)
{
	struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
	unsigned int mask;

	/* Every pin supports GPIO_OUT and GPIO_IN functions */
	if (function <= AXP20X_FUNC_GPIO_IN)
		return axp20x_pmx_set(pctldev, group,
				      pctl->funcs[function].muxval);

	if (function == AXP20X_FUNC_LDO)
		mask = pctl->desc->ldo_mask;
	else
		mask = pctl->desc->adc_mask;

	if (!(BIT(group) & mask))
		return -EINVAL;

	/*
	 * We let the regulator framework handle the LDO muxing as muxing bits
	 * are basically also regulators on/off bits. It's better not to enforce
	 * any state of the regulator when selecting LDO mux so that we don't
	 * interfere with the regulator driver.
	 */
	if (function == AXP20X_FUNC_LDO)
		return 0;

	return axp20x_pmx_set(pctldev, group, pctl->funcs[function].muxval);
}

static int axp20x_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
					 struct pinctrl_gpio_range *range,
					 unsigned int offset, bool input)
{
	struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);

	if (input)
		return axp20x_pmx_set(pctldev, offset,
				      pctl->funcs[AXP20X_FUNC_GPIO_IN].muxval);

	return axp20x_pmx_set(pctldev, offset,
			      pctl->funcs[AXP20X_FUNC_GPIO_OUT].muxval);
}

static const struct pinmux_ops axp20x_pmx_ops = {
	.get_functions_count	= axp20x_pmx_func_cnt,
	.get_function_name	= axp20x_pmx_func_name,
	.get_function_groups	= axp20x_pmx_func_groups,
	.set_mux		= axp20x_pmx_set_mux,
	.gpio_set_direction	= axp20x_pmx_gpio_set_direction,
	.strict			= true,
};

static int axp20x_groups_cnt(struct pinctrl_dev *pctldev)
{
	struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);

	return pctl->desc->npins;
}

static int axp20x_group_pins(struct pinctrl_dev *pctldev, unsigned int selector,
			     const unsigned int **pins, unsigned int *num_pins)
{
	struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);

	*pins = (unsigned int *)&pctl->desc->pins[selector];
	*num_pins = 1;

	return 0;
}

static const char *axp20x_group_name(struct pinctrl_dev *pctldev,
				     unsigned int selector)
{
	struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);

	return pctl->desc->pins[selector].name;
}

static const struct pinctrl_ops axp20x_pctrl_ops = {
	.dt_node_to_map		= pinconf_generic_dt_node_to_map_group,
	.dt_free_map		= pinconf_generic_dt_free_map,
	.get_groups_count	= axp20x_groups_cnt,
	.get_group_name		= axp20x_group_name,
	.get_group_pins		= axp20x_group_pins,
};

static int axp20x_funcs_groups_from_mask(struct device *dev, unsigned int mask,
					  unsigned int mask_len,
					  struct axp20x_pinctrl_function *func,
					  const struct pinctrl_pin_desc *pins)
{
	unsigned long int mask_cpy = mask;
	const char **group;
	unsigned int ngroups = hweight8(mask);
	int bit;

	func->ngroups = ngroups;
	if (func->ngroups > 0) {
		func->groups = devm_kcalloc(dev,
					    ngroups, sizeof(const char *),
					    GFP_KERNEL);
		if (!func->groups)
			return -ENOMEM;
		group = func->groups;
		for_each_set_bit(bit, &mask_cpy, mask_len) {
			*group = pins[bit].name;
			group++;
		}
	}

	return 0;
}

static int axp20x_build_funcs_groups(struct platform_device *pdev)
{
	struct axp20x_pctl *pctl = platform_get_drvdata(pdev);
	int i, ret, pin, npins = pctl->desc->npins;

	pctl->funcs[AXP20X_FUNC_GPIO_OUT].name = "gpio_out";
	pctl->funcs[AXP20X_FUNC_GPIO_OUT].muxval = AXP20X_MUX_GPIO_OUT;
	pctl->funcs[AXP20X_FUNC_GPIO_IN].name = "gpio_in";
	pctl->funcs[AXP20X_FUNC_GPIO_IN].muxval = AXP20X_MUX_GPIO_IN;
	pctl->funcs[AXP20X_FUNC_LDO].name = "ldo";
	/*
	 * Muxval for LDO is useless as we won't use it.
	 * See comment in axp20x_pmx_set_mux.
	 */
	pctl->funcs[AXP20X_FUNC_ADC].name = "adc";
	pctl->funcs[AXP20X_FUNC_ADC].muxval = pctl->desc->adc_mux;

	/* Every pin supports GPIO_OUT and GPIO_IN functions */
	for (i = 0; i <= AXP20X_FUNC_GPIO_IN; i++) {
		pctl->funcs[i].ngroups = npins;
		pctl->funcs[i].groups = devm_kcalloc(&pdev->dev,
						     npins, sizeof(char *),
						     GFP_KERNEL);
		if (!pctl->funcs[i].groups)
			return -ENOMEM;
		for (pin = 0; pin < npins; pin++)
			pctl->funcs[i].groups[pin] = pctl->desc->pins[pin].name;
	}

	ret = axp20x_funcs_groups_from_mask(&pdev->dev, pctl->desc->ldo_mask,
				      npins, &pctl->funcs[AXP20X_FUNC_LDO],
				      pctl->desc->pins);
	if (ret)
		return ret;

	ret = axp20x_funcs_groups_from_mask(&pdev->dev, pctl->desc->adc_mask,
				      npins, &pctl->funcs[AXP20X_FUNC_ADC],
				      pctl->desc->pins);
	if (ret)
		return ret;

	return 0;
}

static const struct of_device_id axp20x_pctl_match[] = {
	{ .compatible = "x-powers,axp209-gpio", .data = &axp20x_data, },
	{ .compatible = "x-powers,axp221-gpio", .data = &axp22x_data, },
	{ .compatible = "x-powers,axp813-gpio", .data = &axp813_data, },
	{ }
};
MODULE_DEVICE_TABLE(of, axp20x_pctl_match);

static int axp20x_pctl_probe(struct platform_device *pdev)
{
	struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
	struct axp20x_pctl *pctl;
	struct device *dev = &pdev->dev;
	struct pinctrl_desc *pctrl_desc;
	int ret;

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

	if (!axp20x) {
		dev_err(&pdev->dev, "Parent drvdata not set\n");
		return -EINVAL;
	}

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

	pctl->chip.base			= -1;
	pctl->chip.can_sleep		= true;
	pctl->chip.request		= gpiochip_generic_request;
	pctl->chip.free			= gpiochip_generic_free;
	pctl->chip.parent		= &pdev->dev;
	pctl->chip.label		= dev_name(&pdev->dev);
	pctl->chip.owner		= THIS_MODULE;
	pctl->chip.get			= axp20x_gpio_get;
	pctl->chip.get_direction	= axp20x_gpio_get_direction;
	pctl->chip.set			= axp20x_gpio_set;
	pctl->chip.direction_input	= pinctrl_gpio_direction_input;
	pctl->chip.direction_output	= axp20x_gpio_output;

	pctl->desc = of_device_get_match_data(dev);

	pctl->chip.ngpio		= pctl->desc->npins;

	pctl->regmap = axp20x->regmap;
	pctl->dev = &pdev->dev;

	platform_set_drvdata(pdev, pctl);

	ret = axp20x_build_funcs_groups(pdev);
	if (ret) {
		dev_err(&pdev->dev, "failed to build groups\n");
		return ret;
	}

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

	pctrl_desc->name = dev_name(&pdev->dev);
	pctrl_desc->owner = THIS_MODULE;
	pctrl_desc->pins = pctl->desc->pins;
	pctrl_desc->npins = pctl->desc->npins;
	pctrl_desc->pctlops = &axp20x_pctrl_ops;
	pctrl_desc->pmxops = &axp20x_pmx_ops;

	pctl->pctl_dev = devm_pinctrl_register(&pdev->dev, pctrl_desc, pctl);
	if (IS_ERR(pctl->pctl_dev)) {
		dev_err(&pdev->dev, "couldn't register pinctrl driver\n");
		return PTR_ERR(pctl->pctl_dev);
	}

	ret = devm_gpiochip_add_data(&pdev->dev, &pctl->chip, pctl);
	if (ret) {
		dev_err(&pdev->dev, "Failed to register GPIO chip\n");
		return ret;
	}

	ret = gpiochip_add_pin_range(&pctl->chip, dev_name(&pdev->dev),
				     pctl->desc->pins->number,
				     pctl->desc->pins->number,
				     pctl->desc->npins);
	if (ret) {
		dev_err(&pdev->dev, "failed to add pin range\n");
		return ret;
	}

	dev_info(&pdev->dev, "AXP209 pinctrl and GPIO driver loaded\n");

	return 0;
}

static struct platform_driver axp20x_pctl_driver = {
	.probe		= axp20x_pctl_probe,
	.driver = {
		.name		= "axp20x-gpio",
		.of_match_table	= axp20x_pctl_match,
	},
};

module_platform_driver(axp20x_pctl_driver);

MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
MODULE_DESCRIPTION("AXP20x PMIC pinctrl and GPIO driver");
MODULE_LICENSE("GPL");
