/*
 * Copyright (c) 2019 Vestas Wind Systems A/S
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief GPIO driver for the LMP90xxx AFE.
 */

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

#define LOG_LEVEL CONFIG_GPIO_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(gpio_lmp90xxx);

#include <drivers/adc/lmp90xxx.h>

#include "gpio_utils.h"

struct gpio_lmp90xxx_config {
	/* gpio_driver_config needs to be first */
	struct gpio_driver_config common;
	char *parent_dev_name;
};

struct gpio_lmp90xxx_data {
	/* gpio_driver_data needs to be first */
	struct gpio_driver_data common;
	struct device *parent;
};

static int gpio_lmp90xxx_config(struct device *dev,
				gpio_pin_t pin, gpio_flags_t flags)
{
	struct gpio_lmp90xxx_data *data = dev->driver_data;
	int err = 0;

	if (pin > LMP90XXX_GPIO_MAX) {
		return -EINVAL;
	}

	if ((flags & GPIO_SINGLE_ENDED) != 0) {
		return -ENOTSUP;
	}

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

	if (flags & GPIO_INT_ENABLE) {
		/* LMP90xxx GPIOs do not support interrupts */
		return -ENOTSUP;
	}

	switch (flags & GPIO_DIR_MASK) {
	case GPIO_INPUT:
		err = lmp90xxx_gpio_set_input(data->parent, pin);
		break;
	case GPIO_OUTPUT:
		if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0) {
			err = lmp90xxx_gpio_set_pin_value(data->parent, pin,
							  true);
		} else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0) {
			err = lmp90xxx_gpio_set_pin_value(data->parent, pin,
							  false);
		}

		if (err) {
			return err;
		}
		err = lmp90xxx_gpio_set_output(data->parent, pin);
		break;
	default:
		return -ENOTSUP;
	}

	return err;
}

static int gpio_lmp90xxx_port_get_raw(struct device *dev,
				      gpio_port_value_t *value)
{
	struct gpio_lmp90xxx_data *data = dev->driver_data;

	return lmp90xxx_gpio_port_get_raw(data->parent, value);
}

static int gpio_lmp90xxx_port_set_masked_raw(struct device *dev,
					     gpio_port_pins_t mask,
					     gpio_port_value_t value)
{
	struct gpio_lmp90xxx_data *data = dev->driver_data;

	return lmp90xxx_gpio_port_set_masked_raw(data->parent, mask, value);
}

static int gpio_lmp90xxx_port_set_bits_raw(struct device *dev,
					   gpio_port_pins_t pins)
{
	struct gpio_lmp90xxx_data *data = dev->driver_data;

	return lmp90xxx_gpio_port_set_bits_raw(data->parent, pins);
}

static int gpio_lmp90xxx_port_clear_bits_raw(struct device *dev,
					     gpio_port_pins_t pins)
{
	struct gpio_lmp90xxx_data *data = dev->driver_data;

	return lmp90xxx_gpio_port_clear_bits_raw(data->parent, pins);
}

static int gpio_lmp90xxx_port_toggle_bits(struct device *dev,
					  gpio_port_pins_t pins)
{
	struct gpio_lmp90xxx_data *data = dev->driver_data;

	return lmp90xxx_gpio_port_toggle_bits(data->parent, pins);
}

static int gpio_lmp90xxx_pin_interrupt_configure(struct device *dev,
						 gpio_pin_t pin,
						 enum gpio_int_mode mode,
						 enum gpio_int_trig trig)
{
	ARG_UNUSED(dev);
	ARG_UNUSED(pin);
	ARG_UNUSED(mode);
	ARG_UNUSED(trig);

	return -ENOTSUP;
}

static int gpio_lmp90xxx_init(struct device *dev)
{
	const struct gpio_lmp90xxx_config *config = dev->config->config_info;
	struct gpio_lmp90xxx_data *data = dev->driver_data;

	data->parent = device_get_binding(config->parent_dev_name);
	if (!data->parent) {
		LOG_ERR("parent LMP90xxx device '%s' not found",
			config->parent_dev_name);
		return -EINVAL;
	}

	return 0;
}

static const struct gpio_driver_api gpio_lmp90xxx_api = {
	.pin_configure = gpio_lmp90xxx_config,
	.port_set_masked_raw = gpio_lmp90xxx_port_set_masked_raw,
	.port_set_bits_raw = gpio_lmp90xxx_port_set_bits_raw,
	.port_clear_bits_raw = gpio_lmp90xxx_port_clear_bits_raw,
	.port_toggle_bits = gpio_lmp90xxx_port_toggle_bits,
	.pin_interrupt_configure = gpio_lmp90xxx_pin_interrupt_configure,
	.port_get_raw = gpio_lmp90xxx_port_get_raw,
};

BUILD_ASSERT_MSG(CONFIG_GPIO_LMP90XXX_INIT_PRIORITY >
		 CONFIG_ADC_LMP90XXX_INIT_PRIORITY,
		 "LMP90xxx GPIO driver must be initialized after LMP90xxx ADC "
		 "driver");

#define GPIO_LMP90XXX_DEVICE(id)					\
	static const struct gpio_lmp90xxx_config gpio_lmp90xxx_##id##_cfg = {\
		.common = {                                             \
			.port_pin_mask =                                \
				 GPIO_PORT_PIN_MASK_FROM_NGPIOS(        \
					DT_INST_##id##_TI_LMP90XXX_GPIO_NGPIOS)\
		},                                                      \
		.parent_dev_name =					\
			DT_INST_##id##_TI_LMP90XXX_GPIO_BUS_NAME,	\
	};								\
									\
	static struct gpio_lmp90xxx_data gpio_lmp90xxx_##id##_data;	\
									\
	DEVICE_AND_API_INIT(gpio_lmp90xxx_##id,				\
			    DT_INST_##id##_TI_LMP90XXX_GPIO_LABEL,	\
			    &gpio_lmp90xxx_init,			\
			    &gpio_lmp90xxx_##id##_data,			\
			    &gpio_lmp90xxx_##id##_cfg, POST_KERNEL,	\
			    CONFIG_GPIO_LMP90XXX_INIT_PRIORITY,		\
			    &gpio_lmp90xxx_api)

#ifdef DT_INST_0_TI_LMP90XXX_GPIO
GPIO_LMP90XXX_DEVICE(0);
#endif
