summaryrefslogtreecommitdiff
path: root/zephyr/subsys/emul/ap_pwrseq/emul_power_signals.c
diff options
context:
space:
mode:
Diffstat (limited to 'zephyr/subsys/emul/ap_pwrseq/emul_power_signals.c')
-rw-r--r--zephyr/subsys/emul/ap_pwrseq/emul_power_signals.c550
1 files changed, 0 insertions, 550 deletions
diff --git a/zephyr/subsys/emul/ap_pwrseq/emul_power_signals.c b/zephyr/subsys/emul/ap_pwrseq/emul_power_signals.c
deleted file mode 100644
index e8f211bb56..0000000000
--- a/zephyr/subsys/emul/ap_pwrseq/emul_power_signals.c
+++ /dev/null
@@ -1,550 +0,0 @@
-/* Copyright 2022 The ChromiumOS Authors
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "ap_power/ap_power.h"
-#include "ap_power/ap_power_events.h"
-#include "chipset.h"
-#include "emul/emul_power_signals.h"
-#include "power_signals.h"
-#include "test_state.h"
-
-#include <zephyr/drivers/adc.h>
-#include <zephyr/drivers/espi.h>
-#include <zephyr/drivers/espi_emul.h>
-#include <zephyr/drivers/gpio/gpio_emul.h>
-#include <zephyr/kernel.h>
-#include <zephyr/logging/log.h>
-#include <zephyr/ztest.h>
-
-LOG_MODULE_REGISTER(emul_power_signal, CONFIG_EMUL_POWER_SIGNALS_LOG_LEVEL);
-
-/**
- * @brief Power signal source type.
- */
-enum power_signal_emul_source {
- PWR_SIG_EMUL_SRC_GPIO,
- PWR_SIG_EMUL_SRC_VW,
- PWR_SIG_EMUL_SRC_EXT,
- PWR_SIG_EMUL_SRC_ADC,
-};
-
-/**
- * @brief Power signal containers definition.
- */
-union power_signal_emul_signal_spec {
- struct gpio_dt_spec gpio;
- struct adc_dt_spec adc;
-};
-
-/**
- * @brief Power signal descriptor.
- */
-struct power_signal_emul_signal_desc {
- const enum power_signal enum_id;
- const char *name;
- const enum power_signal_emul_source source;
- const union power_signal_emul_signal_spec spec;
-};
-
-/**
- * @brief Power signal output definition.
- */
-struct power_signal_emul_output {
- struct power_signal_emul_signal_desc desc;
- const int assert_value;
- const int assert_delay_ms;
- const int deassert_value;
- const int deassert_delay_ms;
- const int init_value;
- const bool retain;
- const bool invert;
- struct k_work_delayable d_work;
- int value;
-};
-
-enum power_signal_edge {
- EDGE_ACTIVE_ON_ASSERT,
- EDGE_ACTIVE_ON_DEASSERT,
- EDGE_ACTIVE_ON_BOTH,
-};
-
-/**
- * @brief Power signal input definition.
- */
-struct power_signal_emul_input {
- struct power_signal_emul_signal_desc desc;
- const int assert_value;
- const int init_value;
- const bool retain;
- const enum power_signal_edge edge;
- struct gpio_callback cb;
- int value;
-};
-
-/**
- * @brief Power signal node definition,
- * One node contains at least one input signal and one or more output
- * signals.
- */
-struct power_signal_emul_node {
- const char *name;
- struct power_signal_emul_input input;
- const int outputs_count;
- struct power_signal_emul_output *const outputs;
-};
-
-#define EMUL_POWER_SIGNAL_GET_SOURCE(inst) \
- COND_CODE_1( \
- DT_NODE_HAS_COMPAT(inst, intel_ap_pwrseq_gpio), \
- (PWR_SIG_EMUL_SRC_GPIO), \
- (COND_CODE_1( \
- DT_NODE_HAS_COMPAT(inst, intel_ap_pwrseq_vw), \
- (PWR_SIG_EMUL_SRC_VW), \
- (COND_CODE_1(DT_NODE_HAS_COMPAT( \
- inst, intel_ap_pwrseq_external), \
- (PWR_SIG_EMUL_SRC_EXT), \
- (PWR_SIG_EMUL_SRC_ADC))))))
-
-#define EMUL_POWER_SIGNAL_GET_SIGNAL_SPEC(inst, dir_signal) \
- { \
- COND_CODE_1(DT_NODE_HAS_COMPAT(DT_PROP(inst, dir_signal), \
- intel_ap_pwrseq_gpio), \
- (.gpio = GPIO_DT_SPEC_GET( \
- DT_PROP(inst, dir_signal), gpios)), \
- ()) \
- }
-
-#define EMUL_POWER_SIGNAL_GET_SIGNAL(inst, dir) \
- { \
- .enum_id = PWR_SIGNAL_ENUM(DT_PROP(inst, dir)), \
- .name = DT_PROP(DT_PROP(inst, dir), enum_name), \
- .source = EMUL_POWER_SIGNAL_GET_SOURCE(DT_PROP(inst, dir)), \
- .spec = EMUL_POWER_SIGNAL_GET_SIGNAL_SPEC(inst, dir), \
- }
-
-#define EMUL_POWER_SIGNAL_IN_DEF(inst) \
- { \
- .desc = EMUL_POWER_SIGNAL_GET_SIGNAL(inst, input_signal), \
- .assert_value = DT_PROP(inst, assert_value), \
- .init_value = DT_PROP_OR(inst, init_value, 0), \
- .edge = DT_STRING_TOKEN(inst, edge), \
- .retain = !DT_NODE_HAS_PROP(inst, init_value), \
- }
-
-#define EMUL_POWER_SIGNAL_OUT_DEF(inst) \
- { \
- .desc = EMUL_POWER_SIGNAL_GET_SIGNAL(inst, output_signal), \
- .assert_value = DT_PROP(inst, assert_value), \
- .assert_delay_ms = DT_PROP(inst, assert_delay_ms), \
- .deassert_value = DT_PROP(inst, deassert_value), \
- .deassert_delay_ms = DT_PROP(inst, deassert_delay_ms), \
- .init_value = DT_PROP_OR(inst, init_value, 0), \
- .retain = !DT_NODE_HAS_PROP(inst, init_value), \
- .invert = DT_PROP(inst, invert_value), \
- },
-
-#define EMUL_POWER_SIGNAL_OUT_ARRAY_DEF(inst) \
- static struct power_signal_emul_output DT_CAT(inst, _output)[] = { \
- DT_FOREACH_CHILD_STATUS_OKAY(inst, EMUL_POWER_SIGNAL_OUT_DEF) \
- };
-
-#define EMUL_POWER_SIGNAL_GET_INPUT_ENUM(inst) ENUM_##inst##_OUTPUT,
-
-#define EMUL_POWER_SIGNAL_NODES_DEF(inst) \
- enum { \
- DT_FOREACH_CHILD_STATUS_OKAY(inst, \
- EMUL_POWER_SIGNAL_GET_INPUT_ENUM) \
- DT_CAT(inst, _OUTPUT_COUNT), \
- }; \
- __COND_CODE(IS_EQ(DT_CAT(inst, _OUTPUT_COUNT), 0), (), \
- (EMUL_POWER_SIGNAL_OUT_ARRAY_DEF(inst))) \
- static struct power_signal_emul_node DT_CAT(inst, _node) = { \
- .name = DT_NODE_FULL_NAME(inst), \
- .input = EMUL_POWER_SIGNAL_IN_DEF(inst), \
- .outputs_count = inst##_OUTPUT_COUNT, \
- .outputs = __COND_CODE(IS_EQ(DT_CAT(inst, _OUTPUT_COUNT), 0), \
- (NULL), (DT_CAT(inst, _output))), \
- };
-
-DT_FOREACH_STATUS_OKAY(intel_ap_pwr_signal_emul, EMUL_POWER_SIGNAL_NODES_DEF)
-
-#define EMUL_POWER_SIGNAL_NODES_ARRAY_GET_NODES_REFS_WITH_COMMA(inst) \
- (&DT_CAT(inst, _node)),
-
-#define EMUL_POWER_SIGNAL_NODES_ARRAY_GET_NODES_REFS(inst) \
- EMUL_POWER_SIGNAL_NODES_ARRAY_GET_NODES_REFS_WITH_COMMA(inst)
-
-#define EMUL_POWER_SIGNAL_NODES_ARRAY_GET_IO_SIGNALS(inst, prop, idx) \
- EMUL_POWER_SIGNAL_NODES_ARRAY_GET_NODES_REFS( \
- DT_PHANDLE_BY_IDX(inst, prop, idx))
-
-#define EMUL_POWER_SIGNAL_NODES_ARRAY_DEF(inst) \
- static struct power_signal_emul_node *DT_CAT(inst, _nodes)[] = { \
- DT_FOREACH_PROP_ELEM( \
- inst, nodes, \
- EMUL_POWER_SIGNAL_NODES_ARRAY_GET_IO_SIGNALS) \
- };
-
-DT_FOREACH_STATUS_OKAY(intel_ap_pwr_test_platform,
- EMUL_POWER_SIGNAL_NODES_ARRAY_DEF)
-
-#define EMUL_POWER_SIGNAL_TEST_PLATFORM_GET_NODES_REFS_ITEM(inst) \
- DT_CAT(inst, _nodes),
-
-#define EMUL_POWER_SIGNAL_TEST_PLATFORM_GET_NODES_REFS(inst) \
- EMUL_POWER_SIGNAL_TEST_PLATFORM_GET_NODES_REFS_ITEM(inst)
-
-#define EMUL_POWER_SIGNAL_TEST_PLATFORM_GET_IO_SIGNALS(inst, prop, idx) \
- EMUL_POWER_SIGNAL_TEST_PLATFORM_GET_NODES_REFS( \
- DT_PHANDLE_BY_IDX(inst, prop, idx))
-
-#define EMUL_POWER_SIGNAL_TEST_PLATFORM_GET_NODES(inst) \
- { \
- DT_FOREACH_PROP_ELEM( \
- inst, nodes, \
- EMUL_POWER_SIGNAL_TEST_PLATFORM_GET_IO_SIGNALS) \
- }
-
-#define EMUL_POWER_SIGNAL_TEST_PLATFORM_DEF(inst) \
- const struct power_signal_emul_test_platform inst = { \
- .name_id = DT_NODE_FULL_NAME(inst), \
- .nodes_count = DT_PROP_LEN(inst, nodes), \
- .nodes = DT_CAT(inst, _nodes), \
- };
-
-DT_FOREACH_STATUS_OKAY(intel_ap_pwr_test_platform,
- EMUL_POWER_SIGNAL_TEST_PLATFORM_DEF)
-
-static K_KERNEL_STACK_DEFINE(work_q_stack,
- CONFIG_EMUL_POWER_SIGNALS_WORK_QUEUE_STACK_SIZE);
-
-struct k_work_q work_q;
-
-static const struct power_signal_emul_test_platform *cur_test_platform;
-
-static bool emul_ready;
-
-/**
- * @brief Set GPIO type power signal to specified value.
- *
- * @param spec Pointer to container for GPIO pin information specified in
- * devicetree.
- * @param value Value to be set on GPIO.
- */
-static void power_signal_emul_set_gpio_value(const struct gpio_dt_spec *spec,
- int value)
-{
- gpio_flags_t gpio_flags;
- int ret;
-
- ret = gpio_emul_flags_get(spec->port, spec->pin, &gpio_flags);
- zassert_ok(ret, "Getting GPIO flags!!");
-
- if (gpio_flags & GPIO_INPUT) {
- ret = gpio_emul_input_set(spec->port, spec->pin, value);
- } else if (gpio_flags & GPIO_OUTPUT) {
- ret = gpio_pin_set(spec->port, spec->pin, value);
- }
- zassert_ok(ret, "Setting GPIO value!!");
-}
-
-/**
- * @brief Set power signal to specified value.
- *
- * @param desc Pointer to power signal descriptor.
- * @param value Value to be set on power signal.
- */
-static void
-power_signal_emul_set_value(struct power_signal_emul_signal_desc *desc,
- int value)
-{
- LOG_DBG("Set Signal %s -> %d", desc->name, value);
-
- switch (desc->source) {
- case PWR_SIG_EMUL_SRC_GPIO:
- power_signal_emul_set_gpio_value(&desc->spec.gpio, !!value);
- break;
-
- case PWR_SIG_EMUL_SRC_EXT:
- zassert_ok(power_signal_set(desc->enum_id, value),
- "Setting %s Signal value!!", desc->name);
- __fallthrough;
-
- case PWR_SIG_EMUL_SRC_VW:
- power_signal_interrupt(desc->enum_id, value);
- break;
-
- default:
- zassert_unreachable("Undefined Signal %s!!", desc->name);
- }
-}
-
-/**
- * @brief Get GPIO type power signal value.
- *
- * @param spec Pointer to container for GPIO pin information specified in
- * devicetree.
- *
- * @return GPIO type power signal value.
- */
-static int power_signal_emul_get_gpio_value(const struct gpio_dt_spec *spec)
-{
- gpio_flags_t gpio_flags;
- int ret;
-
- ret = gpio_emul_flags_get(spec->port, spec->pin, &gpio_flags);
- zassert_ok(ret, "Getting GPIO flags!!");
-
- if (gpio_flags & GPIO_INPUT) {
- ret = gpio_pin_get(spec->port, spec->pin);
- } else if (gpio_flags & GPIO_OUTPUT) {
- ret = gpio_emul_output_get(spec->port, spec->pin);
- }
-
- return ret;
-}
-
-/**
- * @brief Get power signal value.
- *
- * @param desc Pointer to power signal descriptor.
- *
- * @return Power signal value.
- */
-static int
-power_signal_emul_get_value(struct power_signal_emul_signal_desc *desc)
-{
- int ret;
-
- if (desc->source == PWR_SIG_EMUL_SRC_GPIO) {
- ret = power_signal_emul_get_gpio_value(&desc->spec.gpio);
- } else {
- ret = power_signal_get(desc->enum_id);
- }
-
- return ret;
-}
-
-/**
- * @brief Handle GPIO type power signal interrupt.
- *
- * @param port Pointer to GPIO device.
- * @param cb Original struct gpio_callback owning this handler.
- * @param pins Mask of pins that triggers the callback handler.
- */
-static void emul_power_signal_gpio_interrupt(const struct device *port,
- struct gpio_callback *cb,
- gpio_port_pins_t pins)
-{
- struct power_signal_emul_input *in_signal =
- CONTAINER_OF(cb, struct power_signal_emul_input, cb);
- struct power_signal_emul_node *node =
- CONTAINER_OF(in_signal, struct power_signal_emul_node, input);
- int value;
- int delay;
-
- value = power_signal_emul_get_value(&in_signal->desc);
- if (value == in_signal->value) {
- return;
- }
-
- in_signal->value = value;
-
- if (!emul_ready) {
- return;
- }
-
- if (in_signal->edge == EDGE_ACTIVE_ON_DEASSERT &&
- value == in_signal->assert_value) {
- return;
- } else if (in_signal->edge == EDGE_ACTIVE_ON_ASSERT &&
- value != in_signal->assert_value) {
- return;
- }
-
- LOG_DBG("INT: Set Signal %s -> %d", in_signal->desc.name, value);
- for (int i = 0; i < node->outputs_count; i++) {
- struct power_signal_emul_output *out_signal = &node->outputs[i];
-
- out_signal->value = (value == in_signal->assert_value) ^
- out_signal->invert ?
- out_signal->assert_value :
- out_signal->deassert_value;
-
- delay = (value == in_signal->assert_value) ?
- out_signal->assert_delay_ms :
- out_signal->deassert_delay_ms;
-
- LOG_DBG("INT: Delay Signal %s", out_signal->desc.name);
- k_work_schedule_for_queue(&work_q, &out_signal->d_work,
- K_MSEC(delay));
- }
-}
-
-/**
- * @brief Handle power signal delayed work.
- *
- * This will set power signal value accordingly.
- *
- * @param work Pointer to work structure.
- */
-static void emul_signal_work_hanlder(struct k_work *work)
-{
- struct k_work_delayable *d_work = k_work_delayable_from_work(work);
- struct power_signal_emul_output *out_signal =
- CONTAINER_OF(d_work, struct power_signal_emul_output, d_work);
-
- power_signal_emul_set_value(&out_signal->desc, out_signal->value);
-}
-
-/**
- * @brief Initialize power signal emulator node.
- *
- * This will enable corresponding initiator power signal interruption and
- * its handler's power signals work structures.
- *
- * @param node Pointer to node containing power signals.
- */
-static int power_signal_init_node(struct power_signal_emul_node *node)
-{
- struct power_signal_emul_input *in_signal = &node->input;
- struct power_signal_emul_output *out_signal;
-
- if (!node->outputs_count) {
- LOG_ERR("Node does not have output signal!!");
- return -EINVAL;
- }
-
- LOG_DBG("Initializing node: %s", node->name);
- for (int i = 0; i < node->outputs_count; i++) {
- out_signal = &node->outputs[i];
-
- if (out_signal->retain) {
- out_signal->value =
- power_signal_emul_get_value(&out_signal->desc);
- } else {
- /* Not retaining previous value, override */
- power_signal_emul_set_value(&out_signal->desc,
- out_signal->init_value);
- out_signal->value = out_signal->init_value;
- }
- k_work_init_delayable(&out_signal->d_work,
- emul_signal_work_hanlder);
- }
-
- if (in_signal->retain) {
- in_signal->value =
- power_signal_emul_get_value(&in_signal->desc);
- } else {
- /* Not retaining previous value, override */
- power_signal_emul_set_value(&in_signal->desc,
- in_signal->init_value);
- in_signal->value = in_signal->init_value;
- }
- if (in_signal->desc.source == PWR_SIG_EMUL_SRC_GPIO) {
- gpio_init_callback(&in_signal->cb,
- emul_power_signal_gpio_interrupt,
- BIT(in_signal->desc.spec.gpio.pin));
-
- gpio_add_callback(in_signal->desc.spec.gpio.port,
- &in_signal->cb);
-
- gpio_pin_interrupt_configure_dt(&in_signal->desc.spec.gpio,
- GPIO_INT_EDGE_BOTH);
- }
- return 0;
-}
-
-/** See description in emul_power_signals.h */
-int power_signal_emul_load(
- const struct power_signal_emul_test_platform *test_platform)
-{
- int ret;
-
- if (cur_test_platform) {
- LOG_ERR("Power Signal Emulator Busy!!");
- return -EBUSY;
- }
-
- cur_test_platform = test_platform;
-
- LOG_DBG("Loading Emulator test: %s", cur_test_platform->name_id);
-
- for (int i = 0; i < cur_test_platform->nodes_count; i++) {
- ret = power_signal_init_node(cur_test_platform->nodes[i]);
- if (ret) {
- power_signal_emul_unload();
- return ret;
- }
- }
-
- emul_ready = true;
- LOG_DBG("Loading Emulator test Done");
- return 0;
-}
-
-/** See description in emul_power_signals.h */
-int power_signal_emul_unload(void)
-{
- struct power_signal_emul_node *node;
- struct power_signal_emul_output *out_signal;
- struct power_signal_emul_input *in_signal;
-
- if (!cur_test_platform) {
- LOG_ERR("No Test Platform Loaded!!");
- return -EINVAL;
- }
-
- emul_ready = false;
- for (int i = 0; i < cur_test_platform->nodes_count; i++) {
- node = cur_test_platform->nodes[i];
- in_signal = &node->input;
-
- if (in_signal->desc.source != PWR_SIG_EMUL_SRC_GPIO) {
- /* Currently, Only output GPIO signals are supported */
- continue;
- }
-
- for (int j = 0; j < node->outputs_count; j++) {
- static struct k_work_sync work_sync;
-
- out_signal = &node->outputs[j];
- k_work_cancel_delayable_sync(&out_signal->d_work,
- &work_sync);
- }
- gpio_pin_interrupt_configure_dt(&in_signal->desc.spec.gpio,
- GPIO_INT_DISABLE);
- if (in_signal->cb.handler) {
- gpio_remove_callback(in_signal->desc.spec.gpio.port,
- &in_signal->cb);
- }
- }
- cur_test_platform = NULL;
- return 0;
-}
-
-/**
- * @brief Initialize power signal emulator internal work queue.
- *
- * @param dev Unused parameter.
- *
- * @return 0 Return success only.
- */
-static int power_signal_emul_work_q_init(const struct device *dev)
-{
- ARG_UNUSED(dev);
- struct k_work_queue_config cfg = {
- .name = "psignal_emul",
- .no_yield = true,
- };
-
- k_work_queue_start(&work_q, work_q_stack,
- K_KERNEL_STACK_SIZEOF(work_q_stack),
- CONFIG_EMUL_POWER_SIGNALS_WORK_QUEUE_PRIO, &cfg);
- return 0;
-}
-
-SYS_INIT(power_signal_emul_work_q_init, POST_KERNEL,
- CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);