1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #ifndef HDF_CHIP_CONFIG_H
10 #define HDF_CHIP_CONFIG_H
11
12 #include "device_resource_if.h"
13 #include "hdf_base.h"
14 #include "hdf_log.h"
15 #include "osal/osal_mem.h"
16 #include "securec.h"
17
18 #define HDF_CHIP_MAX_POWER_SUPPORTED 2
19
20 #define BUS_FUNC_MAX 1
21
22 enum PowerType
23 {
24 POWER_TYPE_ALWAYS_ON = 0,
25 POWER_TYPE_GPIO
26 };
27
28 struct HdfConfigGpioBasedSwitch {
29 uint8_t gpioId;
30 uint8_t activeLevel;
31 };
32
33 struct HdfPowerConfig {
34 uint8_t powerSeqDelay;
35 uint8_t type;
36 union {
37 struct HdfConfigGpioBasedSwitch gpio;
38 };
39 };
40
41 struct HdfPowersConfig {
42 uint8_t powerCount;
43 struct HdfPowerConfig power[0];
44 };
45
46 enum ResetType
47 {
48 RESET_TYPE_NOT_MANAGEABLE = 0,
49 RESET_TYPE_GPIO
50 };
51
52 struct HdfResetConfig {
53 union {
54 struct HdfConfigGpioBasedSwitch gpio;
55 };
56 uint8_t resetType;
57 uint8_t resetHoldTime;
58 };
59
60 struct HdfChipConfig {
61 const char *name;
62 struct HdfPowersConfig *powers;
63 struct HdfResetConfig reset;
64 uint8_t bootUpTimeOut;
65 };
66
ParsePowerConfig(const struct DeviceResourceNode * node,struct HdfPowerConfig * config)67 static inline int ParsePowerConfig(const struct DeviceResourceNode *node, struct HdfPowerConfig *config) {
68 struct DeviceResourceIface *drsOps = NULL;
69 if (node == NULL || config == NULL) {
70 HDF_LOGE("%s: one of the input para is NULL!", __func__);
71 return HDF_FAILURE;
72 }
73 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
74 if (drsOps == NULL || drsOps->GetUint8 == NULL) {
75 HDF_LOGE("%s: at least one of the paras is NULL!", __func__);
76 return HDF_FAILURE;
77 }
78
79 if (drsOps->GetUint8(node, "powerSeqDelay", &config->powerSeqDelay, 0) != HDF_SUCCESS) {
80 HDF_LOGE("%s: powersSeqDelay fail!", __func__);
81 return HDF_FAILURE;
82 }
83
84 if (drsOps->GetUint8(node, "powerType", &config->type, 0) != HDF_SUCCESS) {
85 HDF_LOGE("%s: type fail!", __func__);
86 return HDF_FAILURE;
87 }
88
89 if (config->type == POWER_TYPE_GPIO) {
90 if (drsOps->GetUint8(node, "gpioId", &config->gpio.gpioId, 0) != HDF_SUCCESS) {
91 HDF_LOGE("%s: gpioId fail!", __func__);
92 return HDF_FAILURE;
93 }
94 if (drsOps->GetUint8(node, "activeLevel", &config->gpio.activeLevel, 0) != HDF_SUCCESS) {
95 HDF_LOGE("%s: activeLevel fail!", __func__);
96 return HDF_FAILURE;
97 }
98 }
99
100 return HDF_SUCCESS;
101 }
102
ParsePowersConfig(const struct DeviceResourceNode * node)103 static inline struct HdfPowersConfig *ParsePowersConfig(const struct DeviceResourceNode *node) {
104 struct DeviceResourceIface *drsOps = NULL;
105 struct DeviceResourceNode *childNode = NULL;
106 struct HdfPowersConfig *config = NULL;
107 uint8_t nodeCount = 0;
108 int32_t ret;
109 if (node == NULL) {
110 HDF_LOGE("%s: input para is NULL!", __func__);
111 return NULL;
112 }
113 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
114 if (drsOps == NULL || drsOps->GetChildNode == NULL) {
115 HDF_LOGE("%s: at least one of the paras is NULL!", __func__);
116 return NULL;
117 }
118 DEV_RES_NODE_FOR_EACH_CHILD_NODE(node, childNode) { ++nodeCount; }
119 if (nodeCount > HDF_CHIP_MAX_POWER_SUPPORTED) {
120 return NULL;
121 }
122 config = OsalMemCalloc(sizeof(struct HdfPowersConfig) + nodeCount * sizeof(struct HdfPowerConfig));
123 if (config == NULL) {
124 return NULL;
125 }
126 config->powerCount = nodeCount;
127 for (uint8_t i = 0; i < nodeCount; i++) {
128 char buff[32] = {0};
129 ret = snprintf_s(buff, 32, 32, "power%d", i);
130 if (ret < 0) {
131 HDF_LOGE("%s:snprintf_s failed!ret=%d, i=%d", __func__, ret, i);
132 break;
133 }
134 const struct DeviceResourceNode *powerNode = drsOps->GetChildNode(node, buff);
135 if (powerNode == NULL) {
136 HDF_LOGE("%s:Can not get node %s", __func__, buff);
137 ret = HDF_FAILURE;
138 break;
139 }
140 ret = ParsePowerConfig(powerNode, config->power + i);
141 if (ret != HDF_SUCCESS) {
142 HDF_LOGE("%s:parse node %s failed!ret=%d", __func__, buff, ret);
143 break;
144 }
145 }
146
147 if (ret != HDF_SUCCESS) {
148 OsalMemFree(config);
149 config = NULL;
150 }
151 return config;
152 }
153
ParseResetConfig(const struct DeviceResourceNode * node,struct HdfResetConfig * reset)154 static inline int ParseResetConfig(const struct DeviceResourceNode *node, struct HdfResetConfig *reset) {
155 struct DeviceResourceIface *drsOps = NULL;
156 if (node == NULL || reset == NULL) {
157 HDF_LOGE("%s: at least one of the paras is NULL!", __func__);
158 return HDF_FAILURE;
159 }
160
161 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
162 if (drsOps == NULL || drsOps->GetUint8 == NULL) {
163 HDF_LOGE("%s: at least one of the paras is NULL!", __func__);
164 return HDF_FAILURE;
165 }
166
167 if (drsOps->GetUint8(node, "resetType", &reset->resetType, 0) != HDF_SUCCESS) {
168 HDF_LOGE("%s: powersSeqDelay fail!", __func__);
169 return HDF_FAILURE;
170 }
171 if (reset->resetType == RESET_TYPE_GPIO) {
172 if (drsOps->GetUint8(node, "gpioId", &reset->gpio.gpioId, 0) != HDF_SUCCESS) {
173 HDF_LOGE("%s: gpioId fail!", __func__);
174 return HDF_FAILURE;
175 }
176
177 if (drsOps->GetUint8(node, "activeLevel", &reset->gpio.activeLevel, 0) != HDF_SUCCESS) {
178 HDF_LOGE("%s: read activeLevel fail!", __func__);
179 return HDF_FAILURE;
180 }
181
182 if (drsOps->GetUint8(node, "resetHoldTime", &reset->resetHoldTime, 0) != HDF_SUCCESS) {
183 HDF_LOGE("%s: read resetHoldTime fail!", __func__);
184 return HDF_FAILURE;
185 }
186 }
187 return HDF_SUCCESS;
188 }
189
ClearChipConfig(struct HdfChipConfig * config)190 static inline void ClearChipConfig(struct HdfChipConfig *config) {
191
192 if (config->powers != NULL) {
193 OsalMemFree(config->powers);
194 config->powers = NULL;
195 }
196 }
197
ParseChipConfig(const struct DeviceResourceNode * node,struct HdfChipConfig * config)198 static inline int32_t ParseChipConfig(const struct DeviceResourceNode *node, struct HdfChipConfig *config) {
199 struct DeviceResourceIface *drsOps = NULL;
200 const struct DeviceResourceNode *devPowerNode = NULL;
201 const struct DeviceResourceNode *resetNode = NULL;
202 int32_t ret = HDF_SUCCESS;
203 if (node == NULL || config == NULL) {
204 HDF_LOGE("%s: invalid node or devLstConfig!", __func__);
205 return HDF_FAILURE;
206 }
207 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
208 if (drsOps == NULL || drsOps->GetUint8 == NULL || drsOps->GetChildNode == NULL) {
209 HDF_LOGE("%s: at least one of the paras is NULL!", __func__);
210 return HDF_FAILURE;
211 }
212 config->name = node->name;
213
214 if (drsOps->GetUint8(node, "bootUpTimeOut", &config->bootUpTimeOut, 0) != HDF_SUCCESS) {
215 HDF_LOGE("%s: bootUpTimeOut fail!", __func__);
216 return HDF_FAILURE;
217 }
218
219 resetNode = drsOps->GetChildNode(node, "reset");
220 if (resetNode == NULL) {
221 HDF_LOGE("%s: GetChildNode fail!", __func__);
222 return HDF_FAILURE;
223 }
224 if (ParseResetConfig(resetNode, &config->reset) != HDF_SUCCESS) {
225 return HDF_FAILURE;
226 }
227
228 do {
229 devPowerNode = drsOps->GetChildNode(node, "powers");
230 if (devPowerNode == NULL) {
231 HDF_LOGE("%s: GetChildNode fail!", __func__);
232 ret = HDF_FAILURE;
233 break;
234 }
235 config->powers = ParsePowersConfig(devPowerNode);
236 if (config->powers == NULL) {
237 ret = HDF_FAILURE;
238 break;
239 }
240 } while (false);
241
242 if (ret != HDF_SUCCESS) {
243 ClearChipConfig(config);
244 }
245 return ret;
246 }
247
248 #endif