// SPDX-License-Identifier: GPL-2.0-only
/*
 * sl28cpld GPIO driver
 *
 * Copyright 2020 Michael Walle <michael@walle.cc>
 */

#include <linux/device.h>
#include <linux/gpio/driver.h>
#include <linux/gpio/regmap.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>

/* GPIO flavor */
#define GPIO_REG_DIR	0x00
#define GPIO_REG_OUT	0x01
#define GPIO_REG_IN	0x02
#define GPIO_REG_IE	0x03
#define GPIO_REG_IP	0x04

/* input-only flavor */
#define GPI_REG_IN	0x00

/* output-only flavor */
#define GPO_REG_OUT	0x00

enum sl28cpld_gpio_type {
	SL28CPLD_GPIO = 1,
	SL28CPLD_GPI,
	SL28CPLD_GPO,
};

static const struct regmap_irq sl28cpld_gpio_irqs[] = {
	REGMAP_IRQ_REG_LINE(0, 8),
	REGMAP_IRQ_REG_LINE(1, 8),
	REGMAP_IRQ_REG_LINE(2, 8),
	REGMAP_IRQ_REG_LINE(3, 8),
	REGMAP_IRQ_REG_LINE(4, 8),
	REGMAP_IRQ_REG_LINE(5, 8),
	REGMAP_IRQ_REG_LINE(6, 8),
	REGMAP_IRQ_REG_LINE(7, 8),
};

static int sl28cpld_gpio_irq_init(struct platform_device *pdev,
				  unsigned int base,
				  struct gpio_regmap_config *config)
{
	struct regmap_irq_chip_data *irq_data;
	struct regmap_irq_chip *irq_chip;
	struct device *dev = &pdev->dev;
	int irq, ret;

	if (!device_property_read_bool(dev, "interrupt-controller"))
		return 0;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;

	irq_chip = devm_kzalloc(dev, sizeof(*irq_chip), GFP_KERNEL);
	if (!irq_chip)
		return -ENOMEM;

	irq_chip->name = "sl28cpld-gpio-irq";
	irq_chip->irqs = sl28cpld_gpio_irqs;
	irq_chip->num_irqs = ARRAY_SIZE(sl28cpld_gpio_irqs);
	irq_chip->num_regs = 1;
	irq_chip->status_base = base + GPIO_REG_IP;
	irq_chip->mask_base = base + GPIO_REG_IE;
	irq_chip->mask_invert = true;
	irq_chip->ack_base = base + GPIO_REG_IP;

	ret = devm_regmap_add_irq_chip_fwnode(dev, dev_fwnode(dev),
					      config->regmap, irq,
					      IRQF_SHARED | IRQF_ONESHOT,
					      0, irq_chip, &irq_data);
	if (ret)
		return ret;

	config->irq_domain = regmap_irq_get_domain(irq_data);

	return 0;
}

static int sl28cpld_gpio_probe(struct platform_device *pdev)
{
	struct gpio_regmap_config config = {0};
	enum sl28cpld_gpio_type type;
	struct regmap *regmap;
	u32 base;
	int ret;

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

	type = (uintptr_t)device_get_match_data(&pdev->dev);
	if (!type)
		return -ENODEV;

	ret = device_property_read_u32(&pdev->dev, "reg", &base);
	if (ret)
		return -EINVAL;

	regmap = dev_get_regmap(pdev->dev.parent, NULL);
	if (!regmap)
		return -ENODEV;

	config.regmap = regmap;
	config.parent = &pdev->dev;
	config.ngpio = 8;

	switch (type) {
	case SL28CPLD_GPIO:
		config.reg_dat_base = base + GPIO_REG_IN;
		config.reg_set_base = base + GPIO_REG_OUT;
		/* reg_dir_out_base might be zero */
		config.reg_dir_out_base = GPIO_REGMAP_ADDR(base + GPIO_REG_DIR);

		/* This type supports interrupts */
		ret = sl28cpld_gpio_irq_init(pdev, base, &config);
		if (ret)
			return ret;
		break;
	case SL28CPLD_GPO:
		config.reg_set_base = base + GPO_REG_OUT;
		break;
	case SL28CPLD_GPI:
		config.reg_dat_base = base + GPI_REG_IN;
		break;
	default:
		dev_err(&pdev->dev, "unknown type %d\n", type);
		return -ENODEV;
	}

	return PTR_ERR_OR_ZERO(devm_gpio_regmap_register(&pdev->dev, &config));
}

static const struct of_device_id sl28cpld_gpio_of_match[] = {
	{ .compatible = "kontron,sl28cpld-gpio", .data = (void *)SL28CPLD_GPIO },
	{ .compatible = "kontron,sl28cpld-gpi", .data = (void *)SL28CPLD_GPI },
	{ .compatible = "kontron,sl28cpld-gpo", .data = (void *)SL28CPLD_GPO },
	{}
};
MODULE_DEVICE_TABLE(of, sl28cpld_gpio_of_match);

static struct platform_driver sl28cpld_gpio_driver = {
	.probe = sl28cpld_gpio_probe,
	.driver = {
		.name = "sl28cpld-gpio",
		.of_match_table = sl28cpld_gpio_of_match,
	},
};
module_platform_driver(sl28cpld_gpio_driver);

MODULE_DESCRIPTION("sl28cpld GPIO Driver");
MODULE_AUTHOR("Michael Walle <michael@walle.cc>");
MODULE_LICENSE("GPL");
