// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright 2021 Google LLC
 */

#include <cros_ec.h>
#include <dm.h>
#include <asm/test.h>
#include <dm/test.h>
#include <test/ut.h>

static int dm_test_cros_ec_hello(struct unit_test_state *uts)
{
	struct udevice *dev;
	uint val;

	ut_assertok(uclass_first_device_err(UCLASS_CROS_EC, &dev));

	ut_assertok(cros_ec_hello(dev, NULL));

	val = 0xdead1357;
	ut_assertok(cros_ec_hello(dev, &val));
	ut_asserteq(0xdead1357, val);

	sandbox_cros_ec_set_test_flags(dev, CROSECT_BREAK_HELLO);
	ut_asserteq(-ENOTSYNC, cros_ec_hello(dev, &val));
	ut_asserteq(0x12345678, val);

	return 0;
}
DM_TEST(dm_test_cros_ec_hello, UTF_SCAN_FDT);

static int dm_test_cros_ec_sku_id(struct unit_test_state *uts)
{
	struct udevice *dev;

	ut_assertok(uclass_first_device_err(UCLASS_CROS_EC, &dev));
	ut_asserteq(1234, cros_ec_get_sku_id(dev));

	/* try the command */
	ut_assertok(run_command("crosec sku", 0));
	ut_assert_nextline("1234");
	ut_assert_console_end();

	return 0;
}
DM_TEST(dm_test_cros_ec_sku_id, UTF_SCAN_FDT | UTF_CONSOLE);

static int dm_test_cros_ec_features(struct unit_test_state *uts)
{
	struct udevice *dev;
	u64 feat;

	ut_assertok(uclass_first_device_err(UCLASS_CROS_EC, &dev));
	ut_assertok(cros_ec_get_features(dev, &feat));
	ut_asserteq_64(1U << EC_FEATURE_FLASH | 1U << EC_FEATURE_I2C |
		1u << EC_FEATURE_VSTORE |
		1ULL << EC_FEATURE_UNIFIED_WAKE_MASKS | 1ULL << EC_FEATURE_ISH,
		feat);

	ut_asserteq(true, cros_ec_check_feature(dev, EC_FEATURE_I2C));
	ut_asserteq(false, cros_ec_check_feature(dev, EC_FEATURE_MOTION_SENSE));
	ut_asserteq(true, cros_ec_check_feature(dev, EC_FEATURE_ISH));

	/* try the command */
	ut_assertok(run_command("crosec features", 0));
	ut_assert_nextline("flash");
	ut_assert_nextline("i2c");
	ut_assert_nextline("vstore");
	ut_assert_nextline("unified_wake_masks");
	ut_assert_nextline("ish");
	ut_assert_console_end();

	return 0;
}
DM_TEST(dm_test_cros_ec_features, UTF_SCAN_FDT | UTF_CONSOLE);

static int dm_test_cros_ec_switches(struct unit_test_state *uts)
{
	struct udevice *dev;

	ut_assertok(uclass_first_device_err(UCLASS_CROS_EC, &dev));
	ut_asserteq(0, cros_ec_get_switches(dev));

	/* try the command */
	ut_assertok(run_command("crosec switches", 0));
	ut_assert_console_end();

	/* Open the lid and check the switch changes */
	sandbox_cros_ec_set_test_flags(dev, CROSECT_LID_OPEN);
	ut_asserteq(EC_SWITCH_LID_OPEN, cros_ec_get_switches(dev));

	/* try the command */
	ut_assertok(run_command("crosec switches", 0));
	ut_assert_nextline("lid open");
	ut_assert_console_end();

	return 0;
}
DM_TEST(dm_test_cros_ec_switches, UTF_SCAN_FDT | UTF_CONSOLE);

static int dm_test_cros_ec_events(struct unit_test_state *uts)
{
	struct udevice *dev;
	u32 events;

	ut_assertok(uclass_first_device_err(UCLASS_CROS_EC, &dev));
	ut_assertok(cros_ec_get_host_events(dev, &events));
	ut_asserteq(0, events);

	/* try the command */
	ut_assertok(run_command("crosec events", 0));
	ut_assert_nextline("00000000");
	ut_assert_console_end();

	/* Open the lid and check the event appears */
	sandbox_cros_ec_set_test_flags(dev, CROSECT_LID_OPEN);
	ut_assertok(cros_ec_get_host_events(dev, &events));
	ut_asserteq(EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN), events);

	/* try the command */
	ut_assertok(run_command("crosec events", 0));
	ut_assert_nextline("00000002");
	ut_assert_nextline("lid_open");
	ut_assert_console_end();

	/* Clear the event */
	ut_assertok(cros_ec_clear_host_events(dev,
		EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN)));
	ut_assertok(cros_ec_get_host_events(dev, &events));
	ut_asserteq(0, events);

	return 0;
}
DM_TEST(dm_test_cros_ec_events, UTF_SCAN_FDT | UTF_CONSOLE);

static int dm_test_cros_ec_vstore(struct unit_test_state *uts)
{
	const int size = EC_VSTORE_SLOT_SIZE;
	u8 test_data[size], data[size];
	struct udevice *dev;
	u32 locked;
	int i;

	ut_assertok(uclass_first_device_err(UCLASS_CROS_EC, &dev));
	ut_asserteq(true, cros_ec_vstore_supported(dev));

	ut_asserteq(4, cros_ec_vstore_info(dev, &locked));
	ut_asserteq(0, locked);

	/* Write some data */
	for (i = 0; i < size; i++)
		test_data[i] = ' ' + i;
	ut_assertok(cros_ec_vstore_write(dev, 2, test_data, size));

	/* Check it is locked */
	ut_asserteq(4, cros_ec_vstore_info(dev, &locked));
	ut_asserteq(1 << 2, locked);

	/* Read it back and compare */
	ut_assertok(cros_ec_vstore_read(dev, 2, data));
	ut_asserteq_mem(test_data, data, size);

	/* Try another slot to make sure it is empty */
	ut_assertok(cros_ec_vstore_read(dev, 0, data));
	for (i = 0; i < size; i++)
		ut_asserteq(0, data[i]);

	return 0;
}
DM_TEST(dm_test_cros_ec_vstore, UTF_SCAN_FDT);
