/*
 * Copyright (c) 2020 Nuvoton Technology Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT nuvoton_npcx_i2c_port

/**
 * @file
 * @brief Nuvoton NPCX smb/i2c port driver
 *
 * This file contains the driver of SMBus/I2C buses (ports) which provides
 * pin-muxing for each i2c io-pads. In order to support "SMBus Multi-Bus"
 * feature, please refer the diagram below, the driver also provides connection
 * between Zephyr i2c api functions and i2c controller driver which provides
 * full support for SMBus/I2C transactions.
 *
 *                           Port SEL
 *                             |
 *                           |\|
 *           SCL_N Port 0----| \     +--------------+
 *           SDA_N Port 0----|  |----|   SMB/I2C    |
 *                           |  |----| Controller N |
 *           SCL_N Port 1----|  |    +--------------+
 *           SDA_N Port 1----| /
 *                           |/
 *
 */

#include <assert.h>
#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/dt-bindings/i2c/i2c.h>
#include <soc.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(i2c_npcx_port, LOG_LEVEL_ERR);

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

/* Device config */
struct i2c_npcx_port_config {
	uint32_t bitrate;
	uint8_t port;
	const struct device *i2c_ctrl;
	/* pinmux configuration */
	const struct pinctrl_dev_config *pcfg;
};

/* I2C api functions */
static int i2c_npcx_port_configure(const struct device *dev,
							uint32_t dev_config)
{
	const struct i2c_npcx_port_config *const config = dev->config;

	if (config->i2c_ctrl == NULL) {
		LOG_ERR("Cannot find i2c controller on port%02x!",
								config->port);
		return -EIO;
	}

	if (!(dev_config & I2C_MODE_MASTER)) {
		return -ENOTSUP;
	}

	if (dev_config & I2C_ADDR_10_BITS) {
		return -ENOTSUP;
	}

	/* Configure i2c controller */
	return npcx_i2c_ctrl_configure(config->i2c_ctrl, dev_config);
}

static int i2c_npcx_port_get_config(const struct device *dev, uint32_t *dev_config)
{
	const struct i2c_npcx_port_config *const config = dev->config;
	uint32_t speed;
	int ret;

	if (config->i2c_ctrl == NULL) {
		LOG_ERR("Cannot find i2c controller on port%02x!", config->port);
		return -EIO;
	}

	ret = npcx_i2c_ctrl_get_speed(config->i2c_ctrl, &speed);
	if (!ret) {
		*dev_config = (I2C_MODE_MASTER | speed);
	}

	return ret;
}

static int i2c_npcx_port_transfer(const struct device *dev,
		struct i2c_msg *msgs, uint8_t num_msgs, uint16_t addr)
{
	const struct i2c_npcx_port_config *const config = dev->config;
	int ret = 0;
	int idx_ctrl = (config->port & 0xF0) >> 4;
	int idx_port = (config->port & 0x0F);

	if (config->i2c_ctrl == NULL) {
		LOG_ERR("Cannot find i2c controller on port%02x!",
								config->port);
		return -EIO;
	}

	/* Lock mutex of i2c/smb controller */
	npcx_i2c_ctrl_mutex_lock(config->i2c_ctrl);

	/* Switch correct port for i2c controller first */
	npcx_pinctrl_i2c_port_sel(idx_ctrl, idx_port);

	/* Start transaction with i2c controller */
	ret = npcx_i2c_ctrl_transfer(config->i2c_ctrl, msgs, num_msgs, addr,
								config->port);

	/* Unlock mutex of i2c/smb controller */
	npcx_i2c_ctrl_mutex_unlock(config->i2c_ctrl);

	return ret;
}

/* I2C driver registration */
static int i2c_npcx_port_init(const struct device *dev)
{
	const struct i2c_npcx_port_config *const config = dev->config;
	uint32_t i2c_config;
	int ret;

	/* Configure pin-mux for I2C device */
	ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
	if (ret < 0) {
		LOG_ERR("I2C pinctrl setup failed (%d)", ret);
		return ret;
	}


	/* Setup initial i2c configuration */
	i2c_config = (I2C_MODE_MASTER | i2c_map_dt_bitrate(config->bitrate));
	ret = i2c_npcx_port_configure(dev, i2c_config);
	if (ret != 0) {
		return ret;
	}

	return 0;
}

static const struct i2c_driver_api i2c_port_npcx_driver_api = {
	.configure = i2c_npcx_port_configure,
	.get_config = i2c_npcx_port_get_config,
	.transfer = i2c_npcx_port_transfer,
};

/* I2C port init macro functions */
#define NPCX_I2C_PORT_INIT(inst)                                               \
	PINCTRL_DT_INST_DEFINE(inst);					       \
									       \
	static const struct i2c_npcx_port_config i2c_npcx_port_cfg_##inst = {  \
		.port = DT_INST_PROP(inst, port),                              \
		.bitrate = DT_INST_PROP(inst, clock_frequency),                \
		.i2c_ctrl = DEVICE_DT_GET(DT_INST_PHANDLE(inst, controller)),  \
		.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst),                  \
	};                                                                     \
									       \
	DEVICE_DT_INST_DEFINE(inst,                                            \
			    i2c_npcx_port_init,                                \
			    NULL, NULL,                                        \
			    &i2c_npcx_port_cfg_##inst,                         \
			    PRE_KERNEL_1, CONFIG_I2C_INIT_PRIORITY,            \
			    &i2c_port_npcx_driver_api);

DT_INST_FOREACH_STATUS_OKAY(NPCX_I2C_PORT_INIT)
