/*
 *
 * 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 1

/**
 * @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);
}

const struct gpio_driver_api 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;
}
