/*
 * Copyright (c) 2020 Vestas Wind Systems A/S
 * Copyright (c) 2017 Linaro Ltd.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT gpio_i2c

/**
 * @file
 * @brief Driver for software driven I2C using GPIO lines
 *
 * This driver implements an I2C interface by driving two GPIO lines under
 * software control.
 *
 * The GPIO pins used must be configured (through devicetree and pinmux) with
 * suitable flags, i.e. the SDA pin as open-collector/open-drain with a pull-up
 * resistor (possibly as an external component attached to the pin).
 *
 * When the SDA pin is read it must return the state of the physical hardware
 * line, not just the last state written to it for output.
 *
 * The SCL pin should be configured in the same manner as SDA, or, if it is
 * known that the hardware attached to pin doesn't attempt clock stretching,
 * then the SCL pin may be a push/pull output.
 */

#include <zephyr/device.h>
#include <errno.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/i2c.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(i2c_gpio);

#include "i2c-priv.h"
#include "i2c_bitbang.h"

/* Driver config */
struct i2c_gpio_config {
	struct gpio_dt_spec scl_gpio;
	struct gpio_dt_spec sda_gpio;
	uint32_t bitrate;
};

/* Driver instance data */
struct i2c_gpio_context {
	struct i2c_bitbang bitbang;	/* Bit-bang library data */
	struct k_mutex mutex;
};

static void i2c_gpio_set_scl(void *io_context, int state)
{
	const struct i2c_gpio_config *config = io_context;

	gpio_pin_set_dt(&config->scl_gpio, state);
}

static void i2c_gpio_set_sda(void *io_context, int state)
{
	const struct i2c_gpio_config *config = io_context;

	gpio_pin_set_dt(&config->sda_gpio, state);
}

static int i2c_gpio_get_sda(void *io_context)
{
	const struct i2c_gpio_config *config = io_context;
	int rc = gpio_pin_get_dt(&config->sda_gpio);

	/* Default high as that would be a NACK */
	return rc != 0;
}

static const struct i2c_bitbang_io io_fns = {
	.set_scl = &i2c_gpio_set_scl,
	.set_sda = &i2c_gpio_set_sda,
	.get_sda = &i2c_gpio_get_sda,
};

static int i2c_gpio_configure(const struct device *dev, uint32_t dev_config)
{
	struct i2c_gpio_context *context = dev->data;
	int rc;

	k_mutex_lock(&context->mutex, K_FOREVER);

	rc = i2c_bitbang_configure(&context->bitbang, dev_config);

	k_mutex_unlock(&context->mutex);

	return rc;
}

static int i2c_gpio_transfer(const struct device *dev, struct i2c_msg *msgs,
				uint8_t num_msgs, uint16_t slave_address)
{
	struct i2c_gpio_context *context = dev->data;
	int rc;

	k_mutex_lock(&context->mutex, K_FOREVER);

	rc = i2c_bitbang_transfer(&context->bitbang, msgs, num_msgs,
				    slave_address);

	k_mutex_unlock(&context->mutex);

	return rc;
}

static int i2c_gpio_recover_bus(const struct device *dev)
{
	struct i2c_gpio_context *context = dev->data;
	int rc;

	k_mutex_lock(&context->mutex, K_FOREVER);

	rc = i2c_bitbang_recover_bus(&context->bitbang);

	k_mutex_unlock(&context->mutex);

	return rc;
}

static struct i2c_driver_api api = {
	.configure = i2c_gpio_configure,
	.transfer = i2c_gpio_transfer,
	.recover_bus = i2c_gpio_recover_bus,
};

static int i2c_gpio_init(const struct device *dev)
{
	struct i2c_gpio_context *context = dev->data;
	const struct i2c_gpio_config *config = dev->config;
	uint32_t bitrate_cfg;
	int err;

	if (!device_is_ready(config->scl_gpio.port)) {
		LOG_ERR("SCL GPIO device not ready");
		return -ENODEV;
	}

	err = gpio_pin_configure_dt(&config->scl_gpio, GPIO_OUTPUT_HIGH);
	if (err) {
		LOG_ERR("failed to configure SCL GPIO pin (err %d)", err);
		return err;
	}

	if (!device_is_ready(config->sda_gpio.port)) {
		LOG_ERR("SDA GPIO device not ready");
		return -ENODEV;
	}

	err = gpio_pin_configure_dt(&config->sda_gpio,
				    GPIO_INPUT | GPIO_OUTPUT_HIGH);
	if (err == -ENOTSUP) {
		err = gpio_pin_configure_dt(&config->sda_gpio,
					    GPIO_OUTPUT_HIGH);
	}
	if (err) {
		LOG_ERR("failed to configure SDA GPIO pin (err %d)", err);
		return err;
	}

	i2c_bitbang_init(&context->bitbang, &io_fns, (void *)config);

	bitrate_cfg = i2c_map_dt_bitrate(config->bitrate);
	err = i2c_bitbang_configure(&context->bitbang,
				    I2C_MODE_CONTROLLER | bitrate_cfg);
	if (err) {
		LOG_ERR("failed to configure I2C bitbang (err %d)", err);
		return err;
	}

	err = k_mutex_init(&context->mutex);
	if (err) {
		LOG_ERR("Failed to create the i2c lock mutex : %d", err);
		return err;
	}

	return 0;
}

#define	DEFINE_I2C_GPIO(_num)						\
									\
static struct i2c_gpio_context i2c_gpio_dev_data_##_num;		\
									\
static const struct i2c_gpio_config i2c_gpio_dev_cfg_##_num = {		\
	.scl_gpio	= GPIO_DT_SPEC_INST_GET(_num, scl_gpios),	\
	.sda_gpio	= GPIO_DT_SPEC_INST_GET(_num, sda_gpios),	\
	.bitrate	= DT_INST_PROP(_num, clock_frequency),		\
};									\
									\
I2C_DEVICE_DT_INST_DEFINE(_num,						\
	    i2c_gpio_init,						\
	    NULL,							\
	    &i2c_gpio_dev_data_##_num,					\
	    &i2c_gpio_dev_cfg_##_num,					\
	    POST_KERNEL, CONFIG_I2C_INIT_PRIORITY, &api);

DT_INST_FOREACH_STATUS_OKAY(DEFINE_I2C_GPIO)
