// SPDX-License-Identifier: GPL-2.0+
//
// Synopsys CREG (Control REGisters) GPIO driver
//
// Copyright (C) 2018 Synopsys
// Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>

#include <linux/gpio/driver.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/platform_device.h>

#define MAX_GPIO	32

struct creg_layout {
	u8 ngpio;
	u8 shift[MAX_GPIO];
	u8 on[MAX_GPIO];
	u8 off[MAX_GPIO];
	u8 bit_per_gpio[MAX_GPIO];
};

struct creg_gpio {
	struct gpio_chip gc;
	void __iomem *regs;
	spinlock_t lock;
	const struct creg_layout *layout;
};

static void creg_gpio_set(struct gpio_chip *gc, unsigned int offset, int val)
{
	struct creg_gpio *hcg = gpiochip_get_data(gc);
	const struct creg_layout *layout = hcg->layout;
	u32 reg, reg_shift, value;
	unsigned long flags;
	int i;

	value = val ? hcg->layout->on[offset] : hcg->layout->off[offset];

	reg_shift = layout->shift[offset];
	for (i = 0; i < offset; i++)
		reg_shift += layout->bit_per_gpio[i] + layout->shift[i];

	spin_lock_irqsave(&hcg->lock, flags);
	reg = readl(hcg->regs);
	reg &= ~(GENMASK(layout->bit_per_gpio[i] - 1, 0) << reg_shift);
	reg |=  (value << reg_shift);
	writel(reg, hcg->regs);
	spin_unlock_irqrestore(&hcg->lock, flags);
}

static int creg_gpio_dir_out(struct gpio_chip *gc, unsigned int offset, int val)
{
	creg_gpio_set(gc, offset, val);

	return 0;
}

static int creg_gpio_validate_pg(struct device *dev, struct creg_gpio *hcg,
				 int i)
{
	const struct creg_layout *layout = hcg->layout;

	if (layout->bit_per_gpio[i] < 1 || layout->bit_per_gpio[i] > 8)
		return -EINVAL;

	/* Check that on value fits its placeholder */
	if (GENMASK(31, layout->bit_per_gpio[i]) & layout->on[i])
		return -EINVAL;

	/* Check that off value fits its placeholder */
	if (GENMASK(31, layout->bit_per_gpio[i]) & layout->off[i])
		return -EINVAL;

	if (layout->on[i] == layout->off[i])
		return -EINVAL;

	return 0;
}

static int creg_gpio_validate(struct device *dev, struct creg_gpio *hcg,
			      u32 ngpios)
{
	u32 reg_len = 0;
	int i;

	if (hcg->layout->ngpio < 1 || hcg->layout->ngpio > MAX_GPIO)
		return -EINVAL;

	if (ngpios < 1 || ngpios > hcg->layout->ngpio) {
		dev_err(dev, "ngpios must be in [1:%u]\n", hcg->layout->ngpio);
		return -EINVAL;
	}

	for (i = 0; i < hcg->layout->ngpio; i++) {
		if (creg_gpio_validate_pg(dev, hcg, i))
			return -EINVAL;

		reg_len += hcg->layout->shift[i] + hcg->layout->bit_per_gpio[i];
	}

	/* Check that we fit in 32 bit register */
	if (reg_len > 32)
		return -EINVAL;

	return 0;
}

static const struct creg_layout hsdk_cs_ctl = {
	.ngpio		= 10,
	.shift		= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	.off		= { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
	.on		= { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
	.bit_per_gpio	= { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }
};

static const struct creg_layout axs10x_flsh_cs_ctl = {
	.ngpio		= 1,
	.shift		= { 0 },
	.off		= { 1 },
	.on		= { 3 },
	.bit_per_gpio	= { 2 }
};

static const struct of_device_id creg_gpio_ids[] = {
	{
		.compatible = "snps,creg-gpio-axs10x",
		.data = &axs10x_flsh_cs_ctl
	}, {
		.compatible = "snps,creg-gpio-hsdk",
		.data = &hsdk_cs_ctl
	}, { /* sentinel */ }
};

static int creg_gpio_probe(struct platform_device *pdev)
{
	const struct of_device_id *match;
	struct device *dev = &pdev->dev;
	struct creg_gpio *hcg;
	u32 ngpios;
	int ret;

	hcg = devm_kzalloc(dev, sizeof(struct creg_gpio), GFP_KERNEL);
	if (!hcg)
		return -ENOMEM;

	hcg->regs = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(hcg->regs))
		return PTR_ERR(hcg->regs);

	match = of_match_node(creg_gpio_ids, pdev->dev.of_node);
	hcg->layout = match->data;
	if (!hcg->layout)
		return -EINVAL;

	ret = of_property_read_u32(dev->of_node, "ngpios", &ngpios);
	if (ret)
		return ret;

	ret = creg_gpio_validate(dev, hcg, ngpios);
	if (ret)
		return ret;

	spin_lock_init(&hcg->lock);

	hcg->gc.parent = dev;
	hcg->gc.label = dev_name(dev);
	hcg->gc.base = -1;
	hcg->gc.ngpio = ngpios;
	hcg->gc.set = creg_gpio_set;
	hcg->gc.direction_output = creg_gpio_dir_out;

	ret = devm_gpiochip_add_data(dev, &hcg->gc, hcg);
	if (ret)
		return ret;

	dev_info(dev, "GPIO controller with %d gpios probed\n", ngpios);

	return 0;
}

static struct platform_driver creg_gpio_snps_driver = {
	.driver = {
		.name = "snps-creg-gpio",
		.of_match_table = creg_gpio_ids,
	},
	.probe  = creg_gpio_probe,
};
builtin_platform_driver(creg_gpio_snps_driver);
