/*
 * Copyright (c) 2024 Advanced Micro Devices, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */


#include <zephyr/drivers/i2c.h>
#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(main, LOG_LEVEL_INF);

#define I2C_MUX_ADDR     0x74
#define I2C_MUX_CHANNEL  0x01U
static const struct device *const axi_i2c1_dev = DEVICE_DT_GET(DT_NODELABEL(axi_i2c1));

static int32_t axi_i2c_master_init(void)
{
	int32_t ret = 0;

	LOG_INF("AXI-I2C: master: init: Start");

	if (device_is_ready(axi_i2c1_dev) == false) {
		LOG_INF("AXI-I2C: master: device is NOT_READY");
		ret = -ENODEV;
		goto out;
	}
	LOG_INF("AXI-I2C: master: device READY");

out:
	if (ret == 0) {
		LOG_INF("AXI-I2C: master: init: PASSED");
	} else {
		LOG_INF("AXI-I2C: master: init: FAILED");
	}

	return ret;
}

static int32_t axi_i2c_master_write(void)
{
	int32_t ret;
	uint8_t datas[6];

	LOG_INF("AXI-I2C: master: write: Start");

	datas[0] = I2C_MUX_CHANNEL;
	LOG_INF("AXI-I2C: master: write: I2C_MUX_ADDR: Progress");
	LOG_INF("AXI-I2C: master: write: data: %02Xh", datas[0]);
	ret = i2c_write(axi_i2c1_dev, datas, 1, I2C_MUX_ADDR);
	if (ret != 0) {
		LOG_INF("AXI-I2C: master: write: I2C_MUX_ADDR FAILED, ret:%d", ret);
		goto out;
	}
	LOG_INF("AXI-I2C: master: write: I2C_MUX_ADDR success");

out:
	if (ret == 0) {
		LOG_INF("AXI-I2C: master: write: PASSED");
	} else {
		LOG_INF("AXI-I2C: master: write: FAILED");
	}

	return ret;
}

static int32_t axi_i2c_master_read(void)
{
	int32_t ret;
	uint8_t datas[6];

	LOG_INF("AXI-I2C: master: read: Start");

	LOG_INF("AXI-I2C: master: read: I2C_MUX_ADDR Progress");
	(void)memset(datas, 0, sizeof(datas));
	ret = i2c_read(axi_i2c1_dev, datas, 3, I2C_MUX_ADDR);
	if (ret != 0) {
		LOG_INF("AXI-I2C: master: read: IIC_SLAVE_ADDR FAILED, ret:%d", ret);
		goto out;
	}
	LOG_INF("AXI-I2C: master: read: I2C_MUX_ADDR success");
	LOG_INF("AXI-I2C: master: read: data: %02Xh %02Xh %02Xh", datas[0], datas[1], datas[2]);

out:
	if (ret == 0) {
		LOG_INF("AXI-I2C: master: read: PASSED");
	} else {
		LOG_INF("AXI-I2C: master: read: FAILED");
	}

	return ret;
}

static int axi_i2c_master_writeread_repstart(void)
{
	int ret;
	uint8_t wr_datas[6];
	uint8_t rd_datas[6];

	LOG_INF("AXI-I2C: master: write-read-repeated-start: Start");

	LOG_INF("AXI-I2C: master: write-read-repeated-start: IIC-Mux Progress");
	wr_datas[0] = I2C_MUX_CHANNEL;
	LOG_INF("AXI-I2C: master: write-repeated-start: data: %02Xh", wr_datas[0]);
	(void)memset(rd_datas, 0, sizeof(rd_datas));
	ret = i2c_write_read(axi_i2c1_dev, I2C_MUX_ADDR, wr_datas, 1, rd_datas, 1);
	if (ret != 0) {
		LOG_INF("AXI-I2C: master: write-read-repeated-start: IIC-Mux FAILED, ret:%d", ret);
		goto out;
	}
	LOG_INF("AXI-I2C: master: write-read-repeated-start: IIC-Mux success");
	LOG_INF("AXI-I2C: master: write-read-repeated-start: read data: %02Xh", rd_datas[0]);

out:
	if (ret == 0) {
		LOG_INF("AXI-I2C: master: write-read-repeated-start: PASSED");
	} else {
		LOG_INF("AXI-I2C: master: write-read-repeated-start: FAILED");
	}

	return ret;
}

static void axi_i2c_master_mode_test(void)
{
	int32_t ret;

	/* AXI-I2C master init */
	ret = axi_i2c_master_init();
	if (ret != 0) {
		goto out;
	}

	/* AXI-I2C master-write */
	ret = axi_i2c_master_write();
	if (ret != 0) {
		goto out;
	}

	/* AXI-I2C master-read */
	ret = axi_i2c_master_read();
	if (ret != 0) {
		goto out;
	}

	/* AXI-I2C master-write-read-repeated-start */
	ret = axi_i2c_master_writeread_repstart();
	if (ret != 0) {
		goto out;
	}

out:
	if (ret != 0) {
		LOG_INF("AXI-I2C: master: mode-test completed, FAILED");
	} else {
		LOG_INF("AXI-I2C: master: mode-test completed, PASSED");
	}
}

int main(void)
{
	/* master usecase */
	axi_i2c_master_mode_test();

	return 0;
}

