// SPDX-License-Identifier: GPL-2.0
/*
 * GPIO driver for TI TPS65219 PMICs
 *
 * Copyright (C) 2022 Texas Instruments Incorporated - http://www.ti.com/
 */

#include <linux/bits.h>
#include <linux/gpio/driver.h>
#include <linux/mfd/tps65219.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>

#define TPS65219_GPIO0_DIR_MASK		BIT(3)
#define TPS65219_GPIO0_OFFSET		2
#define TPS65219_GPIO0_IDX		0
#define TPS65219_GPIO_DIR_IN		1
#define TPS65219_GPIO_DIR_OUT		0

struct tps65219_gpio {
	struct gpio_chip gpio_chip;
	struct tps65219 *tps;
};

static int tps65219_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
{
	struct tps65219_gpio *gpio = gpiochip_get_data(gc);
	int ret, val;

	if (offset != TPS65219_GPIO0_IDX)
		return GPIO_LINE_DIRECTION_OUT;

	ret = regmap_read(gpio->tps->regmap, TPS65219_REG_MFP_1_CONFIG, &val);
	if (ret)
		return ret;

	return !!(val & TPS65219_GPIO0_DIR_MASK);
}

static int tps65219_gpio_get(struct gpio_chip *gc, unsigned int offset)
{
	struct tps65219_gpio *gpio = gpiochip_get_data(gc);
	struct device *dev = gpio->tps->dev;
	int ret, val;

	if (offset != TPS65219_GPIO0_IDX) {
		dev_err(dev, "GPIO%d is output only, cannot get\n", offset);
		return -ENOTSUPP;
	}

	ret = regmap_read(gpio->tps->regmap, TPS65219_REG_MFP_CTRL, &val);
	if (ret)
		return ret;

	ret = !!(val & BIT(TPS65219_MFP_GPIO_STATUS_MASK));
	dev_warn(dev, "GPIO%d = %d, MULTI_DEVICE_ENABLE, not a standard GPIO\n", offset, ret);

	/*
	 * Depending on NVM config, return an error if direction is output, otherwise the GPIO0
	 * status bit.
	 */

	if (tps65219_gpio_get_direction(gc, offset) == TPS65219_GPIO_DIR_OUT)
		return -ENOTSUPP;

	return ret;
}

static void tps65219_gpio_set(struct gpio_chip *gc, unsigned int offset, int value)
{
	struct tps65219_gpio *gpio = gpiochip_get_data(gc);
	struct device *dev = gpio->tps->dev;
	int v, mask, bit;

	bit = (offset == TPS65219_GPIO0_IDX) ? TPS65219_GPIO0_OFFSET : offset - 1;

	mask = BIT(bit);
	v = value ? mask : 0;

	if (regmap_update_bits(gpio->tps->regmap, TPS65219_REG_GENERAL_CONFIG, mask, v))
		dev_err(dev, "GPIO%d, set to value %d failed.\n", offset, value);
}

static int tps65219_gpio_change_direction(struct gpio_chip *gc, unsigned int offset,
					  unsigned int direction)
{
	struct tps65219_gpio *gpio = gpiochip_get_data(gc);
	struct device *dev = gpio->tps->dev;

	/*
	 * Documentation is stating that GPIO0 direction must not be changed in Linux:
	 * Table 8-34. MFP_1_CONFIG(3): MULTI_DEVICE_ENABLE, should only be changed in INITIALIZE
	 * state (prior to ON Request).
	 * Set statically by NVM, changing direction in application can cause a hang.
	 * Below can be used for test purpose only.
	 */

#if 0
	int ret = regmap_update_bits(gpio->tps->regmap, TPS65219_REG_MFP_1_CONFIG,
				     TPS65219_GPIO0_DIR_MASK, direction);
	if (ret) {
		dev_err(dev,
			"GPIO DEBUG enabled: Fail to change direction to %u for GPIO%d.\n",
			direction, offset);
		return ret;
	}
#endif

	dev_err(dev,
		"GPIO%d direction set by NVM, change to %u failed, not allowed by specification\n",
		 offset, direction);

	return -ENOTSUPP;
}

static int tps65219_gpio_direction_input(struct gpio_chip *gc, unsigned int offset)
{
	struct tps65219_gpio *gpio = gpiochip_get_data(gc);
	struct device *dev = gpio->tps->dev;

	if (offset != TPS65219_GPIO0_IDX) {
		dev_err(dev, "GPIO%d is output only, cannot change to input\n", offset);
		return -ENOTSUPP;
	}

	if (tps65219_gpio_get_direction(gc, offset) == TPS65219_GPIO_DIR_IN)
		return 0;

	return tps65219_gpio_change_direction(gc, offset, TPS65219_GPIO_DIR_IN);
}

static int tps65219_gpio_direction_output(struct gpio_chip *gc, unsigned int offset, int value)
{
	tps65219_gpio_set(gc, offset, value);
	if (offset != TPS65219_GPIO0_IDX)
		return 0;

	if (tps65219_gpio_get_direction(gc, offset) == TPS65219_GPIO_DIR_OUT)
		return 0;

	return tps65219_gpio_change_direction(gc, offset, TPS65219_GPIO_DIR_OUT);
}

static const struct gpio_chip tps65219_template_chip = {
	.label			= "tps65219-gpio",
	.owner			= THIS_MODULE,
	.get_direction		= tps65219_gpio_get_direction,
	.direction_input	= tps65219_gpio_direction_input,
	.direction_output	= tps65219_gpio_direction_output,
	.get			= tps65219_gpio_get,
	.set			= tps65219_gpio_set,
	.base			= -1,
	.ngpio			= 3,
	.can_sleep		= true,
};

static int tps65219_gpio_probe(struct platform_device *pdev)
{
	struct tps65219 *tps = dev_get_drvdata(pdev->dev.parent);
	struct tps65219_gpio *gpio;

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

	gpio->tps = tps;
	gpio->gpio_chip = tps65219_template_chip;
	gpio->gpio_chip.parent = tps->dev;

	return devm_gpiochip_add_data(&pdev->dev, &gpio->gpio_chip, gpio);
}

static struct platform_driver tps65219_gpio_driver = {
	.driver = {
		.name = "tps65219-gpio",
	},
	.probe = tps65219_gpio_probe,
};
module_platform_driver(tps65219_gpio_driver);

MODULE_ALIAS("platform:tps65219-gpio");
MODULE_AUTHOR("Jonathan Cormier <jcormier@criticallink.com>");
MODULE_DESCRIPTION("TPS65219 GPIO driver");
MODULE_LICENSE("GPL");
