Add support for ppc shell command with subcommands that can print the status of PPC (dead battery, sinking, sourcing, vbus detected), dump registers and request the PPC to exit dead battery mode. Signed-off-by: Michał Barnaś <mb@semihalf.com>
135 lines
3.8 KiB
C
135 lines
3.8 KiB
C
/*
|
|
* Copyright 2023 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <zephyr/device.h>
|
|
#include <zephyr/shell/shell.h>
|
|
#include <zephyr/drivers/usb_c/usbc_ppc.h>
|
|
|
|
/** Macro used to iterate over USB-C connector and call a function if the node has PPC property */
|
|
#define CALL_IF_HAS_PPC(usb_node, func) \
|
|
COND_CODE_1(DT_NODE_HAS_PROP(usb_node, ppc), \
|
|
(ret |= func(DEVICE_DT_GET(DT_PHANDLE_BY_IDX(usb_node, ppc, 0)));), ())
|
|
|
|
/**
|
|
* @brief Command that dumps registers of one or all of the PPCs
|
|
*
|
|
* @param sh Shell structure
|
|
* @param argc Arguments count
|
|
* @param argv Device name
|
|
* @return int ORed return values of all the functions executed, 0 in case of success
|
|
*/
|
|
static int cmd_ppc_dump(const struct shell *sh, size_t argc, char **argv)
|
|
{
|
|
int ret = 0;
|
|
|
|
if (argc <= 1) {
|
|
DT_FOREACH_STATUS_OKAY_VARGS(usb_c_connector, CALL_IF_HAS_PPC, ppc_dump_regs);
|
|
} else {
|
|
const struct device *dev = device_get_binding(argv[1]);
|
|
|
|
ret = ppc_dump_regs(dev);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Function used to pretty print status of the PPC
|
|
*
|
|
* @param dev Pointer to the PPC device structure
|
|
*/
|
|
static int print_status(const struct device *dev)
|
|
{
|
|
printk("PPC %s:\n", dev->name);
|
|
printk(" Dead battery: %d\n", ppc_is_dead_battery_mode(dev));
|
|
printk(" Is sourcing: %d\n", ppc_is_vbus_source(dev));
|
|
printk(" Is sinking: %d\n", ppc_is_vbus_sink(dev));
|
|
printk(" Is VBUS present: %d\n", ppc_is_vbus_present(dev));
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @brief Command that prints the status of one or all of the PPCs
|
|
*
|
|
* @param sh Shell structure
|
|
* @param argc Arguments count
|
|
* @param argv Device name
|
|
* @return int ORed return values of all the functions executed, 0 in case of success
|
|
*/
|
|
static int cmd_ppc_status(const struct shell *sh, size_t argc, char **argv)
|
|
{
|
|
int ret = 0;
|
|
|
|
if (argc <= 1) {
|
|
DT_FOREACH_STATUS_OKAY_VARGS(usb_c_connector, CALL_IF_HAS_PPC, print_status);
|
|
} else {
|
|
const struct device *dev = device_get_binding(argv[1]);
|
|
|
|
ret = print_status(dev);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Command that requests one or all of the PPCs to try exiting the dead battery mode
|
|
*
|
|
* @param sh Shell structure
|
|
* @param argc Arguments count
|
|
* @param argv Device name
|
|
* @return int ORed return values of all the functions executed, 0 in case of success
|
|
*/
|
|
static int cmd_ppc_exit_db(const struct shell *sh, size_t argc, char **argv)
|
|
{
|
|
int ret = 0;
|
|
|
|
if (argc <= 1) {
|
|
DT_FOREACH_STATUS_OKAY_VARGS(usb_c_connector, CALL_IF_HAS_PPC,
|
|
ppc_exit_dead_battery_mode);
|
|
} else {
|
|
const struct device *dev = device_get_binding(argv[1]);
|
|
|
|
ret = ppc_exit_dead_battery_mode(dev);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Function used to create subcommands with devices names
|
|
*
|
|
* @param idx counter of devices
|
|
* @param entry shell structure that will be filled
|
|
*/
|
|
static void device_name_get(size_t idx, struct shell_static_entry *entry)
|
|
{
|
|
const struct device *dev = shell_device_lookup(idx, NULL);
|
|
|
|
entry->syntax = (dev != NULL) ? dev->name : NULL;
|
|
entry->handler = NULL;
|
|
entry->help = NULL;
|
|
entry->subcmd = NULL;
|
|
}
|
|
|
|
SHELL_DYNAMIC_CMD_CREATE(list_device_names, device_name_get);
|
|
|
|
SHELL_STATIC_SUBCMD_SET_CREATE(sub_ppc_cmds,
|
|
SHELL_CMD_ARG(dump, &list_device_names,
|
|
"Dump PPC registers\n"
|
|
"Usage: ppc dump [<ppc device>]",
|
|
cmd_ppc_dump, 1, 1),
|
|
SHELL_CMD_ARG(status, &list_device_names,
|
|
"Write PPC power status\n"
|
|
"Usage: ppc statuc [<ppc device>]",
|
|
cmd_ppc_status, 1, 1),
|
|
SHELL_CMD_ARG(exitdb, &list_device_names,
|
|
"Exit from the dead battery mode\n"
|
|
"Usage: ppc exitdb [<ppc device>]",
|
|
cmd_ppc_exit_db, 1, 1),
|
|
SHELL_SUBCMD_SET_END);
|
|
|
|
SHELL_CMD_REGISTER(ppc, &sub_ppc_cmds, "PPC (USB-C PD) diagnostics", NULL);
|