summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Chase <jnchase@google.com>2020-08-13 22:14:27 -0400
committerCommit Bot <commit-bot@chromium.org>2020-08-18 15:24:15 +0000
commitb2c401063dcb61031eaf127d36ed97b31bdd0fc7 (patch)
treeae961ecfbc32291bb4ad17de472557a10f5706a4
parenteb511fa00b6da4a8b1a1601978da7dd5f578b560 (diff)
downloadchrome-ec-b2c401063dcb61031eaf127d36ed97b31bdd0fc7.tar.gz
endeavour: add pse host command
This will allow userspace to turn PoE ports off and on. BUG=b:163786867 TEST=manual BRANCH=none Change-Id: Ib9716c5ebc6806f79c8cf85843b93d8c1ff0cba3 Signed-off-by: Jeff Chase <jnchase@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2354544 Reviewed-by: Ting Shen <phoenixshen@chromium.org>
-rw-r--r--board/endeavour/pse.c96
-rw-r--r--include/ec_commands.h27
2 files changed, 116 insertions, 7 deletions
diff --git a/board/endeavour/pse.c b/board/endeavour/pse.c
index ad481b46da..cce1a104b1 100644
--- a/board/endeavour/pse.c
+++ b/board/endeavour/pse.c
@@ -12,6 +12,7 @@
#include "console.h"
#include "ec_commands.h"
#include "hooks.h"
+#include "host_command.h"
#include "i2c.h"
#include "string.h"
#include "timer.h"
@@ -20,10 +21,13 @@
#define LTC4291_I2C_ADDR 0x2C
#define LTC4291_REG_SUPEVN_COR 0x0B
+#define LTC4291_REG_STATPWR 0x10
#define LTC4291_REG_STATPIN 0x11
#define LTC4291_REG_OPMD 0x12
#define LTC4291_REG_DISENA 0x13
#define LTC4291_REG_DETENA 0x14
+#define LTC4291_REG_DETPB 0x18
+#define LTC4291_REG_PWRPB 0x19
#define LTC4291_REG_RSTPB 0x1A
#define LTC4291_REG_ID 0x1B
#define LTC4291_REG_DEVID 0x43
@@ -31,10 +35,16 @@
#define LTC4291_REG_HPMD2 0x4B
#define LTC4291_REG_HPMD3 0x50
#define LTC4291_REG_HPMD4 0x55
+#define LTC4291_REG_LPWRPB 0x6E
#define LTC4291_FLD_STATPIN_AUTO BIT(0)
#define LTC4291_FLD_RSTPB_RSTALL BIT(4)
+#define LTC4291_STATPWR_ON_PORT(port) (0x01 << (port))
+#define LTC4291_DETENA_EN_PORT(port) (0x11 << (port))
+#define LTC4291_DETPB_EN_PORT(port) (0x11 << (port))
+#define LTC4291_PWRPB_OFF_PORT(port) (0x10 << (port))
+
#define LTC4291_OPMD_AUTO 0xFF
#define LTC4291_DISENA_ALL 0x0F
#define LTC4291_DETENA_ALL 0xFF
@@ -43,7 +53,9 @@
#define LTC4291_HPMD_MIN 0x00
#define LTC4291_HPMD_MAX 0xA8
-#define LTC4291_RESET_DELAY_US 20000
+#define LTC4291_PORT_MAX 4
+
+#define LTC4291_RESET_DELAY_US (20 * MSEC)
#define I2C_PSE_READ(reg, data) \
i2c_read8(I2C_PORT_PSE, LTC4291_I2C_ADDR, LTC4291_REG_##reg, (data))
@@ -80,6 +92,18 @@ static int pse_port_hpmd[4] = {
LTC4291_HPMD_MIN,
};
+static int pse_port_enable(int port)
+{
+ /* Enable detection and classification */
+ return I2C_PSE_WRITE(DETPB, LTC4291_DETPB_EN_PORT(port));
+}
+
+static int pse_port_disable(int port)
+{
+ /* Request power off (this also disables detection/classification) */
+ return I2C_PSE_WRITE(PWRPB, LTC4291_PWRPB_OFF_PORT(port));
+}
+
static int pse_init_worker(void)
{
timestamp_t deadline;
@@ -117,7 +141,7 @@ static int pse_init_worker(void)
return err;
/* Set maximum power each port is allowed to allocate. */
- for (port = 0; port < 4; port++) {
+ for (port = 0; port < LTC4291_PORT_MAX; port++) {
err = pse_write_hpmd(port, pse_port_hpmd[port]);
if (err != 0)
return err;
@@ -164,18 +188,76 @@ static int command_pse(int argc, char **argv)
return EC_ERROR_PARAM_COUNT;
port = atoi(argv[1]);
- if (port < 1 || port > 4)
+ if (port < 0 || port >= LTC4291_PORT_MAX)
return EC_ERROR_PARAM1;
if (!strncmp(argv[2], "off", 3))
- return EC_ERROR_UNIMPLEMENTED;
+ return pse_port_disable(port);
+ else if (!strncmp(argv[2], "on", 2))
+ return pse_port_enable(port);
else if (!strncmp(argv[2], "min", 3))
- return pse_write_hpmd(port - 1, LTC4291_HPMD_MIN);
+ return pse_write_hpmd(port, LTC4291_HPMD_MIN);
else if (!strncmp(argv[2], "max", 3))
- return pse_write_hpmd(port - 1, LTC4291_HPMD_MAX);
+ return pse_write_hpmd(port, LTC4291_HPMD_MAX);
else
return EC_ERROR_PARAM2;
}
DECLARE_CONSOLE_COMMAND(pse, command_pse,
- "<port# 1-4> <off | min | max>",
+ "<port# 0-3> <off | on | min | max>",
"Set PSE port power");
+
+static int ec_command_pse_status(int port, uint8_t *status)
+{
+ int detena, statpwr;
+ int err;
+
+ err = I2C_PSE_READ(DETENA, &detena);
+ if (err != 0)
+ return err;
+
+ err = I2C_PSE_READ(STATPWR, &statpwr);
+ if (err != 0)
+ return err;
+
+ if ((detena & LTC4291_DETENA_EN_PORT(port)) == 0)
+ *status = EC_PSE_STATUS_DISABLED;
+ else if ((statpwr & LTC4291_STATPWR_ON_PORT(port)) == 0)
+ *status = EC_PSE_STATUS_ENABLED;
+ else
+ *status = EC_PSE_STATUS_POWERED;
+
+ return 0;
+}
+
+static enum ec_status ec_command_pse(struct host_cmd_handler_args *args)
+{
+ const struct ec_params_pse *p = args->params;
+ int err = 0;
+
+ if (p->port >= LTC4291_PORT_MAX)
+ return EC_RES_INVALID_PARAM;
+
+ switch (p->cmd) {
+ case EC_PSE_STATUS: {
+ struct ec_response_pse_status *r = args->response;
+
+ args->response_size = sizeof(*r);
+ err = ec_command_pse_status(p->port, &r->status);
+ break;
+ }
+ case EC_PSE_ENABLE:
+ err = pse_port_enable(p->port);
+ break;
+ case EC_PSE_DISABLE:
+ err = pse_port_disable(p->port);
+ break;
+ default:
+ return EC_RES_INVALID_PARAM;
+ }
+
+ if (err)
+ return EC_RES_ERROR;
+
+ return EC_RES_SUCCESS;
+}
+DECLARE_HOST_COMMAND(EC_CMD_PSE, ec_command_pse, EC_VER_MASK(0));
diff --git a/include/ec_commands.h b/include/ec_commands.h
index b1b583abdb..edc0d8010f 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -5134,6 +5134,33 @@ struct __ec_align4 ec_response_ec_codec_wov_read_audio_shm {
};
/*****************************************************************************/
+/* Commands for PoE PSE controller */
+
+#define EC_CMD_PSE 0x00C0
+
+enum ec_pse_subcmd {
+ EC_PSE_STATUS = 0x0,
+ EC_PSE_ENABLE = 0x1,
+ EC_PSE_DISABLE = 0x2,
+ EC_PSE_SUBCMD_COUNT,
+};
+
+struct __ec_align1 ec_params_pse {
+ uint8_t cmd; /* enum ec_pse_subcmd */
+ uint8_t port; /* PSE port */
+};
+
+enum ec_pse_status {
+ EC_PSE_STATUS_DISABLED = 0x0,
+ EC_PSE_STATUS_ENABLED = 0x1,
+ EC_PSE_STATUS_POWERED = 0x2,
+};
+
+struct __ec_align1 ec_response_pse_status {
+ uint8_t status; /* enum ec_pse_status */
+};
+
+/*****************************************************************************/
/* System commands */
/*