From 82ce05526bc3574cce03bebdeb73deaf5a0848fb Mon Sep 17 00:00:00 2001 From: Emmanuel Vadot Date: Sun, 11 Mar 2018 04:37:05 +0000 Subject: [PATCH] extres/regulators: Add sysctls for regulators For each regulators create an hw.regulator.. : uvolt: Current value always_on: 1 If the reg is always on boot_on: 1 If the reg is set at boot time enable_cnt: Number of consumer(s) enable_delay: Delay before enabling the regulator ramp_delay: The Ramp delay max_uamp: The maximum value of the regulator in uAmps min_uamp: The minimal value of the regulator in uAmps max_uvolt: The maximum value of the regulator in uVolts min_uvolt: The minimal value of the regulator in uVolts Reviewed by: ian Differential Revision: https://reviews.freebsd.org/D14578 --- sys/dev/extres/regulator/regulator.c | 88 ++++++++++++++++++++++++++++ sys/dev/extres/regulator/regulator.h | 3 + 2 files changed, 91 insertions(+) diff --git a/sys/dev/extres/regulator/regulator.c b/sys/dev/extres/regulator/regulator.c index 10307b135dea..7b79766d0527 100644 --- a/sys/dev/extres/regulator/regulator.c +++ b/sys/dev/extres/regulator/regulator.c @@ -51,6 +51,8 @@ __FBSDID("$FreeBSD$"); #include "regdev_if.h" +SYSCTL_NODE(_hw, OID_AUTO, regulator, CTLFLAG_RD, NULL, "Regulators"); + MALLOC_DEFINE(M_REGULATOR, "regulator", "Regulator framework"); #define DIV_ROUND_UP(n,d) howmany(n, d) @@ -112,6 +114,8 @@ struct regnode { int enable_cnt; /* Enabled counter */ struct regnode_std_param std_param; /* Standard parameters */ + + struct sysctl_ctx_list sysctl_ctx; }; /* @@ -147,6 +151,29 @@ SX_SYSINIT(regulator_topology, ®node_topo_lock, "Regulator topology lock"); #define REGNODE_XLOCK(_sc) sx_xlock(&((_sc)->lock)) #define REGNODE_UNLOCK(_sc) sx_unlock(&((_sc)->lock)) +/* + * sysctl handler + */ +static int +regnode_uvolt_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct regnode *regnode = arg1; + int rv, uvolt; + + if (regnode->std_param.min_uvolt == regnode->std_param.max_uvolt) { + uvolt = regnode->std_param.min_uvolt; + } else { + REG_TOPO_SLOCK(); + if ((rv = regnode_get_voltage(regnode, &uvolt)) != 0) { + REG_TOPO_UNLOCK(); + return (rv); + } + REG_TOPO_UNLOCK(); + } + + return sysctl_handle_int(oidp, &uvolt, sizeof(uvolt), req); +} + /* ---------------------------------------------------------------------------- * * Default regulator methods for base class. @@ -233,6 +260,7 @@ regnode_create(device_t pdev, regnode_class_t regnode_class, struct regnode_init_def *def) { struct regnode *regnode; + struct sysctl_oid *regnode_oid; KASSERT(def->name != NULL, ("regulator name is NULL")); KASSERT(def->name[0] != '\0', ("regulator name is empty")); @@ -277,6 +305,66 @@ regnode_create(device_t pdev, regnode_class_t regnode_class, regnode->ofw_node = def->ofw_node; #endif + sysctl_ctx_init(®node->sysctl_ctx); + regnode_oid = SYSCTL_ADD_NODE(®node->sysctl_ctx, + SYSCTL_STATIC_CHILDREN(_hw_regulator), + OID_AUTO, regnode->name, + CTLFLAG_RD, 0, "A regulator node"); + + SYSCTL_ADD_INT(®node->sysctl_ctx, + SYSCTL_CHILDREN(regnode_oid), + OID_AUTO, "min_uvolt", + CTLFLAG_RD, ®node->std_param.min_uvolt, 0, + "Minimal voltage (in uV)"); + SYSCTL_ADD_INT(®node->sysctl_ctx, + SYSCTL_CHILDREN(regnode_oid), + OID_AUTO, "max_uvolt", + CTLFLAG_RD, ®node->std_param.max_uvolt, 0, + "Maximal voltage (in uV)"); + SYSCTL_ADD_INT(®node->sysctl_ctx, + SYSCTL_CHILDREN(regnode_oid), + OID_AUTO, "min_uamp", + CTLFLAG_RD, ®node->std_param.min_uamp, 0, + "Minimal amperage (in uA)"); + SYSCTL_ADD_INT(®node->sysctl_ctx, + SYSCTL_CHILDREN(regnode_oid), + OID_AUTO, "max_uamp", + CTLFLAG_RD, ®node->std_param.max_uamp, 0, + "Maximal amperage (in uA)"); + SYSCTL_ADD_INT(®node->sysctl_ctx, + SYSCTL_CHILDREN(regnode_oid), + OID_AUTO, "ramp_delay", + CTLFLAG_RD, ®node->std_param.ramp_delay, 0, + "Ramp delay (in uV/us)"); + SYSCTL_ADD_INT(®node->sysctl_ctx, + SYSCTL_CHILDREN(regnode_oid), + OID_AUTO, "enable_delay", + CTLFLAG_RD, ®node->std_param.enable_delay, 0, + "Enable delay (in us)"); + SYSCTL_ADD_INT(®node->sysctl_ctx, + SYSCTL_CHILDREN(regnode_oid), + OID_AUTO, "enable_cnt", + CTLFLAG_RD, ®node->enable_cnt, 0, + "The regulator enable counter"); + SYSCTL_ADD_INT(®node->sysctl_ctx, + SYSCTL_CHILDREN(regnode_oid), + OID_AUTO, "boot_on", + CTLFLAG_RD, (int *) ®node->std_param.boot_on, 0, + "Is enabled on boot"); + SYSCTL_ADD_INT(®node->sysctl_ctx, + SYSCTL_CHILDREN(regnode_oid), + OID_AUTO, "always_on", + CTLFLAG_RD, (int *)®node->std_param.always_on, 0, + "Is always enabled"); + + SYSCTL_ADD_PROC(®node->sysctl_ctx, + SYSCTL_CHILDREN(regnode_oid), + OID_AUTO, "uvolt", + CTLTYPE_INT | CTLFLAG_RD, + regnode, 0, regnode_uvolt_sysctl, + "I", + "Current voltage (in uV)"); + return (regnode); } diff --git a/sys/dev/extres/regulator/regulator.h b/sys/dev/extres/regulator/regulator.h index 75d673d37c00..7ef6524df35a 100644 --- a/sys/dev/extres/regulator/regulator.h +++ b/sys/dev/extres/regulator/regulator.h @@ -31,11 +31,14 @@ #include "opt_platform.h" #include +#include #ifdef FDT #include #endif #include "regnode_if.h" +SYSCTL_DECL(_hw_regulator); + #define REGULATOR_FLAGS_STATIC 0x00000001 /* Static strings */ #define REGULATOR_FLAGS_NOT_DISABLE 0x00000002 /* Cannot be disabled */