// SPDX-License-Identifier: GPL-2.0-only
/*
 * ZTE ZX296702 GPIO driver
 *
 * Author: Jun Nie <jun.nie@linaro.org>
 *
 * Copyright (C) 2015 Linaro Ltd.
 */
#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/gpio/driver.h>
#include <linux/irqchip/chained_irq.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/slab.h>
#include <linux/spinlock.h>

#define ZX_GPIO_DIR	0x00
#define ZX_GPIO_IVE	0x04
#define ZX_GPIO_IV	0x08
#define ZX_GPIO_IEP	0x0C
#define ZX_GPIO_IEN	0x10
#define ZX_GPIO_DI	0x14
#define ZX_GPIO_DO1	0x18
#define ZX_GPIO_DO0	0x1C
#define ZX_GPIO_DO	0x20

#define ZX_GPIO_IM	0x28
#define ZX_GPIO_IE	0x2C

#define ZX_GPIO_MIS	0x30
#define ZX_GPIO_IC	0x34

#define ZX_GPIO_NR	16

struct zx_gpio {
	raw_spinlock_t		lock;

	void __iomem		*base;
	struct gpio_chip	gc;
};

static int zx_direction_input(struct gpio_chip *gc, unsigned offset)
{
	struct zx_gpio *chip = gpiochip_get_data(gc);
	unsigned long flags;
	u16 gpiodir;

	if (offset >= gc->ngpio)
		return -EINVAL;

	raw_spin_lock_irqsave(&chip->lock, flags);
	gpiodir = readw_relaxed(chip->base + ZX_GPIO_DIR);
	gpiodir &= ~BIT(offset);
	writew_relaxed(gpiodir, chip->base + ZX_GPIO_DIR);
	raw_spin_unlock_irqrestore(&chip->lock, flags);

	return 0;
}

static int zx_direction_output(struct gpio_chip *gc, unsigned offset,
		int value)
{
	struct zx_gpio *chip = gpiochip_get_data(gc);
	unsigned long flags;
	u16 gpiodir;

	if (offset >= gc->ngpio)
		return -EINVAL;

	raw_spin_lock_irqsave(&chip->lock, flags);
	gpiodir = readw_relaxed(chip->base + ZX_GPIO_DIR);
	gpiodir |= BIT(offset);
	writew_relaxed(gpiodir, chip->base + ZX_GPIO_DIR);

	if (value)
		writew_relaxed(BIT(offset), chip->base + ZX_GPIO_DO1);
	else
		writew_relaxed(BIT(offset), chip->base + ZX_GPIO_DO0);
	raw_spin_unlock_irqrestore(&chip->lock, flags);

	return 0;
}

static int zx_get_value(struct gpio_chip *gc, unsigned offset)
{
	struct zx_gpio *chip = gpiochip_get_data(gc);

	return !!(readw_relaxed(chip->base + ZX_GPIO_DI) & BIT(offset));
}

static void zx_set_value(struct gpio_chip *gc, unsigned offset, int value)
{
	struct zx_gpio *chip = gpiochip_get_data(gc);

	if (value)
		writew_relaxed(BIT(offset), chip->base + ZX_GPIO_DO1);
	else
		writew_relaxed(BIT(offset), chip->base + ZX_GPIO_DO0);
}

static int zx_irq_type(struct irq_data *d, unsigned trigger)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct zx_gpio *chip = gpiochip_get_data(gc);
	int offset = irqd_to_hwirq(d);
	unsigned long flags;
	u16 gpiois, gpioi_epos, gpioi_eneg, gpioiev;
	u16 bit = BIT(offset);

	if (offset < 0 || offset >= ZX_GPIO_NR)
		return -EINVAL;

	raw_spin_lock_irqsave(&chip->lock, flags);

	gpioiev = readw_relaxed(chip->base + ZX_GPIO_IV);
	gpiois = readw_relaxed(chip->base + ZX_GPIO_IVE);
	gpioi_epos = readw_relaxed(chip->base + ZX_GPIO_IEP);
	gpioi_eneg = readw_relaxed(chip->base + ZX_GPIO_IEN);

	if (trigger & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
		gpiois |= bit;
		if (trigger & IRQ_TYPE_LEVEL_HIGH)
			gpioiev |= bit;
		else
			gpioiev &= ~bit;
	} else
		gpiois &= ~bit;

	if ((trigger & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
		gpioi_epos |= bit;
		gpioi_eneg |= bit;
	} else {
		if (trigger & IRQ_TYPE_EDGE_RISING) {
			gpioi_epos |= bit;
			gpioi_eneg &= ~bit;
		} else if (trigger & IRQ_TYPE_EDGE_FALLING) {
			gpioi_eneg |= bit;
			gpioi_epos &= ~bit;
		}
	}

	writew_relaxed(gpiois, chip->base + ZX_GPIO_IVE);
	writew_relaxed(gpioi_epos, chip->base + ZX_GPIO_IEP);
	writew_relaxed(gpioi_eneg, chip->base + ZX_GPIO_IEN);
	writew_relaxed(gpioiev, chip->base + ZX_GPIO_IV);
	raw_spin_unlock_irqrestore(&chip->lock, flags);

	return 0;
}

static void zx_irq_handler(struct irq_desc *desc)
{
	unsigned long pending;
	int offset;
	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
	struct zx_gpio *chip = gpiochip_get_data(gc);
	struct irq_chip *irqchip = irq_desc_get_chip(desc);

	chained_irq_enter(irqchip, desc);

	pending = readw_relaxed(chip->base + ZX_GPIO_MIS);
	writew_relaxed(pending, chip->base + ZX_GPIO_IC);
	if (pending) {
		for_each_set_bit(offset, &pending, ZX_GPIO_NR)
			generic_handle_irq(irq_find_mapping(gc->irq.domain,
							    offset));
	}

	chained_irq_exit(irqchip, desc);
}

static void zx_irq_mask(struct irq_data *d)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct zx_gpio *chip = gpiochip_get_data(gc);
	u16 mask = BIT(irqd_to_hwirq(d) % ZX_GPIO_NR);
	u16 gpioie;

	raw_spin_lock(&chip->lock);
	gpioie = readw_relaxed(chip->base + ZX_GPIO_IM) | mask;
	writew_relaxed(gpioie, chip->base + ZX_GPIO_IM);
	gpioie = readw_relaxed(chip->base + ZX_GPIO_IE) & ~mask;
	writew_relaxed(gpioie, chip->base + ZX_GPIO_IE);
	raw_spin_unlock(&chip->lock);
}

static void zx_irq_unmask(struct irq_data *d)
{
	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
	struct zx_gpio *chip = gpiochip_get_data(gc);
	u16 mask = BIT(irqd_to_hwirq(d) % ZX_GPIO_NR);
	u16 gpioie;

	raw_spin_lock(&chip->lock);
	gpioie = readw_relaxed(chip->base + ZX_GPIO_IM) & ~mask;
	writew_relaxed(gpioie, chip->base + ZX_GPIO_IM);
	gpioie = readw_relaxed(chip->base + ZX_GPIO_IE) | mask;
	writew_relaxed(gpioie, chip->base + ZX_GPIO_IE);
	raw_spin_unlock(&chip->lock);
}

static struct irq_chip zx_irqchip = {
	.name		= "zx-gpio",
	.irq_mask	= zx_irq_mask,
	.irq_unmask	= zx_irq_unmask,
	.irq_set_type	= zx_irq_type,
};

static int zx_gpio_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct zx_gpio *chip;
	struct gpio_irq_chip *girq;
	int irq, id, ret;

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

	chip->base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(chip->base))
		return PTR_ERR(chip->base);

	id = of_alias_get_id(dev->of_node, "gpio");

	raw_spin_lock_init(&chip->lock);
	chip->gc.request = gpiochip_generic_request;
	chip->gc.free = gpiochip_generic_free;
	chip->gc.direction_input = zx_direction_input;
	chip->gc.direction_output = zx_direction_output;
	chip->gc.get = zx_get_value;
	chip->gc.set = zx_set_value;
	chip->gc.base = ZX_GPIO_NR * id;
	chip->gc.ngpio = ZX_GPIO_NR;
	chip->gc.label = dev_name(dev);
	chip->gc.parent = dev;
	chip->gc.owner = THIS_MODULE;

	/*
	 * irq_chip support
	 */
	writew_relaxed(0xffff, chip->base + ZX_GPIO_IM);
	writew_relaxed(0, chip->base + ZX_GPIO_IE);
	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;
	girq = &chip->gc.irq;
	girq->chip = &zx_irqchip;
	girq->parent_handler = zx_irq_handler;
	girq->num_parents = 1;
	girq->parents = devm_kcalloc(&pdev->dev, 1,
				     sizeof(*girq->parents),
				     GFP_KERNEL);
	if (!girq->parents)
		return -ENOMEM;
	girq->parents[0] = irq;
	girq->default_type = IRQ_TYPE_NONE;
	girq->handler = handle_simple_irq;

	ret = gpiochip_add_data(&chip->gc, chip);
	if (ret)
		return ret;

	platform_set_drvdata(pdev, chip);
	dev_info(dev, "ZX GPIO chip registered\n");

	return 0;
}

static const struct of_device_id zx_gpio_match[] = {
	{
		.compatible = "zte,zx296702-gpio",
	},
	{ },
};

static struct platform_driver zx_gpio_driver = {
	.probe		= zx_gpio_probe,
	.driver = {
		.name	= "zx_gpio",
		.of_match_table = of_match_ptr(zx_gpio_match),
	},
};
builtin_platform_driver(zx_gpio_driver)
