/*
 * 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 "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)
