// SPDX-License-Identifier: GPL-2.0-only
/*
 * Maxim MAX7360 Core Driver
 *
 * Copyright 2025 Bootlin
 *
 * Authors:
 *    Kamel Bouhara <kamel.bouhara@bootlin.com>
 *    Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
 */

#include <linux/array_size.h>
#include <linux/bits.h>
#include <linux/delay.h>
#include <linux/device/devres.h>
#include <linux/dev_printk.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/mfd/core.h>
#include <linux/mfd/max7360.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/types.h>

static const struct mfd_cell max7360_cells[] = {
	{ .name           = "max7360-pinctrl" },
	{ .name           = "max7360-pwm" },
	{ .name           = "max7360-keypad" },
	{ .name           = "max7360-rotary" },
	{
		.name           = "max7360-gpo",
		.of_compatible	= "maxim,max7360-gpo",
	},
	{
		.name           = "max7360-gpio",
		.of_compatible	= "maxim,max7360-gpio",
	},
};

static const struct regmap_range max7360_volatile_ranges[] = {
	regmap_reg_range(MAX7360_REG_KEYFIFO, MAX7360_REG_KEYFIFO),
	regmap_reg_range(MAX7360_REG_I2C_TIMEOUT, MAX7360_REG_RTR_CNT),
};

static const struct regmap_access_table max7360_volatile_table = {
	.yes_ranges = max7360_volatile_ranges,
	.n_yes_ranges = ARRAY_SIZE(max7360_volatile_ranges),
};

static const struct regmap_config max7360_regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,
	.max_register = MAX7360_REG_PWMCFG(MAX7360_PORT_PWM_COUNT - 1),
	.volatile_table = &max7360_volatile_table,
	.cache_type = REGCACHE_MAPLE,
};

static int max7360_mask_irqs(struct regmap *regmap)
{
	struct device *dev = regmap_get_device(regmap);
	unsigned int val;
	int ret;

	/*
	 * GPIO/PWM interrupts are not masked on reset: as the MAX7360 "INTI"
	 * interrupt line is shared between GPIOs and rotary encoder, this could
	 * result in repeated spurious interrupts on the rotary encoder driver
	 * if the GPIO driver is not loaded. Mask them now to avoid this
	 * situation.
	 */
	for (unsigned int i = 0; i < MAX7360_PORT_PWM_COUNT; i++) {
		ret = regmap_write_bits(regmap, MAX7360_REG_PWMCFG(i),
					MAX7360_PORT_CFG_INTERRUPT_MASK,
					MAX7360_PORT_CFG_INTERRUPT_MASK);
		if (ret)
			return dev_err_probe(dev, ret,
					     "Failed to write MAX7360 port configuration\n");
	}

	/* Read GPIO in register, to ACK any pending IRQ. */
	ret = regmap_read(regmap, MAX7360_REG_GPIOIN, &val);
	if (ret)
		return dev_err_probe(dev, ret, "Failed to read GPIO values\n");

	return 0;
}

static int max7360_reset(struct regmap *regmap)
{
	struct device *dev = regmap_get_device(regmap);
	int ret;

	ret = regmap_write(regmap, MAX7360_REG_GPIOCFG, MAX7360_GPIO_CFG_GPIO_RST);
	if (ret) {
		dev_err(dev, "Failed to reset GPIO configuration: %x\n", ret);
		return ret;
	}

	ret = regcache_drop_region(regmap, MAX7360_REG_GPIOCFG, MAX7360_REG_GPIO_LAST);
	if (ret) {
		dev_err(dev, "Failed to drop regmap cache: %x\n", ret);
		return ret;
	}

	ret = regmap_write(regmap, MAX7360_REG_SLEEP, 0);
	if (ret) {
		dev_err(dev, "Failed to reset autosleep configuration: %x\n", ret);
		return ret;
	}

	ret = regmap_write(regmap, MAX7360_REG_DEBOUNCE, 0);
	if (ret)
		dev_err(dev, "Failed to reset GPO port count: %x\n", ret);

	return ret;
}

static int max7360_probe(struct i2c_client *client)
{
	struct device *dev = &client->dev;
	struct regmap *regmap;
	int ret;

	regmap = devm_regmap_init_i2c(client, &max7360_regmap_config);
	if (IS_ERR(regmap))
		return dev_err_probe(dev, PTR_ERR(regmap), "Failed to initialise regmap\n");

	ret = max7360_reset(regmap);
	if (ret)
		return dev_err_probe(dev, ret, "Failed to reset device\n");

	/* Get the device out of shutdown mode. */
	ret = regmap_write_bits(regmap, MAX7360_REG_GPIOCFG,
				MAX7360_GPIO_CFG_GPIO_EN,
				MAX7360_GPIO_CFG_GPIO_EN);
	if (ret)
		return dev_err_probe(dev, ret, "Failed to enable GPIO and PWM module\n");

	ret = max7360_mask_irqs(regmap);
	if (ret)
		return dev_err_probe(dev, ret, "Could not mask interrupts\n");

	ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
				   max7360_cells, ARRAY_SIZE(max7360_cells),
				   NULL, 0, NULL);
	if (ret)
		return dev_err_probe(dev, ret, "Failed to register child devices\n");

	return 0;
}

static const struct of_device_id max7360_dt_match[] = {
	{ .compatible = "maxim,max7360" },
	{}
};
MODULE_DEVICE_TABLE(of, max7360_dt_match);

static struct i2c_driver max7360_driver = {
	.driver = {
		.name = "max7360",
		.of_match_table = max7360_dt_match,
	},
	.probe = max7360_probe,
};
module_i2c_driver(max7360_driver);

MODULE_DESCRIPTION("Maxim MAX7360 I2C IO Expander core driver");
MODULE_AUTHOR("Kamel Bouhara <kamel.bouhara@bootlin.com>");
MODULE_LICENSE("GPL");
