/* SPDX-License-Identifier: GPL-2.0-only */

#include <device/i2c_simple.h>
#include <limits.h>
#include <tests/test.h>

/* Simulate two i2c devices, both on bus 0, each with three uint8_t regs
   implemented. */
typedef struct {
	uint8_t reg;
	uint8_t data;
} i2c_ex_regs_t;

typedef struct {
	unsigned int bus;
	uint8_t slave;
	i2c_ex_regs_t regs[3];
} i2c_ex_devs_t;

i2c_ex_devs_t i2c_ex_devs[] = {
	{
		.bus = 0,
		.slave = 0xA,
		.regs = {
			{.reg = 0x0, .data = 0xB},
			{.reg = 0x1, .data = 0x6},
			{.reg = 0x2, .data = 0xF},
		}
	},
	{
		.bus = 0,
		.slave = 0x3,
		.regs = {
			{.reg = 0x0, .data = 0xDE},
			{.reg = 0x1, .data = 0xAD},
			{.reg = 0x2, .data = 0xBE},
		}
	},
};

int platform_i2c_transfer(unsigned int bus, struct i2c_msg *segments, int count)
{
	int i;
	int reg;
	struct i2c_msg *tmp = segments;
	i2c_ex_devs_t *i2c_dev = NULL;

	check_expected(count);

	for (i = 0; i < count; i++, segments++) {
		check_expected_ptr(segments->buf);
		check_expected(segments->flags);
	}

	reg = tmp->buf[0];

	/* Find object for requested device */
	for (i = 0; i < ARRAY_SIZE(i2c_ex_devs); i++)
		if (i2c_ex_devs[i].slave == tmp->slave) {
			i2c_dev = &i2c_ex_devs[i];
			break;
		}

	if (i2c_dev == NULL)
		return -1;

	/* Write commands */
	if (tmp->len > 1) {
		i2c_dev->regs[reg].data = tmp->buf[1];
	};

	/* Read commands */
	for (i = 0; i < count; i++, tmp++)
		if (tmp->flags & I2C_M_RD) {
			*(tmp->buf) = i2c_dev->regs[reg].data;
		};

	return 0;
}

static void mock_expect_params_platform_i2c_transfer(void)
{
	unsigned long int expected_flags[] = {0, I2C_M_RD, I2C_M_TEN, I2C_M_RECV_LEN,
					      I2C_M_NOSTART};

	/* Flags should always be only within supported range */
	expect_in_set_count(platform_i2c_transfer, segments->flags, expected_flags, -1);

	expect_not_value_count(platform_i2c_transfer, segments->buf, NULL, -1);

	expect_in_range_count(platform_i2c_transfer, count, 1, INT_MAX, -1);
}

#define MASK 0x3
#define SHIFT 0x1

static void i2c_read_field_test(void **state)
{
	int i, j;
	uint8_t buf;

	mock_expect_params_platform_i2c_transfer();

	/* Read particular bits in all registers in all devices, then compare
	   with expected value. */
	for (i = 0; i < ARRAY_SIZE(i2c_ex_devs); i++)
		for (j = 0; j < ARRAY_SIZE(i2c_ex_devs[0].regs); j++) {
			i2c_read_field(i2c_ex_devs[i].bus, i2c_ex_devs[i].slave,
				       i2c_ex_devs[i].regs[j].reg, &buf, MASK, SHIFT);
			assert_int_equal(
				(i2c_ex_devs[i].regs[j].data & (MASK << SHIFT)) >> SHIFT, buf);
		};

	/* Read whole registers */
	for (i = 0; i < ARRAY_SIZE(i2c_ex_devs); i++)
		for (j = 0; j < ARRAY_SIZE(i2c_ex_devs[0].regs); j++) {
			i2c_read_field(i2c_ex_devs[i].bus, i2c_ex_devs[i].slave,
				       i2c_ex_devs[i].regs[j].reg, &buf, 0xFF, 0);
			assert_int_equal(i2c_ex_devs[i].regs[j].data, buf);
		};
}

static void i2c_write_field_test(void **state)
{
	int i, j;
	uint8_t buf, tmp;

	mock_expect_params_platform_i2c_transfer();

	/* Clear particular bits in all registers in all devices, then compare
	   with expected value. */
	for (i = 0; i < ARRAY_SIZE(i2c_ex_devs); i++)
		for (j = 0; j < ARRAY_SIZE(i2c_ex_devs[0].regs); j++) {
			buf = 0x0;
			tmp = i2c_ex_devs[i].regs[j].data;
			i2c_write_field(i2c_ex_devs[i].bus, i2c_ex_devs[i].slave,
					i2c_ex_devs[i].regs[j].reg, buf, MASK, SHIFT);
			assert_int_equal(i2c_ex_devs[i].regs[j].data,
					 (tmp & ~(MASK << SHIFT)) | (buf << SHIFT));
		};

	/* Set all bits in all registers, this time verify using
	   i2c_read_field() accessor. */
	for (i = 0; i < ARRAY_SIZE(i2c_ex_devs); i++)
		for (j = 0; j < ARRAY_SIZE(i2c_ex_devs[0].regs); j++) {
			i2c_write_field(i2c_ex_devs[i].bus, i2c_ex_devs[i].slave,
					i2c_ex_devs[i].regs[j].reg, 0xFF, 0xFF, 0);
			i2c_read_field(i2c_ex_devs[i].bus, i2c_ex_devs[i].slave,
				       i2c_ex_devs[i].regs[j].reg, &buf, 0xFF, 0);
			assert_int_equal(buf, 0xFF);
		};
}

int main(void)
{
	const struct CMUnitTest tests[] = {cmocka_unit_test(i2c_read_field_test),
					   cmocka_unit_test(i2c_write_field_test)};

	return cb_run_group_tests(tests, NULL, NULL);
}
