/*
 * Copyright (c) 2024 TOKITA Hiroshi
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT awinic_aw9523b_gpio

#include <zephyr/kernel.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/gpio/gpio_utils.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/drivers/mfd/aw9523b.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/ring_buffer.h>

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

#define AW9523B_GPOMD             BIT(4)
#define AW9523B_RESET_PULSE_WIDTH 20
#define AW9523B_REG_CONFIG(n)     (AW9523B_REG_CONFIG0 + n)
#define AW9523B_REG_INT(n)        (AW9523B_REG_INT0 + n)
#define AW9523B_REG_OUTPUT(n)     (AW9523B_REG_OUTPUT0 + n)

enum read_write_toggle_t {
	READ,
	WRITE,
	TOGGLE,
};

struct gpio_aw9523b_config {
	struct gpio_driver_config common;
	const struct device *mfd_dev;
	struct i2c_dt_spec i2c;
	bool port0_push_pull;
#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios)
	struct gpio_dt_spec reset_gpio;
#endif
#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
	struct gpio_dt_spec int_gpio;
	gpio_callback_handler_t int_cb;
#endif
};

struct gpio_aw9523b_data {
	struct gpio_driver_data common;
#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
	const struct device *dev;
	sys_slist_t callbacks;
	struct gpio_callback gpio_callback;
	struct k_work intr_worker;
	gpio_port_value_t prev_value;
	gpio_port_pins_t rising_event_pins;
	gpio_port_pins_t falling_event_pins;
#endif
};

static int gpio_aw9523b_pin_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags)
{
	const struct gpio_aw9523b_config *const config = dev->config;
	const uint8_t port = (pin < 8) ? 0 : 1;
	const uint8_t mask = BIT(pin % 8);
	const uint8_t input_en = (flags & GPIO_INPUT) ? mask : 0x00;
	const uint8_t out_high = (flags & GPIO_OUTPUT_INIT_HIGH) ? mask : 0x00;
	int err;

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

	/* Either INPUT or OUTPUT must be set */
	if ((!(flags & GPIO_INPUT) && !(flags & GPIO_OUTPUT)) ||
	    ((flags & GPIO_INPUT) && (flags & GPIO_OUTPUT))) {
		return -ENOTSUP;
	}

	/* Open-drain support is per port, not per pin.
	 * So can't really support the API as-is.
	 */
	if (port == 0 && !config->port0_push_pull) {
		if (!((flags & GPIO_SINGLE_ENDED) && (flags & GPIO_LINE_OPEN_DRAIN))) {
			return -ENOTSUP;
		}
	} else {
		if (flags & GPIO_SINGLE_ENDED) {
			return -ENOTSUP;
		}
	}

	if ((flags & GPIO_INPUT) && ((flags & GPIO_PULL_UP) || (flags & GPIO_PULL_DOWN))) {
		return -ENOTSUP;
	}

	k_sem_take(aw9523b_get_lock(config->mfd_dev), K_FOREVER);

	err = i2c_reg_update_byte_dt(&config->i2c, AW9523B_REG_CONFIG(port), mask, input_en);
	if (err) {
		LOG_ERR("%s: Failed to set pin%d direction (%d)", dev->name, pin, err);
		goto on_error;
	}

#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
	if (config->int_gpio.port) {
		if (input_en) {
			struct gpio_aw9523b_data *const data = dev->data;
			uint8_t buf[2];

			/* Read initial pin state */
			err = i2c_burst_read_dt(&config->i2c, AW9523B_REG_INPUT0, buf, sizeof(buf));
			if (err) {
				LOG_ERR("%s: Read initial pin state failed (%d)", dev->name, err);
				goto on_error;
			}

			WRITE_BIT(data->prev_value, pin, sys_get_le16(buf) & BIT(pin));
		} else {
			struct gpio_aw9523b_data *const data = dev->data;

			WRITE_BIT(data->falling_event_pins, pin, 0);
			WRITE_BIT(data->rising_event_pins, pin, 0);
		}
	}
#endif

	err = i2c_reg_update_byte_dt(&config->i2c, AW9523B_REG_OUTPUT(port), mask, out_high);
	if (err) {
		LOG_ERR("%s: Failed to set initial pin state (%d)", dev->name, err);
		return err;
	}

on_error:
	k_sem_give(aw9523b_get_lock(config->mfd_dev));

	return err;
}

/**
 * Common implementation of Read, Write, and Toggle
 *
 * @param[in]       dev Specify device instance.
 * @param[in]      mask Register mask to select pins to operate.
 * @param[in,out] value When mode is READ, this param is pointer to result value storing region.
 *                      When mode is WRITE, this param is used as input value.
 *                      When mode is TOGGLE, this param will ignored.
 * @param[in]      mode Choose mode from READ, WRITE or TOGGLE.
 */
static int gpio_aw9523b_port_read_write_toggle(const struct device *dev, gpio_port_pins_t mask,
					       gpio_port_value_t *value,
					       enum read_write_toggle_t mode)
{
	const struct gpio_aw9523b_config *const config = dev->config;
	uint8_t buf[2];
	gpio_port_value_t old_value;
	gpio_port_value_t new_value;
	int err;

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

	k_sem_take(aw9523b_get_lock(config->mfd_dev), K_FOREVER);

	/*
	 * As with interrupts, the INPUT values are read for each address
	 * to keep the internal state correct.
	 */
	err = i2c_burst_read_dt(&config->i2c, AW9523B_REG_INPUT0, &buf[0], 1);
	if (err) {
		LOG_ERR("%s: Failed to read port0 status (%d)", dev->name, err);
		goto end;
	}
	err = i2c_burst_read_dt(&config->i2c, AW9523B_REG_INPUT1, &buf[1], 1);
	if (err) {
		LOG_ERR("%s: Failed to read port1 status (%d)", dev->name, err);
		goto end;
	}

	if (mode == READ) {
		goto end;
	}

	old_value = sys_get_le16(buf);

	if (mode == WRITE) {
		new_value = (old_value & ~mask) | (*value & mask);
	} else {
		new_value = (old_value & ~mask) | (~old_value & mask);
	}

	if (new_value == old_value) {
		goto end;
	}

	*(uint16_t *)buf = sys_get_le16((uint8_t *)&new_value);
	err = i2c_burst_write_dt(&config->i2c, AW9523B_REG_OUTPUT0, buf, sizeof(buf));
	if (err) {
		LOG_ERR("%s: Failed to set port (%d)", dev->name, err);
	}

end:
	k_sem_give(aw9523b_get_lock(config->mfd_dev));

	if (err == 0 && mode == READ) {
		*value = sys_get_le16(buf);
	}

	return err;
}

static int gpio_aw9523b_port_get_raw(const struct device *dev, gpio_port_value_t *value)
{
	return gpio_aw9523b_port_read_write_toggle(dev, UINT16_MAX, value, READ);
}

static int gpio_aw9523b_port_set_masked_raw(const struct device *dev, gpio_port_pins_t mask,
					    gpio_port_value_t value)
{
	return gpio_aw9523b_port_read_write_toggle(dev, mask, &value, WRITE);
}

static int gpio_aw9523b_port_set_bits_raw(const struct device *dev, gpio_port_pins_t pins)
{
	return gpio_aw9523b_port_read_write_toggle(dev, pins, &pins, WRITE);
}

static int gpio_aw9523b_port_clear_bits_raw(const struct device *dev, gpio_port_pins_t pins)
{
	const gpio_port_value_t zero = 0;

	/* If WRITE is specified, this pointer is used for reading only. It can cast. */
	return gpio_aw9523b_port_read_write_toggle(dev, pins, (gpio_port_value_t *)&zero, WRITE);
}

static int gpio_aw9523b_port_toggle_bits(const struct device *dev, gpio_port_pins_t pins)
{
	return gpio_aw9523b_port_read_write_toggle(dev, pins, NULL, TOGGLE);
}

static __maybe_unused void gpio_aw9523b_interrupt_worker(struct k_work *work)
{
	struct gpio_aw9523b_data *const data =
		CONTAINER_OF(work, struct gpio_aw9523b_data, intr_worker);
	const struct gpio_aw9523b_config *const config = data->dev->config;
	gpio_port_value_t value, rising, falling;
	uint8_t buf[2];
	int err;

	/*
	 * We need to read INPUT0 to deassert INTN when that is asserted by
	 * pin0-7 interruption, and same also INPUT1 for pin8-15.
	 * It cannot deassert by burst-read.
	 */
	err = i2c_burst_read_dt(&config->i2c, AW9523B_REG_INPUT0, &buf[0], 1);
	if (err) {
		LOG_ERR("%s: Failed to read INPUT0 %d", data->dev->name, err);
	}
	err = i2c_burst_read_dt(&config->i2c, AW9523B_REG_INPUT1, &buf[1], 1);
	if (err) {
		LOG_ERR("%s: Failed to read INPUT1 %d", data->dev->name, err);
	}

	value = sys_get_le16(buf);

	rising = (value ^ data->prev_value) & (value & data->rising_event_pins);
	falling = (value ^ data->prev_value) & (~value & data->falling_event_pins);

	data->prev_value = value;

	gpio_fire_callbacks(&data->callbacks, data->dev, rising | falling);
}

static __maybe_unused int gpio_aw9523b_pin_interrupt_configure(const struct device *dev,
							       gpio_pin_t pin,
							       enum gpio_int_mode mode,
							       enum gpio_int_trig trig)
{
	const struct gpio_aw9523b_config *const config = dev->config;
	struct gpio_aw9523b_data *const data = dev->data;
	const uint8_t port = (pin < 8) ? 0 : 1;
	const uint8_t mask = BIT(port ? pin - 8 : pin);
	const uint8_t n_int_en = (mode & GPIO_INT_MODE_EDGE) ? 0x00 : 0xFF;
	uint8_t buf[2];
	int err;

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

	if (mode == GPIO_INT_MODE_LEVEL) {
		return -ENOTSUP;
	}
	if (data->common.invert & BIT(pin)) {
		WRITE_BIT(data->falling_event_pins, pin, trig & GPIO_INT_HIGH_1);
		WRITE_BIT(data->rising_event_pins, pin, trig & GPIO_INT_LOW_0);
	} else {
		WRITE_BIT(data->falling_event_pins, pin, trig & GPIO_INT_LOW_0);
		WRITE_BIT(data->rising_event_pins, pin, trig & GPIO_INT_HIGH_1);
	}

	k_sem_take(aw9523b_get_lock(config->mfd_dev), K_FOREVER);

	err = i2c_reg_update_byte_dt(&config->i2c, AW9523B_REG_INT(port), mask, n_int_en);
	if (err) {
		LOG_ERR("%s: Failed to configure pin interruption (%d)", dev->name, err);
		goto end;
	}

	if (!n_int_en) {
		/* Read initial pin state */
		err = i2c_burst_read_dt(&config->i2c, AW9523B_REG_INPUT0, buf, sizeof(buf));
		if (err) {
			LOG_ERR("%s: Failed to read initial pin state (%d)", dev->name, err);
			goto end;
		}

		WRITE_BIT(data->prev_value, pin, sys_get_le16(buf) & BIT(pin));
	} else {
		WRITE_BIT(data->falling_event_pins, pin, 0);
		WRITE_BIT(data->rising_event_pins, pin, 0);
	}

end:
	k_sem_give(aw9523b_get_lock(config->mfd_dev));

	return err;
}

static __maybe_unused int gpio_aw9523b_manage_callback(const struct device *dev,
						       struct gpio_callback *callback, bool set)
{
	const struct gpio_aw9523b_config *const config = dev->config;
	struct gpio_aw9523b_data *const data = dev->data;
	int err;

	k_sem_take(aw9523b_get_lock(config->mfd_dev), K_FOREVER);

	err = gpio_manage_callback(&data->callbacks, callback, set);
	if (err) {
		LOG_ERR("%s: gpio_manage_callback failed (%d)", dev->name, err);
	}

	k_sem_give(aw9523b_get_lock(config->mfd_dev));

	return err;
}

static __maybe_unused void gpio_aw9523b_int_handler(const struct device *gpio_dev,
						    struct gpio_callback *cb, uint32_t pins)
{
	struct gpio_aw9523b_data *data = CONTAINER_OF(cb, struct gpio_aw9523b_data, gpio_callback);

	k_work_submit(&data->intr_worker);
}

static DEVICE_API(gpio, gpio_aw9523b_api) = {
	.pin_configure = gpio_aw9523b_pin_configure,
	.port_get_raw = gpio_aw9523b_port_get_raw,
	.port_set_masked_raw = gpio_aw9523b_port_set_masked_raw,
	.port_set_bits_raw = gpio_aw9523b_port_set_bits_raw,
	.port_clear_bits_raw = gpio_aw9523b_port_clear_bits_raw,
	.port_toggle_bits = gpio_aw9523b_port_toggle_bits,
#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
	.pin_interrupt_configure = gpio_aw9523b_pin_interrupt_configure,
	.manage_callback = gpio_aw9523b_manage_callback,
#endif
};

static int gpio_aw9523b_init(const struct device *dev)
{
	const struct gpio_aw9523b_config *const config = dev->config;
	const uint8_t int_init_data[] = {0xFF, 0xFF};
	uint8_t buf[2];
	int err;
#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(int_gpios)
	struct gpio_aw9523b_data *const data = dev->data;

	if (!config->int_gpio.port) {
		goto end_init_int_gpio;
	}

	/* Store self-reference for interrupt handling */
	data->dev = dev;

	/* Prepare interrupt worker */
	k_work_init(&data->intr_worker, gpio_aw9523b_interrupt_worker);

	if (!gpio_is_ready_dt(&config->int_gpio)) {
		LOG_ERR("%s: Interrupt GPIO not ready", dev->name);
		return -ENODEV;
	}

	err = gpio_pin_configure_dt(&config->int_gpio, GPIO_INPUT);
	if (err) {
		LOG_ERR("%s: Failed to configure interrupt pin %d (%d)", dev->name,
			config->int_gpio.pin, err);
		return err;
	}

	err = gpio_pin_interrupt_configure_dt(&config->int_gpio, GPIO_INT_EDGE_TO_ACTIVE);
	if (err) {
		LOG_ERR("%s: Failed to configure interrupt %d (%d)", dev->name,
			config->int_gpio.pin, err);
		return err;
	}

	gpio_init_callback(&data->gpio_callback, config->int_cb, BIT(config->int_gpio.pin));
	err = gpio_add_callback(config->int_gpio.port, &data->gpio_callback);
	if (err) {
		LOG_ERR("%s: Failed to add interrupt callback for pin %d (%d)", dev->name,
			config->int_gpio.pin, err);
		return err;
	}

end_init_int_gpio:
#endif

#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios)
	if (!config->reset_gpio.port) {
		goto end_hw_reset;
	}

	if (!gpio_is_ready_dt(&config->reset_gpio)) {
		LOG_ERR("%s: Reset GPIO not ready", dev->name);
		return -ENODEV;
	}

	err = gpio_pin_configure_dt(&config->reset_gpio, GPIO_OUTPUT_ACTIVE);
	if (err) {
		LOG_ERR("%s: Failed to configure reset pin %d (%d)", dev->name,
			config->reset_gpio.pin, err);
		return err;
	}

	k_busy_wait(AW9523B_RESET_PULSE_WIDTH);

	err = gpio_pin_set_dt(&config->reset_gpio, 0);
	if (err) {
		LOG_ERR("%s: Failed to set 0 reset pin %d (%d)", dev->name, config->reset_gpio.pin,
			err);
		return err;
	}

end_hw_reset:
#endif

	if (!device_is_ready(config->i2c.bus)) {
		return -ENODEV;
	}

	k_sem_init(aw9523b_get_lock(config->mfd_dev), 1, 1);

	/* Software reset */
	err = i2c_reg_read_byte_dt(&config->i2c, AW9523B_REG_SW_RSTN, buf);
	if (err) {
		LOG_ERR("%s: Failed to software reset (%d)", dev->name, err);
		return err;
	}

	/* Disabling all interrupts */
	err = i2c_burst_write_dt(&config->i2c, AW9523B_REG_INT0, int_init_data, sizeof(buf));
	if (err) {
		LOG_ERR("%s: Failed to disable all interrupts (%d)", dev->name, err);
		return err;
	}

	if (!config->port0_push_pull) {
		/* Configure port0 to push-pull mode */
		err = i2c_reg_update_byte_dt(&config->i2c, AW9523B_REG_CTL, AW9523B_GPOMD, 0xFF);
		if (err) {
			LOG_ERR("%s: Failed to configure port0 to push-pull (%d)", dev->name, err);
			return err;
		}
	}

	return 0;
}

#define GPIO_AW9523B_DEFINE(inst)                                                                  \
	static struct gpio_aw9523b_data gpio_aw9523b_data##inst;                                   \
                                                                                                   \
	static const struct gpio_aw9523b_config gpio_aw9523b_config##inst = {                      \
		.common = {                                                                        \
			.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(inst),                    \
		},                                                                                 \
		.mfd_dev = DEVICE_DT_GET(DT_INST_PARENT(inst)),                                    \
		.i2c = I2C_DT_SPEC_GET(DT_INST_PARENT(inst)),                                      \
		.port0_push_pull = DT_INST_PROP_OR(inst, port0_push_pull, false),                  \
		IF_ENABLED(DT_INST_PROP_HAS_IDX(inst, int_gpios, 0), (                             \
			   .int_gpio = GPIO_DT_SPEC_INST_GET(inst, int_gpios),                     \
			   .int_cb = gpio_aw9523b_int_handler,                                     \
		))                                                                                 \
		IF_ENABLED(DT_INST_PROP_HAS_IDX(inst, reset_gpios, 0), (                           \
			   .reset_gpio = GPIO_DT_SPEC_INST_GET(inst, reset_gpios),                 \
		))                                                                                 \
	};                                                                                         \
												   \
	DEVICE_DT_INST_DEFINE(inst, gpio_aw9523b_init, NULL, &gpio_aw9523b_data##inst,             \
			      &gpio_aw9523b_config##inst, POST_KERNEL,                             \
			      CONFIG_MFD_INIT_PRIORITY, &gpio_aw9523b_api);

DT_INST_FOREACH_STATUS_OKAY(GPIO_AW9523B_DEFINE)
