/*
 * Copyright (c) 2018 Peter Bigot Consulting, LLC
 * Copyright (c) 2018 Aapo Vienamo
 * Copyright (c) 2019 Nordic Semiconductor ASA
 * Copyright (c) 2019 Vestas Wind Systems A/S
 * Copyright (c) 2020 ZedBlox Ltd.
 * Copyright (c) 2021 Laird Connectivity
 *
 * SPDX-License-Identifier: Apache-2.0
 */

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

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(pca953x, CONFIG_GPIO_LOG_LEVEL);

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

/* PCA953X Register addresses */
#define PCA953X_INPUT_PORT		0x00
#define PCA953X_OUTPUT_PORT		0x01
#define PCA953X_CONFIGURATION		0x03

/* Number of pins supported by the device */
#define NUM_PINS 8

/* Max to select all pins supported on the device. */
#define ALL_PINS ((uint8_t)BIT_MASK(NUM_PINS))

/** Cache of the output configuration and data of the pins. */
struct pca953x_pin_state {
	uint8_t dir;
	uint8_t input;
	uint8_t output;
};

struct pca953x_irq_state {
	uint8_t rising;
	uint8_t falling;
};

/** Runtime driver data */
struct pca953x_drv_data {
	/* gpio_driver_data needs to be first */
	struct gpio_driver_data common;
	struct pca953x_pin_state pin_state;
	struct k_sem lock;
	struct gpio_callback gpio_cb;
	struct k_work work;
	struct pca953x_irq_state irq_state;
	const struct device *dev;
	/* user ISR cb */
	sys_slist_t cb;
};

/** Configuration data */
struct pca953x_config {
	/* gpio_driver_config needs to be first */
	struct gpio_driver_config common;
	struct i2c_dt_spec i2c;
	const struct gpio_dt_spec gpio_int;
	bool interrupt_enabled;
};

/**
 * @brief Gets the state of input pins of the PCA953X I/O Port and
 * stores in driver data struct.
 *
 * @param dev Pointer to the device structure for the driver instance.
 *
 * @retval 0 If successful.
 * @retval Negative value for error code.
 */
static int update_input(const struct device *dev)
{
	const struct pca953x_config *cfg = dev->config;
	struct pca953x_drv_data *drv_data = dev->data;
	uint8_t input_states;
	int rc = 0;

	rc = i2c_reg_read_byte_dt(&cfg->i2c, PCA953X_INPUT_PORT, &input_states);

	if (rc == 0) {
		drv_data->pin_state.input = input_states;
	}
	return rc;
}

/**
 * @brief Handles interrupt triggered by the interrupt pin of PCA953X I/O Port.
 *
 * If nint_gpios is configured in device tree then this will be triggered each
 * time a gpio configured as an input changes state. The gpio input states are
 * read in this function which clears the interrupt.
 *
 * @param dev Pointer to the device structure for the driver instance.
 */
static void gpio_pca953x_handle_interrupt(const struct device *dev)
{
	struct pca953x_drv_data *drv_data = dev->data;
	struct pca953x_irq_state *irq_state = &drv_data->irq_state;
	int rc;
	uint8_t previous_state;
	uint8_t current_state;
	uint8_t transitioned_pins;
	uint8_t interrupt_status = 0;

	k_sem_take(&drv_data->lock, K_FOREVER);

	/* Any interrupts enabled? */
	if (!irq_state->rising && !irq_state->falling) {
		rc = -EINVAL;
		goto out;
	}

	/* Store previous input state then read new value */
	previous_state = drv_data->pin_state.input;
	rc = update_input(dev);
	if (rc != 0) {
		goto out;
	}

	/* Find out which input pins have changed state */
	current_state = drv_data->pin_state.input;
	transitioned_pins = previous_state ^ current_state;

	/* Mask gpio transactions with rising/falling edge interrupt config */
	interrupt_status = (irq_state->rising & transitioned_pins &
			  current_state);
	interrupt_status |= (irq_state->falling & transitioned_pins &
			   previous_state);

out:
	k_sem_give(&drv_data->lock);

	if ((rc == 0) && (interrupt_status)) {
		gpio_fire_callbacks(&drv_data->cb, dev, interrupt_status);
	}
}

/**
 * @brief Work handler for PCA953X interrupt
 *
 * @param work Work struct that contains pointer to interrupt handler function
 */
static void gpio_pca953x_work_handler(struct k_work *work)
{
	struct pca953x_drv_data *drv_data =
		CONTAINER_OF(work, struct pca953x_drv_data, work);

	gpio_pca953x_handle_interrupt(drv_data->dev);
}

/**
 * @brief ISR for interrupt pin of PCA953X
 *
 * @param dev Pointer to the device structure for the driver instance.
 * @param gpio_cb Pointer to callback function struct
 * @param pins Bitmask of pins that triggered interrupt
 */
static void gpio_pca953x_init_cb(const struct device *dev,
				 struct gpio_callback *gpio_cb, uint32_t pins)
{
	struct pca953x_drv_data *drv_data =
		CONTAINER_OF(gpio_cb, struct pca953x_drv_data, gpio_cb);

	ARG_UNUSED(pins);

	k_work_submit(&drv_data->work);
}

static int gpio_pca953x_config(const struct device *dev, gpio_pin_t pin,
			       gpio_flags_t flags)
{
	const struct pca953x_config *cfg = dev->config;
	struct pca953x_drv_data *drv_data = dev->data;
	struct pca953x_pin_state *pins = &drv_data->pin_state;
	int rc = 0;
	bool data_first = false;

	/* Can't do I2C bus operations from an ISR */
	if (k_is_in_isr()) {
		return -EWOULDBLOCK;
	}

	/* Single Ended lines (Open drain and open source) not supported */
	if ((flags & GPIO_SINGLE_ENDED) != 0) {
		return -ENOTSUP;
	}

	/* The PCA953X has no internal pull up support */
	if (((flags & GPIO_PULL_UP) != 0) || ((flags & GPIO_PULL_DOWN) != 0)) {
		return -ENOTSUP;
	}

	/* Simultaneous input & output mode not supported */
	if (((flags & GPIO_INPUT) != 0) && ((flags & GPIO_OUTPUT) != 0)) {
		return -ENOTSUP;
	}

	k_sem_take(&drv_data->lock, K_FOREVER);

	/* Ensure either Output or Input is specified */
	if ((flags & GPIO_OUTPUT) != 0) {
		pins->dir &= ~BIT(pin);
		if ((flags & GPIO_OUTPUT_INIT_LOW) != 0) {
			pins->output &= ~BIT(pin);
			data_first = true;
		} else if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0) {
			pins->output |= BIT(pin);
			data_first = true;
		}
	} else if ((flags & GPIO_INPUT) != 0) {
		pins->dir |= BIT(pin);
	} else {
		rc = -ENOTSUP;
		goto out;
	}

	/* Set output values */
	if (data_first) {
		rc = i2c_reg_write_byte_dt(&cfg->i2c, PCA953X_OUTPUT_PORT, pins->output);
	}

	if (rc == 0) {
		/* Set pin directions */
		rc = i2c_reg_write_byte_dt(&cfg->i2c, PCA953X_CONFIGURATION, pins->dir);
	}

	if (rc == 0) {
		/* Refresh input status */
		rc = update_input(dev);
	}

out:
	k_sem_give(&drv_data->lock);
	return rc;
}

static int gpio_pca953x_port_read(const struct device *dev,
				 gpio_port_value_t *value)
{
	const struct pca953x_config *cfg = dev->config;
	struct pca953x_drv_data *drv_data = dev->data;
	uint8_t input_pin_data;
	int rc = 0;

	/* Can't do I2C bus operations from an ISR */
	if (k_is_in_isr()) {
		return -EWOULDBLOCK;
	}

	k_sem_take(&drv_data->lock, K_FOREVER);

	/* Read Input Register */
	rc = i2c_reg_read_byte_dt(&cfg->i2c, PCA953X_INPUT_PORT, &input_pin_data);

	LOG_DBG("read %x got %d", input_pin_data, rc);

	if (rc == 0) {
		drv_data->pin_state.input = input_pin_data;
		*value = (gpio_port_value_t)(drv_data->pin_state.input);
	}

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

static int gpio_pca953x_port_write(const struct device *dev,
				   gpio_port_pins_t mask,
				   gpio_port_value_t value,
				   gpio_port_value_t toggle)
{
	const struct pca953x_config *cfg = dev->config;
	struct pca953x_drv_data *drv_data = dev->data;
	uint8_t *outp = &drv_data->pin_state.output;
	int rc;
	uint8_t orig_out;
	uint8_t out;

	/* Can't do I2C bus operations from an ISR */
	if (k_is_in_isr()) {
		return -EWOULDBLOCK;
	}

	k_sem_take(&drv_data->lock, K_FOREVER);

	orig_out = *outp;
	out = ((orig_out & ~mask) | (value & mask)) ^ toggle;

	rc = i2c_reg_write_byte_dt(&cfg->i2c, PCA953X_OUTPUT_PORT, out);

	if (rc == 0) {
		*outp = out;
	}

	k_sem_give(&drv_data->lock);

	LOG_DBG("write %x msk %08x val %08x => %x: %d", orig_out, mask,
		value, out, rc);

	return rc;
}

static int gpio_pca953x_port_set_masked(const struct device *dev,
					gpio_port_pins_t mask,
					gpio_port_value_t value)
{
	return gpio_pca953x_port_write(dev, mask, value, 0);
}

static int gpio_pca953x_port_set_bits(const struct device *dev,
				      gpio_port_pins_t pins)
{
	return gpio_pca953x_port_write(dev, pins, pins, 0);
}

static int gpio_pca953x_port_clear_bits(const struct device *dev,
					gpio_port_pins_t pins)
{
	return gpio_pca953x_port_write(dev, pins, 0, 0);
}

static int gpio_pca953x_port_toggle_bits(const struct device *dev,
					 gpio_port_pins_t pins)
{
	return gpio_pca953x_port_write(dev, 0, 0, pins);
}

static int gpio_pca953x_pin_interrupt_configure(const struct device *dev,
						gpio_pin_t pin,
						enum gpio_int_mode mode,
						enum gpio_int_trig trig)
{
	const struct pca953x_config *cfg = dev->config;
	struct pca953x_drv_data *drv_data = dev->data;
	struct pca953x_irq_state *irq = &drv_data->irq_state;

	if (!cfg->interrupt_enabled) {
		return -ENOTSUP;
	}
	/* Device does not support level-triggered interrupts. */
	if (mode == GPIO_INT_MODE_LEVEL) {
		return -ENOTSUP;
	}

	k_sem_take(&drv_data->lock, K_FOREVER);

	if (mode == GPIO_INT_MODE_DISABLED) {
		irq->falling &= ~BIT(pin);
		irq->rising &= ~BIT(pin);
	} else { /* GPIO_INT_MODE_EDGE */
		if (trig == GPIO_INT_TRIG_BOTH) {
			irq->falling |= BIT(pin);
			irq->rising |= BIT(pin);
		} else if (trig == GPIO_INT_TRIG_LOW) {
			irq->falling |= BIT(pin);
			irq->rising &= ~BIT(pin);
		} else if (trig == GPIO_INT_TRIG_HIGH) {
			irq->falling &= ~BIT(pin);
			irq->rising |= BIT(pin);
		}
	}

	k_sem_give(&drv_data->lock);

	return 0;
}

static int gpio_pca953x_manage_callback(const struct device *dev,
					struct gpio_callback *callback,
					bool set)
{
	struct pca953x_drv_data *data = dev->data;

	return gpio_manage_callback(&data->cb, callback, set);
}

/**
 * @brief Initialization function of PCA953X
 *
 * This sets initial input/ output configuration and output states.
 * The interrupt is configured if this is enabled.
 *
 * @param dev Device struct
 * @return 0 if successful, failed otherwise.
 */
static int gpio_pca953x_init(const struct device *dev)
{
	const struct pca953x_config *cfg = dev->config;
	struct pca953x_drv_data *drv_data = dev->data;
	int rc = 0;

	if (!device_is_ready(cfg->i2c.bus)) {
		LOG_ERR("I2C bus device not found");
		goto out;
	}

	/* Do an initial read, this clears the interrupt pin and sets
	 * up the initial value of the pin state input data.
	 */
	rc = update_input(dev);
	if (rc) {
		goto out;
	}

	if (cfg->interrupt_enabled) {
		if (!device_is_ready(cfg->gpio_int.port)) {
			LOG_ERR("Cannot get pointer to gpio interrupt device");
			rc = -EINVAL;
			goto out;
		}

		drv_data->dev = dev;

		k_work_init(&drv_data->work, gpio_pca953x_work_handler);

		rc = gpio_pin_configure_dt(&cfg->gpio_int, GPIO_INPUT);
		if (rc) {
			goto out;
		}

		rc = gpio_pin_interrupt_configure_dt(&cfg->gpio_int,
						GPIO_INT_EDGE_TO_ACTIVE);
		if (rc) {
			goto out;
		}

		gpio_init_callback(&drv_data->gpio_cb,
					gpio_pca953x_init_cb,
					BIT(cfg->gpio_int.pin));

		rc = gpio_add_callback(cfg->gpio_int.port,
					&drv_data->gpio_cb);
	}
out:
	if (rc) {
		LOG_ERR("%s init failed: %d", dev->name, rc);
	} else {
		LOG_INF("%s init ok", dev->name);
	}
	return rc;
}

static const struct gpio_driver_api api_table = {
	.pin_configure = gpio_pca953x_config,
	.port_get_raw = gpio_pca953x_port_read,
	.port_set_masked_raw = gpio_pca953x_port_set_masked,
	.port_set_bits_raw = gpio_pca953x_port_set_bits,
	.port_clear_bits_raw = gpio_pca953x_port_clear_bits,
	.port_toggle_bits = gpio_pca953x_port_toggle_bits,
	.pin_interrupt_configure = gpio_pca953x_pin_interrupt_configure,
	.manage_callback = gpio_pca953x_manage_callback,
};

#define GPIO_PCA953X_INIT(n)							\
	static const struct pca953x_config pca953x_cfg_##n = {			\
		.i2c = I2C_DT_SPEC_INST_GET(n),					\
		.common = {							\
			.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n),	\
		},								\
		.interrupt_enabled = DT_INST_NODE_HAS_PROP(n, nint_gpios),	\
		.gpio_int = GPIO_DT_SPEC_INST_GET_OR(n, nint_gpios, {0}),	\
	};									\
										\
	static struct pca953x_drv_data pca953x_drvdata_##n = {			\
		.lock = Z_SEM_INITIALIZER(pca953x_drvdata_##n.lock, 1, 1),	\
		.pin_state.dir = ALL_PINS,					\
		.pin_state.output = ALL_PINS,					\
	};									\
	DEVICE_DT_INST_DEFINE(n,						\
		gpio_pca953x_init,						\
		NULL,								\
		&pca953x_drvdata_##n,						\
		&pca953x_cfg_##n,						\
		POST_KERNEL,							\
		CONFIG_GPIO_PCA953X_INIT_PRIORITY,				\
		&api_table);

#define DT_DRV_COMPAT ti_tca9538
DT_INST_FOREACH_STATUS_OKAY(GPIO_PCA953X_INIT)
