1 /*
2 * Copyright (c) 2022-2023 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 #include "device_resource_if.h"
10 #include "hdf_log.h"
11 #include "osal_io.h"
12 #include "osal_mem.h"
13 #include "pin/pin_core.h"
14
15 #define HDF_LOG_TAG pin_virtual
16
17 #define VIRTUAL_PIN_FUNC_MAX 6
18 #define VIRTUAL_PIN_MAX_NUMBER 16
19 #define VIRTUAL_PIN_MAX_PIN_COUNT 32
20
21
22 struct VirtualPinDesc {
23 const char *pinName;
24 uint32_t init;
25 uint32_t index;
26 int32_t pullType;
27 int32_t strength;
28 const char *curFunc;
29 const char *func[VIRTUAL_PIN_FUNC_MAX];
30 };
31
32 struct VirtualPinCntlr {
33 struct PinCntlr cntlr;
34 struct VirtualPinDesc *desc;
35 uint16_t number;
36 uint32_t pinCount;
37 };
38
VirtualPinSetPull(struct PinCntlr * cntlr,uint32_t index,enum PinPullType pullType)39 static int32_t VirtualPinSetPull(struct PinCntlr *cntlr, uint32_t index, enum PinPullType pullType)
40 {
41 struct VirtualPinCntlr *virtual = NULL;
42
43 if (cntlr == NULL) {
44 HDF_LOGE("VirtualPinSetPull: cntlr is null!");
45 return HDF_ERR_INVALID_OBJECT;
46 }
47
48 if (index >= cntlr->pinCount) {
49 HDF_LOGE("VirtualPinSetPull: invalid index:%u!", index);
50 return HDF_ERR_INVALID_PARAM;
51 }
52
53 virtual = (struct VirtualPinCntlr *)cntlr;
54 virtual->desc[index].pullType = pullType;
55 return HDF_SUCCESS;
56 }
57
VirtualPinGetPull(struct PinCntlr * cntlr,uint32_t index,enum PinPullType * pullType)58 static int32_t VirtualPinGetPull(struct PinCntlr *cntlr, uint32_t index, enum PinPullType *pullType)
59 {
60 struct VirtualPinCntlr *virtual = NULL;
61
62 if (cntlr == NULL || pullType == NULL) {
63 HDF_LOGE("VirtualPinGetPull: cntlr or pullType is null!");
64 return HDF_ERR_INVALID_OBJECT;
65 }
66
67 if (index >= cntlr->pinCount) {
68 HDF_LOGE("VirtualPinGetPull: invalid index:%u!", index);
69 return HDF_ERR_INVALID_PARAM;
70 }
71
72 virtual = (struct VirtualPinCntlr *)cntlr;
73 *pullType = virtual->desc[index].pullType;
74 return HDF_SUCCESS;
75 }
76
VirtualPinSetStrength(struct PinCntlr * cntlr,uint32_t index,uint32_t strength)77 static int32_t VirtualPinSetStrength(struct PinCntlr *cntlr, uint32_t index, uint32_t strength)
78 {
79 struct VirtualPinCntlr *virtual = NULL;
80
81 if (cntlr == NULL) {
82 HDF_LOGE("VirtualPinSetStrength: cntlr is null!");
83 return HDF_ERR_INVALID_OBJECT;
84 }
85
86 if (index >= cntlr->pinCount) {
87 HDF_LOGE("VirtualPinSetStrength: invalid index:%u!", index);
88 return HDF_ERR_INVALID_PARAM;
89 }
90
91 virtual = (struct VirtualPinCntlr *)cntlr;
92 virtual->desc[index].strength = strength;
93 return HDF_SUCCESS;
94 }
95
VirtualPinGetStrength(struct PinCntlr * cntlr,uint32_t index,uint32_t * strength)96 static int32_t VirtualPinGetStrength(struct PinCntlr *cntlr, uint32_t index, uint32_t *strength)
97 {
98 struct VirtualPinCntlr *virtual = NULL;
99
100 if (cntlr == NULL || strength == NULL) {
101 HDF_LOGE("VirtualPinGetStrength: cntlr or strength is null!");
102 return HDF_ERR_INVALID_OBJECT;
103 }
104
105 if (index >= cntlr->pinCount) {
106 HDF_LOGE("VirtualPinGetStrength: invalid index:%u!", index);
107 return HDF_ERR_INVALID_PARAM;
108 }
109
110 virtual = (struct VirtualPinCntlr *)cntlr;
111 *strength = virtual->desc[index].strength;
112 return HDF_SUCCESS;
113 }
114
VirtualPinSetFunc(struct PinCntlr * cntlr,uint32_t index,const char * funcName)115 static int32_t VirtualPinSetFunc(struct PinCntlr *cntlr, uint32_t index, const char *funcName)
116 {
117 int ret;
118 uint32_t funcNum;
119 struct VirtualPinCntlr *virtual = NULL;
120
121 if (cntlr == NULL || funcName == NULL) {
122 HDF_LOGE("VirtualPinSetFunc: cntlr or funcName is null!");
123 return HDF_ERR_INVALID_OBJECT;
124 }
125
126 if (index >= cntlr->pinCount) {
127 HDF_LOGE("VirtualPinSetFunc: invalid index:%u!", index);
128 return HDF_ERR_INVALID_PARAM;
129 }
130
131 virtual = (struct VirtualPinCntlr *)cntlr;
132
133 for (funcNum = 0; funcNum < VIRTUAL_PIN_FUNC_MAX; funcNum++) {
134 ret = strcmp(funcName, virtual->desc[index].func[funcNum]);
135 if (ret == 0) {
136 virtual->desc[index].curFunc = virtual->desc[index].func[funcNum];
137 return HDF_SUCCESS;
138 }
139 }
140 HDF_LOGE("VirtualPinSetFunc: set pin function fail!");
141 return HDF_ERR_IO;
142 }
143
VirtualPinGetFunc(struct PinCntlr * cntlr,uint32_t index,const char ** funcName)144 static int32_t VirtualPinGetFunc(struct PinCntlr *cntlr, uint32_t index, const char **funcName)
145 {
146 struct VirtualPinCntlr *virtual = NULL;
147
148 if (cntlr == NULL || funcName == NULL) {
149 HDF_LOGE("VirtualPinGetFunc: cntlr or funcName is null!");
150 return HDF_ERR_INVALID_OBJECT;
151 }
152
153 if (index >= cntlr->pinCount) {
154 HDF_LOGE("VirtualPinGetFunc: invalid index:%u!", index);
155 return HDF_ERR_INVALID_PARAM;
156 }
157
158 virtual = (struct VirtualPinCntlr *)cntlr;
159 *funcName = virtual->desc[index].curFunc;
160 HDF_LOGD("VirtualPinGetFunc: get pin function success!");
161 return HDF_SUCCESS;
162 }
163
164 static struct PinCntlrMethod g_method = {
165 .SetPinPull = VirtualPinSetPull,
166 .GetPinPull = VirtualPinGetPull,
167 .SetPinStrength = VirtualPinSetStrength,
168 .GetPinStrength = VirtualPinGetStrength,
169 .SetPinFunc = VirtualPinSetFunc,
170 .GetPinFunc = VirtualPinGetFunc,
171 };
172
VirtualPinReadFunc(struct VirtualPinDesc * desc,const struct DeviceResourceNode * node,struct DeviceResourceIface * drsOps)173 static int32_t VirtualPinReadFunc(struct VirtualPinDesc *desc,
174 const struct DeviceResourceNode *node, struct DeviceResourceIface *drsOps)
175 {
176 int32_t ret;
177 uint32_t funcNum = 0;
178
179 ret = drsOps->GetString(node, "F0", &desc->func[funcNum], "NULL");
180 if (ret != HDF_SUCCESS) {
181 HDF_LOGE("VirtualPinReadFunc: read F0 fail, ret: %d!", ret);
182 return ret;
183 }
184
185 funcNum++;
186 ret = drsOps->GetString(node, "F1", &desc->func[funcNum], "NULL");
187 if (ret != HDF_SUCCESS) {
188 HDF_LOGE("VirtualPinReadFunc: read F1 fail, ret: %d!", ret);
189 return ret;
190 }
191
192 funcNum++;
193 ret = drsOps->GetString(node, "F2", &desc->func[funcNum], "NULL");
194 if (ret != HDF_SUCCESS) {
195 HDF_LOGE("VirtualPinReadFunc: read F2 fail, ret: %d!", ret);
196 return ret;
197 }
198
199 funcNum++;
200 ret = drsOps->GetString(node, "F3", &desc->func[funcNum], "NULL");
201 if (ret != HDF_SUCCESS) {
202 HDF_LOGE("VirtualPinReadFunc: read F3 fail, ret: %d!", ret);
203 return ret;
204 }
205
206 funcNum++;
207 ret = drsOps->GetString(node, "F4", &desc->func[funcNum], "NULL");
208 if (ret != HDF_SUCCESS) {
209 HDF_LOGE("VirtualPinReadFunc: read F4 fail, ret: %d!", ret);
210 return ret;
211 }
212
213 funcNum++;
214 ret = drsOps->GetString(node, "F5", &desc->func[funcNum], "NULL");
215 if (ret != HDF_SUCCESS) {
216 HDF_LOGE("VirtualPinReadFunc: read F5 fail, ret: %d!", ret);
217 return ret;
218 }
219 return HDF_SUCCESS;
220 }
221
VirtualPinParsePinNode(const struct DeviceResourceNode * node,struct VirtualPinCntlr * virtual,int32_t index)222 static int32_t VirtualPinParsePinNode(const struct DeviceResourceNode *node,
223 struct VirtualPinCntlr *virtual, int32_t index)
224 {
225 int32_t ret;
226 struct DeviceResourceIface *drsOps = NULL;
227
228 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
229 if (drsOps == NULL || drsOps->GetUint32 == NULL || drsOps->GetString == NULL) {
230 HDF_LOGE("VirtualPinParsePinNode: invalid drs or ops!");
231 return HDF_FAILURE;
232 }
233 ret = drsOps->GetString(node, "pinName", &virtual->desc[index].pinName, "NULL");
234 if (ret != HDF_SUCCESS) {
235 HDF_LOGE("VirtualPinParsePinNode: read pinName fail, ret: %d!", ret);
236 return ret;
237 }
238
239 ret = drsOps->GetUint32(node, "init", &virtual->desc[index].init, 0);
240 if (ret != HDF_SUCCESS) {
241 HDF_LOGE("VirtualPinParsePinNode: read init fail, ret: %d!", ret);
242 return ret;
243 }
244
245 ret = VirtualPinReadFunc(&virtual->desc[index], node, drsOps);
246 if (ret != HDF_SUCCESS) {
247 HDF_LOGE("VirtualPinParsePinNode: pin read func fail, ret: %d!", ret);
248 return ret;
249 }
250 virtual->cntlr.pins[index].pinName = virtual->desc[index].pinName;
251 virtual->cntlr.pins[index].priv = (void *)node;
252 virtual->desc[index].curFunc = virtual->desc[index].func[0]; // default func
253 HDF_LOGD("VirtualPinParsePinNode: pin parse pin node %s success!", virtual->cntlr.pins[index].pinName);
254 return HDF_SUCCESS;
255 }
256
VirtualPinCntlrInit(struct HdfDeviceObject * device,struct VirtualPinCntlr * virtual)257 static int32_t VirtualPinCntlrInit(struct HdfDeviceObject *device, struct VirtualPinCntlr *virtual)
258 {
259 struct DeviceResourceIface *drsOps = NULL;
260 int32_t ret;
261
262 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
263 if (drsOps == NULL || drsOps->GetUint32 == NULL || drsOps->GetUint16 == NULL) {
264 HDF_LOGE("VirtualPinCntlrInit: invalid drs ops fail!");
265 return HDF_FAILURE;
266 }
267
268 ret = drsOps->GetUint16(device->property, "number", &virtual->number, 0);
269 if (ret != HDF_SUCCESS) {
270 HDF_LOGE("VirtualPinCntlrInit: read number fail, ret: %d!", ret);
271 return ret;
272 }
273 if (virtual->number > VIRTUAL_PIN_MAX_NUMBER) {
274 HDF_LOGE("VirtualPinCntlrInit: invalid number:%hu!", virtual->number);
275 return HDF_ERR_INVALID_PARAM;
276 }
277
278 ret = drsOps->GetUint32(device->property, "pinCount", &virtual->pinCount, 0);
279 if (ret != HDF_SUCCESS) {
280 HDF_LOGE("VirtualPinCntlrInit: read pinCount fail, ret: %d!", ret);
281 return ret;
282 }
283 if (virtual->pinCount >= VIRTUAL_PIN_MAX_PIN_COUNT) {
284 HDF_LOGE("VirtualPinCntlrInit: invalid pinCount:%u!", virtual->pinCount);
285 return HDF_ERR_INVALID_PARAM;
286 }
287
288 virtual->cntlr.pinCount = virtual->pinCount;
289 virtual->cntlr.number = virtual->number;
290 virtual->desc = (struct VirtualPinDesc *)OsalMemCalloc(sizeof(struct VirtualPinDesc) * virtual->pinCount);
291 if (virtual->desc == NULL) {
292 HDF_LOGE("VirtualPinCntlrInit: memcalloc virtual desc fail!");
293 return HDF_ERR_MALLOC_FAIL;
294 }
295 virtual->cntlr.pins = (struct PinDesc *)OsalMemCalloc(sizeof(struct PinDesc) * virtual->pinCount);
296 if (virtual->cntlr.pins == NULL) {
297 HDF_LOGE("VirtualPinCntlrInit: memcalloc virtual cntlr pins fail!");
298 OsalMemFree(virtual->desc);
299 return HDF_ERR_MALLOC_FAIL;
300 }
301 return HDF_SUCCESS;
302 }
303
VirtualPinBind(struct HdfDeviceObject * device)304 static int32_t VirtualPinBind(struct HdfDeviceObject *device)
305 {
306 (void)device;
307 return HDF_SUCCESS;
308 }
309
VirtualPinInit(struct HdfDeviceObject * device)310 static int32_t VirtualPinInit(struct HdfDeviceObject *device)
311 {
312 int32_t ret;
313 int32_t index = 0;
314 const struct DeviceResourceNode *childNode = NULL;
315 struct VirtualPinCntlr *virtual = NULL;
316
317 virtual = (struct VirtualPinCntlr *)OsalMemCalloc(sizeof(*virtual));
318 if (virtual == NULL) {
319 HDF_LOGE("VirtualPinInit: memcalloc virtual fail!");
320 return HDF_ERR_MALLOC_FAIL;
321 }
322
323 ret = VirtualPinCntlrInit(device, virtual);
324 if (ret != HDF_SUCCESS) {
325 HDF_LOGE("VirtualPinInit: pin cntlr init fail, ret: %d!", ret);
326 OsalMemFree(virtual);
327 return ret;
328 }
329
330 DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) {
331 ret = VirtualPinParsePinNode(childNode, virtual, index);
332 if (ret != HDF_SUCCESS) {
333 HDF_LOGE("VirtualPinInit: pin parse node fail, ret: %d!", ret);
334 OsalMemFree(virtual);
335 OsalMemFree(virtual->desc);
336 OsalMemFree(virtual->cntlr.pins);
337 return ret;
338 }
339 index++;
340 }
341
342 virtual->cntlr.method = &g_method;
343 ret = PinCntlrAdd(&virtual->cntlr);
344 if (ret != HDF_SUCCESS) {
345 HDF_LOGE("VirtualPinInit: add pin cntlr fail, ret: %d!", ret);
346 OsalMemFree(virtual);
347 OsalMemFree(virtual->desc);
348 OsalMemFree(virtual->cntlr.pins);
349 return ret;
350 }
351 HDF_LOGI("VirtualPinInit: pin init success!");
352 return HDF_SUCCESS;
353 }
354
VirtualPinRelease(struct HdfDeviceObject * device)355 static void VirtualPinRelease(struct HdfDeviceObject *device)
356 {
357 int32_t ret;
358 uint16_t number;
359 struct PinCntlr *cntlr = NULL;
360 struct VirtualPinCntlr *virtual = NULL;
361 struct DeviceResourceIface *drsOps = NULL;
362
363 HDF_LOGI("VirtualPinRelease: enter!");
364 if (device == NULL || device->property == NULL) {
365 HDF_LOGE("VirtualPinRelease: device or property is null!");
366 return;
367 }
368 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
369 if (drsOps == NULL || drsOps->GetUint16 == NULL) {
370 HDF_LOGE("VirtualPinRelease: invalid drs ops!");
371 return;
372 }
373
374 ret = drsOps->GetUint16(device->property, "number", &number, 0);
375 if (ret != HDF_SUCCESS) {
376 HDF_LOGE("VirtualPinRelease: read cntlr number fail, ret: %d!", ret);
377 return;
378 }
379
380 cntlr = PinCntlrGetByNumber(number);
381 if (cntlr == NULL) {
382 HDF_LOGE("VirtualPinRelease: cntlr is null!");
383 return;
384 }
385
386 PinCntlrRemove(cntlr);
387 virtual = (struct VirtualPinCntlr *)cntlr;
388 OsalMemFree(virtual->desc);
389 OsalMemFree(virtual->cntlr.pins);
390 OsalMemFree(virtual);
391 }
392
393 static struct HdfDriverEntry g_virtualPinDriverEntry = {
394 .moduleVersion = 1,
395 .Bind = VirtualPinBind,
396 .Init = VirtualPinInit,
397 .Release = VirtualPinRelease,
398 .moduleName = "virtual_pin_driver",
399 };
400 HDF_INIT(g_virtualPinDriverEntry);
401