blob: 5642bd664a6d0d04b975f58d14019cd8a347205e [file] [log] [blame]
/*
* Copyright (c) 2022 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* Verify SMBUS Basic API, tests should work on any board
*/
#include <zephyr/kernel.h>
#include <zephyr/ztest.h>
#include <zephyr/drivers/smbus.h>
#include <smbus_utils.h>
BUILD_ASSERT(DT_NODE_HAS_STATUS(DT_NODELABEL(smbus0), okay),
"SMBus node is disabled!");
#define FAKE_ADDRESS 0x10
/**
* The test is run in userspace only if CONFIG_USERSPACE option is
* enabled, otherwise it is the same as ZTEST()
*/
ZTEST_USER(test_smbus_general, test_smbus_basic_api)
{
const struct device *const dev = DEVICE_DT_GET(DT_NODELABEL(smbus0));
uint32_t cfg = SMBUS_MODE_CONTROLLER;
uint32_t cfg_tmp;
int ret;
zassert_true(device_is_ready(dev), "Device is not ready");
ret = smbus_configure(dev, cfg);
zassert_ok(ret, "SMBUS config failed");
ret = smbus_get_config(dev, &cfg_tmp);
zassert_ok(ret, "SMBUS get_config failed");
zassert_equal(cfg, cfg_tmp, "get_config returned invalid config");
}
/**
* The test is run in userspace only if CONFIG_USERSPACE option is
* enabled, otherwise it is the same as ZTEST()
*/
ZTEST_USER(test_smbus_general, test_smbus_smbalert_api)
{
const struct device *const dev = DEVICE_DT_GET(DT_NODELABEL(smbus0));
void *dummy; /* For the dummy function pointer use this */
int ret;
/* Note! Only for test using stack variables to ease userspace tests */
struct smbus_callback callback = {
.handler = (void *)&dummy,
.addr = FAKE_ADDRESS,
};
zassert_true(device_is_ready(dev), "Device is not ready");
/* Smbalert callbacks */
/* Try to remove not existing callback */
ret = smbus_smbalert_remove_cb(dev, &callback);
if (IS_ENABLED(CONFIG_SMBUS_INTEL_PCH_SMBALERT)) {
zassert_equal(ret, -ENOENT, "Callback remove failed");
} else {
zassert_equal(ret, -ENOSYS, "Check for ENOSYS failed");
}
/* Set callback */
ret = smbus_smbalert_set_cb(dev, &callback);
if (IS_ENABLED(CONFIG_SMBUS_INTEL_PCH_SMBALERT)) {
zassert_ok(ret, "Callback set failed");
} else {
zassert_equal(ret, -ENOSYS, "Check for ENOSYS failed");
}
/* Remove existing callback */
ret = smbus_smbalert_remove_cb(dev, &callback);
if (IS_ENABLED(CONFIG_SMBUS_INTEL_PCH_SMBALERT)) {
zassert_ok(ret, "Callback remove failed");
} else {
zassert_equal(ret, -ENOSYS, "Check for ENOSYS failed");
}
}
/**
* The test is run in userspace only if CONFIG_USERSPACE option is
* enabled, otherwise it is the same as ZTEST()
*/
ZTEST_USER(test_smbus_general, test_smbus_host_notify_api)
{
const struct device *const dev = DEVICE_DT_GET(DT_NODELABEL(smbus0));
void *dummy; /* For the dummy function pointer use this */
int ret;
/* Note! Only for test using stack variables to ease userspace tests */
struct smbus_callback callback = {
.handler = (void *)&dummy,
.addr = FAKE_ADDRESS,
};
zassert_true(device_is_ready(dev), "Device is not ready");
/* Host Notify callbacks */
/* Try to remove not existing callback */
ret = smbus_host_notify_remove_cb(dev, &callback);
if (IS_ENABLED(CONFIG_SMBUS_INTEL_PCH_HOST_NOTIFY)) {
zassert_equal(ret, -ENOENT, "Callback remove failed");
} else {
zassert_equal(ret, -ENOSYS, "Check for ENOSYS failed");
}
/* Set callback */
ret = smbus_host_notify_set_cb(dev, &callback);
if (IS_ENABLED(CONFIG_SMBUS_INTEL_PCH_HOST_NOTIFY)) {
zassert_ok(ret, "Callback set failed");
} else {
zassert_equal(ret, -ENOSYS, "Check for ENOSYS failed");
}
/* Remove existing callback */
ret = smbus_host_notify_remove_cb(dev, &callback);
if (IS_ENABLED(CONFIG_SMBUS_INTEL_PCH_HOST_NOTIFY)) {
zassert_ok(ret, "Callback remove failed");
} else {
zassert_equal(ret, -ENOSYS, "Check for ENOSYS failed");
}
}
/**
* The test is run in userspace only if CONFIG_USERSPACE option is
* enabled, otherwise it is the same as ZTEST()
*/
ZTEST_USER(test_smbus_general, test_smbus_api_errors)
{
const struct device *const dev = DEVICE_DT_GET(DT_NODELABEL(smbus0));
uint8_t fake_addr = 0x10;
uint8_t buf[2];
int ret;
zassert_true(device_is_ready(dev), "Device is not ready");
/* Test parsing SMBus quick */
ret = smbus_quick(dev, fake_addr, 3);
zassert_equal(ret, -EINVAL, "Wrong parameter check failed");
/* Test parsing SMBus block_write */
ret = smbus_block_write(dev, fake_addr, 0, 0, buf);
zassert_equal(ret, -EINVAL, "Wrong parameter check failed");
ret = smbus_block_write(dev, fake_addr, 0, SMBUS_BLOCK_BYTES_MAX + 1,
buf);
zassert_equal(ret, -EINVAL, "Wrong parameter check failed");
}
/* Setup is needed for userspace access */
static void *smbus_test_setup(void)
{
const struct device *const dev = DEVICE_DT_GET(DT_NODELABEL(smbus0));
zassert_true(device_is_ready(dev), "Device is not ready");
k_object_access_grant(dev, k_current_get());
return NULL;
}
ZTEST_SUITE(test_smbus_general, NULL, smbus_test_setup, NULL, NULL, NULL);