• 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     HDF_LOGD("%s: set pin Pull success.", __func__);
57     return HDF_SUCCESS;
58 }
59 
Hi35xxPinGetPull(struct PinCntlr * cntlr,uint32_t index,enum PinPullType * pullType)60 static int32_t Hi35xxPinGetPull(struct PinCntlr *cntlr, uint32_t index, enum PinPullType *pullType)
61 {
62     uint32_t value;
63     struct Hi35xxPinCntlr *hi35xx = NULL;
64     hi35xx = (struct Hi35xxPinCntlr *)cntlr;
65 
66     value = OSAL_READL(hi35xx->regBase + index * HI35XX_PIN_REG_SIZE);
67     *pullType = (enum PinPullType)((value & PIN_PULL_TYPE_MASK) >> PIN_PULL_TYPE_OFFSET);
68     HDF_LOGD("%s: get pin Pull success.", __func__);
69     return HDF_SUCCESS;
70 }
71 
Hi35xxPinSetStrength(struct PinCntlr * cntlr,uint32_t index,uint32_t strength)72 static int32_t Hi35xxPinSetStrength(struct PinCntlr *cntlr, uint32_t index, uint32_t strength)
73 {
74     uint32_t value;
75     struct Hi35xxPinCntlr *hi35xx = NULL;
76 
77     hi35xx = (struct Hi35xxPinCntlr *)cntlr;
78     value = OSAL_READL(hi35xx->regBase + index * HI35XX_PIN_REG_SIZE);
79     value = (value & ~PIN_STRENGTH_MASK) | (strength << PIN_STRENGTH_OFFSET);
80     OSAL_WRITEL(value, hi35xx->regBase + index * HI35XX_PIN_REG_SIZE);
81     HDF_LOGD("%s: set pin Strength success.", __func__);
82     return HDF_SUCCESS;
83 }
84 
Hi35xxPinGetStrength(struct PinCntlr * cntlr,uint32_t index,uint32_t * strength)85 static int32_t Hi35xxPinGetStrength(struct PinCntlr *cntlr, uint32_t index, uint32_t *strength)
86 {
87     uint32_t value;
88     struct Hi35xxPinCntlr *hi35xx = NULL;
89     hi35xx = (struct Hi35xxPinCntlr *)cntlr;
90 
91     value = OSAL_READL(hi35xx->regBase + index * HI35XX_PIN_REG_SIZE);
92     *strength = (value & PIN_STRENGTH_MASK) >> PIN_STRENGTH_OFFSET;
93     HDF_LOGD("%s: get pin Strength success.", __func__);
94     return HDF_SUCCESS;
95 }
96 
Hi35xxPinSetFunc(struct PinCntlr * cntlr,uint32_t index,const char * funcName)97 static int32_t Hi35xxPinSetFunc(struct PinCntlr *cntlr, uint32_t index, const char *funcName)
98 {
99     uint32_t value;
100     int ret;
101     uint32_t funcNum;
102     struct Hi35xxPinCntlr *hi35xx = NULL;
103 
104     hi35xx = (struct Hi35xxPinCntlr *)cntlr;
105 
106     for (funcNum = 0; funcNum < HI35XX_PIN_FUNC_MAX; funcNum++) {
107         ret = strcmp(funcName, hi35xx->desc[index].func[funcNum]);
108         if (ret == 0) {
109             value = OSAL_READL(hi35xx->regBase + index * HI35XX_PIN_REG_SIZE);
110             value = (value & ~PIN_FUNC_MASK) | funcNum;
111             OSAL_WRITEL(value, hi35xx->regBase + index * HI35XX_PIN_REG_SIZE);
112             HDF_LOGD("%s: set pin function success.", __func__);
113             return HDF_SUCCESS;
114         }
115     }
116     HDF_LOGE("%s: set pin Function failed.", __func__);
117     return HDF_ERR_IO;
118 }
119 
Hi35xxPinGetFunc(struct PinCntlr * cntlr,uint32_t index,const char ** funcName)120 static int32_t Hi35xxPinGetFunc(struct PinCntlr *cntlr, uint32_t index, const char **funcName)
121 {
122     uint32_t value;
123     uint32_t funcNum;
124     struct Hi35xxPinCntlr *hi35xx = NULL;
125 
126     hi35xx = (struct Hi35xxPinCntlr *)cntlr;
127 
128     value = OSAL_READL(hi35xx->regBase + index * HI35XX_PIN_REG_SIZE);
129     funcNum = value & PIN_FUNC_MASK;
130     *funcName = hi35xx->desc[index].func[funcNum];
131     HDF_LOGD("%s: get pin function success.", __func__);
132     return HDF_SUCCESS;
133 }
134 
135 static struct PinCntlrMethod g_method = {
136     .SetPinPull = Hi35xxPinSetPull,
137     .GetPinPull = Hi35xxPinGetPull,
138     .SetPinStrength = Hi35xxPinSetStrength,
139     .GetPinStrength = Hi35xxPinGetStrength,
140     .SetPinFunc = Hi35xxPinSetFunc,
141     .GetPinFunc = Hi35xxPinGetFunc,
142 };
143 
Hi35xxPinReadFunc(struct Hi35xxPinDesc * desc,const struct DeviceResourceNode * node,struct DeviceResourceIface * drsOps)144 static int32_t Hi35xxPinReadFunc(struct Hi35xxPinDesc *desc,
145     const struct DeviceResourceNode *node, struct DeviceResourceIface *drsOps)
146 {
147     int32_t ret;
148     uint32_t funcNum = 0;
149 
150     ret = drsOps->GetString(node, "F0", &desc->func[funcNum], "NULL");
151     if (ret != HDF_SUCCESS) {
152         HDF_LOGE("%s: read F0 failed", __func__);
153         return ret;
154     }
155 
156     funcNum++;
157     ret = drsOps->GetString(node, "F1", &desc->func[funcNum], "NULL");
158     if (ret != HDF_SUCCESS) {
159         HDF_LOGE("%s: read F1 failed", __func__);
160         return ret;
161     }
162 
163     funcNum++;
164     ret = drsOps->GetString(node, "F2", &desc->func[funcNum], "NULL");
165     if (ret != HDF_SUCCESS) {
166         HDF_LOGE("%s: read F2 failed", __func__);
167         return ret;
168     }
169 
170     funcNum++;
171     ret = drsOps->GetString(node, "F3", &desc->func[funcNum], "NULL");
172     if (ret != HDF_SUCCESS) {
173         HDF_LOGE("%s: read F3 failed", __func__);
174         return ret;
175     }
176 
177     funcNum++;
178     ret = drsOps->GetString(node, "F4", &desc->func[funcNum], "NULL");
179     if (ret != HDF_SUCCESS) {
180         HDF_LOGE("%s: read F4 failed", __func__);
181         return ret;
182     }
183 
184     funcNum++;
185     ret = drsOps->GetString(node, "F5", &desc->func[funcNum], "NULL");
186     if (ret != HDF_SUCCESS) {
187         HDF_LOGE("%s: read F5 failed", __func__);
188         return ret;
189     }
190     return HDF_SUCCESS;
191 }
192 
Hi35xxPinParsePinNode(const struct DeviceResourceNode * node,struct Hi35xxPinCntlr * hi35xx,int32_t index)193 static int32_t Hi35xxPinParsePinNode(const struct DeviceResourceNode *node,
194     struct Hi35xxPinCntlr *hi35xx, int32_t index)
195 {
196     int32_t ret;
197     struct DeviceResourceIface *drsOps = NULL;
198 
199     drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
200     if (drsOps == NULL || drsOps->GetUint32 == NULL || drsOps->GetString == NULL) {
201         HDF_LOGE("%s: invalid drs ops fail!", __func__);
202         return HDF_FAILURE;
203     }
204     ret = drsOps->GetString(node, "pinName", &hi35xx->desc[index].pinName, "NULL");
205     if (ret != HDF_SUCCESS) {
206         HDF_LOGE("%s: read pinName failed", __func__);
207         return ret;
208     }
209 
210     ret = drsOps->GetUint32(node, "init", &hi35xx->desc[index].init, 0);
211     if (ret != HDF_SUCCESS) {
212         HDF_LOGE("%s: read init failed", __func__);
213         return ret;
214     }
215 
216     ret = Hi35xxPinReadFunc(&hi35xx->desc[index], node, drsOps);
217     if (ret != HDF_SUCCESS) {
218         HDF_LOGE("%s:Pin read Func failed", __func__);
219         return ret;
220     }
221     hi35xx->cntlr.pins[index].pinName = hi35xx->desc[index].pinName;
222     hi35xx->cntlr.pins[index].priv = (void *)node;
223     return HDF_SUCCESS;
224 }
225 
Hi35xxPinCntlrInit(struct HdfDeviceObject * device,struct Hi35xxPinCntlr * hi35xx)226 static int32_t Hi35xxPinCntlrInit(struct HdfDeviceObject *device, struct Hi35xxPinCntlr *hi35xx)
227 {
228     struct DeviceResourceIface *drsOps = NULL;
229     int32_t ret;
230 
231     drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
232     if (drsOps == NULL || drsOps->GetUint32 == NULL || drsOps->GetUint16 == NULL) {
233         HDF_LOGE("%s: invalid drs ops fail!", __func__);
234         return HDF_FAILURE;
235     }
236     ret = drsOps->GetUint16(device->property, "number", &hi35xx->number, 0);
237     if (ret != HDF_SUCCESS) {
238         HDF_LOGE("%s: read number failed", __func__);
239         return ret;
240     }
241 
242     ret = drsOps->GetUint32(device->property, "regStartBasePhy", &hi35xx->regStartBasePhy, 0);
243     if (ret != HDF_SUCCESS) {
244         HDF_LOGE("%s: read regStartBasePhy failed", __func__);
245         return ret;
246     }
247     ret = drsOps->GetUint32(device->property, "regSize", &hi35xx->regSize, 0);
248     if (ret != HDF_SUCCESS) {
249         HDF_LOGE("%s: read regSize failed", __func__);
250         return ret;
251     }
252     ret = drsOps->GetUint32(device->property, "pinCount", &hi35xx->pinCount, 0);
253     if (ret != HDF_SUCCESS) {
254         HDF_LOGE("%s: read pinCount failed", __func__);
255         return ret;
256     }
257     hi35xx->cntlr.pinCount = hi35xx->pinCount;
258     hi35xx->cntlr.number = hi35xx->number;
259     hi35xx->regBase = OsalIoRemap(hi35xx->regStartBasePhy, hi35xx->regSize);
260     if (hi35xx->regBase == NULL) {
261         HDF_LOGE("%s: remap Pin base failed", __func__);
262         return HDF_ERR_IO;
263     }
264     hi35xx->desc = (struct Hi35xxPinDesc *)OsalMemCalloc(sizeof(struct Hi35xxPinDesc) * hi35xx->pinCount);
265     hi35xx->cntlr.pins = (struct PinDesc *)OsalMemCalloc(sizeof(struct PinDesc) * hi35xx->pinCount);
266     return HDF_SUCCESS;
267 }
268 
Hi35xxPinBind(struct HdfDeviceObject * device)269 static int32_t Hi35xxPinBind(struct HdfDeviceObject *device)
270 {
271     (void)device;
272     return HDF_SUCCESS;
273 }
274 
Hi35xxPinInit(struct HdfDeviceObject * device)275 static int32_t Hi35xxPinInit(struct HdfDeviceObject *device)
276 {
277     int32_t ret;
278     int32_t index;
279     const struct DeviceResourceNode *childNode = NULL;
280     struct Hi35xxPinCntlr *hi35xx = NULL;
281 
282     hi35xx = (struct Hi35xxPinCntlr *)OsalMemCalloc(sizeof(*hi35xx));
283     if (hi35xx == NULL) {
284         HDF_LOGE("%s: alloc hi35xx failed", __func__);
285         return HDF_ERR_MALLOC_FAIL;
286     }
287 
288     ret = Hi35xxPinCntlrInit(device, hi35xx);
289     index = 0;
290 
291     DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) {
292         ret = Hi35xxPinParsePinNode(childNode, hi35xx, index);
293         if (ret != HDF_SUCCESS) {
294             return ret;
295         }
296         index++;
297     }
298 
299     hi35xx->cntlr.method = &g_method;
300     ret = PinCntlrAdd(&hi35xx->cntlr);
301     if (ret != HDF_SUCCESS) {
302         HDF_LOGE("%s: add Pin cntlr: failed", __func__);
303         ret = HDF_FAILURE;
304     }
305     HDF_LOGI("%s: Pin Init success", __func__);
306     return HDF_SUCCESS;
307 }
308 
Hi35xxPinRelease(struct HdfDeviceObject * device)309 static void Hi35xxPinRelease(struct HdfDeviceObject *device)
310 {
311     int32_t ret;
312     uint16_t number;
313     struct PinCntlr *cntlr = NULL;
314     struct Hi35xxPinCntlr *hi35xx = NULL;
315     struct DeviceResourceIface *drsOps = NULL;
316 
317     HDF_LOGI("%s: enter", __func__);
318     if (device == NULL || device->property == NULL) {
319         HDF_LOGE("%s: device or property is null", __func__);
320         return;
321     }
322     drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
323     if (drsOps == NULL || drsOps->GetUint32 == NULL || drsOps->GetString == NULL) {
324         HDF_LOGE("%s: invalid drs ops", __func__);
325         return;
326     }
327 
328     ret = drsOps->GetUint16(device->property, "number", &number, 0);
329     if (ret != HDF_SUCCESS) {
330         HDF_LOGE("%s: read cntlr number failed", __func__);
331         return;
332     }
333 
334     cntlr = PinCntlrGetByNumber(number);
335     PinCntlrRemove(cntlr);
336     hi35xx = (struct Hi35xxPinCntlr *)cntlr;
337     if (hi35xx != NULL) {
338         if (hi35xx->regBase != NULL) {
339             OsalIoUnmap((void *)hi35xx->regBase);
340         }
341         OsalMemFree(hi35xx);
342     }
343 }
344 
345 static struct HdfDriverEntry g_hi35xxPinDriverEntry = {
346     .moduleVersion = 1,
347     .Bind = Hi35xxPinBind,
348     .Init = Hi35xxPinInit,
349     .Release = Hi35xxPinRelease,
350     .moduleName = "hi35xx_pin_driver",
351 };
352 HDF_INIT(g_hi35xxPinDriverEntry);