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 #include "pin_core.h"
10 #include "hdf_log.h"
11
12 #define HDF_LOG_TAG pin_core
13
14 #define MAX_CNT_PER_CNTLR 20
15
16 static struct DListHead g_cntlrListHead;
17 static OsalSpinlock g_listLock;
18 static uint32_t g_irqSave;
19
PinCntlrListGet(void)20 static struct DListHead *PinCntlrListGet(void)
21 {
22 static struct DListHead *head = NULL;
23 uint32_t irqSave;
24 if (head == NULL) {
25 head = &g_cntlrListHead;
26 DListHeadInit(head);
27 OsalSpinInit(&g_listLock);
28 }
29 while (OsalSpinLockIrqSave(&g_listLock, &irqSave) != HDF_SUCCESS);
30 g_irqSave = irqSave;
31 return head;
32 }
33
PinCntlrListPut(void)34 static void PinCntlrListPut(void)
35 {
36 (void)OsalSpinUnlockIrqRestore(&g_listLock, &g_irqSave);
37 }
38
PinCntlrAdd(struct PinCntlr * cntlr)39 int32_t PinCntlrAdd(struct PinCntlr *cntlr)
40 {
41 struct DListHead *head = NULL;
42
43 if (cntlr == NULL) {
44 HDF_LOGE("%s: invalid object cntlr is NULL!", __func__);
45 return HDF_ERR_INVALID_OBJECT;
46 }
47 DListHeadInit(&cntlr->node);
48
49 if (cntlr->method == NULL) {
50 HDF_LOGE("%s: no method supplied!", __func__);
51 return HDF_ERR_INVALID_OBJECT;
52 }
53
54 if (cntlr->pinCount >= MAX_CNT_PER_CNTLR) {
55 HDF_LOGE("%s: invalid pinCount:%u", __func__, cntlr->pinCount);
56 return HDF_ERR_INVALID_PARAM;
57 }
58
59 OsalSpinInit(&cntlr->spin);
60
61 head = PinCntlrListGet();
62 DListInsertTail(&cntlr->node, head);
63 PinCntlrListPut();
64 return HDF_SUCCESS;
65 }
66
PinCntlrRemove(struct PinCntlr * cntlr)67 void PinCntlrRemove(struct PinCntlr *cntlr)
68 {
69 if (cntlr == NULL) {
70 HDF_LOGE("%s: cntlr is NULL!", __func__);
71 return;
72 }
73
74 (void)PinCntlrListGet();
75 DListRemove(&cntlr->node);
76 PinCntlrListPut();
77 (void)OsalSpinDestroy(&cntlr->spin);
78 }
79
PinCntlrGetPinDescByName(const char * pinName)80 struct PinDesc *PinCntlrGetPinDescByName(const char *pinName)
81 {
82 struct DListHead *head = NULL;
83 struct PinCntlr *cntlr = NULL;
84 struct PinCntlr *tmp = NULL;
85 uint16_t num;
86
87 if (pinName == NULL) {
88 HDF_LOGE("%s: pinName is NULL!", __func__);
89 return NULL;
90 }
91
92 head = PinCntlrListGet();
93
94 DLIST_FOR_EACH_ENTRY_SAFE(cntlr, tmp, head, struct PinCntlr, node) {
95 for (num = 0; num < cntlr->pinCount; num++) {
96 if (cntlr->pins[num].pinName == NULL) {
97 continue;
98 }
99 if (!strcmp(cntlr->pins[num].pinName, pinName)) {
100 PinCntlrListPut();
101 HDF_LOGI("%s: cntlr->pins[%d].pinName is %s!", __func__, num, cntlr->pins[num].pinName);
102 return &cntlr->pins[num];
103 }
104 }
105 }
106 PinCntlrListPut();
107 HDF_LOGE("%s: pinName:%s doesn't matching!", __func__, pinName);
108 return NULL;
109 }
110
PinCntlrGetByNumber(uint16_t number)111 struct PinCntlr *PinCntlrGetByNumber(uint16_t number)
112 {
113 struct DListHead *head = NULL;
114 struct PinCntlr *cntlr = NULL;
115 struct PinCntlr *tmp = NULL;
116
117 head = PinCntlrListGet();
118
119 DLIST_FOR_EACH_ENTRY_SAFE(cntlr, tmp, head, struct PinCntlr, node) {
120 if (cntlr->number == number) {
121 PinCntlrListPut();
122 HDF_LOGI("%s: get cntlr by number success!", __func__);
123 return cntlr;
124 }
125 }
126 PinCntlrListPut();
127 HDF_LOGE("%s: get cntlr by number error!", __func__);
128 return NULL;
129 }
130
PinCntlrGetByPin(struct PinDesc * desc)131 struct PinCntlr *PinCntlrGetByPin(struct PinDesc *desc)
132 {
133 struct DListHead *head = NULL;
134 struct PinCntlr *cntlr = NULL;
135 struct PinCntlr *tmp = NULL;
136 int32_t num;
137
138 head = PinCntlrListGet();
139
140 DLIST_FOR_EACH_ENTRY_SAFE(cntlr, tmp, head, struct PinCntlr, node) {
141 for (num = 0; num <cntlr->pinCount; num++) {
142 if (desc == &cntlr->pins[num]) {
143 PinCntlrListPut();
144 HDF_LOGI("%s: get cntlr by desc success!", __func__);
145 return cntlr;
146 }
147 }
148 }
149 PinCntlrListPut();
150 HDF_LOGE("%s: pinCtrl:%s not in any controllers!", __func__, desc->pinName);
151 return NULL;
152 }
153
GetPinIndex(struct PinCntlr * cntlr,struct PinDesc * desc)154 static int32_t GetPinIndex(struct PinCntlr *cntlr, struct PinDesc *desc)
155 {
156 uint16_t index;
157 int32_t ret;
158
159 for (index = 0; index < cntlr->pinCount; index++) {
160 if (cntlr->pins[index].pinName == NULL) {
161 HDF_LOGE("%s: cntlr->pin[index].pinName is NULL!", __func__);
162 break;
163 }
164 ret = strcmp(cntlr->pins[index].pinName, desc->pinName);
165 if (ret == 0) {
166 HDF_LOGI("%s: get pin index:%d success!", __func__, index);
167 return (int32_t)index;
168 }
169 }
170 HDF_LOGE("%s: get pin index failed!", __func__);
171 return HDF_ERR_INVALID_PARAM;
172 }
173
PinCntlrPutPin(struct PinDesc * desc)174 void PinCntlrPutPin(struct PinDesc *desc)
175 {
176 (void)desc;
177 }
178
PinCntlrSetPinPull(struct PinCntlr * cntlr,struct PinDesc * desc,enum PinPullType pullType)179 int32_t PinCntlrSetPinPull(struct PinCntlr *cntlr, struct PinDesc *desc, enum PinPullType pullType)
180 {
181 int32_t ret;
182 uint32_t index;
183 uint32_t irqSave;
184
185 if (cntlr == NULL) {
186 HDF_LOGE("%s: invalid object cntlr is NULL!", __func__);
187 return HDF_ERR_INVALID_OBJECT;
188 }
189
190 if (cntlr->method == NULL || cntlr->method->SetPinPull == NULL) {
191 HDF_LOGE("%s: method or SetPinPull is NULL", __func__);
192 return HDF_ERR_NOT_SUPPORT;
193 }
194
195 if (desc == NULL) {
196 HDF_LOGE("%s: desc is NULL", __func__);
197 return HDF_ERR_INVALID_PARAM;
198 }
199
200 index = (uint32_t)GetPinIndex(cntlr, desc);
201 if (index < HDF_SUCCESS) {
202 HDF_LOGE("%s: get pin index fail!", __func__);
203 return HDF_ERR_INVALID_PARAM;
204 }
205
206 (void)OsalSpinLockIrqSave(&cntlr->spin, &irqSave);
207 ret = cntlr->method->SetPinPull(cntlr, index, pullType);
208 (void)OsalSpinUnlockIrqRestore(&cntlr->spin, &irqSave);
209 return ret;
210 }
211
PinCntlrGetPinPull(struct PinCntlr * cntlr,struct PinDesc * desc,enum PinPullType * pullType)212 int32_t PinCntlrGetPinPull(struct PinCntlr *cntlr, struct PinDesc *desc, enum PinPullType *pullType)
213 {
214 int32_t ret;
215 uint32_t index;
216 uint32_t irqSave;
217 if (cntlr == NULL) {
218 HDF_LOGE("%s: invalid object cntlr is NULL!", __func__);
219 return HDF_ERR_INVALID_OBJECT;
220 }
221
222 if (cntlr->method == NULL || cntlr->method->GetPinPull == NULL) {
223 HDF_LOGE("%s: method or GetPinPull is NULL", __func__);
224 return HDF_ERR_NOT_SUPPORT;
225 }
226
227 if (desc == NULL) {
228 HDF_LOGE("%s: desc is NULL", __func__);
229 return HDF_ERR_INVALID_PARAM;
230 }
231
232 if (pullType == NULL) {
233 HDF_LOGE("%s: pullType is NULL", __func__);
234 return HDF_ERR_INVALID_PARAM;
235 }
236
237 index = (uint32_t)GetPinIndex(cntlr, desc);
238 if (index < HDF_SUCCESS) {
239 HDF_LOGE("%s: get pin index failed!", __func__);
240 return HDF_ERR_INVALID_PARAM;
241 }
242
243 (void)OsalSpinLockIrqSave(&cntlr->spin, &irqSave);
244 ret = cntlr->method->GetPinPull(cntlr, index, pullType);
245 (void)OsalSpinUnlockIrqRestore(&cntlr->spin, &irqSave);
246
247 return ret;
248 }
249
PinCntlrSetPinStrength(struct PinCntlr * cntlr,struct PinDesc * desc,uint32_t strength)250 int32_t PinCntlrSetPinStrength(struct PinCntlr *cntlr, struct PinDesc *desc, uint32_t strength)
251 {
252 int32_t ret;
253 uint32_t index;
254 uint32_t irqSave;
255
256 if (cntlr == NULL) {
257 HDF_LOGE("%s: invalid object cntlr is NULL!", __func__);
258 return HDF_ERR_INVALID_OBJECT;
259 }
260
261 if (cntlr->method == NULL || cntlr->method->SetPinStrength == NULL) {
262 HDF_LOGE("%s: method or SetStrength is NULL", __func__);
263 return HDF_ERR_NOT_SUPPORT;
264 }
265
266 if (desc == NULL) {
267 HDF_LOGE("%s: desc is NULL", __func__);
268 return HDF_ERR_INVALID_PARAM;
269 }
270
271 index = (uint32_t)GetPinIndex(cntlr, desc);
272 if (index < HDF_SUCCESS) {
273 HDF_LOGE("%s: get pin index fail!", __func__);
274 return HDF_ERR_INVALID_PARAM;
275 }
276
277 (void)OsalSpinLockIrqSave(&cntlr->spin, &irqSave);
278 ret = cntlr->method->SetPinStrength(cntlr, index, strength);
279 (void)OsalSpinUnlockIrqRestore(&cntlr->spin, &irqSave);
280 return ret;
281 }
282
PinCntlrGetPinStrength(struct PinCntlr * cntlr,struct PinDesc * desc,uint32_t * strength)283 int32_t PinCntlrGetPinStrength(struct PinCntlr *cntlr, struct PinDesc *desc, uint32_t *strength)
284 {
285 int32_t ret;
286 uint32_t index;
287 uint32_t irqSave;
288 if (cntlr == NULL) {
289 HDF_LOGE("%s: invalid object cntlr is NULL!", __func__);
290 return HDF_ERR_INVALID_OBJECT;
291 }
292
293 if (cntlr->method == NULL || cntlr->method->GetPinStrength == NULL) {
294 HDF_LOGE("%s: method or GetStrength is NULL", __func__);
295 return HDF_ERR_NOT_SUPPORT;
296 }
297
298 if (desc == NULL) {
299 HDF_LOGE("%s: desc is NULL", __func__);
300 return HDF_ERR_INVALID_PARAM;
301 }
302
303 if (strength == NULL) {
304 HDF_LOGE("%s: strength is NULL", __func__);
305 return HDF_ERR_INVALID_PARAM;
306 }
307
308 index = (uint32_t)GetPinIndex(cntlr, desc);
309 if (index < HDF_SUCCESS) {
310 HDF_LOGE("%s: get pin index failed!", __func__);
311 return HDF_ERR_INVALID_PARAM;
312 }
313
314 (void)OsalSpinLockIrqSave(&cntlr->spin, &irqSave);
315 ret = cntlr->method->GetPinStrength(cntlr, index, strength);
316 (void)OsalSpinUnlockIrqRestore(&cntlr->spin, &irqSave);
317
318 return ret;
319 }
320
PinCntlrSetPinFunc(struct PinCntlr * cntlr,struct PinDesc * desc,const char * funcName)321 int32_t PinCntlrSetPinFunc(struct PinCntlr *cntlr, struct PinDesc *desc, const char *funcName)
322 {
323 int32_t ret;
324 uint32_t index;
325 uint32_t irqSave;
326
327 if (cntlr == NULL) {
328 HDF_LOGE("%s: invalid object cntlr is NULL!", __func__);
329 return HDF_ERR_INVALID_OBJECT;
330 }
331
332 if (cntlr->method == NULL || cntlr->method->SetPinFunc == NULL) {
333 HDF_LOGE("%s: method or SetPinFunc is NULL", __func__);
334 return HDF_ERR_NOT_SUPPORT;
335 }
336
337 if (desc == NULL) {
338 HDF_LOGE("%s: desc is NULL", __func__);
339 return HDF_ERR_INVALID_PARAM;
340 }
341
342 index = (uint32_t)GetPinIndex(cntlr, desc);
343 if (index < HDF_SUCCESS) {
344 HDF_LOGE("%s: get pin index failed!", __func__);
345 return HDF_ERR_INVALID_PARAM;
346 }
347
348 if (funcName == NULL) {
349 HDF_LOGE("%s: invalid funcName pointer", __func__);
350 return HDF_ERR_INVALID_PARAM;
351 }
352
353 (void)OsalSpinLockIrqSave(&cntlr->spin, &irqSave);
354 ret = cntlr->method->SetPinFunc(cntlr, index, funcName);
355 (void)OsalSpinUnlockIrqRestore(&cntlr->spin, &irqSave);
356 return ret;
357 }
358
PinCntlrGetPinFunc(struct PinCntlr * cntlr,struct PinDesc * desc,const char ** funcName)359 int32_t PinCntlrGetPinFunc(struct PinCntlr *cntlr, struct PinDesc *desc, const char **funcName)
360 {
361 int32_t ret;
362 uint32_t index;
363 uint32_t irqSave;
364
365 if (cntlr == NULL) {
366 HDF_LOGE("%s: invalid object cntlr is NULL!", __func__);
367 return HDF_ERR_INVALID_OBJECT;
368 }
369
370 if (cntlr->method == NULL || cntlr->method->GetPinFunc == NULL) {
371 HDF_LOGE("%s: method or SetPinFunc is NULL", __func__);
372 return HDF_ERR_NOT_SUPPORT;
373 }
374
375 if (desc == NULL) {
376 HDF_LOGE("%s: desc is NULL", __func__);
377 return HDF_ERR_INVALID_PARAM;
378 }
379
380 index = (uint32_t)GetPinIndex(cntlr, desc);
381 if (index < HDF_SUCCESS) {
382 HDF_LOGE("%s: get pin index failed!", __func__);
383 return HDF_ERR_INVALID_PARAM;
384 }
385
386 (void)OsalSpinLockIrqSave(&cntlr->spin, &irqSave);
387 ret = cntlr->method->GetPinFunc(cntlr, index, funcName);
388 (void)OsalSpinUnlockIrqRestore(&cntlr->spin, &irqSave);
389 return ret;
390 }
391