// SPDX-License-Identifier: GPL-2.0
/*
 * Intel Whiskey Cove PMIC GPIO Driver
 *
 * This driver is written based on gpio-crystalcove.c
 *
 * Copyright (C) 2016 Intel Corporation. All rights reserved.
 */

#include <linux/bitops.h>
#include <linux/gpio/driver.h>
#include <linux/interrupt.h>
#include <linux/mfd/intel_soc_pmic.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/seq_file.h>

/*
 * Whiskey Cove PMIC has 13 physical GPIO pins divided into 3 banks:
 * Bank 0: Pin  0 - 6
 * Bank 1: Pin  7 - 10
 * Bank 2: Pin 11 - 12
 * Each pin has one output control register and one input control register.
 */
#define BANK0_NR_PINS		7
#define BANK1_NR_PINS		4
#define BANK2_NR_PINS		2
#define WCOVE_GPIO_NUM		(BANK0_NR_PINS + BANK1_NR_PINS + BANK2_NR_PINS)
#define WCOVE_VGPIO_NUM		94
/* GPIO output control registers (one per pin): 0x4e44 - 0x4e50 */
#define GPIO_OUT_CTRL_BASE	0x4e44
/* GPIO input control registers (one per pin): 0x4e51 - 0x4e5d */
#define GPIO_IN_CTRL_BASE	0x4e51

/*
 * GPIO interrupts are organized in two groups:
 * Group 0: Bank 0 pins (Pin 0 - 6)
 * Group 1: Bank 1 and Bank 2 pins (Pin 7 - 12)
 * Each group has two registers (one bit per pin): status and mask.
 */
#define GROUP0_NR_IRQS		7
#define GROUP1_NR_IRQS		6
#define IRQ_MASK_BASE		0x4e19
#define IRQ_STATUS_BASE		0x4e0b
#define GPIO_IRQ0_MASK		GENMASK(6, 0)
#define GPIO_IRQ1_MASK		GENMASK(5, 0)
#define UPDATE_IRQ_TYPE		BIT(0)
#define UPDATE_IRQ_MASK		BIT(1)

#define CTLI_INTCNT_DIS		(0 << 1)
#define CTLI_INTCNT_NE		(1 << 1)
#define CTLI_INTCNT_PE		(2 << 1)
#define CTLI_INTCNT_BE		(3 << 1)

#define CTLO_DIR_IN		(0 << 5)
#define CTLO_DIR_OUT		(1 << 5)

#define CTLO_DRV_MASK		(1 << 4)
#define CTLO_DRV_OD		(0 << 4)
#define CTLO_DRV_CMOS		(1 << 4)

#define CTLO_DRV_REN		(1 << 3)

#define CTLO_RVAL_2KDOWN	(0 << 1)
#define CTLO_RVAL_2KUP		(1 << 1)
#define CTLO_RVAL_50KDOWN	(2 << 1)
#define CTLO_RVAL_50KUP		(3 << 1)

#define CTLO_INPUT_SET		(CTLO_DRV_CMOS | CTLO_DRV_REN | CTLO_RVAL_2KUP)
#define CTLO_OUTPUT_SET		(CTLO_DIR_OUT | CTLO_INPUT_SET)

enum ctrl_register {
	CTRL_IN,
	CTRL_OUT,
	IRQ_STATUS,
	IRQ_MASK,
};

/*
 * struct wcove_gpio - Whiskey Cove GPIO controller
 * @buslock: for bus lock/sync and unlock.
 * @chip: the abstract gpio_chip structure.
 * @dev: the gpio device
 * @regmap: the regmap from the parent device.
 * @regmap_irq_chip: the regmap of the gpio irq chip.
 * @update: pending IRQ setting update, to be written to the chip upon unlock.
 * @intcnt: the Interrupt Detect value to be written.
 * @set_irq_mask: true if the IRQ mask needs to be set, false to clear.
 */
struct wcove_gpio {
	struct mutex buslock;
	struct gpio_chip chip;
	struct device *dev;
	struct regmap *regmap;
	struct regmap_irq_chip_data *regmap_irq_chip;
	int update;
	int intcnt;
	bool set_irq_mask;
};

static inline int to_reg(int gpio, enum ctrl_register type)
{
	unsigned int reg = type == CTRL_IN ? GPIO_IN_CTRL_BASE : GPIO_OUT_CTRL_BASE;

	if (gpio >= WCOVE_GPIO_NUM)
		return -ENOTSUPP;

	return reg + gpio;
}

static inline int to_ireg(int gpio, enum ctrl_register type, unsigned int *mask)
{
	unsigned int reg = type == IRQ_STATUS ? IRQ_STATUS_BASE : IRQ_MASK_BASE;

	if (gpio < GROUP0_NR_IRQS) {
		reg += 0;
		*mask = BIT(gpio);
	} else {
		reg += 1;
		*mask = BIT(gpio - GROUP0_NR_IRQS);
	}

	return reg;
}

static void wcove_update_irq_mask(struct wcove_gpio *wg, irq_hw_number_t gpio)
{
	unsigned int mask, reg = to_ireg(gpio, IRQ_MASK, &mask);

	if (wg->set_irq_mask)
		regmap_set_bits(wg->regmap, reg, mask);
	else
		regmap_clear_bits(wg->regmap, reg, mask);
}

static void wcove_update_irq_ctrl(struct wcove_gpio *wg, irq_hw_number_t gpio)
{
	int reg = to_reg(gpio, CTRL_IN);

	regmap_update_bits(wg->regmap, reg, CTLI_INTCNT_BE, wg->intcnt);
}

static int wcove_gpio_dir_in(struct gpio_chip *chip, unsigned int gpio)
{
	struct wcove_gpio *wg = gpiochip_get_data(chip);
	int reg = to_reg(gpio, CTRL_OUT);

	if (reg < 0)
		return 0;

	return regmap_write(wg->regmap, reg, CTLO_INPUT_SET);
}

static int wcove_gpio_dir_out(struct gpio_chip *chip, unsigned int gpio,
				    int value)
{
	struct wcove_gpio *wg = gpiochip_get_data(chip);
	int reg = to_reg(gpio, CTRL_OUT);

	if (reg < 0)
		return 0;

	return regmap_write(wg->regmap, reg, CTLO_OUTPUT_SET | value);
}

static int wcove_gpio_get_direction(struct gpio_chip *chip, unsigned int gpio)
{
	struct wcove_gpio *wg = gpiochip_get_data(chip);
	unsigned int val;
	int ret, reg = to_reg(gpio, CTRL_OUT);

	if (reg < 0)
		return GPIO_LINE_DIRECTION_OUT;

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

	if (val & CTLO_DIR_OUT)
		return GPIO_LINE_DIRECTION_OUT;

	return GPIO_LINE_DIRECTION_IN;
}

static int wcove_gpio_get(struct gpio_chip *chip, unsigned int gpio)
{
	struct wcove_gpio *wg = gpiochip_get_data(chip);
	unsigned int val;
	int ret, reg = to_reg(gpio, CTRL_IN);

	if (reg < 0)
		return 0;

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

	return val & 0x1;
}

static void wcove_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)
{
	struct wcove_gpio *wg = gpiochip_get_data(chip);
	int reg = to_reg(gpio, CTRL_OUT);

	if (reg < 0)
		return;

	if (value)
		regmap_set_bits(wg->regmap, reg, 1);
	else
		regmap_clear_bits(wg->regmap, reg, 1);
}

static int wcove_gpio_set_config(struct gpio_chip *chip, unsigned int gpio,
				 unsigned long config)
{
	struct wcove_gpio *wg = gpiochip_get_data(chip);
	int reg = to_reg(gpio, CTRL_OUT);

	if (reg < 0)
		return 0;

	switch (pinconf_to_config_param(config)) {
	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
		return regmap_update_bits(wg->regmap, reg, CTLO_DRV_MASK,
					  CTLO_DRV_OD);
	case PIN_CONFIG_DRIVE_PUSH_PULL:
		return regmap_update_bits(wg->regmap, reg, CTLO_DRV_MASK,
					  CTLO_DRV_CMOS);
	default:
		break;
	}

	return -ENOTSUPP;
}

static int wcove_irq_type(struct irq_data *data, unsigned int type)
{
	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
	struct wcove_gpio *wg = gpiochip_get_data(chip);
	irq_hw_number_t gpio = irqd_to_hwirq(data);

	if (gpio >= WCOVE_GPIO_NUM)
		return 0;

	switch (type) {
	case IRQ_TYPE_NONE:
		wg->intcnt = CTLI_INTCNT_DIS;
		break;
	case IRQ_TYPE_EDGE_BOTH:
		wg->intcnt = CTLI_INTCNT_BE;
		break;
	case IRQ_TYPE_EDGE_RISING:
		wg->intcnt = CTLI_INTCNT_PE;
		break;
	case IRQ_TYPE_EDGE_FALLING:
		wg->intcnt = CTLI_INTCNT_NE;
		break;
	default:
		return -EINVAL;
	}

	wg->update |= UPDATE_IRQ_TYPE;

	return 0;
}

static void wcove_bus_lock(struct irq_data *data)
{
	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
	struct wcove_gpio *wg = gpiochip_get_data(chip);

	mutex_lock(&wg->buslock);
}

static void wcove_bus_sync_unlock(struct irq_data *data)
{
	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
	struct wcove_gpio *wg = gpiochip_get_data(chip);
	irq_hw_number_t gpio = irqd_to_hwirq(data);

	if (wg->update & UPDATE_IRQ_TYPE)
		wcove_update_irq_ctrl(wg, gpio);
	if (wg->update & UPDATE_IRQ_MASK)
		wcove_update_irq_mask(wg, gpio);
	wg->update = 0;

	mutex_unlock(&wg->buslock);
}

static void wcove_irq_unmask(struct irq_data *data)
{
	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
	struct wcove_gpio *wg = gpiochip_get_data(chip);
	irq_hw_number_t gpio = irqd_to_hwirq(data);

	if (gpio >= WCOVE_GPIO_NUM)
		return;

	wg->set_irq_mask = false;
	wg->update |= UPDATE_IRQ_MASK;
}

static void wcove_irq_mask(struct irq_data *data)
{
	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
	struct wcove_gpio *wg = gpiochip_get_data(chip);
	irq_hw_number_t gpio = irqd_to_hwirq(data);

	if (gpio >= WCOVE_GPIO_NUM)
		return;

	wg->set_irq_mask = true;
	wg->update |= UPDATE_IRQ_MASK;
}

static struct irq_chip wcove_irqchip = {
	.name			= "Whiskey Cove",
	.irq_mask		= wcove_irq_mask,
	.irq_unmask		= wcove_irq_unmask,
	.irq_set_type		= wcove_irq_type,
	.irq_bus_lock		= wcove_bus_lock,
	.irq_bus_sync_unlock	= wcove_bus_sync_unlock,
};

static irqreturn_t wcove_gpio_irq_handler(int irq, void *data)
{
	struct wcove_gpio *wg = (struct wcove_gpio *)data;
	unsigned int virq, gpio;
	unsigned long pending;
	u8 p[2];

	if (regmap_bulk_read(wg->regmap, IRQ_STATUS_BASE, p, 2)) {
		dev_err(wg->dev, "Failed to read irq status register\n");
		return IRQ_NONE;
	}

	pending = (p[0] & GPIO_IRQ0_MASK) | ((p[1] & GPIO_IRQ1_MASK) << 7);
	if (!pending)
		return IRQ_NONE;

	/* Iterate until no interrupt is pending */
	while (pending) {
		/* One iteration is for all pending bits */
		for_each_set_bit(gpio, &pending, WCOVE_GPIO_NUM) {
			unsigned int mask, reg = to_ireg(gpio, IRQ_STATUS, &mask);

			virq = irq_find_mapping(wg->chip.irq.domain, gpio);
			handle_nested_irq(virq);
			regmap_set_bits(wg->regmap, reg, mask);
		}

		/* Next iteration */
		if (regmap_bulk_read(wg->regmap, IRQ_STATUS_BASE, p, 2)) {
			dev_err(wg->dev, "Failed to read irq status\n");
			break;
		}

		pending = (p[0] & GPIO_IRQ0_MASK) | ((p[1] & GPIO_IRQ1_MASK) << 7);
	}

	return IRQ_HANDLED;
}

static void wcove_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
{
	unsigned int ctlo, ctli, irq_mask, irq_status;
	struct wcove_gpio *wg = gpiochip_get_data(chip);
	int gpio, mask, ret = 0;

	for (gpio = 0; gpio < WCOVE_GPIO_NUM; gpio++) {
		ret += regmap_read(wg->regmap, to_reg(gpio, CTRL_OUT), &ctlo);
		ret += regmap_read(wg->regmap, to_reg(gpio, CTRL_IN), &ctli);
		if (ret) {
			dev_err(wg->dev, "Failed to read registers: CTRL out/in\n");
			break;
		}

		ret += regmap_read(wg->regmap, to_ireg(gpio, IRQ_MASK, &mask), &irq_mask);
		ret += regmap_read(wg->regmap, to_ireg(gpio, IRQ_STATUS, &mask), &irq_status);
		if (ret) {
			dev_err(wg->dev, "Failed to read registers: IRQ status/mask\n");
			break;
		}

		seq_printf(s, " gpio-%-2d %s %s %s %s ctlo=%2x,%s %s\n",
			   gpio, ctlo & CTLO_DIR_OUT ? "out" : "in ",
			   ctli & 0x1 ? "hi" : "lo",
			   ctli & CTLI_INTCNT_NE ? "fall" : "    ",
			   ctli & CTLI_INTCNT_PE ? "rise" : "    ",
			   ctlo,
			   irq_mask & mask ? "mask  " : "unmask",
			   irq_status & mask ? "pending" : "       ");
	}
}

static int wcove_gpio_probe(struct platform_device *pdev)
{
	struct intel_soc_pmic *pmic;
	struct wcove_gpio *wg;
	int virq, ret, irq;
	struct device *dev;
	struct gpio_irq_chip *girq;

	/*
	 * This gpio platform device is created by a mfd device (see
	 * drivers/mfd/intel_soc_pmic_bxtwc.c for details). Information
	 * shared by all sub-devices created by the mfd device, the regmap
	 * pointer for instance, is stored as driver data of the mfd device
	 * driver.
	 */
	pmic = dev_get_drvdata(pdev->dev.parent);
	if (!pmic)
		return -ENODEV;

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

	dev = &pdev->dev;

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

	wg->regmap_irq_chip = pmic->irq_chip_data;

	platform_set_drvdata(pdev, wg);

	mutex_init(&wg->buslock);
	wg->chip.label = KBUILD_MODNAME;
	wg->chip.direction_input = wcove_gpio_dir_in;
	wg->chip.direction_output = wcove_gpio_dir_out;
	wg->chip.get_direction = wcove_gpio_get_direction;
	wg->chip.get = wcove_gpio_get;
	wg->chip.set = wcove_gpio_set;
	wg->chip.set_config = wcove_gpio_set_config;
	wg->chip.base = -1;
	wg->chip.ngpio = WCOVE_VGPIO_NUM;
	wg->chip.can_sleep = true;
	wg->chip.parent = pdev->dev.parent;
	wg->chip.dbg_show = wcove_gpio_dbg_show;
	wg->dev = dev;
	wg->regmap = pmic->regmap;

	virq = regmap_irq_get_virq(wg->regmap_irq_chip, irq);
	if (virq < 0) {
		dev_err(dev, "Failed to get virq by irq %d\n", irq);
		return virq;
	}

	girq = &wg->chip.irq;
	girq->chip = &wcove_irqchip;
	/* This will let us handle the parent IRQ in the driver */
	girq->parent_handler = NULL;
	girq->num_parents = 0;
	girq->parents = NULL;
	girq->default_type = IRQ_TYPE_NONE;
	girq->handler = handle_simple_irq;
	girq->threaded = true;

	ret = devm_request_threaded_irq(dev, virq, NULL, wcove_gpio_irq_handler,
					IRQF_ONESHOT, pdev->name, wg);
	if (ret) {
		dev_err(dev, "Failed to request irq %d\n", virq);
		return ret;
	}

	ret = devm_gpiochip_add_data(dev, &wg->chip, wg);
	if (ret) {
		dev_err(dev, "Failed to add gpiochip: %d\n", ret);
		return ret;
	}

	/* Enable GPIO0 interrupts */
	ret = regmap_clear_bits(wg->regmap, IRQ_MASK_BASE + 0, GPIO_IRQ0_MASK);
	if (ret)
		return ret;

	/* Enable GPIO1 interrupts */
	ret = regmap_clear_bits(wg->regmap, IRQ_MASK_BASE + 1, GPIO_IRQ1_MASK);
	if (ret)
		return ret;

	return 0;
}

/*
 * Whiskey Cove PMIC itself is a analog device(but with digital control
 * interface) providing power management support for other devices in
 * the accompanied SoC, so we have no .pm for Whiskey Cove GPIO driver.
 */
static struct platform_driver wcove_gpio_driver = {
	.driver = {
		.name = "bxt_wcove_gpio",
	},
	.probe = wcove_gpio_probe,
};

module_platform_driver(wcove_gpio_driver);

MODULE_AUTHOR("Ajay Thomas <ajay.thomas.david.rajamanickam@intel.com>");
MODULE_AUTHOR("Bin Gao <bin.gao@intel.com>");
MODULE_DESCRIPTION("Intel Whiskey Cove GPIO Driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:bxt_wcove_gpio");
