/*
 * Copyright (c), 2023 Basalte bv
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT nxp_sc18im704_gpio

#include <errno.h>
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/init.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/gpio/gpio_utils.h>

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

#include "i2c/i2c_sc18im704.h"

#define GPIO_SC18IM_MAX_PINS		8

/* After reset the GPIO config registers are 0x55 */
#define GPIO_SC18IM_DEFAULT_CONF	0x55

#define GPIO_SC18IM_CONF_INPUT		0x01
#define GPIO_SC18IM_CONF_PUSH_PULL	0x02
#define GPIO_SC18IM_CONF_OPEN_DRAIN	0x03
#define GPIO_SC18IM_CONF_MASK		0x03

struct gpio_sc18im_config {
	/* gpio_driver_config needs to be first */
	struct gpio_driver_config common;

	const struct device *bridge;
};

struct gpio_sc18im_data {
	/* gpio_driver_data needs to be first */
	struct gpio_driver_data common;

	uint8_t conf1;
	uint8_t conf2;
	uint8_t output_state;
};

static int gpio_sc18im_port_set_raw(const struct device *port,
				    uint8_t mask, uint8_t value, uint8_t toggle)
{
	const struct gpio_sc18im_config *cfg = port->config;
	struct gpio_sc18im_data *data = port->data;
	uint8_t buf[] = {
		SC18IM704_CMD_WRITE_GPIO,
		data->output_state,
		SC18IM704_CMD_STOP,
	};
	int ret;

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

	buf[1] &= ~mask;
	buf[1] |= (value & mask);
	buf[1] ^= toggle;

	ret = sc18im704_transfer(cfg->bridge, buf, sizeof(buf), NULL, 0);
	if (ret < 0) {
		LOG_ERR("Failed to write GPIO state (%d)", ret);
		return ret;
	}

	data->output_state = buf[1];

	return 0;
}

static int gpio_sc18im_pin_configure(const struct device *port, gpio_pin_t pin,
				     gpio_flags_t flags)
{
	const struct gpio_sc18im_config *cfg = port->config;
	struct gpio_sc18im_data *data = port->data;
	uint8_t pin_conf;
	int ret;
	uint8_t buf[] = {
		SC18IM704_CMD_WRITE_REG,
		0x00,
		0x00,
		SC18IM704_CMD_STOP,
	};

	if (pin >= GPIO_SC18IM_MAX_PINS) {
		return -EINVAL;
	}

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

	if (flags & GPIO_INPUT) {
		pin_conf = GPIO_SC18IM_CONF_INPUT;
	} else if (flags & GPIO_OUTPUT) {
		if (flags & GPIO_SINGLE_ENDED) {
			if (flags & GPIO_LINE_OPEN_DRAIN) {
				pin_conf = GPIO_SC18IM_CONF_OPEN_DRAIN;
			} else {
				/* Open-drain is the only supported single-ended mode */
				return -ENOTSUP;
			}
		} else {
			/* Default to push/pull */
			pin_conf = GPIO_SC18IM_CONF_PUSH_PULL;
		}
	} else {
		/* Neither input nor output mode is selected */
		return -ENOTSUP;
	}

	ret = sc18im704_claim(cfg->bridge);
	if (ret < 0) {
		LOG_ERR("Failed to claim bridge (%d)", ret);
		return ret;
	}

	if (pin < 4) {
		/* Shift the config to the pin offset */
		data->conf1 &= ~(GPIO_SC18IM_CONF_MASK << (pin * 2));
		data->conf1 |= pin_conf << (pin * 2);

		buf[1] = SC18IM704_REG_GPIO_CONF1;
		buf[2] = data->conf1;
	} else {
		/* Shift the config to the pin offset */
		data->conf2 &= ~(GPIO_SC18IM_CONF_MASK << ((pin - 4) * 2));
		data->conf2 |= pin_conf << ((pin - 4) * 2);

		buf[1] = SC18IM704_REG_GPIO_CONF2;
		buf[2] = data->conf2;
	}

	ret = sc18im704_transfer(cfg->bridge, buf, sizeof(buf), NULL, 0);
	if (ret < 0) {
		LOG_ERR("Failed to configure GPIO (%d)", ret);
	}

	if (ret == 0 && flags & GPIO_OUTPUT) {
		if (flags & GPIO_OUTPUT_INIT_HIGH) {
			gpio_sc18im_port_set_raw(port, BIT(pin), BIT(pin), 0);
		}
		if (flags & GPIO_OUTPUT_INIT_LOW) {
			gpio_sc18im_port_set_raw(port, BIT(pin), 0, 0);
		}
	}

	sc18im704_release(cfg->bridge);

	return ret;
}

#ifdef CONFIG_GPIO_GET_CONFIG
static int gpio_sc18im_pin_get_config(const struct device *port, gpio_pin_t pin,
				      gpio_flags_t *flags)
{
	struct gpio_sc18im_data *data = port->data;
	uint8_t conf;

	if (pin >= GPIO_SC18IM_MAX_PINS) {
		return -EINVAL;
	}

	if (pin < 4) {
		conf = (data->conf1 >> (2 * pin)) & GPIO_SC18IM_CONF_MASK;
	} else {
		conf = (data->conf2 >> (2 * (pin - 4))) & GPIO_SC18IM_CONF_MASK;
	}

	switch (conf) {
	case GPIO_SC18IM_CONF_PUSH_PULL:
		*flags = GPIO_OUTPUT | GPIO_PUSH_PULL;
		break;
	case GPIO_SC18IM_CONF_OPEN_DRAIN:
		*flags = GPIO_OUTPUT | GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_DRAIN;
		break;
	case GPIO_SC18IM_CONF_INPUT:
	default:
		*flags = GPIO_INPUT;
		break;
	}

	return 0;
}
#endif

static int gpio_sc18im_port_get_raw(const struct device *port, gpio_port_value_t *value)
{
	const struct gpio_sc18im_config *cfg = port->config;

	uint8_t buf[] = {
		SC18IM704_CMD_READ_GPIO,
		SC18IM704_CMD_STOP,
	};
	uint8_t data;
	int ret;

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

	ret = sc18im704_transfer(cfg->bridge, buf, sizeof(buf), &data, 1);
	if (ret < 0) {
		LOG_ERR("Failed to read GPIO state (%d)", ret);
		return ret;
	}

	*value = data;

	return 0;
}

static int gpio_sc18im_port_set_masked_raw(const struct device *port,
					   gpio_port_pins_t mask,
					   gpio_port_value_t value)
{
	return gpio_sc18im_port_set_raw(port, (uint8_t)mask, (uint8_t)value, 0);
}

static int gpio_sc18im_port_set_bits_raw(const struct device *port, gpio_port_pins_t pins)
{
	return gpio_sc18im_port_set_raw(port, (uint8_t)pins, (uint8_t)pins, 0);
}

static int gpio_sc18im_port_clear_bits_raw(const struct device *port, gpio_port_pins_t pins)
{
	return gpio_sc18im_port_set_raw(port, (uint8_t)pins, 0, 0);
}

static int gpio_sc18im_port_toggle_bits(const struct device *port, gpio_port_pins_t pins)
{
	return gpio_sc18im_port_set_raw(port, 0, 0, (uint8_t)pins);
}

static int gpio_sc18im_pin_interrupt_configure(const struct device *port, gpio_pin_t pin,
					       enum gpio_int_mode mode, enum gpio_int_trig trig)
{
	ARG_UNUSED(port);
	ARG_UNUSED(pin);
	ARG_UNUSED(mode);
	ARG_UNUSED(trig);

	return -ENOTSUP;
}

static int gpio_sc18im_init(const struct device *dev)
{
	const struct gpio_sc18im_config *cfg = dev->config;

	if (!device_is_ready(cfg->bridge)) {
		LOG_ERR("Parent device not ready");
		return -ENODEV;
	}

	return 0;
}

static const struct gpio_driver_api gpio_sc18im_driver_api = {
	.pin_configure = gpio_sc18im_pin_configure,
#ifdef CONFIG_GPIO_GET_CONFIG
	.pin_get_config = gpio_sc18im_pin_get_config,
#endif
	.port_get_raw = gpio_sc18im_port_get_raw,
	.port_set_masked_raw = gpio_sc18im_port_set_masked_raw,
	.port_set_bits_raw = gpio_sc18im_port_set_bits_raw,
	.port_clear_bits_raw = gpio_sc18im_port_clear_bits_raw,
	.port_toggle_bits = gpio_sc18im_port_toggle_bits,
	.pin_interrupt_configure = gpio_sc18im_pin_interrupt_configure,
};

#define CHECK_COMPAT(node)									\
	COND_CODE_1(DT_NODE_HAS_COMPAT(node, nxp_sc18im704_i2c), (DEVICE_DT_GET(node)), ())

#define GPIO_SC18IM704_I2C_SIBLING(n)								\
	DT_FOREACH_CHILD_STATUS_OKAY(DT_INST_PARENT(n), CHECK_COMPAT)

#define GPIO_SC18IM704_DEFINE(n)								\
	static const struct gpio_sc18im_config gpio_sc18im_config_##n = {			\
		.common = {									\
			.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(n),			\
		},										\
		.bridge = GPIO_SC18IM704_I2C_SIBLING(n),					\
	};											\
	static struct gpio_sc18im_data gpio_sc18im_data_##n = {					\
		.conf1 = GPIO_SC18IM_DEFAULT_CONF,						\
		.conf2 = GPIO_SC18IM_DEFAULT_CONF,						\
	};											\
												\
	DEVICE_DT_INST_DEFINE(n, gpio_sc18im_init, NULL,					\
			      &gpio_sc18im_data_##n, &gpio_sc18im_config_##n,			\
			      POST_KERNEL, CONFIG_GPIO_SC18IM704_INIT_PRIORITY,			\
			      &gpio_sc18im_driver_api);

DT_INST_FOREACH_STATUS_OKAY(GPIO_SC18IM704_DEFINE);
