/*
 * Copyright (c) 2021 Synopsys
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT cypress_cy8c95xx_gpio_port

#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(cy8c95xx, CONFIG_GPIO_LOG_LEVEL);

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

/** Cache of the output configuration and data of the pins. */
struct cy8c95xx_pin_state {
	uint8_t dir;
	uint8_t data_out;
	uint8_t pull_up;
	uint8_t pull_down;
};

/** Runtime driver data */
struct cy8c95xx_drv_data {
	/* gpio_driver_data needs to be first */
	struct gpio_driver_data common;
	struct cy8c95xx_pin_state pin_state;
	struct k_sem *lock;
};

/** Configuration data */
struct cy8c95xx_config {
	/* gpio_driver_config needs to be first */
	struct gpio_driver_config common;
	struct i2c_dt_spec i2c;
	uint8_t port_num;
};

#define CY8C95XX_REG_INPUT_DATA0                0x00
#define CY8C95XX_REG_OUTPUT_DATA0               0x08
#define CY8C95XX_REG_PORT_SELECT                0x18
#define CY8C95XX_REG_DIR                        0x1C
#define CY8C95XX_REG_PULL_UP                    0x1D
#define CY8C95XX_REG_PULL_DOWN                  0x1E
#define CY8C95XX_REG_ID                         0x2E

static int write_pin_state(const struct cy8c95xx_config *cfg, struct cy8c95xx_pin_state *pins)
{
	int rc;

	rc = i2c_reg_write_byte_dt(&cfg->i2c, CY8C95XX_REG_OUTPUT_DATA0 + cfg->port_num,
				   pins->data_out);
	if (rc) {
		return rc;
	}

	rc = i2c_reg_write_byte_dt(&cfg->i2c, CY8C95XX_REG_PORT_SELECT, cfg->port_num);
	if (rc) {
		return rc;
	}

	rc = i2c_reg_write_byte_dt(&cfg->i2c, CY8C95XX_REG_DIR, pins->dir);
	if (rc) {
		return rc;
	}

	rc = i2c_reg_write_byte_dt(&cfg->i2c, CY8C95XX_REG_PULL_UP, pins->pull_up);
	if (rc) {
		return rc;
	}

	rc = i2c_reg_write_byte_dt(&cfg->i2c, CY8C95XX_REG_PULL_DOWN, pins->pull_down);

	return rc;
}

static int cy8c95xx_config(const struct device *dev,
			   gpio_pin_t pin,
			   gpio_flags_t flags)
{
	const struct cy8c95xx_config *cfg = dev->config;
	struct cy8c95xx_drv_data *drv_data = dev->data;
	struct cy8c95xx_pin_state *pins = &drv_data->pin_state;
	int rc = 0;
	uint32_t io_flags;

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

	/* Open-drain not implemented */
	if ((flags & GPIO_SINGLE_ENDED) != 0U) {
		return -ENOTSUP;
	}

	WRITE_BIT(pins->pull_up, pin, (flags & GPIO_PULL_UP) != 0U);
	WRITE_BIT(pins->pull_down, pin, (flags & GPIO_PULL_DOWN) != 0U);

	/* Disconnected pin not implemented*/
	io_flags = flags & (GPIO_INPUT | GPIO_OUTPUT);
	if (io_flags == GPIO_DISCONNECTED) {
		return -ENOTSUP;
	}

	k_sem_take(drv_data->lock, K_FOREVER);

	if ((flags & GPIO_OUTPUT) != 0) {
		pins->dir &= ~BIT(pin);
		if ((flags & GPIO_OUTPUT_INIT_LOW) != 0) {
			pins->data_out &= ~BIT(pin);
		} else if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0) {
			pins->data_out |= BIT(pin);
		}
	} else {
		pins->dir |= BIT(pin);
	}

	LOG_DBG("CFG %u %x : DIR %04x ; DAT %04x",
		pin, flags, pins->dir, pins->data_out);

	rc = write_pin_state(cfg, pins);

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

static int port_get(const struct device *dev,
		    gpio_port_value_t *value)
{
	const struct cy8c95xx_config *cfg = dev->config;
	struct cy8c95xx_drv_data *drv_data = dev->data;
	uint8_t pin_data = 0;
	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);

	rc = i2c_reg_read_byte_dt(&cfg->i2c, CY8C95XX_REG_INPUT_DATA0 + cfg->port_num, &pin_data);

	if (rc == 0) {
		*value = pin_data;
	}

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

static int port_write(const struct device *dev,
		      gpio_port_pins_t mask,
		      gpio_port_value_t value,
		      gpio_port_value_t toggle)
{
	const struct cy8c95xx_config *cfg = dev->config;
	struct cy8c95xx_drv_data *drv_data = dev->data;
	uint8_t *outp = &drv_data->pin_state.data_out;
	uint8_t out = ((*outp & ~mask) | (value & mask)) ^ toggle;

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

	k_sem_take(drv_data->lock, K_FOREVER);

	int rc = i2c_reg_write_byte_dt(&cfg->i2c, CY8C95XX_REG_OUTPUT_DATA0 + cfg->port_num, out);

	if (rc == 0) {
		*outp = out;
	}
	k_sem_give(drv_data->lock);

	LOG_DBG("write msk %04x val %04x tog %04x => %04x: %d",
		mask, value, toggle, out, rc);

	return rc;
}

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

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

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

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

static int pin_interrupt_configure(const struct device *dev,
				   gpio_pin_t pin,
				   enum gpio_int_mode mode,
				   enum gpio_int_trig trig)
{
	return -ENOTSUP;
}

/**
 * @brief Initialization function of CY8C95XX
 *
 * @param dev Device struct
 * @return 0 if successful, failed otherwise.
 */
static int cy8c95xx_init(const struct device *dev)
{
	const struct cy8c95xx_config *cfg = dev->config;
	struct cy8c95xx_drv_data *drv_data = dev->data;
	int rc;
	uint8_t data = 0;

	k_sem_take(drv_data->lock, K_FOREVER);

	if (!device_is_ready(cfg->i2c.bus)) {
		LOG_ERR("%s is not ready", cfg->i2c.bus->name);
		rc = -ENODEV;
		goto out;
	}

	rc = i2c_reg_read_byte_dt(&cfg->i2c, CY8C95XX_REG_ID, &data);
	if (rc) {
		goto out;
	}
	LOG_DBG("cy8c95xx device ID %02X", data & 0xF0);
	if ((data & 0xF0) != 0x20) {
		LOG_WRN("driver only support [0-2] ports operations");
	}

	/* Reset state mediated by initial configuration */
	drv_data->pin_state = (struct cy8c95xx_pin_state) {
		.dir = 0xFF,
		.data_out = 0xFF,
		.pull_up = 0xFF,
		.pull_down = 0x00,
	};
	rc = write_pin_state(cfg, &drv_data->pin_state);
out:
	if (rc != 0) {
		LOG_ERR("%s init failed: %d", dev->name, rc);
	} else {
		LOG_DBG("%s init ok", dev->name);
	}
	k_sem_give(drv_data->lock);
	return rc;
}

static const struct gpio_driver_api api_table = {
	.pin_configure = cy8c95xx_config,
	.port_get_raw = port_get,
	.port_set_masked_raw = port_set_masked,
	.port_set_bits_raw = port_set_bits,
	.port_clear_bits_raw = port_clear_bits,
	.port_toggle_bits = port_toggle_bits,
	.pin_interrupt_configure = pin_interrupt_configure,
};

static struct k_sem cy8c95xx_lock = Z_SEM_INITIALIZER(cy8c95xx_lock, 1, 1);

#define GPIO_PORT_INIT(idx) \
static const struct cy8c95xx_config cy8c95xx_##idx##_cfg = { \
	.common = { \
		.port_pin_mask = 0xFF, \
	}, \
	.i2c = I2C_DT_SPEC_INST_GET(idx), \
	.port_num = DT_INST_REG_ADDR(idx), \
}; \
static struct cy8c95xx_drv_data cy8c95xx_##idx##_drvdata = { \
	.lock = &cy8c95xx_lock, \
}; \
DEVICE_DT_INST_DEFINE(idx, cy8c95xx_init, NULL, \
				&cy8c95xx_##idx##_drvdata, &cy8c95xx_##idx##_cfg, \
				POST_KERNEL, CONFIG_GPIO_CY8C95XX_INIT_PRIORITY, \
				&api_table);

DT_INST_FOREACH_STATUS_OKAY(GPIO_PORT_INIT)
