* 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