// SPDX-License-Identifier: GPL-2.0
/*
 * Driver for STMicroelectronics Multi-Function eXpander (STMFX) core
 *
 * Copyright (C) 2019 STMicroelectronics
 * Author(s): Amelie Delaunay <amelie.delaunay@st.com>.
 */
#include <linux/bitfield.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/mfd/core.h>
#include <linux/mfd/stmfx.h>
#include <linux/module.h>
#include <linux/regulator/consumer.h>

static bool stmfx_reg_volatile(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case STMFX_REG_SYS_CTRL:
	case STMFX_REG_IRQ_SRC_EN:
	case STMFX_REG_IRQ_PENDING:
	case STMFX_REG_IRQ_GPI_PENDING1:
	case STMFX_REG_IRQ_GPI_PENDING2:
	case STMFX_REG_IRQ_GPI_PENDING3:
	case STMFX_REG_GPIO_STATE1:
	case STMFX_REG_GPIO_STATE2:
	case STMFX_REG_GPIO_STATE3:
	case STMFX_REG_IRQ_GPI_SRC1:
	case STMFX_REG_IRQ_GPI_SRC2:
	case STMFX_REG_IRQ_GPI_SRC3:
	case STMFX_REG_GPO_SET1:
	case STMFX_REG_GPO_SET2:
	case STMFX_REG_GPO_SET3:
	case STMFX_REG_GPO_CLR1:
	case STMFX_REG_GPO_CLR2:
	case STMFX_REG_GPO_CLR3:
		return true;
	default:
		return false;
	}
}

static bool stmfx_reg_writeable(struct device *dev, unsigned int reg)
{
	return (reg >= STMFX_REG_SYS_CTRL);
}

static const struct regmap_config stmfx_regmap_config = {
	.reg_bits	= 8,
	.reg_stride	= 1,
	.val_bits	= 8,
	.max_register	= STMFX_REG_MAX,
	.volatile_reg	= stmfx_reg_volatile,
	.writeable_reg	= stmfx_reg_writeable,
	.cache_type	= REGCACHE_RBTREE,
};

static const struct resource stmfx_pinctrl_resources[] = {
	DEFINE_RES_IRQ(STMFX_REG_IRQ_SRC_EN_GPIO),
};

static const struct resource stmfx_idd_resources[] = {
	DEFINE_RES_IRQ(STMFX_REG_IRQ_SRC_EN_IDD),
	DEFINE_RES_IRQ(STMFX_REG_IRQ_SRC_EN_ERROR),
};

static const struct resource stmfx_ts_resources[] = {
	DEFINE_RES_IRQ(STMFX_REG_IRQ_SRC_EN_TS_DET),
	DEFINE_RES_IRQ(STMFX_REG_IRQ_SRC_EN_TS_NE),
	DEFINE_RES_IRQ(STMFX_REG_IRQ_SRC_EN_TS_TH),
	DEFINE_RES_IRQ(STMFX_REG_IRQ_SRC_EN_TS_FULL),
	DEFINE_RES_IRQ(STMFX_REG_IRQ_SRC_EN_TS_OVF),
};

static struct mfd_cell stmfx_cells[] = {
	{
		.of_compatible = "st,stmfx-0300-pinctrl",
		.name = "stmfx-pinctrl",
		.resources = stmfx_pinctrl_resources,
		.num_resources = ARRAY_SIZE(stmfx_pinctrl_resources),
	},
	{
		.of_compatible = "st,stmfx-0300-idd",
		.name = "stmfx-idd",
		.resources = stmfx_idd_resources,
		.num_resources = ARRAY_SIZE(stmfx_idd_resources),
	},
	{
		.of_compatible = "st,stmfx-0300-ts",
		.name = "stmfx-ts",
		.resources = stmfx_ts_resources,
		.num_resources = ARRAY_SIZE(stmfx_ts_resources),
	},
};

static u8 stmfx_func_to_mask(u32 func)
{
	u8 mask = 0;

	if (func & STMFX_FUNC_GPIO)
		mask |= STMFX_REG_SYS_CTRL_GPIO_EN;

	if ((func & STMFX_FUNC_ALTGPIO_LOW) || (func & STMFX_FUNC_ALTGPIO_HIGH))
		mask |= STMFX_REG_SYS_CTRL_ALTGPIO_EN;

	if (func & STMFX_FUNC_TS)
		mask |= STMFX_REG_SYS_CTRL_TS_EN;

	if (func & STMFX_FUNC_IDD)
		mask |= STMFX_REG_SYS_CTRL_IDD_EN;

	return mask;
}

int stmfx_function_enable(struct stmfx *stmfx, u32 func)
{
	u32 sys_ctrl;
	u8 mask;
	int ret;

	ret = regmap_read(stmfx->map, STMFX_REG_SYS_CTRL, &sys_ctrl);
	if (ret)
		return ret;

	/*
	 * IDD and TS have priority in STMFX FW, so if IDD and TS are enabled,
	 * ALTGPIO function is disabled by STMFX FW. If IDD or TS is enabled,
	 * the number of aGPIO available decreases. To avoid GPIO management
	 * disturbance, abort IDD or TS function enable in this case.
	 */
	if (((func & STMFX_FUNC_IDD) || (func & STMFX_FUNC_TS)) &&
	    (sys_ctrl & STMFX_REG_SYS_CTRL_ALTGPIO_EN)) {
		dev_err(stmfx->dev, "ALTGPIO function already enabled\n");
		return -EBUSY;
	}

	/* If TS is enabled, aGPIO[3:0] cannot be used */
	if ((func & STMFX_FUNC_ALTGPIO_LOW) &&
	    (sys_ctrl & STMFX_REG_SYS_CTRL_TS_EN)) {
		dev_err(stmfx->dev, "TS in use, aGPIO[3:0] unavailable\n");
		return -EBUSY;
	}

	/* If IDD is enabled, aGPIO[7:4] cannot be used */
	if ((func & STMFX_FUNC_ALTGPIO_HIGH) &&
	    (sys_ctrl & STMFX_REG_SYS_CTRL_IDD_EN)) {
		dev_err(stmfx->dev, "IDD in use, aGPIO[7:4] unavailable\n");
		return -EBUSY;
	}

	mask = stmfx_func_to_mask(func);

	return regmap_update_bits(stmfx->map, STMFX_REG_SYS_CTRL, mask, mask);
}
EXPORT_SYMBOL_GPL(stmfx_function_enable);

int stmfx_function_disable(struct stmfx *stmfx, u32 func)
{
	u8 mask = stmfx_func_to_mask(func);

	return regmap_update_bits(stmfx->map, STMFX_REG_SYS_CTRL, mask, 0);
}
EXPORT_SYMBOL_GPL(stmfx_function_disable);

static void stmfx_irq_bus_lock(struct irq_data *data)
{
	struct stmfx *stmfx = irq_data_get_irq_chip_data(data);

	mutex_lock(&stmfx->lock);
}

static void stmfx_irq_bus_sync_unlock(struct irq_data *data)
{
	struct stmfx *stmfx = irq_data_get_irq_chip_data(data);

	regmap_write(stmfx->map, STMFX_REG_IRQ_SRC_EN, stmfx->irq_src);

	mutex_unlock(&stmfx->lock);
}

static void stmfx_irq_mask(struct irq_data *data)
{
	struct stmfx *stmfx = irq_data_get_irq_chip_data(data);

	stmfx->irq_src &= ~BIT(data->hwirq % 8);
}

static void stmfx_irq_unmask(struct irq_data *data)
{
	struct stmfx *stmfx = irq_data_get_irq_chip_data(data);

	stmfx->irq_src |= BIT(data->hwirq % 8);
}

static struct irq_chip stmfx_irq_chip = {
	.name			= "stmfx-core",
	.irq_bus_lock		= stmfx_irq_bus_lock,
	.irq_bus_sync_unlock	= stmfx_irq_bus_sync_unlock,
	.irq_mask		= stmfx_irq_mask,
	.irq_unmask		= stmfx_irq_unmask,
};

static irqreturn_t stmfx_irq_handler(int irq, void *data)
{
	struct stmfx *stmfx = data;
	unsigned long bits;
	u32 pending, ack;
	int n, ret;

	ret = regmap_read(stmfx->map, STMFX_REG_IRQ_PENDING, &pending);
	if (ret)
		return IRQ_NONE;

	/*
	 * There is no ACK for GPIO, MFX_REG_IRQ_PENDING_GPIO is a logical OR
	 * of MFX_REG_IRQ_GPI _PENDING1/_PENDING2/_PENDING3
	 */
	ack = pending & ~BIT(STMFX_REG_IRQ_SRC_EN_GPIO);
	if (ack) {
		ret = regmap_write(stmfx->map, STMFX_REG_IRQ_ACK, ack);
		if (ret)
			return IRQ_NONE;
	}

	bits = pending;
	for_each_set_bit(n, &bits, STMFX_REG_IRQ_SRC_MAX)
		handle_nested_irq(irq_find_mapping(stmfx->irq_domain, n));

	return IRQ_HANDLED;
}

static int stmfx_irq_map(struct irq_domain *d, unsigned int virq,
			 irq_hw_number_t hwirq)
{
	irq_set_chip_data(virq, d->host_data);
	irq_set_chip_and_handler(virq, &stmfx_irq_chip, handle_simple_irq);
	irq_set_nested_thread(virq, 1);
	irq_set_noprobe(virq);

	return 0;
}

static void stmfx_irq_unmap(struct irq_domain *d, unsigned int virq)
{
	irq_set_chip_and_handler(virq, NULL, NULL);
	irq_set_chip_data(virq, NULL);
}

static const struct irq_domain_ops stmfx_irq_ops = {
	.map	= stmfx_irq_map,
	.unmap	= stmfx_irq_unmap,
};

static void stmfx_irq_exit(struct i2c_client *client)
{
	struct stmfx *stmfx = i2c_get_clientdata(client);
	int hwirq;

	for (hwirq = 0; hwirq < STMFX_REG_IRQ_SRC_MAX; hwirq++)
		irq_dispose_mapping(irq_find_mapping(stmfx->irq_domain, hwirq));

	irq_domain_remove(stmfx->irq_domain);
}

static int stmfx_irq_init(struct i2c_client *client)
{
	struct stmfx *stmfx = i2c_get_clientdata(client);
	u32 irqoutpin = 0, irqtrigger;
	int ret;

	stmfx->irq_domain = irq_domain_add_simple(stmfx->dev->of_node,
						  STMFX_REG_IRQ_SRC_MAX, 0,
						  &stmfx_irq_ops, stmfx);
	if (!stmfx->irq_domain) {
		dev_err(stmfx->dev, "Failed to create IRQ domain\n");
		return -EINVAL;
	}

	if (!of_property_read_bool(stmfx->dev->of_node, "drive-open-drain"))
		irqoutpin |= STMFX_REG_IRQ_OUT_PIN_TYPE;

	irqtrigger = irq_get_trigger_type(client->irq);
	if ((irqtrigger & IRQ_TYPE_EDGE_RISING) ||
	    (irqtrigger & IRQ_TYPE_LEVEL_HIGH))
		irqoutpin |= STMFX_REG_IRQ_OUT_PIN_POL;

	ret = regmap_write(stmfx->map, STMFX_REG_IRQ_OUT_PIN, irqoutpin);
	if (ret)
		return ret;

	ret = devm_request_threaded_irq(stmfx->dev, client->irq,
					NULL, stmfx_irq_handler,
					irqtrigger | IRQF_ONESHOT,
					"stmfx", stmfx);
	if (ret)
		stmfx_irq_exit(client);

	return ret;
}

static int stmfx_chip_reset(struct stmfx *stmfx)
{
	int ret;

	ret = regmap_write(stmfx->map, STMFX_REG_SYS_CTRL,
			   STMFX_REG_SYS_CTRL_SWRST);
	if (ret)
		return ret;

	msleep(STMFX_BOOT_TIME_MS);

	return ret;
}

static int stmfx_chip_init(struct i2c_client *client)
{
	struct stmfx *stmfx = i2c_get_clientdata(client);
	u32 id;
	u8 version[2];
	int ret;

	stmfx->vdd = devm_regulator_get_optional(&client->dev, "vdd");
	ret = PTR_ERR_OR_ZERO(stmfx->vdd);
	if (ret == -ENODEV) {
		stmfx->vdd = NULL;
	} else if (ret == -EPROBE_DEFER) {
		return ret;
	} else if (ret) {
		dev_err(&client->dev, "Failed to get VDD regulator: %d\n", ret);
		return ret;
	}

	if (stmfx->vdd) {
		ret = regulator_enable(stmfx->vdd);
		if (ret) {
			dev_err(&client->dev, "VDD enable failed: %d\n", ret);
			return ret;
		}
	}

	ret = regmap_read(stmfx->map, STMFX_REG_CHIP_ID, &id);
	if (ret) {
		dev_err(&client->dev, "Error reading chip ID: %d\n", ret);
		goto err;
	}

	/*
	 * Check that ID is the complement of the I2C address:
	 * STMFX I2C address follows the 7-bit format (MSB), that's why
	 * client->addr is shifted.
	 *
	 * STMFX_I2C_ADDR|       STMFX         |        Linux
	 *   input pin   | I2C device address  | I2C device address
	 *---------------------------------------------------------
	 *       0       | b: 1000 010x h:0x84 |       0x42
	 *       1       | b: 1000 011x h:0x86 |       0x43
	 */
	if (FIELD_GET(STMFX_REG_CHIP_ID_MASK, ~id) != (client->addr << 1)) {
		dev_err(&client->dev, "Unknown chip ID: %#x\n", id);
		ret = -EINVAL;
		goto err;
	}

	ret = regmap_bulk_read(stmfx->map, STMFX_REG_FW_VERSION_MSB,
			       version, ARRAY_SIZE(version));
	if (ret) {
		dev_err(&client->dev, "Error reading FW version: %d\n", ret);
		goto err;
	}

	dev_info(&client->dev, "STMFX id: %#x, fw version: %x.%02x\n",
		 id, version[0], version[1]);

	ret = stmfx_chip_reset(stmfx);
	if (ret) {
		dev_err(&client->dev, "Failed to reset chip: %d\n", ret);
		goto err;
	}

	return 0;

err:
	if (stmfx->vdd)
		return regulator_disable(stmfx->vdd);

	return ret;
}

static int stmfx_chip_exit(struct i2c_client *client)
{
	struct stmfx *stmfx = i2c_get_clientdata(client);

	regmap_write(stmfx->map, STMFX_REG_IRQ_SRC_EN, 0);
	regmap_write(stmfx->map, STMFX_REG_SYS_CTRL, 0);

	if (stmfx->vdd)
		return regulator_disable(stmfx->vdd);

	return 0;
}

static int stmfx_probe(struct i2c_client *client,
		       const struct i2c_device_id *id)
{
	struct device *dev = &client->dev;
	struct stmfx *stmfx;
	int ret;

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

	i2c_set_clientdata(client, stmfx);

	stmfx->dev = dev;

	stmfx->map = devm_regmap_init_i2c(client, &stmfx_regmap_config);
	if (IS_ERR(stmfx->map)) {
		ret = PTR_ERR(stmfx->map);
		dev_err(dev, "Failed to allocate register map: %d\n", ret);
		return ret;
	}

	mutex_init(&stmfx->lock);

	ret = stmfx_chip_init(client);
	if (ret) {
		if (ret == -ETIMEDOUT)
			return -EPROBE_DEFER;
		return ret;
	}

	if (client->irq < 0) {
		dev_err(dev, "Failed to get IRQ: %d\n", client->irq);
		ret = client->irq;
		goto err_chip_exit;
	}

	ret = stmfx_irq_init(client);
	if (ret)
		goto err_chip_exit;

	ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
				   stmfx_cells, ARRAY_SIZE(stmfx_cells), NULL,
				   0, stmfx->irq_domain);
	if (ret)
		goto err_irq_exit;

	return 0;

err_irq_exit:
	stmfx_irq_exit(client);
err_chip_exit:
	stmfx_chip_exit(client);

	return ret;
}

static int stmfx_remove(struct i2c_client *client)
{
	stmfx_irq_exit(client);

	return stmfx_chip_exit(client);
}

#ifdef CONFIG_PM_SLEEP
static int stmfx_suspend(struct device *dev)
{
	struct stmfx *stmfx = dev_get_drvdata(dev);
	int ret;

	ret = regmap_raw_read(stmfx->map, STMFX_REG_SYS_CTRL,
			      &stmfx->bkp_sysctrl, sizeof(stmfx->bkp_sysctrl));
	if (ret)
		return ret;

	ret = regmap_raw_read(stmfx->map, STMFX_REG_IRQ_OUT_PIN,
			      &stmfx->bkp_irqoutpin,
			      sizeof(stmfx->bkp_irqoutpin));
	if (ret)
		return ret;

	if (stmfx->vdd)
		return regulator_disable(stmfx->vdd);

	return 0;
}

static int stmfx_resume(struct device *dev)
{
	struct stmfx *stmfx = dev_get_drvdata(dev);
	int ret;

	if (stmfx->vdd) {
		ret = regulator_enable(stmfx->vdd);
		if (ret) {
			dev_err(stmfx->dev,
				"VDD enable failed: %d\n", ret);
			return ret;
		}
	}

	ret = regmap_raw_write(stmfx->map, STMFX_REG_SYS_CTRL,
			       &stmfx->bkp_sysctrl, sizeof(stmfx->bkp_sysctrl));
	if (ret)
		return ret;

	ret = regmap_raw_write(stmfx->map, STMFX_REG_IRQ_OUT_PIN,
			       &stmfx->bkp_irqoutpin,
			       sizeof(stmfx->bkp_irqoutpin));
	if (ret)
		return ret;

	ret = regmap_raw_write(stmfx->map, STMFX_REG_IRQ_SRC_EN,
			       &stmfx->irq_src, sizeof(stmfx->irq_src));
	if (ret)
		return ret;

	return 0;
}
#endif

static SIMPLE_DEV_PM_OPS(stmfx_dev_pm_ops, stmfx_suspend, stmfx_resume);

static const struct of_device_id stmfx_of_match[] = {
	{ .compatible = "st,stmfx-0300", },
	{},
};
MODULE_DEVICE_TABLE(of, stmfx_of_match);

static struct i2c_driver stmfx_driver = {
	.driver = {
		.name = "stmfx-core",
		.of_match_table = of_match_ptr(stmfx_of_match),
		.pm = &stmfx_dev_pm_ops,
	},
	.probe = stmfx_probe,
	.remove = stmfx_remove,
};
module_i2c_driver(stmfx_driver);

MODULE_DESCRIPTION("STMFX core driver");
MODULE_AUTHOR("Amelie Delaunay <amelie.delaunay@st.com>");
MODULE_LICENSE("GPL v2");
