/*
 *
 * Copyright (c) 2021 metraTec GmbH
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file Driver for MPC23xxx I2C/SPI-based GPIO driver.
 */

#include <errno.h>
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/util.h>
#include <zephyr/drivers/gpio.h>

#include <zephyr/drivers/gpio/gpio_utils.h>
#include "gpio_mcp23xxx.h"

#define LOG_LEVEL CONFIG_GPIO_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(gpio_mcp23xxx);

#define MCP23XXX_RESET_TIME_US 2

/**
 * @brief Reads given register from mcp23xxx.
 *
 * The registers of the mcp23x0x consist of one 8 bit port.
 * The registers of the mcp23x1x consist of two 8 bit ports.
 *
 * @param dev The mcp23xxx device.
 * @param reg The register to be read.
 * @param buf The buffer to read data to.
 * @return 0 if successful.
 *		   Otherwise <0 will be returned.
 */
static int read_port_regs(const struct device *dev, uint8_t reg, uint16_t *buf)
{
	const struct mcp23xxx_config *config = dev->config;

	if (config->ngpios == 16U) {
		reg *= 2;
	}

	return config->read_fn(dev, reg, buf);
}

/**
 * @brief Writes registers of the mcp23xxx.
 *
 * On the mcp23x08 one 8 bit port will be written.
 * On the mcp23x17 two 8 bit ports will be written.
 *
 * @param dev The mcp23xxx device.
 * @param reg Register to be written.
 * @param buf The new register value.
 *
 * @return 0 if successful. Otherwise <0 will be returned.
 */
static int write_port_regs(const struct device *dev, uint8_t reg, uint16_t value)
{
	const struct mcp23xxx_config *config = dev->config;

	if (config->ngpios == 16U) {
		reg *= 2;
	}

	return config->write_fn(dev, reg, value);
}

/**
 * @brief Writes to the IOCON register of the mcp23xxx.
 *
 * IOCON is the only register that is not 16 bits wide on 16-pin devices; instead, it is mirrored in
 * two adjacent memory locations. Because the underlying `write_fn` always does a 16-bit write for
 * 16-pin devices, make sure we write the same value to both IOCON locations.
 *
 * @param dev The mcp23xxx device.
 * @param value the IOCON value to write
 *
 * @return 0 if successful. Otherwise <0 will be returned.
 */
static int write_iocon(const struct device *dev, uint8_t value)
{
	struct mcp23xxx_drv_data *drv_data = dev->data;

	uint16_t extended_value = value | (value << 8);
	int ret = write_port_regs(dev, REG_IOCON, extended_value);

	if (ret == 0) {
		drv_data->reg_cache.iocon = extended_value;
	}

	return ret;
}

/**
 * @brief Setup the pin direction.
 *
 * @param dev The mcp23xxx device.
 * @param pin The pin number.
 * @param flags Flags of pin or port.
 * @return 0 if successful. Otherwise <0 will be returned.
 */
static int setup_pin_dir(const struct device *dev, uint32_t pin, int flags)
{
	struct mcp23xxx_drv_data *drv_data = dev->data;
	uint16_t dir = drv_data->reg_cache.iodir;
	uint16_t output = drv_data->reg_cache.gpio;
	int ret;

	if ((flags & GPIO_OUTPUT) != 0U) {
		if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0U) {
			output |= BIT(pin);
		} else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0U) {
			output &= ~BIT(pin);
		}
		dir &= ~BIT(pin);
	} else {
		dir |= BIT(pin);
	}

	ret = write_port_regs(dev, REG_GPIO, output);
	if (ret != 0) {
		return ret;
	}

	drv_data->reg_cache.gpio = output;

	ret = write_port_regs(dev, REG_IODIR, dir);
	if (ret == 0) {
		drv_data->reg_cache.iodir = dir;
	}

	return ret;
}

/**
 * @brief Setup pin pull up/pull down.
 *
 * @param dev The mcp23xxx device.
 * @param pin The pin number.
 * @param flags Flags of pin or port.
 * @return 0 if successful. Otherwise <0 will be returned.
 */
static int setup_pin_pull(const struct device *dev, uint32_t pin, int flags)
{
	struct mcp23xxx_drv_data *drv_data = dev->data;
	uint16_t port;
	int ret;

	port = drv_data->reg_cache.gppu;

	if ((flags & GPIO_PULL_DOWN) != 0U) {
		return -ENOTSUP;
	}

	WRITE_BIT(port, pin, (flags & GPIO_PULL_UP) != 0);

	ret = write_port_regs(dev, REG_GPPU, port);
	if (ret == 0) {
		drv_data->reg_cache.gppu = port;
	}

	return ret;
}

static int mcp23xxx_pin_cfg(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags)
{
	struct mcp23xxx_drv_data *drv_data = dev->data;
	const struct mcp23xxx_config *config = dev->config;
	int ret;

	if (k_is_in_isr()) {
		return -EWOULDBLOCK;
	}

	k_sem_take(&drv_data->lock, K_FOREVER);

	if ((bool)(flags & GPIO_SINGLE_ENDED) != config->is_open_drain ||
	    (bool)(flags & GPIO_LINE_OPEN_DRAIN) != config->is_open_drain) {
		ret = -ENOTSUP;
		goto done;
	}

	ret = setup_pin_dir(dev, pin, flags);
	if (ret < 0) {
		LOG_ERR("Error setting pin direction (%d)", ret);
		goto done;
	}

	ret = setup_pin_pull(dev, pin, flags);
	if (ret < 0) {
		LOG_ERR("Error setting pin pull up/pull down (%d)", ret);
		goto done;
	}

done:
	k_sem_give(&drv_data->lock);
	return ret;
}

static int mcp23xxx_port_get_raw(const struct device *dev, uint32_t *value)
{
	struct mcp23xxx_drv_data *drv_data = dev->data;
	uint16_t buf;
	int ret;

	if (k_is_in_isr()) {
		return -EWOULDBLOCK;
	}

	k_sem_take(&drv_data->lock, K_FOREVER);

	ret = read_port_regs(dev, REG_GPIO, &buf);
	if (ret == 0) {
		*value = buf;
	}

	k_sem_give(&drv_data->lock);
	return ret;
}

static int mcp23xxx_port_set_masked_raw(const struct device *dev, uint32_t mask, uint32_t value)
{
	struct mcp23xxx_drv_data *drv_data = dev->data;
	uint16_t buf;
	int ret;

	if (k_is_in_isr()) {
		return -EWOULDBLOCK;
	}

	k_sem_take(&drv_data->lock, K_FOREVER);

	buf = drv_data->reg_cache.gpio;
	buf = (buf & ~mask) | (mask & value);

	ret = write_port_regs(dev, REG_GPIO, buf);
	if (ret == 0) {
		drv_data->reg_cache.gpio = buf;
	}

	k_sem_give(&drv_data->lock);
	return ret;
}

static int mcp23xxx_port_set_bits_raw(const struct device *dev, uint32_t mask)
{
	return mcp23xxx_port_set_masked_raw(dev, mask, mask);
}

static int mcp23xxx_port_clear_bits_raw(const struct device *dev, uint32_t mask)
{
	return mcp23xxx_port_set_masked_raw(dev, mask, 0);
}

static int mcp23xxx_port_toggle_bits(const struct device *dev, uint32_t mask)
{
	struct mcp23xxx_drv_data *drv_data = dev->data;
	uint16_t buf;
	int ret;

	if (k_is_in_isr()) {
		return -EWOULDBLOCK;
	}

	k_sem_take(&drv_data->lock, K_FOREVER);

	buf = drv_data->reg_cache.gpio;
	buf ^= mask;

	ret = write_port_regs(dev, REG_GPIO, buf);
	if (ret == 0) {
		drv_data->reg_cache.gpio = buf;
	}

	k_sem_give(&drv_data->lock);

	return ret;
}

static int mcp23xxx_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin,
					    enum gpio_int_mode mode, enum gpio_int_trig trig)
{
	struct mcp23xxx_drv_data *drv_data = dev->data;
	const struct mcp23xxx_config *config = dev->config;

	if (!config->gpio_int.port) {
		return -ENOTSUP;
	}

	if (k_is_in_isr()) {
		return -EWOULDBLOCK;
	}

	k_sem_take(&drv_data->lock, K_FOREVER);

	uint16_t gpinten = drv_data->reg_cache.gpinten;
	uint16_t defval = drv_data->reg_cache.defval;
	uint16_t intcon = drv_data->reg_cache.intcon;

	int ret;

	switch (mode) {
	case GPIO_INT_MODE_DISABLED:
		gpinten &= ~BIT(pin);
		break;

	case GPIO_INT_MODE_LEVEL:
		gpinten |= BIT(pin);
		intcon |= BIT(pin);

		switch (trig) {
		case GPIO_INT_TRIG_LOW:
			defval |= BIT(pin);
			break;
		case GPIO_INT_TRIG_HIGH:
			defval &= ~BIT(pin);
			break;
		case GPIO_INT_TRIG_BOTH:
			/* can't happen */
			ret = -ENOTSUP;
			goto done;
		default:
			ret = -EINVAL;
			goto done;
		}
		break;

	case GPIO_INT_MODE_EDGE:
		gpinten |= BIT(pin);
		intcon &= ~BIT(pin);

		switch (trig) {
		case GPIO_INT_TRIG_LOW:
			drv_data->rising_edge_ints &= ~BIT(pin);
			drv_data->falling_edge_ints |= BIT(pin);
			break;
		case GPIO_INT_TRIG_HIGH:
			drv_data->rising_edge_ints |= BIT(pin);
			drv_data->falling_edge_ints &= ~BIT(pin);
			break;
		case GPIO_INT_TRIG_BOTH:
			drv_data->rising_edge_ints |= BIT(pin);
			drv_data->falling_edge_ints |= BIT(pin);
			break;
		default:
			ret = -EINVAL;
			goto done;
		}
		break;
	}

	ret = write_port_regs(dev, REG_GPINTEN, gpinten);
	if (ret != 0) {
		goto done;
	}
	drv_data->reg_cache.gpinten = gpinten;

	ret = write_port_regs(dev, REG_DEFVAL, defval);
	if (ret != 0) {
		goto done;
	}
	drv_data->reg_cache.defval = defval;

	ret = write_port_regs(dev, REG_INTCON, intcon);
	if (ret != 0) {
		goto done;
	}
	drv_data->reg_cache.intcon = intcon;

done:
	k_sem_give(&drv_data->lock);

	return ret;
}

static int mcp23xxx_manage_callback(const struct device *dev, struct gpio_callback *callback,
				    bool set)
{
	struct mcp23xxx_drv_data *drv_data = dev->data;
	const struct mcp23xxx_config *config = dev->config;

	if (!config->gpio_int.port) {
		return -ENOTSUP;
	}

	if (k_is_in_isr()) {
		return -EWOULDBLOCK;
	}

	k_sem_take(&drv_data->lock, K_FOREVER);

	int ret = gpio_manage_callback(&drv_data->callbacks, callback, set);

	k_sem_give(&drv_data->lock);

	return ret;
}

static void mcp23xxx_work_handler(struct k_work *work)
{
	struct mcp23xxx_drv_data *drv_data = CONTAINER_OF(work, struct mcp23xxx_drv_data, work);
	const struct device *dev = drv_data->dev;

	int ret;

	k_sem_take(&drv_data->lock, K_FOREVER);

	uint16_t intf;

	ret = read_port_regs(dev, REG_INTF, &intf);
	if (ret != 0) {
		LOG_ERR("Failed to read INTF");
		goto fail;
	}

	if (!intf) {
		/* Probable causes:
		 * - REG_GPIO was read from somewhere else before the interrupt handler had a chance
		 *   to run
		 * - Even though the datasheet says differently, reading INTCAP while a level
		 *   interrupt is active briefly (~2ns) causes the interrupt line to go high and
		 *   low again. This causes a second ISR to be scheduled, which then won't
		 *   find any active interrupts if the callback has disabled the level interrupt.
		 */
		LOG_ERR("Spurious interrupt");
		goto fail;
	}

	uint16_t intcap;

	/* Read INTCAP to acknowledge the interrupt */
	ret = read_port_regs(dev, REG_INTCAP, &intcap);
	if (ret != 0) {
		LOG_ERR("Failed to read INTCAP");
		goto fail;
	}

	/* mcp23xxx does not support single-edge interrupts in hardware, filter them out manually */
	uint16_t level_ints = drv_data->reg_cache.gpinten & drv_data->reg_cache.intcon;

	intf &= level_ints | (intcap & drv_data->rising_edge_ints) |
		(~intcap & drv_data->falling_edge_ints);

	k_sem_give(&drv_data->lock);
	gpio_fire_callbacks(&drv_data->callbacks, dev, intf);
	return;

fail:
	k_sem_give(&drv_data->lock);
}

static void mcp23xxx_int_gpio_handler(const struct device *port, struct gpio_callback *cb,
				      gpio_port_pins_t pins)
{
	struct mcp23xxx_drv_data *drv_data =
		CONTAINER_OF(cb, struct mcp23xxx_drv_data, int_gpio_cb);

	k_work_submit(&drv_data->work);
}

DEVICE_API(gpio, gpio_mcp23xxx_api_table) = {
	.pin_configure = mcp23xxx_pin_cfg,
	.port_get_raw = mcp23xxx_port_get_raw,
	.port_set_masked_raw = mcp23xxx_port_set_masked_raw,
	.port_set_bits_raw = mcp23xxx_port_set_bits_raw,
	.port_clear_bits_raw = mcp23xxx_port_clear_bits_raw,
	.port_toggle_bits = mcp23xxx_port_toggle_bits,
	.pin_interrupt_configure = mcp23xxx_pin_interrupt_configure,
	.manage_callback = mcp23xxx_manage_callback,
};

/**
 * @brief Initialization function of MCP23XXX
 *
 * @param dev Device struct.
 * @return 0 if successful. Otherwise <0 is returned.
 */
int gpio_mcp23xxx_init(const struct device *dev)
{
	const struct mcp23xxx_config *config = dev->config;
	struct mcp23xxx_drv_data *drv_data = dev->data;
	int err;

	if (config->ngpios != 8U && config->ngpios != 16U) {
		LOG_ERR("Invalid value ngpios=%u. Expected 8 or 16!", config->ngpios);
		return -EINVAL;
	}

	err = config->bus_fn(dev);
	if (err < 0) {
		return err;
	}

	k_sem_init(&drv_data->lock, 0, 1);

	/* If the RESET line is available, pulse it. */
	if (config->gpio_reset.port) {
		err = gpio_pin_configure_dt(&config->gpio_reset, GPIO_OUTPUT_ACTIVE);
		if (err != 0) {
			LOG_ERR("Failed to configure RESET line: %d", err);
			return -EIO;
		}

		k_usleep(MCP23XXX_RESET_TIME_US);

		err = gpio_pin_set_dt(&config->gpio_reset, 0);
		if (err != 0) {
			LOG_ERR("Failed to deactivate RESET line: %d", err);
			return -EIO;
		}
	}

	/* If the INT line is available, configure the callback for it. */
	if (config->gpio_int.port) {
		if (config->ngpios == 16) {
			/* send both ports' interrupts through one IRQ pin */
			err = write_iocon(dev, REG_IOCON_MIRROR);

			if (err != 0) {
				LOG_ERR("Failed to enable mirrored IRQ pins: %d", err);
				return -EIO;
			}
		}

		if (!gpio_is_ready_dt(&config->gpio_int)) {
			LOG_ERR("INT port is not ready");
			return -ENODEV;
		}

		drv_data->dev = dev;
		k_work_init(&drv_data->work, mcp23xxx_work_handler);

		err = gpio_pin_configure_dt(&config->gpio_int, GPIO_INPUT);
		if (err != 0) {
			LOG_ERR("Failed to configure INT line: %d", err);
			return -EIO;
		}

		gpio_init_callback(&drv_data->int_gpio_cb, mcp23xxx_int_gpio_handler,
				   BIT(config->gpio_int.pin));
		err = gpio_add_callback(config->gpio_int.port, &drv_data->int_gpio_cb);
		if (err != 0) {
			LOG_ERR("Failed to add INT callback: %d", err);
			return -EIO;
		}

		err = gpio_pin_interrupt_configure_dt(&config->gpio_int, GPIO_INT_EDGE_TO_ACTIVE);
		if (err != 0) {
			LOG_ERR("Failed to configure INT interrupt: %d", err);
			return -EIO;
		}
	}

	k_sem_give(&drv_data->lock);

	return 0;
}
