feat:add linux hdf regulator

Signed-off-by: s00442234 <susha@huawei.com>
This commit is contained in:
s00442234
2021-12-18 16:39:07 +08:00
parent afe96398dd
commit dc75a392ff
12 changed files with 1335 additions and 666 deletions
+1 -1
View File
@@ -130,7 +130,7 @@ int32_t RegulatorSetCurrent(DevHandle handle, uint32_t minUa, uint32_t maxUa);
*
* @since 1.0
*/
int32_t RegulatorGetCurrent(DevHandle handle, uint32_t *current);
int32_t RegulatorGetCurrent(DevHandle handle, uint32_t *regCurrent);
/**
* @brief Get a regulator status
*
@@ -97,12 +97,16 @@ struct RegulatorNode {
};
struct RegulatorMethod {
int32_t (*open)(struct RegulatorNode *node);
int32_t (*close)(struct RegulatorNode *node);
int32_t (*release)(struct RegulatorNode *node);
int32_t (*enable)(struct RegulatorNode *node);
int32_t (*disable)(struct RegulatorNode *node);
int32_t (*forceDisable)(struct RegulatorNode *node);
int32_t (*setVoltage)(struct RegulatorNode *node, uint32_t minUv, uint32_t maxUv);
int32_t (*getVoltage)(struct RegulatorNode *node, uint32_t *voltage);
int32_t (*setCurrent)(struct RegulatorNode *node, uint32_t minUa, uint32_t maxUa);
int32_t (*getCurrent)(struct RegulatorNode *node, uint32_t *current);
int32_t (*getCurrent)(struct RegulatorNode *node, uint32_t *regCurrent);
int32_t (*getStatus)(struct RegulatorNode *node, uint32_t *status);
};
@@ -120,6 +124,7 @@ int32_t RegulatorNodeClose(struct RegulatorNode *node);
* @return success or fail
*/
int32_t RegulatorNodeAdd(struct RegulatorNode *node);
int32_t RegulatorNodeRemove(const char *name);
/**
* @brief remove all regulator controllers
* @param
@@ -173,7 +178,7 @@ int32_t RegulatorNodeSetCurrent(struct RegulatorNode *node, uint32_t minUA, uint
* @param current regulator current
* @return success or fail
*/
int32_t RegulatorNodeGetCurrent(struct RegulatorNode *node, uint32_t *current);
int32_t RegulatorNodeGetCurrent(struct RegulatorNode *node, uint32_t *regCurrent);
/**
* @brief get regulator status
* @param node Indicates a regulator controller.
@@ -29,7 +29,7 @@ struct RegulatorTreeInfo {
const char *name; /* regulator name */
struct RegulatorNode *parent; /* regulator parent info */
struct DListHead node;
struct DListHead childHead; /* child regulator list */
struct DListHead childHead; /* next level child regulator list */
};
struct RegulatorTreeManager {
@@ -45,6 +45,9 @@ void RegulatorTreePrint(void);
struct RegulatorNode *RegulatorTreeGetParent(const char *name);
int32_t RegulatorTreeChildForceDisable(struct RegulatorNode *node);
bool RegulatorTreeIsAllChildDisable(const char *name);
bool RegulatorTreeIsChildAlwayson(const char *name);
bool RegulatorTreeIsChildStatusOn(const char *name);
bool RegulatorTreeIsUpNodeComplete(const char *name);
#ifdef __cplusplus
#if __cplusplus
File diff suppressed because it is too large Load Diff
@@ -147,15 +147,15 @@ int32_t RegulatorSetCurrent(DevHandle handle, uint32_t minUa, uint32_t maxUa)
return HDF_SUCCESS;
}
int32_t RegulatorGetCurrent(DevHandle handle, uint32_t *current)
int32_t RegulatorGetCurrent(DevHandle handle, uint32_t *regCurrent)
{
struct RegulatorNode *node = (struct RegulatorNode *)handle;
if (node == NULL || current == NULL) {
if (node == NULL || regCurrent == NULL) {
HDF_LOGE("%s: param is null", __func__);
return HDF_FAILURE;
}
int ret = RegulatorNodeGetCurrent(node, current);
int ret = RegulatorNodeGetCurrent(node, regCurrent);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s: RegulatorNodeGetCurrent fail", __func__);
return HDF_FAILURE;
@@ -8,6 +8,7 @@
#include "regulator_tree_mgr.h"
#include "osal_mem.h"
#include "securec.h"
static struct RegulatorTreeManager *g_regulatorTreeManager = NULL;
static int RegulatorChildNodeAdd(struct RegulatorTreeInfo *pRegulator, struct RegulatorNode *child)
@@ -28,21 +29,26 @@ static int RegulatorChildNodeAdd(struct RegulatorTreeInfo *pRegulator, struct Re
HDF_LOGI("RegulatorChildNodeAdd: add %s child node success!", pRegulator->name);
return HDF_SUCCESS;
}
void RegulatorChildListDestroy(struct RegulatorTreeInfo *pRegulator)
{
CHECK_NULL_PTR_RETURN(pRegulator);
struct RegulatorChildNode *nodeInfo = NULL;
struct RegulatorChildNode *tmp = NULL;
DLIST_FOR_EACH_ENTRY(nodeInfo, &pRegulator->childHead, struct RegulatorChildNode, node) {
DLIST_FOR_EACH_ENTRY_SAFE(nodeInfo, tmp, &pRegulator->childHead, struct RegulatorChildNode, node) {
DListRemove(&nodeInfo->node);
OsalMemFree(nodeInfo);
}
}
struct RegulatorNode *RegulatorTreeGetParent(const char *name)
// name:the regulator node name; fun :get the node parent struct RegulatorNode
struct RegulatorNode * RegulatorTreeGetParent(const char *name)
{
CHECK_NULL_PTR_RETURN_VALUE(name, NULL);
struct RegulatorTreeInfo *pos = NULL;
struct RegulatorTreeInfo *tmp = NULL;
struct RegulatorTreeManager *manager = g_regulatorTreeManager;
CHECK_NULL_PTR_RETURN_VALUE(manager, NULL);
@@ -51,7 +57,7 @@ struct RegulatorNode *RegulatorTreeGetParent(const char *name)
return NULL;
}
DLIST_FOR_EACH_ENTRY(pos, &manager->treeMgrHead, struct RegulatorTreeInfo, node) {
DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->treeMgrHead, struct RegulatorTreeInfo, node) {
if (strcmp(pos->name, name) == 0) {
if (pos->parent == NULL) {
(void)OsalMutexUnlock(&manager->lock);
@@ -70,11 +76,13 @@ struct RegulatorNode *RegulatorTreeGetParent(const char *name)
return NULL;
}
// next level child
static struct DListHead *RegulatorTreeGetChild(const char *name)
{
CHECK_NULL_PTR_RETURN_VALUE(name, NULL);
struct RegulatorTreeInfo *pos = NULL;
struct RegulatorTreeInfo *tmp = NULL;
struct RegulatorTreeManager *manager = g_regulatorTreeManager;
CHECK_NULL_PTR_RETURN_VALUE(manager, NULL);
@@ -83,7 +91,7 @@ static struct DListHead *RegulatorTreeGetChild(const char *name)
return NULL;
}
DLIST_FOR_EACH_ENTRY(pos, &manager->treeMgrHead, struct RegulatorTreeInfo, node) {
DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->treeMgrHead, struct RegulatorTreeInfo, node) {
if (strcmp(pos->name, name) == 0) {
(void)OsalMutexUnlock(&manager->lock);
HDF_LOGI("RegulatorTreeGetChild: get %s child success!", name);
@@ -96,6 +104,61 @@ static struct DListHead *RegulatorTreeGetChild(const char *name)
return NULL;
}
// name:the regulator node name
bool RegulatorTreeIsUpNodeComplete(const char *name)
{
CHECK_NULL_PTR_RETURN_VALUE(name, false);
struct RegulatorNode *node = RegulatorTreeGetParent(name);
CHECK_NULL_PTR_RETURN_VALUE(node, false);
if ((node->regulatorInfo.parentName == NULL) || (strlen(node->regulatorInfo.parentName) == 0)) {
return true;
} else {
return RegulatorTreeIsUpNodeComplete(node->regulatorInfo.name);
}
}
bool RegulatorTreeIsChildAlwayson(const char *name)
{
CHECK_NULL_PTR_RETURN_VALUE(name, false);
struct DListHead *pList = RegulatorTreeGetChild(name);
CHECK_NULL_PTR_RETURN_VALUE(pList, false);
struct RegulatorChildNode *nodeInfo = NULL;
struct RegulatorChildNode *tmp = NULL;
DLIST_FOR_EACH_ENTRY_SAFE(nodeInfo, tmp, pList, struct RegulatorChildNode, node) {
if (nodeInfo->child->regulatorInfo.constraints.alwaysOn) {
HDF_LOGD("RegulatorTreeIsChildAlwayson:%s's child %s alwaysOn true!",
name, nodeInfo->child->regulatorInfo.name);
return true;
}
}
HDF_LOGD("RegulatorTreeIsChildAlwayson:%s's all child alwaysOn false!", name);
return false;
}
bool RegulatorTreeIsChildStatusOn(const char *name)
{
CHECK_NULL_PTR_RETURN_VALUE(name, false);
struct DListHead *pList = RegulatorTreeGetChild(name);
CHECK_NULL_PTR_RETURN_VALUE(pList, false);
struct RegulatorChildNode *nodeInfo = NULL;
struct RegulatorChildNode *tmp = NULL;
DLIST_FOR_EACH_ENTRY_SAFE(nodeInfo, tmp, pList, struct RegulatorChildNode, node) {
if (nodeInfo->child->regulatorInfo.status == REGULATOR_STATUS_ON) {
HDF_LOGD("RegulatorTreeIsChildAlwayson:%s's child %s status on!",
name, nodeInfo->child->regulatorInfo.name);
return true;
}
}
HDF_LOGD("RegulatorTreeIsChildAlwayson:%s's all child status off!", name);
return false;
}
bool RegulatorTreeIsAllChildDisable(const char *name)
{
CHECK_NULL_PTR_RETURN_VALUE(name, true);
@@ -103,7 +166,8 @@ bool RegulatorTreeIsAllChildDisable(const char *name)
CHECK_NULL_PTR_RETURN_VALUE(pList, true);
struct RegulatorChildNode *nodeInfo = NULL;
DLIST_FOR_EACH_ENTRY(nodeInfo, pList, struct RegulatorChildNode, node) {
struct RegulatorChildNode *tmp = NULL;
DLIST_FOR_EACH_ENTRY_SAFE(nodeInfo, tmp, pList, struct RegulatorChildNode, node) {
if (nodeInfo->child->regulatorInfo.status == REGULATOR_STATUS_ON) {
HDF_LOGI("RegulatorTreeIsAllChildDisable:%s's child %s on!", name, nodeInfo->child->regulatorInfo.name);
return false;
@@ -118,10 +182,11 @@ int32_t RegulatorTreeChildForceDisable(struct RegulatorNode *node)
{
CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_PARAM);
struct DListHead *pList = RegulatorTreeGetChild(node->regulatorInfo.name);
CHECK_NULL_PTR_RETURN_VALUE(pList, HDF_ERR_INVALID_PARAM);
CHECK_NULL_PTR_RETURN_VALUE(pList, HDF_SUCCESS);
struct RegulatorChildNode *nodeInfo = NULL;
DLIST_FOR_EACH_ENTRY(nodeInfo, pList, struct RegulatorChildNode, node) {
struct RegulatorChildNode *tmp = NULL;
DLIST_FOR_EACH_ENTRY_SAFE(nodeInfo, tmp, pList, struct RegulatorChildNode, node) {
if (RegulatorTreeChildForceDisable(nodeInfo->child) != HDF_SUCCESS) {
HDF_LOGE("RegulatorTreeChildForceDisable: %s fail!", nodeInfo->child->regulatorInfo.name);
return HDF_FAILURE;
@@ -150,17 +215,18 @@ static int32_t RegulatorTreeManagerNodeInit(const char *name)
struct RegulatorTreeInfo *nodeInfo = NULL;
struct RegulatorTreeInfo *pos = NULL;
struct RegulatorTreeInfo *tmp = NULL;
struct RegulatorTreeManager *manager = g_regulatorTreeManager;
CHECK_NULL_PTR_RETURN_VALUE(manager, HDF_FAILURE);
if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) {
HDF_LOGE("RegulatorTreeSetParent: lock regulator manager fail!");
HDF_LOGE("RegulatorTreeManagerNodeInit: lock regulator manager fail!");
return HDF_ERR_DEVICE_BUSY;
}
DLIST_FOR_EACH_ENTRY(pos, &manager->treeMgrHead, struct RegulatorTreeInfo, node) {
DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->treeMgrHead, struct RegulatorTreeInfo, node) {
if (strcmp(pos->name, name) == 0) {
HDF_LOGI("node %s has exists!", name);
HDF_LOGI("RegulatorTreeManagerNodeInit: node %s has exists!", name);
(void)OsalMutexUnlock(&manager->lock);
return HDF_SUCCESS;
}
@@ -179,12 +245,14 @@ static int32_t RegulatorTreeManagerNodeInit(const char *name)
return HDF_SUCCESS;
}
// set regulator (name)'s (parent) info
static int RegulatorTreeSetParent(const char *name, struct RegulatorNode *parent)
{
CHECK_NULL_PTR_RETURN_VALUE(name, HDF_ERR_INVALID_PARAM);
CHECK_NULL_PTR_RETURN_VALUE(parent, HDF_ERR_INVALID_PARAM);
struct RegulatorTreeInfo *pos = NULL;
struct RegulatorTreeInfo *tmp = NULL;
struct RegulatorTreeManager *manager = g_regulatorTreeManager;
CHECK_NULL_PTR_RETURN_VALUE(manager, HDF_FAILURE);
@@ -193,7 +261,7 @@ static int RegulatorTreeSetParent(const char *name, struct RegulatorNode *parent
return HDF_ERR_DEVICE_BUSY;
}
DLIST_FOR_EACH_ENTRY(pos, &manager->treeMgrHead, struct RegulatorTreeInfo, node) {
DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->treeMgrHead, struct RegulatorTreeInfo, node) {
if (strcmp(pos->name, name) == 0) {
pos->parent = parent;
(void)OsalMutexUnlock(&manager->lock);
@@ -206,12 +274,15 @@ static int RegulatorTreeSetParent(const char *name, struct RegulatorNode *parent
HDF_LOGI("RegulatorTreeSetParent:%s does not exist!", name);
return HDF_FAILURE;
}
// add (child) to regulator (name)'s childHead
static int RegulatorTreeSetChild(const char *name, struct RegulatorNode *child)
{
CHECK_NULL_PTR_RETURN_VALUE(name, HDF_ERR_INVALID_PARAM);
CHECK_NULL_PTR_RETURN_VALUE(child, HDF_ERR_INVALID_PARAM);
struct RegulatorTreeInfo *pos = NULL;
struct RegulatorTreeInfo *tmp = NULL;
struct RegulatorTreeManager *manager = g_regulatorTreeManager;
CHECK_NULL_PTR_RETURN_VALUE(manager, HDF_FAILURE);
@@ -220,7 +291,7 @@ static int RegulatorTreeSetChild(const char *name, struct RegulatorNode *child)
return HDF_ERR_DEVICE_BUSY;
}
DLIST_FOR_EACH_ENTRY(pos, &manager->treeMgrHead, struct RegulatorTreeInfo, node) {
DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->treeMgrHead, struct RegulatorTreeInfo, node) {
if (strcmp(pos->name, name) == 0) {
if (RegulatorChildNodeAdd(pos, child) != HDF_SUCCESS) {
HDF_LOGE("RegulatorTreeSetChild: RegulatorChildNodeAdd fail!");
@@ -228,7 +299,7 @@ static int RegulatorTreeSetChild(const char *name, struct RegulatorNode *child)
return HDF_FAILURE;
}
(void)OsalMutexUnlock(&manager->lock);
HDF_LOGI("RegulatorTreeSetChild: set %s parent success!", name);
HDF_LOGI("RegulatorTreeSetChild: set %s child success!", name);
return HDF_SUCCESS;
}
}
@@ -238,6 +309,12 @@ static int RegulatorTreeSetChild(const char *name, struct RegulatorNode *child)
return HDF_FAILURE;
}
/*
* name: child regulator node name
* child: child regulator node info
* parent: parent regulator node info
* process: set regultor (name)'s RegulatorTreeInfo:parent,and add (name) to (parent)'s RegulatorTreeInfo:childHead
*/
int RegulatorTreeSet(const char *name, struct RegulatorNode *child, struct RegulatorNode *parent)
{
CHECK_NULL_PTR_RETURN_VALUE(name, HDF_ERR_INVALID_PARAM);
@@ -262,7 +339,8 @@ int RegulatorTreeSet(const char *name, struct RegulatorNode *child, struct Regul
return HDF_FAILURE;
}
HDF_LOGI("RegulatorTreeSet: set [%s], parent[%s] success!", name, parent->regulatorInfo.name);
HDF_LOGI("RegulatorTreeSet: set [%s], parent[%s] and child info success!",
name, parent->regulatorInfo.name);
return HDF_SUCCESS;
}
static void RegulatorTreePrintChild(const char *name, struct DListHead *childHead)
@@ -271,16 +349,18 @@ static void RegulatorTreePrintChild(const char *name, struct DListHead *childHea
CHECK_NULL_PTR_RETURN(name);
struct RegulatorChildNode *nodeInfo = NULL;
struct RegulatorChildNode *tmp = NULL;
DLIST_FOR_EACH_ENTRY(nodeInfo, childHead, struct RegulatorChildNode, node) {
DLIST_FOR_EACH_ENTRY_SAFE(nodeInfo, tmp, childHead, struct RegulatorChildNode, node) {
HDF_LOGI("RegulatorTreePrintChild: %s's child %s !",
name, nodeInfo->child->regulatorInfo.name);
}
}
static void RegulatorTreePrint(void)
void RegulatorTreePrint(void)
{
struct RegulatorTreeInfo *pos = NULL;
struct RegulatorTreeInfo *tmp = NULL;
struct RegulatorTreeManager *manager = g_regulatorTreeManager;
CHECK_NULL_PTR_RETURN(manager);
@@ -289,7 +369,7 @@ static void RegulatorTreePrint(void)
return;
}
DLIST_FOR_EACH_ENTRY(pos, &manager->treeMgrHead, struct RegulatorTreeInfo, node) {
DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->treeMgrHead, struct RegulatorTreeInfo, node) {
HDF_LOGI("RegulatorTreePrint %s info IN ---->", pos->name);
if (pos->parent != NULL) {
HDF_LOGI("RegulatorTreePrint %s info, parent name[%s]",
@@ -305,6 +385,7 @@ static void RegulatorTreePrint(void)
int RegulatorTreeNodeRemoveAll(void)
{
struct RegulatorTreeInfo *nodeInfo = NULL;
struct RegulatorTreeInfo *tmp = NULL;
struct RegulatorTreeManager *manager = g_regulatorTreeManager;
CHECK_NULL_PTR_RETURN_VALUE(manager, HDF_FAILURE);
@@ -313,7 +394,7 @@ int RegulatorTreeNodeRemoveAll(void)
return HDF_ERR_DEVICE_BUSY;
}
DLIST_FOR_EACH_ENTRY(nodeInfo, &manager->treeMgrHead, struct RegulatorTreeInfo, node) {
DLIST_FOR_EACH_ENTRY_SAFE(nodeInfo, tmp, &manager->treeMgrHead, struct RegulatorTreeInfo, node) {
RegulatorChildListDestroy(nodeInfo);
DListRemove(&nodeInfo->node);
OsalMemFree(nodeInfo);
+13 -12
View File
@@ -12,6 +12,10 @@
#include "osal_thread.h"
#include "osal_time.h"
#include "regulator_if.h"
#if defined(CONFIG_DRIVERS_HDF_PLATFORM_REGULATOR)
#include "virtual/regulator_linux_voltage_virtual_driver.h"
#include "virtual/regulator_linux_current_virtual_driver.h"
#endif
#define HDF_LOG_TAG regulator_test_c
@@ -73,7 +77,6 @@ static int32_t RegulatorSetVoltageTest(struct RegulatorTest *test)
return HDF_SUCCESS;
}
HDF_LOGD("%s: UV[%d, %d]", __func__, test->maxUv, test->minUv);
if (RegulatorSetVoltage(test->handle, test->minUv, test->maxUv) != HDF_SUCCESS) {
HDF_LOGE("%s:[%d, %d] test fail", __func__, test->maxUv, test->minUv);
return HDF_FAILURE;
@@ -97,7 +100,6 @@ static int32_t RegulatorGetVoltageTest(struct RegulatorTest *test)
return HDF_FAILURE;
}
HDF_LOGD("%s: UV[%d]", __func__, test->uv);
return HDF_SUCCESS;
}
static int32_t RegulatorSetCurrentTest(struct RegulatorTest *test)
@@ -111,7 +113,6 @@ static int32_t RegulatorSetCurrentTest(struct RegulatorTest *test)
return HDF_SUCCESS;
}
HDF_LOGD("%s: Ua[%d, %d]", __func__, test->minUa, test->maxUa);
if (RegulatorSetCurrent(test->handle, test->minUa, test->maxUa) != HDF_SUCCESS) {
HDF_LOGE("%s:[%d, %d] test fail", __func__, test->minUa, test->maxUa);
return HDF_FAILURE;
@@ -135,7 +136,6 @@ static int32_t RegulatorGetCurrentTest(struct RegulatorTest *test)
return HDF_FAILURE;
}
HDF_LOGD("%s: Ua[%d]", __func__, test->ua);
return HDF_SUCCESS;
}
static int32_t RegulatorGetStatusTest(struct RegulatorTest *test)
@@ -155,7 +155,6 @@ static int32_t RegulatorGetStatusTest(struct RegulatorTest *test)
return HDF_FAILURE;
}
HDF_LOGD("%s: status[%d]", __func__, test->status);
return HDF_SUCCESS;
}
static int RegulatorTestThreadFunc(void *param)
@@ -269,8 +268,6 @@ static int32_t RegulatorTestEntry(struct RegulatorTest *test, int32_t cmd)
int32_t i;
int32_t ret = HDF_ERR_NOT_SUPPORT;
HDF_LOGD("regulator test-- -- -- -- -- -->%s: enter cmd %d", __func__, cmd);
if (test == NULL || test->name == NULL) {
HDF_LOGE("%s: test null cmd %d", __func__, cmd);
return HDF_ERR_INVALID_OBJECT;
@@ -301,7 +298,6 @@ static int32_t RegulatorTestEntry(struct RegulatorTest *test, int32_t cmd)
static int32_t RegulatorTestBind(struct HdfDeviceObject *device)
{
static struct RegulatorTest test;
HDF_LOGD("RegulatorTestBind in\r\n");
if (device != NULL) {
device->service = &test.service;
@@ -309,7 +305,7 @@ static int32_t RegulatorTestBind(struct HdfDeviceObject *device)
HDF_LOGE("%s: device is NULL", __func__);
}
HDF_LOGD("RegulatorTestBind out\r\n");
HDF_LOGI("RegulatorTestBind success\r\n");
return HDF_SUCCESS;
}
@@ -364,7 +360,7 @@ static int32_t RegulatorTestInitFromHcs(struct RegulatorTest *test, const struct
return HDF_FAILURE;
}
HDF_LOGD("regulator test init:[%s][%d]--[%d][%d]--[%d][%d]!",
HDF_LOGI("regulator test init:[%s][%d]--[%d][%d]--[%d][%d]!",
test->name, test->mode, test->minUv, test->maxUv, test->minUa, test->maxUa);
return HDF_SUCCESS;
@@ -374,7 +370,12 @@ static int32_t RegulatorTestInit(struct HdfDeviceObject *device)
{
struct RegulatorTest *test = NULL;
HDF_LOGD("RegulatorTestInit in\r\n");
HDF_LOGI("RegulatorTestInit in\r\n");
#if defined(CONFIG_DRIVERS_HDF_PLATFORM_REGULATOR)
VirtualVoltageRegulatorAdapterInit();
VirtualCurrentRegulatorAdapterInit();
#endif
if (device == NULL || device->service == NULL || device->property == NULL) {
HDF_LOGE("%s: invalid parameter", __func__);
@@ -388,7 +389,7 @@ static int32_t RegulatorTestInit(struct HdfDeviceObject *device)
}
test->TestEntry = RegulatorTestEntry;
HDF_LOGD("%s: success", __func__);
HDF_LOGI("%s: success", __func__);
return HDF_SUCCESS;
}
@@ -0,0 +1,217 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regmap.h>
#include <linux/sysfs.h>
#include "hdf_log.h"
#include "hdf_base.h"
#define HDF_LOG_TAG regulator_virtual_current
struct VirtualCurrentRegulatorDev {
struct regmap *regmap;
struct regulator_dev *dev;
};
// note:linux kernel constraints:len(devName) + len(supplyName) < REG_STR_SIZE(64)
static struct regulator_consumer_supply g_virtualCurrentRegulatorSupplies[] = {
REGULATOR_SUPPLY("vir-current-reg-hdf-adp", "regulator_adapter_consumer01"),
};
// virtual regulator init info
static struct regulator_init_data g_virtualCurrentRegulatorInitData = {
.constraints = {
.name = "virtual_current_regulator",
.min_uA = 1000,
.max_uA = 50000,
.valid_ops_mask = REGULATOR_CHANGE_CURRENT |
REGULATOR_CHANGE_STATUS,
},
.num_consumer_supplies = ARRAY_SIZE(g_virtualCurrentRegulatorSupplies),
.consumer_supplies = g_virtualCurrentRegulatorSupplies,
};
static void VirtualCurrentRegulatorDevRelease(struct device *dev)
{
}
static struct platform_device g_virtualCurrentRegulatorPlatformDevice = {
.name = "virtual_current_regulator_dev",
.id = -1,
.dev = {
.release = VirtualCurrentRegulatorDevRelease,
}
};
enum RegulatorStatus {
VIR_REGULATOR_STATUS_OFF,
VIR_REGULATOR_STATUS_ON,
};
static int g_virStatus = VIR_REGULATOR_STATUS_OFF;
static int VirtualCurrentRegulatorEnable(struct regulator_dev *rdev)
{
if (rdev == NULL) {
HDF_LOGE("%s: rdev NULL", __func__);
return HDF_FAILURE;
}
g_virStatus = VIR_REGULATOR_STATUS_ON;
return HDF_SUCCESS;
}
static int VirtualCurrentRegulatorDisable(struct regulator_dev *rdev)
{
if (rdev == NULL) {
HDF_LOGE("%s: rdev NULL", __func__);
return HDF_FAILURE;
}
g_virStatus = VIR_REGULATOR_STATUS_OFF;
return HDF_SUCCESS;
}
static int VirtualCurrentRegulatorIsEnabled(struct regulator_dev *rdev)
{
if (rdev == NULL) {
HDF_LOGE("%s: rdev NULL", __func__);
return HDF_FAILURE;
}
return g_virStatus;
}
static int VirtualCurrentRegulatorSetCurrent(struct regulator_dev *rdev, int min_uA,
int max_uA)
{
if ((rdev == NULL) || (rdev->constraints == NULL)) {
HDF_LOGE("%s: rdev NULL", __func__);
return HDF_FAILURE;
}
struct regulation_constraints *regu_constraints = rdev->constraints;
if (regu_constraints->min_uA == min_uA &&
regu_constraints->max_uA == max_uA) {
return HDF_SUCCESS;
}
return HDF_SUCCESS;
}
#define VIRTUAL_CURRENT_VAL_500 500
static int VirtualCurrentRegulatorGetCurrent(struct regulator_dev *rdev)
{
if (rdev == NULL) {
HDF_LOGE("%s: rdev NULL", __func__);
return HDF_FAILURE;
}
return VIRTUAL_CURRENT_VAL_500;
}
static struct regulator_ops g_virtualCurrentRegulatorOps = {
.enable = VirtualCurrentRegulatorEnable,
.disable = VirtualCurrentRegulatorDisable,
.is_enabled = VirtualCurrentRegulatorIsEnabled,
.set_current_limit = VirtualCurrentRegulatorSetCurrent,
.get_current_limit = VirtualCurrentRegulatorGetCurrent,
};
static struct regulator_desc g_virtualCurrentRegulatorDesc = {
.name = "regulator_virtual_current",
.type = REGULATOR_CURRENT,
.ops = &g_virtualCurrentRegulatorOps,
.owner = THIS_MODULE,
};
static int VirtualCurrentRegulatorPlatformProbe(struct platform_device *platform_dev)
{
if (platform_dev == NULL) {
HDF_LOGE("%s: platform_dev null!", __func__);
return HDF_FAILURE;
}
struct VirtualCurrentRegulatorDev *data;
struct regulator_config config;
memset(&config, 0, sizeof(struct regulator_config));
data = devm_kzalloc(&platform_dev->dev, sizeof(*data), GFP_KERNEL);
if (!data) {
HDF_LOGE("%s: devm_kzalloc error!", __func__);
return -ENOMEM;
}
config.dev = &platform_dev->dev;
config.init_data = &g_virtualCurrentRegulatorInitData;
config.driver_data = data;
data->dev = regulator_register(&g_virtualCurrentRegulatorDesc, &config);
if (IS_ERR(data->dev)) {
HDF_LOGE("%s: failed to register regulator %s\n", __func__, g_virtualCurrentRegulatorDesc.name);
return PTR_ERR(data->dev);
}
platform_set_drvdata(platform_dev, data);
HDF_LOGI("%s: success", __func__);
return 0;
}
static int VirtualCurrentRegulatorPlatformRemove(struct platform_device *platform_dev)
{
struct VirtualCurrentRegulatorDev *rdev = platform_get_drvdata(platform_dev);
regulator_unregister(rdev->dev);
platform_set_drvdata(platform_dev, NULL);
HDF_LOGI("%s: success", __func__);
return 0;
}
static struct platform_driver g_virtualCurrentRegulatorPlatformDriver = {
.driver = {
.name = "virtual_current_regulator_dev",
.owner = THIS_MODULE,
},
.probe = VirtualCurrentRegulatorPlatformProbe,
.remove = VirtualCurrentRegulatorPlatformRemove,
};
int VirtualCurrentRegulatorAdapterInit(void)
{
int ret = platform_device_register(&g_virtualCurrentRegulatorPlatformDevice);
if(ret == 0) {
ret = platform_driver_register(&g_virtualCurrentRegulatorPlatformDriver);
} else {
HDF_LOGE("%s:device register fail %d", __func__, ret);
}
return ret;
}
static int __init VirtualCurrentRegulatorInit(void)
{
int ret = platform_device_register(&g_virtualCurrentRegulatorPlatformDevice);
if(ret == 0) {
ret = platform_driver_register(&g_virtualCurrentRegulatorPlatformDriver);
}
return ret;
}
static void __exit VirtualCurrentRegulatorExit(void)
{
platform_device_unregister(&g_virtualCurrentRegulatorPlatformDevice);
platform_driver_unregister(&g_virtualCurrentRegulatorPlatformDriver);
}
MODULE_DESCRIPTION("Virtual current Regulator Controller Platform Device Drivers");
MODULE_LICENSE("GPL");
@@ -0,0 +1,15 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef REGULATOR_LINUX_CURRENT_VIRTUAL_DRIVER_H
#define REGULATOR_LINUX_CURRENT_VIRTUAL_DRIVER_H
#include "hdf_base.h"
int VirtualCurrentRegulatorAdapterInit(void);
#endif /* REGULATOR_LINUX_CURRENT_VIRTUAL_DRIVER_H */
@@ -0,0 +1,221 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regmap.h>
#include <linux/sysfs.h>
#include "hdf_log.h"
#include "hdf_base.h"
#define HDF_LOG_TAG regulator_virtual
struct VirtualVoltageRegulatorDev {
struct regmap *regmap;
struct regulator_dev *dev;
};
// note:linux kernel constraints:len(devName) + len(supplyName) < REG_STR_SIZE(64)
static struct regulator_consumer_supply g_virtualVoltageRegulatorVoltSupplies[] = {
REGULATOR_SUPPLY("vir-voltage-reg-hdf-adp", "regulator_adapter_consumer01"),
};
// virtual regulator init info
static struct regulator_init_data g_virtualVoltageRegulatorInitData = {
.constraints = {
.name = "virtual_regulator",
.min_uV = 1000,
.max_uV = 50000,
.always_on = 1,
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
REGULATOR_CHANGE_STATUS,
},
.num_consumer_supplies = ARRAY_SIZE(g_virtualVoltageRegulatorVoltSupplies),
.consumer_supplies = g_virtualVoltageRegulatorVoltSupplies,
};
static void VirtualVoltageRegulatorDevRelease(struct device *dev)
{
}
static struct platform_device g_virtualVoltageRegulatorPlatformDevice = {
.name = "virtual_regulator_dev",
.id = -1,
.dev = {
.release = VirtualVoltageRegulatorDevRelease,
}
};
enum RegulatorStatus {
VIR_REGULATOR_STATUS_OFF,
VIR_REGULATOR_STATUS_ON,
};
static int g_virStatus = VIR_REGULATOR_STATUS_OFF;
static int VirtualVoltageRegulatorEnable(struct regulator_dev *rdev)
{
if (rdev == NULL) {
HDF_LOGE("%s: rdev NULL", __func__);
return HDF_FAILURE;
}
g_virStatus = VIR_REGULATOR_STATUS_ON;
return HDF_SUCCESS;
}
static int VirtualVoltageRegulatorDisable(struct regulator_dev *rdev)
{
if (rdev == NULL) {
HDF_LOGE("%s: rdev NULL", __func__);
return HDF_FAILURE;
}
g_virStatus = VIR_REGULATOR_STATUS_OFF;
return HDF_SUCCESS;
}
static int VirtualVoltageRegulatorIsEnabled(struct regulator_dev *rdev)
{
if (rdev == NULL) {
HDF_LOGE("%s: rdev NULL", __func__);
return HDF_FAILURE;
}
return g_virStatus;
}
static int VirtualVoltageRegulatorSetVoltage(struct regulator_dev *rdev, int min_uV,
int max_uV, unsigned *selector)
{
if ((rdev == NULL) || (rdev->constraints == NULL)) {
HDF_LOGE("%s: rdev NULL", __func__);
return HDF_FAILURE;
}
struct regulation_constraints *regu_constraints = rdev->constraints;
if (regu_constraints->min_uV == min_uV &&
regu_constraints->max_uV == max_uV) {
return HDF_SUCCESS;
}
return HDF_SUCCESS;
}
#define VIRTUAL_VOLTAGE_VAL_500 500
static int VirtualVoltageRegulatorGetVoltage(struct regulator_dev *rdev)
{
if (rdev == NULL) {
HDF_LOGE("%s: rdev NULL", __func__);
return HDF_FAILURE;
}
return VIRTUAL_VOLTAGE_VAL_500;
}
static struct regulator_ops g_virtualVoltageRegulatorOps = {
.enable = VirtualVoltageRegulatorEnable,
.disable = VirtualVoltageRegulatorDisable,
.is_enabled = VirtualVoltageRegulatorIsEnabled,
.set_voltage = VirtualVoltageRegulatorSetVoltage,
.get_voltage = VirtualVoltageRegulatorGetVoltage,
};
static struct regulator_desc g_virtualVoltageRegulatorDesc = {
.name = "regulator_virtual",
.type = REGULATOR_VOLTAGE,
.ops = &g_virtualVoltageRegulatorOps,
.min_uV = 1000,
.owner = THIS_MODULE,
};
static int VirtualVoltageRegulatorPlatformProbe(struct platform_device *platform_dev)
{
if (platform_dev == NULL) {
HDF_LOGE("%s: platform_dev null!", __func__);
return HDF_FAILURE;
}
struct VirtualVoltageRegulatorDev *data;
struct regulator_config config;
memset(&config, 0, sizeof(struct regulator_config));
data = devm_kzalloc(&platform_dev->dev, sizeof(*data), GFP_KERNEL);
if (!data) {
return -ENOMEM;
}
config.dev = &platform_dev->dev;
config.init_data = &g_virtualVoltageRegulatorInitData;
config.driver_data = data;
data->dev = regulator_register(&g_virtualVoltageRegulatorDesc, &config);
if (IS_ERR(data->dev)) {
HDF_LOGE("%s: failed to register regulator %s\n", __func__, g_virtualVoltageRegulatorDesc.name);
return PTR_ERR(data->dev);
}
platform_set_drvdata(platform_dev, data);
HDF_LOGI("%s: success", __func__);
return 0;
}
static int VirtualVoltageRegulatorPlatformRemove(struct platform_device *platform_dev)
{
struct VirtualVoltageRegulatorDev *rdev = platform_get_drvdata(platform_dev);
regulator_unregister(rdev->dev);
platform_set_drvdata(platform_dev, NULL);
HDF_LOGI("VirtualVoltageRegulatorPlatformRemove");
return 0;
}
static struct platform_driver g_virtualVoltageRegulatorPlatformDriver = {
.driver = {
.name = "virtual_regulator_dev",
.owner = THIS_MODULE,
},
.probe = VirtualVoltageRegulatorPlatformProbe,
.remove = VirtualVoltageRegulatorPlatformRemove,
};
int VirtualVoltageRegulatorAdapterInit(void)
{
HDF_LOGI("VirtualVoltageRegulatorAdapterInit");
int ret = platform_device_register(&g_virtualVoltageRegulatorPlatformDevice);
if(ret == 0) {
ret = platform_driver_register(&g_virtualVoltageRegulatorPlatformDriver);
} else {
HDF_LOGE("VirtualVoltageRegulatorAdapterInit:device register fail %d", ret);
}
return ret;
}
static int __init VirtualVoltageRegulatorInit(void)
{
HDF_LOGI("VirtualVoltageRegulatorInit");
int ret = platform_device_register(&g_virtualVoltageRegulatorPlatformDevice);
if(ret == 0) {
ret = platform_driver_register(&g_virtualVoltageRegulatorPlatformDriver);
}
return ret;
}
static void __exit VirtualVoltageRegulatorExit(void)
{
HDF_LOGI("VirtualVoltageRegulatorExit");
platform_device_unregister(&g_virtualVoltageRegulatorPlatformDevice);
platform_driver_unregister(&g_virtualVoltageRegulatorPlatformDriver);
}
MODULE_DESCRIPTION("Virtual voltage Regulator Controller Platform Device Drivers");
MODULE_LICENSE("GPL");
@@ -0,0 +1,15 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef REGULATOR_LINUX_VOLTAGE_VIRTUAL_DRIVER_H
#define REGULATOR_LINUX_VOLTAGE_VIRTUAL_DRIVER_H
#include "hdf_base.h"
int VirtualVoltageRegulatorAdapterInit(void);
#endif /* REGULATOR_LINUX_VOLTAGE_VIRTUAL_DRIVER_H */
@@ -273,11 +273,10 @@ static int32_t VirtualRegulatorInit(struct HdfDeviceObject *device)
ret = VirtualRegulatorParseAndInit(device, childNode);
if (ret != HDF_SUCCESS) {
HDF_LOGE("%s:VirtualRegulatorParseAndInit fail", __func__);
RegulatorNodeRemoveAll();
return HDF_FAILURE;
}
}
HDF_LOGI("%s: success", __func__);
return HDF_SUCCESS;
}