/*
 * 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_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,
};

#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);
