• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "pin_hi35xx.h"
17 #include "device_resource_if.h"
18 #include "hdf_log.h"
19 #include "osal_io.h"
20 #include "osal_mem.h"
21 #include "pin_core.h"
22 
23 #define HDF_LOG_TAG pin_hi35xx
24 
25 #define HI35XX_PIN_FUNC_MAX  6
26 #define HI35XX_PIN_REG_SIZE  4
27 
28 struct Hi35xxPinDesc {
29     const char *pinName;
30     uint32_t init;
31     uint32_t index;
32     int32_t pullType;
33     int32_t strength;
34     const char *func[HI35XX_PIN_FUNC_MAX];
35 };
36 
37 struct Hi35xxPinCntlr {
38     struct PinCntlr cntlr;
39     struct Hi35xxPinDesc *desc;
40     volatile unsigned char *regBase;
41     uint16_t number;
42     uint32_t regStartBasePhy;
43     uint32_t regSize;
44     uint32_t pinCount;
45 };
46 
Hi35xxPinSetPull(struct PinCntlr * cntlr,uint32_t index,enum PinPullType pullType)47 static int32_t Hi35xxPinSetPull(struct PinCntlr *cntlr, uint32_t index, enum PinPullType pullType)
48 {
49     uint32_t value;
50     struct Hi35xxPinCntlr *hi35xx = NULL;
51 
52     hi35xx = (struct Hi35xxPinCntlr *)cntlr;
53     value = OSAL_READL(hi35xx->regBase + index * HI35XX_PIN_REG_SIZE);
54     value = (value & ~PIN_PULL_TYPE_MASK) | ((uint32_t)pullType << PIN_PULL_TYPE_OFFSET);
55     OSAL_WRITEL(value, hi35xx->regBase + index * HI35XX_PIN_REG_SIZE);
56 
57     HDF_LOGD("%s: set pin Pull success.", __func__);
58     return HDF_SUCCESS;
59 }
60 
Hi35xxPinGetPull(struct PinCntlr * cntlr,uint32_t index,enum PinPullType * pullType)61 static int32_t Hi35xxPinGetPull(struct PinCntlr *cntlr, uint32_t index, enum PinPullType *pullType)
62 {
63     uint32_t value;
64     struct Hi35xxPinCntlr *hi35xx = NULL;
65     hi35xx = (struct Hi35xxPinCntlr *)cntlr;
66 
67     value = OSAL_READL(hi35xx->regBase + index * HI35XX_PIN_REG_SIZE);
68     *pullType = (enum PinPullType)((value & PIN_PULL_TYPE_MASK) >> PIN_PULL_TYPE_OFFSET);
69 
70     HDF_LOGD("%s: get pin Pull success.", __func__);
71     return HDF_SUCCESS;
72 }
73 
Hi35xxPinSetStrength(struct PinCntlr * cntlr,uint32_t index,uint32_t strength)74 static int32_t Hi35xxPinSetStrength(struct PinCntlr *cntlr, uint32_t index, uint32_t strength)
75 {
76     uint32_t value;
77     struct Hi35xxPinCntlr *hi35xx = NULL;
78 
79     hi35xx = (struct Hi35xxPinCntlr *)cntlr;
80     value = OSAL_READL(hi35xx->regBase + index * HI35XX_PIN_REG_SIZE);
81     value = (value & ~PIN_STRENGTH_MASK) | (strength << PIN_STRENGTH_OFFSET);
82     OSAL_WRITEL(value, hi35xx->regBase + index * HI35XX_PIN_REG_SIZE);
83     HDF_LOGD("%s: set pin Strength success.", __func__);
84     return HDF_SUCCESS;
85 }
86 
Hi35xxPinGetStrength(struct PinCntlr * cntlr,uint32_t index,uint32_t * strength)87 static int32_t Hi35xxPinGetStrength(struct PinCntlr *cntlr, uint32_t index, uint32_t *strength)
88 {
89     uint32_t value;
90     struct Hi35xxPinCntlr *hi35xx = NULL;
91     hi35xx = (struct Hi35xxPinCntlr *)cntlr;
92 
93     value = OSAL_READL(hi35xx->regBase + index * HI35XX_PIN_REG_SIZE);
94     *strength = (value & PIN_STRENGTH_MASK) >> PIN_STRENGTH_OFFSET;
95     HDF_LOGD("%s: get pin Strength success.", __func__);
96     return HDF_SUCCESS;
97 }
98 
Hi35xxPinSetFunc(struct PinCntlr * cntlr,uint32_t index,const char * funcName)99 static int32_t Hi35xxPinSetFunc(struct PinCntlr *cntlr, uint32_t index, const char *funcName)
100 {
101     uint32_t value;
102     int ret;
103     uint32_t funcNum;
104     struct Hi35xxPinCntlr *hi35xx = NULL;
105 
106     hi35xx = (struct Hi35xxPinCntlr *)cntlr;
107 
108     for (funcNum = 0; funcNum < HI35XX_PIN_FUNC_MAX; funcNum++) {
109         ret = strcmp(funcName, hi35xx->desc[index].func[funcNum]);
110         if (ret == 0) {
111             value = OSAL_READL(hi35xx->regBase + index * HI35XX_PIN_REG_SIZE);
112             value = (value & ~PIN_FUNC_MASK) | funcNum;
113             OSAL_WRITEL(value, hi35xx->regBase + index * HI35XX_PIN_REG_SIZE);
114             HDF_LOGD("%s: set pin function success.", __func__);
115             return HDF_SUCCESS;
116         }
117     }
118     HDF_LOGE("%s: set pin Function failed.", __func__);
119     return HDF_ERR_IO;
120 }
121 
Hi35xxPinGetFunc(struct PinCntlr * cntlr,uint32_t index,const char ** funcName)122 static int32_t Hi35xxPinGetFunc(struct PinCntlr *cntlr, uint32_t index, const char **funcName)
123 {
124     uint32_t value;
125     uint32_t funcNum;
126     struct Hi35xxPinCntlr *hi35xx = NULL;
127 
128     hi35xx = (struct Hi35xxPinCntlr *)cntlr;
129 
130     value = OSAL_READL(hi35xx->regBase + index * HI35XX_PIN_REG_SIZE);
131     funcNum = value & PIN_FUNC_MASK;
132     *funcName = hi35xx->desc[index].func[funcNum];
133     HDF_LOGD("%s: get pin function success.", __func__);
134     return HDF_SUCCESS;
135 }
136 
137 static struct PinCntlrMethod g_method = {
138     .SetPinPull = Hi35xxPinSetPull,
139     .GetPinPull = Hi35xxPinGetPull,
140     .SetPinStrength = Hi35xxPinSetStrength,
141     .GetPinStrength = Hi35xxPinGetStrength,
142     .SetPinFunc = Hi35xxPinSetFunc,
143     .GetPinFunc = Hi35xxPinGetFunc,
144 };
145 
Hi35xxPinReadFunc(struct Hi35xxPinDesc * desc,const struct DeviceResourceNode * node,struct DeviceResourceIface * drsOps)146 static int32_t Hi35xxPinReadFunc(struct Hi35xxPinDesc *desc,
147                                  const struct DeviceResourceNode *node,
148                                  struct DeviceResourceIface *drsOps)
149 {
150     int32_t ret;
151     uint32_t funcNum = 0;
152 
153     ret = drsOps->GetString(node, "F0", &desc->func[funcNum], "NULL");
154     if (ret != HDF_SUCCESS) {
155         HDF_LOGE("%s: read F0 failed", __func__);
156         return ret;
157     }
158 
159     funcNum++;
160     ret = drsOps->GetString(node, "F1", &desc->func[funcNum], "NULL");
161     if (ret != HDF_SUCCESS) {
162         HDF_LOGE("%s: read F1 failed", __func__);
163         return ret;
164     }
165 
166     funcNum++;
167     ret = drsOps->GetString(node, "F2", &desc->func[funcNum], "NULL");
168     if (ret != HDF_SUCCESS) {
169         HDF_LOGE("%s: read F2 failed", __func__);
170         return ret;
171     }
172 
173     funcNum++;
174     ret = drsOps->GetString(node, "F3", &desc->func[funcNum], "NULL");
175     if (ret != HDF_SUCCESS) {
176         HDF_LOGE("%s: read F3 failed", __func__);
177         return ret;
178     }
179 
180     funcNum++;
181     ret = drsOps->GetString(node, "F4", &desc->func[funcNum], "NULL");
182     if (ret != HDF_SUCCESS) {
183         HDF_LOGE("%s: read F4 failed", __func__);
184         return ret;
185     }
186 
187     funcNum++;
188     ret = drsOps->GetString(node, "F5", &desc->func[funcNum], "NULL");
189     if (ret != HDF_SUCCESS) {
190         HDF_LOGE("%s: read F5 failed", __func__);
191         return ret;
192     }
193     HDF_LOGD("%s:Pin Read Func succe. F0:%s", __func__, desc->func[0]);
194 
195     return HDF_SUCCESS;
196 }
197 
Hi35xxPinParsePinNode(const struct DeviceResourceNode * node,struct Hi35xxPinCntlr * hi35xx,int32_t index)198 static int32_t Hi35xxPinParsePinNode(const struct DeviceResourceNode *node,
199                                      struct Hi35xxPinCntlr *hi35xx,
200                                      int32_t index)
201 {
202     int32_t ret;
203     struct DeviceResourceIface *drsOps = NULL;
204 
205     drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
206     if (drsOps == NULL || drsOps->GetUint32 == NULL || drsOps->GetString == NULL) {
207         HDF_LOGE("%s: invalid drs ops fail!", __func__);
208         return HDF_FAILURE;
209     }
210     ret = drsOps->GetString(node, "pinName", &hi35xx->desc[index].pinName, "NULL");
211     if (ret != HDF_SUCCESS) {
212         HDF_LOGE("%s: read pinName failed", __func__);
213         return ret;
214     }
215 
216     ret = drsOps->GetUint32(node, "init", &hi35xx->desc[index].init, 0);
217     if (ret != HDF_SUCCESS) {
218         HDF_LOGE("%s: read init failed", __func__);
219         return ret;
220     }
221 
222     ret = Hi35xxPinReadFunc(&hi35xx->desc[index], node, drsOps);
223     if (ret != HDF_SUCCESS) {
224         HDF_LOGE("%s:Pin read Func failed", __func__);
225         return ret;
226     }
227     hi35xx->cntlr.pins[index].pinName = hi35xx->desc[index].pinName;
228     hi35xx->cntlr.pins[index].priv = (void *)node;
229     HDF_LOGD("%s:Pin Parse Pin Node success.", __func__);
230     return HDF_SUCCESS;
231 }
232 
Hi35xxPinCntlrInit(struct HdfDeviceObject * device,struct Hi35xxPinCntlr * hi35xx)233 static int32_t Hi35xxPinCntlrInit(struct HdfDeviceObject *device, struct Hi35xxPinCntlr *hi35xx)
234 {
235     struct DeviceResourceIface *drsOps = NULL;
236     int32_t ret;
237 
238     drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
239     if (drsOps == NULL || drsOps->GetUint32 == NULL || drsOps->GetUint16 == NULL) {
240         HDF_LOGE("%s: invalid drs ops fail!", __func__);
241         return HDF_FAILURE;
242     }
243     ret = drsOps->GetUint16(device->property, "number", &hi35xx->number, 0);
244     if (ret != HDF_SUCCESS) {
245         HDF_LOGE("%s: read number failed", __func__);
246         return ret;
247     }
248 
249     ret = drsOps->GetUint32(device->property, "regStartBasePhy", &hi35xx->regStartBasePhy, 0);
250     if (ret != HDF_SUCCESS) {
251         HDF_LOGE("%s: read regStartBasePhy failed", __func__);
252         return ret;
253     }
254     ret = drsOps->GetUint32(device->property, "regSize", &hi35xx->regSize, 0);
255     if (ret != HDF_SUCCESS) {
256         HDF_LOGE("%s: read regSize failed", __func__);
257         return ret;
258     }
259     ret = drsOps->GetUint32(device->property, "pinCount", &hi35xx->pinCount, 0);
260     if (ret != HDF_SUCCESS) {
261         HDF_LOGE("%s: read pinCount failed", __func__);
262         return ret;
263     }
264     hi35xx->cntlr.pinCount = hi35xx->pinCount;
265     hi35xx->cntlr.number = hi35xx->number;
266     hi35xx->regBase = OsalIoRemap(hi35xx->regStartBasePhy, hi35xx->regSize);
267     if (hi35xx->regBase == NULL) {
268         HDF_LOGE("%s: remap Pin base failed", __func__);
269         return HDF_ERR_IO;
270     }
271     hi35xx->desc = (struct Hi35xxPinDesc *)OsalMemCalloc(sizeof(struct Hi35xxPinDesc) * hi35xx->pinCount);
272     hi35xx->cntlr.pins = (struct PinDesc *)OsalMemCalloc(sizeof(struct PinDesc) * hi35xx->pinCount);
273     HDF_LOGD("%s: Pin Cntlr Init success", __func__);
274     return HDF_SUCCESS;
275 }
276 
Hi35xxPinBind(struct HdfDeviceObject * device)277 static int32_t Hi35xxPinBind(struct HdfDeviceObject *device)
278 {
279     (void)device;
280     HDF_LOGD("%s: success", __func__);
281     return HDF_SUCCESS;
282 }
283 
Hi35xxPinInit(struct HdfDeviceObject * device)284 static int32_t Hi35xxPinInit(struct HdfDeviceObject *device)
285 {
286     int32_t ret;
287     int32_t index;
288     const struct DeviceResourceNode *childNode = NULL;
289     struct Hi35xxPinCntlr *hi35xx = NULL;
290 
291     HDF_LOGI("%s: Enter", __func__);
292     hi35xx = (struct Hi35xxPinCntlr *)OsalMemCalloc(sizeof(*hi35xx));
293     if (hi35xx == NULL) {
294         HDF_LOGE("%s: alloc hi35xx failed", __func__);
295         return HDF_ERR_MALLOC_FAIL;
296     }
297 
298     ret = Hi35xxPinCntlrInit(device, hi35xx);
299     index = 0;
300 
301     DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) {
302         ret = Hi35xxPinParsePinNode(childNode, hi35xx, index);
303         if (ret != HDF_SUCCESS) {
304             return ret;
305         }
306         index++;
307     }
308 
309     hi35xx->cntlr.method = &g_method;
310     ret = PinCntlrAdd(&hi35xx->cntlr);
311     if (ret != HDF_SUCCESS) {
312         HDF_LOGE("%s: add Pin cntlr: failed", __func__);
313         ret = HDF_FAILURE;
314     }
315     HDF_LOGD("%s: Pin Init success", __func__);
316     return HDF_SUCCESS;
317 }
318 
Hi35xxPinRelease(struct HdfDeviceObject * device)319 static void Hi35xxPinRelease(struct HdfDeviceObject *device)
320 {
321     int32_t ret;
322     uint16_t number;
323     struct PinCntlr *cntlr = NULL;
324     struct Hi35xxPinCntlr *hi35xx = NULL;
325     struct DeviceResourceIface *drsOps = NULL;
326 
327     HDF_LOGI("%s: Enter", __func__);
328     if (device == NULL || device->property == NULL) {
329         HDF_LOGE("%s: device or property is null", __func__);
330         return;
331     }
332     drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
333     if (drsOps == NULL || drsOps->GetUint32 == NULL || drsOps->GetString == NULL) {
334         HDF_LOGE("%s: invalid drs ops", __func__);
335         return;
336     }
337 
338     ret = drsOps->GetUint16(device->property, "number", &number, 0);
339     if (ret != HDF_SUCCESS) {
340         HDF_LOGE("%s: read cntlr number failed", __func__);
341         return;
342     }
343 
344     cntlr = PinCntlrGetByNumber(number);
345     PinCntlrRemove(cntlr);
346     hi35xx = (struct Hi35xxPinCntlr *)cntlr;
347     if (hi35xx != NULL) {
348         if (hi35xx->regBase != NULL) {
349             OsalIoUnmap((void *)hi35xx->regBase);
350         }
351         OsalMemFree(hi35xx);
352     }
353 }
354 
355 static struct HdfDriverEntry g_hi35xxPinDriverEntry = {
356     .moduleVersion = 1,
357     .Bind = Hi35xxPinBind,
358     .Init = Hi35xxPinInit,
359     .Release = Hi35xxPinRelease,
360     .moduleName = "hi35xx_pin_driver",
361 };
362 HDF_INIT(g_hi35xxPinDriverEntry);