• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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