mirror of
https://github.com/openharmony/drivers_framework.git
synced 2026-08-27 20:49:55 -04:00
be7361f52b
Signed-off-by: jiachanglin <jiachanglin@huawei.com>
248 lines
7.4 KiB
C
248 lines
7.4 KiB
C
/*
|
|
* 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 HDF_CHIP_CONFIG_H
|
|
#define HDF_CHIP_CONFIG_H
|
|
|
|
#include "device_resource_if.h"
|
|
#include "hdf_base.h"
|
|
#include "hdf_log.h"
|
|
#include "osal/osal_mem.h"
|
|
#include "securec.h"
|
|
|
|
#define HDF_CHIP_MAX_POWER_SUPPORTED 2
|
|
|
|
#define BUS_FUNC_MAX 1
|
|
|
|
enum PowerType
|
|
{
|
|
POWER_TYPE_ALWAYS_ON = 0,
|
|
POWER_TYPE_GPIO
|
|
};
|
|
|
|
struct HdfConfigGpioBasedSwitch {
|
|
uint16_t gpioId;
|
|
uint8_t activeLevel;
|
|
};
|
|
|
|
struct HdfPowerConfig {
|
|
uint8_t powerSeqDelay;
|
|
uint8_t type;
|
|
union {
|
|
struct HdfConfigGpioBasedSwitch gpio;
|
|
};
|
|
};
|
|
|
|
struct HdfPowersConfig {
|
|
uint8_t powerCount;
|
|
struct HdfPowerConfig power[0];
|
|
};
|
|
|
|
enum ResetType
|
|
{
|
|
RESET_TYPE_NOT_MANAGEABLE = 0,
|
|
RESET_TYPE_GPIO
|
|
};
|
|
|
|
struct HdfResetConfig {
|
|
union {
|
|
struct HdfConfigGpioBasedSwitch gpio;
|
|
};
|
|
uint8_t resetType;
|
|
uint8_t resetHoldTime;
|
|
};
|
|
|
|
struct HdfChipConfig {
|
|
const char *name;
|
|
struct HdfPowersConfig *powers;
|
|
struct HdfResetConfig reset;
|
|
uint8_t bootUpTimeOut;
|
|
};
|
|
|
|
static inline int ParsePowerConfig(const struct DeviceResourceNode *node, struct HdfPowerConfig *config) {
|
|
struct DeviceResourceIface *drsOps = NULL;
|
|
if (node == NULL || config == NULL) {
|
|
HDF_LOGE("%s: one of the input para is NULL!", __func__);
|
|
return HDF_FAILURE;
|
|
}
|
|
drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
|
|
if (drsOps == NULL || drsOps->GetUint8 == NULL) {
|
|
HDF_LOGE("%s: at least one of the paras is NULL!", __func__);
|
|
return HDF_FAILURE;
|
|
}
|
|
|
|
if (drsOps->GetUint8(node, "powerSeqDelay", &config->powerSeqDelay, 0) != HDF_SUCCESS) {
|
|
HDF_LOGE("%s: powersSeqDelay fail!", __func__);
|
|
return HDF_FAILURE;
|
|
}
|
|
|
|
if (drsOps->GetUint8(node, "powerType", &config->type, 0) != HDF_SUCCESS) {
|
|
HDF_LOGE("%s: type fail!", __func__);
|
|
return HDF_FAILURE;
|
|
}
|
|
|
|
if (config->type == POWER_TYPE_GPIO) {
|
|
if (drsOps->GetUint16(node, "gpioId", &config->gpio.gpioId, 0) != HDF_SUCCESS) {
|
|
HDF_LOGE("%s: gpioId fail!", __func__);
|
|
return HDF_FAILURE;
|
|
}
|
|
if (drsOps->GetUint8(node, "activeLevel", &config->gpio.activeLevel, 0) != HDF_SUCCESS) {
|
|
HDF_LOGE("%s: activeLevel fail!", __func__);
|
|
return HDF_FAILURE;
|
|
}
|
|
}
|
|
|
|
return HDF_SUCCESS;
|
|
}
|
|
|
|
static inline struct HdfPowersConfig *ParsePowersConfig(const struct DeviceResourceNode *node) {
|
|
struct DeviceResourceIface *drsOps = NULL;
|
|
struct DeviceResourceNode *childNode = NULL;
|
|
struct HdfPowersConfig *config = NULL;
|
|
uint8_t nodeCount = 0;
|
|
int32_t ret;
|
|
if (node == NULL) {
|
|
HDF_LOGE("%s: input para is NULL!", __func__);
|
|
return NULL;
|
|
}
|
|
drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
|
|
if (drsOps == NULL || drsOps->GetChildNode == NULL) {
|
|
HDF_LOGE("%s: at least one of the paras is NULL!", __func__);
|
|
return NULL;
|
|
}
|
|
DEV_RES_NODE_FOR_EACH_CHILD_NODE(node, childNode) { ++nodeCount; }
|
|
if (nodeCount > HDF_CHIP_MAX_POWER_SUPPORTED) {
|
|
return NULL;
|
|
}
|
|
config = OsalMemCalloc(sizeof(struct HdfPowersConfig) + nodeCount * sizeof(struct HdfPowerConfig));
|
|
if (config == NULL) {
|
|
return NULL;
|
|
}
|
|
config->powerCount = nodeCount;
|
|
for (uint8_t i = 0; i < nodeCount; i++) {
|
|
char buff[32] = {0};
|
|
ret = snprintf_s(buff, 32, 32, "power%d", i);
|
|
if (ret < 0) {
|
|
HDF_LOGE("%s:snprintf_s failed!ret=%d, i=%d", __func__, ret, i);
|
|
break;
|
|
}
|
|
const struct DeviceResourceNode *powerNode = drsOps->GetChildNode(node, buff);
|
|
if (powerNode == NULL) {
|
|
HDF_LOGE("%s:Can not get node %s", __func__, buff);
|
|
ret = HDF_FAILURE;
|
|
break;
|
|
}
|
|
ret = ParsePowerConfig(powerNode, config->power + i);
|
|
if (ret != HDF_SUCCESS) {
|
|
HDF_LOGE("%s:parse node %s failed!ret=%d", __func__, buff, ret);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (ret != HDF_SUCCESS) {
|
|
OsalMemFree(config);
|
|
config = NULL;
|
|
}
|
|
return config;
|
|
}
|
|
|
|
static inline int ParseResetConfig(const struct DeviceResourceNode *node, struct HdfResetConfig *reset) {
|
|
struct DeviceResourceIface *drsOps = NULL;
|
|
if (node == NULL || reset == NULL) {
|
|
HDF_LOGE("%s: at least one of the paras is NULL!", __func__);
|
|
return HDF_FAILURE;
|
|
}
|
|
|
|
drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
|
|
if (drsOps == NULL || drsOps->GetUint8 == NULL) {
|
|
HDF_LOGE("%s: at least one of the paras is NULL!", __func__);
|
|
return HDF_FAILURE;
|
|
}
|
|
|
|
if (drsOps->GetUint8(node, "resetType", &reset->resetType, 0) != HDF_SUCCESS) {
|
|
HDF_LOGE("%s: powersSeqDelay fail!", __func__);
|
|
return HDF_FAILURE;
|
|
}
|
|
if (reset->resetType == RESET_TYPE_GPIO) {
|
|
if (drsOps->GetUint16(node, "gpioId", &reset->gpio.gpioId, 0) != HDF_SUCCESS) {
|
|
HDF_LOGE("%s: gpioId fail!", __func__);
|
|
return HDF_FAILURE;
|
|
}
|
|
|
|
if (drsOps->GetUint8(node, "activeLevel", &reset->gpio.activeLevel, 0) != HDF_SUCCESS) {
|
|
HDF_LOGE("%s: read activeLevel fail!", __func__);
|
|
return HDF_FAILURE;
|
|
}
|
|
|
|
if (drsOps->GetUint8(node, "resetHoldTime", &reset->resetHoldTime, 0) != HDF_SUCCESS) {
|
|
HDF_LOGE("%s: read resetHoldTime fail!", __func__);
|
|
return HDF_FAILURE;
|
|
}
|
|
}
|
|
return HDF_SUCCESS;
|
|
}
|
|
|
|
static inline void ClearChipConfig(struct HdfChipConfig *config) {
|
|
|
|
if (config->powers != NULL) {
|
|
OsalMemFree(config->powers);
|
|
config->powers = NULL;
|
|
}
|
|
}
|
|
|
|
static inline int32_t ParseChipConfig(const struct DeviceResourceNode *node, struct HdfChipConfig *config) {
|
|
struct DeviceResourceIface *drsOps = NULL;
|
|
const struct DeviceResourceNode *devPowerNode = NULL;
|
|
const struct DeviceResourceNode *resetNode = NULL;
|
|
int32_t ret = HDF_SUCCESS;
|
|
if (node == NULL || config == NULL) {
|
|
HDF_LOGE("%s: invalid node or devLstConfig!", __func__);
|
|
return HDF_FAILURE;
|
|
}
|
|
drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
|
|
if (drsOps == NULL || drsOps->GetUint8 == NULL || drsOps->GetChildNode == NULL) {
|
|
HDF_LOGE("%s: at least one of the paras is NULL!", __func__);
|
|
return HDF_FAILURE;
|
|
}
|
|
config->name = node->name;
|
|
|
|
if (drsOps->GetUint8(node, "bootUpTimeOut", &config->bootUpTimeOut, 0) != HDF_SUCCESS) {
|
|
HDF_LOGE("%s: bootUpTimeOut fail!", __func__);
|
|
return HDF_FAILURE;
|
|
}
|
|
|
|
resetNode = drsOps->GetChildNode(node, "reset");
|
|
if (resetNode == NULL) {
|
|
HDF_LOGE("%s: GetChildNode fail!", __func__);
|
|
return HDF_FAILURE;
|
|
}
|
|
if (ParseResetConfig(resetNode, &config->reset) != HDF_SUCCESS) {
|
|
return HDF_FAILURE;
|
|
}
|
|
|
|
do {
|
|
devPowerNode = drsOps->GetChildNode(node, "powers");
|
|
if (devPowerNode == NULL) {
|
|
HDF_LOGE("%s: GetChildNode fail!", __func__);
|
|
ret = HDF_FAILURE;
|
|
break;
|
|
}
|
|
config->powers = ParsePowersConfig(devPowerNode);
|
|
if (config->powers == NULL) {
|
|
ret = HDF_FAILURE;
|
|
break;
|
|
}
|
|
} while (false);
|
|
|
|
if (ret != HDF_SUCCESS) {
|
|
ClearChipConfig(config);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
#endif |