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

#define DT_DRV_COMPAT telink_b91_i2c

#include "i2c.h"
#include "clock.h"

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

#include <zephyr/drivers/i2c.h>
#include "i2c-priv.h"
#include <zephyr/drivers/pinctrl.h>

/* I2C configuration structure */
struct i2c_b91_cfg {
	uint32_t bitrate;
	const struct pinctrl_dev_config *pcfg;
};

/* I2C data structure */
struct i2c_b91_data {
	struct k_sem mutex;
};

/* API implementation: configure */
static int i2c_b91_configure(const struct device *dev, uint32_t dev_config)
{
	ARG_UNUSED(dev);

	uint32_t i2c_speed = 0u;

	/* check address size */
	if (dev_config & I2C_ADDR_10_BITS) {
		LOG_ERR("10-bits address is not supported");
		return -ENOTSUP;
	}

	/* check I2C Master/Slave configuration */
	if (!(dev_config & I2C_MODE_MASTER)) {
		LOG_ERR("I2C slave is not implemented");
		return -ENOTSUP;
	}

	/* check i2c speed */
	switch (I2C_SPEED_GET(dev_config)) {
	case I2C_SPEED_STANDARD:
		i2c_speed = 100000u;
		break;

	case I2C_SPEED_FAST:
		i2c_speed = 400000U;
		break;

	case I2C_SPEED_FAST_PLUS:
	case I2C_SPEED_HIGH:
	case I2C_SPEED_ULTRA:
	default:
		LOG_ERR("Unsupported I2C speed requested");
		return -ENOTSUP;
	}

	/* init i2c */
	i2c_master_init();
	i2c_set_master_clk((unsigned char)(sys_clk.pclk * 1000 * 1000 / (4 * i2c_speed)));

	return 0;
}

/* API implementation: transfer */
static int i2c_b91_transfer(const struct device *dev,
			    struct i2c_msg *msgs,
			    uint8_t num_msgs,
			    uint16_t addr)
{
	int status = 0;
	uint8_t send_stop = 0;
	struct i2c_b91_data *data = dev->data;

	/* get the mutex */
	k_sem_take(&data->mutex, K_FOREVER);

	/* loop through all messages */
	for (int i = 0; i < num_msgs; i++) {
		/* check addr size */
		if (msgs[i].flags & I2C_MSG_ADDR_10_BITS) {
			LOG_ERR("10-bits address is not supported");
			k_sem_give(&data->mutex);
			return -ENOTSUP;
		}

		/* config stop bit */
		send_stop = msgs[i].flags & I2C_MSG_STOP ? 1 : 0;
		i2c_master_send_stop(send_stop);

		/* transfer data */
		if (msgs[i].flags & I2C_MSG_READ) {
			status = i2c_master_read(addr, msgs[i].buf, msgs[i].len);
		} else {
			status = i2c_master_write(addr, msgs[i].buf, msgs[i].len);
		}

		/* check status */
		if (!status) {
			LOG_ERR("Failed to transfer I2C messages\n");
			k_sem_give(&data->mutex);
			return -EIO;
		}
	}

	/* release the mutex */
	k_sem_give(&data->mutex);

	return 0;
};

/* API implementation: init */
static int i2c_b91_init(const struct device *dev)
{
	int status = 0;
	const struct i2c_b91_cfg *cfg = dev->config;
	struct i2c_b91_data *data = dev->data;
	uint32_t dev_config = (I2C_MODE_MASTER | i2c_map_dt_bitrate(cfg->bitrate));

	/* init mutex */
	k_sem_init(&data->mutex, 1, 1);

	/* config i2c on startup */
	status = i2c_b91_configure(dev, dev_config);
	if (status != 0) {
		LOG_ERR("Failed to configure I2C on init");
		return status;
	}

	/* configure pins */
	status = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
	if (status < 0) {
		LOG_ERR("Failed to configure I2C pins");
		return status;
	}

	return 0;
}

/* I2C driver APIs structure */
static const struct i2c_driver_api i2c_b91_api = {
	.configure = i2c_b91_configure,
	.transfer = i2c_b91_transfer,
};

BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) <= 1,
	     "unsupported I2C instance");

/* I2C driver registration */
#define I2C_B91_INIT(inst)					      \
								      \
	PINCTRL_DT_INST_DEFINE(inst);				      \
								      \
	static struct i2c_b91_data i2c_b91_data_##inst;		      \
								      \
	static struct i2c_b91_cfg i2c_b91_cfg_##inst = {	      \
		.bitrate = DT_INST_PROP(inst, clock_frequency),	      \
		.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst),	      \
	};							      \
								      \
	I2C_DEVICE_DT_INST_DEFINE(inst, i2c_b91_init,		      \
				  NULL,				      \
				  &i2c_b91_data_##inst,		      \
				  &i2c_b91_cfg_##inst,		      \
				  POST_KERNEL,			      \
				  CONFIG_I2C_INIT_PRIORITY,	      \
				  &i2c_b91_api);

DT_INST_FOREACH_STATUS_OKAY(I2C_B91_INIT)
