/*
 * Copyright (C) 2013 Google, Inc
 *
 * SPDX-License-Identifier:	GPL-2.0+
 *
 * Note: Test coverage does not include 10-bit addressing
 */

#include <common.h>
#include <dm.h>
#include <fdtdec.h>
#include <i2c.h>
#include <dm/device-internal.h>
#include <dm/test.h>
#include <dm/uclass-internal.h>
#include <dm/ut.h>
#include <dm/util.h>
#include <asm/state.h>
#include <asm/test.h>

static const int busnum;
static const int chip = 0x2c;

/* Test that we can find buses and chips */
static int dm_test_i2c_find(struct dm_test_state *dms)
{
	struct udevice *bus, *dev;
	const int no_chip = 0x10;

	ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_I2C, busnum,
						       false, &bus));

	/*
	 * i2c_post_bind() will bind devices to chip selects. Check this then
	 * remove the emulation and the slave device.
	 */
	ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
	ut_assertok(dm_i2c_probe(bus, chip, 0, &dev));
	ut_asserteq(-ENODEV, dm_i2c_probe(bus, no_chip, 0, &dev));
	ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_I2C, 1, &bus));

	return 0;
}
DM_TEST(dm_test_i2c_find, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);

static int dm_test_i2c_read_write(struct dm_test_state *dms)
{
	struct udevice *bus, *dev;
	uint8_t buf[5];

	ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
	ut_assertok(i2c_get_chip(bus, chip, 1, &dev));
	ut_assertok(dm_i2c_read(dev, 0, buf, 5));
	ut_assertok(memcmp(buf, "\0\0\0\0\0", sizeof(buf)));
	ut_assertok(dm_i2c_write(dev, 2, (uint8_t *)"AB", 2));
	ut_assertok(dm_i2c_read(dev, 0, buf, 5));
	ut_assertok(memcmp(buf, "\0\0AB\0", sizeof(buf)));

	return 0;
}
DM_TEST(dm_test_i2c_read_write, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);

static int dm_test_i2c_speed(struct dm_test_state *dms)
{
	struct udevice *bus, *dev;
	uint8_t buf[5];

	ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));

	/* Use test mode so we create the required errors for invalid speeds */
	sandbox_i2c_set_test_mode(bus, true);
	ut_assertok(i2c_get_chip(bus, chip, 1, &dev));
	ut_assertok(dm_i2c_set_bus_speed(bus, 100000));
	ut_assertok(dm_i2c_read(dev, 0, buf, 5));
	ut_assertok(dm_i2c_set_bus_speed(bus, 400000));
	ut_asserteq(400000, dm_i2c_get_bus_speed(bus));
	ut_assertok(dm_i2c_read(dev, 0, buf, 5));
	ut_asserteq(-EINVAL, dm_i2c_write(dev, 0, buf, 5));
	sandbox_i2c_set_test_mode(bus, false);

	return 0;
}
DM_TEST(dm_test_i2c_speed, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);

static int dm_test_i2c_offset_len(struct dm_test_state *dms)
{
	struct udevice *bus, *dev;
	uint8_t buf[5];

	ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
	ut_assertok(i2c_get_chip(bus, chip, 1, &dev));
	ut_assertok(i2c_set_chip_offset_len(dev, 1));
	ut_assertok(dm_i2c_read(dev, 0, buf, 5));

	/* This is not supported by the uclass */
	ut_asserteq(-EINVAL, i2c_set_chip_offset_len(dev, 5));

	return 0;
}
DM_TEST(dm_test_i2c_offset_len, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);

static int dm_test_i2c_probe_empty(struct dm_test_state *dms)
{
	struct udevice *bus, *dev;

	ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));

	/* Use test mode so that this chip address will always probe */
	sandbox_i2c_set_test_mode(bus, true);
	ut_assertok(dm_i2c_probe(bus, SANDBOX_I2C_TEST_ADDR, 0, &dev));
	sandbox_i2c_set_test_mode(bus, false);

	return 0;
}
DM_TEST(dm_test_i2c_probe_empty, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);

static int dm_test_i2c_bytewise(struct dm_test_state *dms)
{
	struct udevice *bus, *dev;
	struct udevice *eeprom;
	uint8_t buf[5];

	ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
	ut_assertok(i2c_get_chip(bus, chip, 1, &dev));
	ut_assertok(dm_i2c_read(dev, 0, buf, 5));
	ut_assertok(memcmp(buf, "\0\0\0\0\0", sizeof(buf)));

	/* Tell the EEPROM to only read/write one register at a time */
	ut_assertok(uclass_first_device(UCLASS_I2C_EMUL, &eeprom));
	ut_assertnonnull(eeprom);
	sandbox_i2c_eeprom_set_test_mode(eeprom, SIE_TEST_MODE_SINGLE_BYTE);

	/* Now we only get the first byte - the rest will be 0xff */
	ut_assertok(dm_i2c_read(dev, 0, buf, 5));
	ut_assertok(memcmp(buf, "\0\xff\xff\xff\xff", sizeof(buf)));

	/* If we do a separate transaction for each byte, it works */
	ut_assertok(i2c_set_chip_flags(dev, DM_I2C_CHIP_RD_ADDRESS));
	ut_assertok(dm_i2c_read(dev, 0, buf, 5));
	ut_assertok(memcmp(buf, "\0\0\0\0\0", sizeof(buf)));

	/* This will only write A */
	ut_assertok(i2c_set_chip_flags(dev, 0));
	ut_assertok(dm_i2c_write(dev, 2, (uint8_t *)"AB", 2));
	ut_assertok(dm_i2c_read(dev, 0, buf, 5));
	ut_assertok(memcmp(buf, "\0\xff\xff\xff\xff", sizeof(buf)));

	/* Check that the B was ignored */
	ut_assertok(i2c_set_chip_flags(dev, DM_I2C_CHIP_RD_ADDRESS));
	ut_assertok(dm_i2c_read(dev, 0, buf, 5));
	ut_assertok(memcmp(buf, "\0\0A\0\0\0", sizeof(buf)));

	/* Now write it again with the new flags, it should work */
	ut_assertok(i2c_set_chip_flags(dev, DM_I2C_CHIP_WR_ADDRESS));
	ut_assertok(dm_i2c_write(dev, 2, (uint8_t *)"AB", 2));
	ut_assertok(dm_i2c_read(dev, 0, buf, 5));
	ut_assertok(memcmp(buf, "\0\xff\xff\xff\xff", sizeof(buf)));

	ut_assertok(i2c_set_chip_flags(dev, DM_I2C_CHIP_WR_ADDRESS |
						DM_I2C_CHIP_RD_ADDRESS));
	ut_assertok(dm_i2c_read(dev, 0, buf, 5));
	ut_assertok(memcmp(buf, "\0\0AB\0\0", sizeof(buf)));

	/* Restore defaults */
	sandbox_i2c_eeprom_set_test_mode(eeprom, SIE_TEST_MODE_NONE);
	ut_assertok(i2c_set_chip_flags(dev, 0));

	return 0;
}
DM_TEST(dm_test_i2c_bytewise, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);

static int dm_test_i2c_offset(struct dm_test_state *dms)
{
	struct udevice *eeprom;
	struct udevice *dev;
	uint8_t buf[5];

	ut_assertok(i2c_get_chip_for_busnum(busnum, chip, 1, &dev));

	/* Do a transfer so we can find the emulator */
	ut_assertok(dm_i2c_read(dev, 0, buf, 5));
	ut_assertok(uclass_first_device(UCLASS_I2C_EMUL, &eeprom));

	/* Offset length 0 */
	sandbox_i2c_eeprom_set_offset_len(eeprom, 0);
	ut_assertok(i2c_set_chip_offset_len(dev, 0));
	ut_assertok(dm_i2c_write(dev, 10 /* ignored */, (uint8_t *)"AB", 2));
	ut_assertok(dm_i2c_read(dev, 0, buf, 5));
	ut_assertok(memcmp(buf, "AB\0\0\0\0", sizeof(buf)));

	/* Offset length 1 */
	sandbox_i2c_eeprom_set_offset_len(eeprom, 1);
	ut_assertok(i2c_set_chip_offset_len(dev, 1));
	ut_assertok(dm_i2c_write(dev, 2, (uint8_t *)"AB", 2));
	ut_assertok(dm_i2c_read(dev, 0, buf, 5));
	ut_assertok(memcmp(buf, "ABAB\0", sizeof(buf)));

	/* Offset length 2 */
	sandbox_i2c_eeprom_set_offset_len(eeprom, 2);
	ut_assertok(i2c_set_chip_offset_len(dev, 2));
	ut_assertok(dm_i2c_write(dev, 0x210, (uint8_t *)"AB", 2));
	ut_assertok(dm_i2c_read(dev, 0x210, buf, 5));
	ut_assertok(memcmp(buf, "AB\0\0\0", sizeof(buf)));

	/* Offset length 3 */
	sandbox_i2c_eeprom_set_offset_len(eeprom, 2);
	ut_assertok(i2c_set_chip_offset_len(dev, 2));
	ut_assertok(dm_i2c_write(dev, 0x410, (uint8_t *)"AB", 2));
	ut_assertok(dm_i2c_read(dev, 0x410, buf, 5));
	ut_assertok(memcmp(buf, "AB\0\0\0", sizeof(buf)));

	/* Offset length 4 */
	sandbox_i2c_eeprom_set_offset_len(eeprom, 2);
	ut_assertok(i2c_set_chip_offset_len(dev, 2));
	ut_assertok(dm_i2c_write(dev, 0x420, (uint8_t *)"AB", 2));
	ut_assertok(dm_i2c_read(dev, 0x420, buf, 5));
	ut_assertok(memcmp(buf, "AB\0\0\0", sizeof(buf)));

	/* Restore defaults */
	sandbox_i2c_eeprom_set_offset_len(eeprom, 1);

	return 0;
}
DM_TEST(dm_test_i2c_offset, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
