• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 #include "timer_hi35xx.h"
16 #include "device_resource_if.h"
17 #include "hdf_base.h"
18 #include "hdf_log.h"
19 #include "osal_mem.h"
20 #include "osal_io.h"
21 #include "osal_irq.h"
22 
23 #define HDF_LOG_TAG timer_hi35xx
24 
TimerHi35xxRegWrite(uint32_t value,volatile uint8_t * addr)25 static int32_t TimerHi35xxRegWrite(uint32_t value, volatile uint8_t *addr)
26 {
27     CHECK_NULL_PTR_RETURN_VALUE(addr, HDF_ERR_INVALID_OBJECT);
28 
29     OSAL_WRITEL(value, addr);
30     return HDF_SUCCESS;
31 }
32 
TimerHi35xxRegRead(volatile uint8_t * addr)33 static uint32_t TimerHi35xxRegRead(volatile uint8_t *addr)
34 {
35     CHECK_NULL_PTR_RETURN_VALUE(addr, HDF_ERR_INVALID_OBJECT);
36 
37     uint32_t val = OSAL_READL(addr);
38     return val;
39 }
40 
TimerHi35xxEnable(struct TimerHi35xxInfo * info,bool enable)41 static int32_t TimerHi35xxEnable(struct TimerHi35xxInfo *info, bool enable)
42 {
43     CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT);
44     uint32_t value = TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_CONTROL);
45     if (enable) {
46         value &= ~TIMERx_CONTROL_TIMEREN;
47         value |= (0x1 << TIMERx_CONTROL_TIMEREN_SHIFT);
48     } else {
49         value &= ~TIMERx_CONTROL_TIMEREN;
50         value |= (0x0 << TIMERx_CONTROL_TIMEREN_SHIFT);
51     }
52     TimerHi35xxRegWrite(value, info->regBase + HI35XX_TIMERx_CONTROL);
53     TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_CONTROL);
54     return HDF_SUCCESS;
55 }
56 
57 // once or period
TimerHi35xxSetMode(struct TimerHi35xxInfo * info,uint16_t mode)58 static int32_t TimerHi35xxSetMode(struct TimerHi35xxInfo *info, uint16_t mode)
59 {
60     CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT);
61     uint32_t value = TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_CONTROL);
62     if ((mode == TIMERx_CONTROL_TIMERMODE_PERIOD) || (mode == TIMERx_CONTROL_TIMERMODE_FREE)) {
63         value &= ~TIMERx_CONTROL_TIMERMODE;
64         value |= (mode << TIMERx_CONTROL_TIMERMODE_SHIFT);
65     } else { // one shot
66         value &= ~TIMERx_CONTROL_ONESHOT;
67         value |= (TIMERx_CONTROL_TIMERMODE_ONESHOT_ONE << TIMERx_CONTROL_ONESHOT_SHIFT);
68     }
69 
70     TimerHi35xxRegWrite(value, info->regBase + HI35XX_TIMERx_CONTROL);
71     return HDF_SUCCESS;
72 }
73 
74 // divide frequence
TimerHi35xxSetPre(struct TimerHi35xxInfo * info,uint16_t pre)75 static int32_t TimerHi35xxSetPre(struct TimerHi35xxInfo *info, uint16_t pre)
76 {
77     CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT);
78     uint32_t value = TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_CONTROL);
79     uint32_t tmpVal;
80     switch (pre) {
81         case TIMERx_CONTROL_TIMERPRE_NOT:
82             tmpVal = TIMERx_CONTROL_TIMERPRE_NOT;
83             break;
84         case TIMERx_CONTROL_TIMERPRE_4_LEVEL:
85             tmpVal = TIMERx_CONTROL_TIMERPRE_4_LEVEL;
86             break;
87         case TIMERx_CONTROL_TIMERPRE_8_LEVEL:
88         case TIMERx_CONTROL_TIMERPRE_UNDEFINE:
89             tmpVal = TIMERx_CONTROL_TIMERPRE_8_LEVEL;
90             break;
91         default:
92             HDF_LOGE("%s: unsupported pre [%u]", __func__, pre);
93             return HDF_ERR_INVALID_PARAM;
94     }
95     value &= ~TIMERx_CONTROL_TIMERPRE;
96     value |= (tmpVal << TIMERx_CONTROL_TIMERPRE_SHIFT);
97     TimerHi35xxRegWrite(value, info->regBase + HI35XX_TIMERx_CONTROL);
98     TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_CONTROL);
99     return HDF_SUCCESS;
100 }
101 
102 // mask interrupts true:not mask; false mask
TimerHi35xxIntEnable(struct TimerHi35xxInfo * info,bool enable)103 static int32_t TimerHi35xxIntEnable(struct TimerHi35xxInfo *info, bool enable)
104 {
105     CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT);
106     uint32_t value = TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_CONTROL);
107     if (enable) {
108         value &= ~TIMERx_CONTROL_INTENABLE;
109         value |= (0x1 << TIMERx_CONTROL_INTENABLE_SHIFT);
110     } else {
111         value &= ~TIMERx_CONTROL_INTENABLE;
112         value |= (0x0 << TIMERx_CONTROL_INTENABLE_SHIFT);
113     }
114     TimerHi35xxRegWrite(value, info->regBase + HI35XX_TIMERx_CONTROL);
115     return HDF_SUCCESS;
116 }
117 
118 // clear timer interrupt
TimerHi35xxIntClear(struct TimerHi35xxInfo * info)119 static int32_t TimerHi35xxIntClear(struct TimerHi35xxInfo *info)
120 {
121     CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT);
122     TimerHi35xxRegWrite(0x0, info->regBase + HI35XX_TIMERx_INTCLR);
123     return HDF_SUCCESS;
124 }
125 
TimerHi35xxTimerSize(struct TimerHi35xxInfo * info,bool is32Bit)126 static int32_t TimerHi35xxTimerSize(struct TimerHi35xxInfo *info, bool is32Bit)
127 {
128     CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT);
129     uint32_t value = TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_CONTROL);
130     if (is32Bit) { // 1:32 bit
131         value &= ~TIMERx_CONTROL_TIMERSIZE;
132         value |= (0x1 << TIMERx_CONTROL_TIMERSIZE_SHIFT);
133     } else { // 0:16 bit
134         value &= ~TIMERx_CONTROL_TIMERSIZE;
135         value |= (0x0 << TIMERx_CONTROL_TIMERSIZE_SHIFT);
136     }
137     TimerHi35xxRegWrite(value, info->regBase + HI35XX_TIMERx_CONTROL);
138     return HDF_SUCCESS;
139 }
140 
141 // timer count value
TimerHi35xxTimerLoadSet(struct TimerHi35xxInfo * info,uint32_t value)142 static int32_t TimerHi35xxTimerLoadSet(struct TimerHi35xxInfo *info, uint32_t value)
143 {
144     CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT);
145 
146     TimerHi35xxRegWrite(value, info->regBase + HI35XX_TIMERx_LOAD);
147     return HDF_SUCCESS;
148 }
149 
TimerHi35xxTimerGetAllReg(struct TimerHi35xxInfo * info)150 static void TimerHi35xxTimerGetAllReg(struct TimerHi35xxInfo *info)
151 {
152     TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_LOAD);
153     TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_VALUE);
154     TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_CONTROL);
155     TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_INTCLR);
156     TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_RIS);
157     TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_MIS);
158     TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_BGLOAD);
159 }
160 
161 // timer count clk
TimerHi35xxScCtrlSet(void)162 static void TimerHi35xxScCtrlSet(void)
163 {
164     volatile uint8_t *regBase =
165         (volatile void *)OsalIoRemap((uintptr_t)HI35XX_SC_CTRL_REG, TIMER_MAX_REG_SIZE);
166     if (regBase == NULL) {
167         HDF_LOGE("%s:OsalIoRemap fail", __func__);
168         return;
169     }
170     uint32_t value = TimerHi35xxRegRead(regBase);
171     value &= ~HI35XX_SC_CTRL_TIMEREN0OV;
172     value |= (0x0 << HI35XX_SC_CTRL_TIMEREN0OV_SHIFT);
173     value &= ~HI35XX_SC_CTRL_TIMEREN1OV;
174     value |= (0x0 << HI35XX_SC_CTRL_TIMEREN1OV_SHIFT);
175     value &= ~HI35XX_SC_CTRL_TIMEREN2OV;
176     value |= (0x0 << HI35XX_SC_CTRL_TIMEREN2OV_SHIFT);
177     value &= ~HI35XX_SC_CTRL_TIMEREN3OV;
178     value |= (0x0 << HI35XX_SC_CTRL_TIMEREN3OV_SHIFT);
179     value &= ~HI35XX_SC_CTRL_TIMEREN4OV;
180     value |= (0x0 << HI35XX_SC_CTRL_TIMEREN4OV_SHIFT);
181     value &= ~HI35XX_SC_CTRL_TIMEREN5OV;
182     value |= (0x0 << HI35XX_SC_CTRL_TIMEREN5OV_SHIFT);
183     value &= ~HI35XX_SC_CTRL_TIMEREN6OV;
184     value |= (0x0 << HI35XX_SC_CTRL_TIMEREN6OV_SHIFT);
185     value &= ~HI35XX_SC_CTRL_TIMEREN7OV;
186     value |= (0x0 << HI35XX_SC_CTRL_TIMEREN7OV_SHIFT);
187     TimerHi35xxRegWrite(value, regBase);
188     TimerHi35xxRegRead(regBase);
189     OsalIoUnmap((void*)regBase);
190     regBase = NULL;
191 }
192 
TimerHi35xxIrqHandle(uint32_t irqId,void * data)193 static uint32_t TimerHi35xxIrqHandle(uint32_t irqId, void *data)
194 {
195     CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_OBJECT);
196     struct TimerHi35xxInfo *info = NULL;
197     info = (struct TimerHi35xxInfo *)data;
198 
199     HDF_LOGD("------------->%s[%s]: timer[%u], irqId [%u] in ",
200         __func__, __TIME__, info->number, irqId);
201 
202     // clear interrupt
203     TimerHi35xxIntClear(info);
204 
205     CHECK_NULL_PTR_RETURN_VALUE(info->cb, HDF_ERR_INVALID_OBJECT);
206     info->cb();
207     HDF_LOGD("------------->%s: timer[%u], irqId [%u] process success", __func__, info->number, irqId);
208     return HDF_SUCCESS;
209 }
210 
TimerHi35xxSet(struct TimerCntrl * cntrl,uint32_t useconds,TimerHandleCb cb)211 static int32_t TimerHi35xxSet(struct TimerCntrl *cntrl, uint32_t useconds, TimerHandleCb cb)
212 {
213     CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT);
214     CHECK_NULL_PTR_RETURN_VALUE(cntrl->priv, HDF_ERR_INVALID_OBJECT);
215     CHECK_NULL_PTR_RETURN_VALUE(cb, HDF_ERR_INVALID_OBJECT);
216 
217     cntrl->info.useconds = useconds;
218     cntrl->info.cb = cb;
219     cntrl->info.isPeriod = true;
220 
221     struct TimerHi35xxInfo *info = cntrl->priv;
222     info->cb = cb;
223     info->isPeriod = true;
224     HDF_LOGD("%s: timer[%u][%d][%d] ",
225         __func__, info->number, cntrl->info.useconds, cntrl->info.isPeriod);
226 
227     if (TimerHi35xxSetMode(info, TIMERx_CONTROL_TIMERMODE_PERIOD) != HDF_SUCCESS) {
228         HDF_LOGE("%s: TimerHi35xxSetMode[%u] fail!", __func__, info->number);
229         return HDF_FAILURE;
230     }
231     return HDF_SUCCESS;
232 }
233 
TimerHi35xxSetOnce(struct TimerCntrl * cntrl,uint32_t useconds,TimerHandleCb cb)234 static int32_t TimerHi35xxSetOnce(struct TimerCntrl *cntrl, uint32_t useconds, TimerHandleCb cb)
235 {
236     CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT);
237     CHECK_NULL_PTR_RETURN_VALUE(cntrl->priv, HDF_ERR_INVALID_OBJECT);
238     CHECK_NULL_PTR_RETURN_VALUE(cb, HDF_ERR_INVALID_OBJECT);
239 
240     cntrl->info.useconds = useconds;
241     cntrl->info.cb = cb;
242     cntrl->info.isPeriod = false;
243 
244     struct TimerHi35xxInfo *info = cntrl->priv;
245     info->cb = cb;
246     info->isPeriod = false;
247     if (TimerHi35xxSetMode(info, TIMERx_CONTROL_TIMERMODE_ONESHOT) != HDF_SUCCESS) {
248         HDF_LOGE("%s: TimerHi35xxSetMode[%u] fail!", __func__, info->number);
249         return HDF_FAILURE;
250     }
251     return HDF_SUCCESS;
252 }
253 
TimerHi35xxSetTimeout(struct TimerCntrl * cntrl)254 static int32_t TimerHi35xxSetTimeout(struct TimerCntrl *cntrl)
255 {
256     CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT);
257     CHECK_NULL_PTR_RETURN_VALUE(cntrl->priv, HDF_ERR_INVALID_OBJECT);
258     unsigned int value;
259     unsigned int maxCnt = ~0x00; /* 32 bit counter */
260     unsigned int maxSeconds = maxCnt / HI35XX_TIMERx_CLOCK_HZ;
261 
262     if (cntrl->info.useconds == 0 || (cntrl->info.useconds / HI35XX_TIMERx_US_TRANS_S) > maxSeconds) {
263         value = maxCnt;
264     } else {
265         value = (cntrl->info.useconds / HI35XX_TIMERx_US_TRANS_S) * HI35XX_TIMERx_CLOCK_HZ;
266     }
267 
268     struct TimerHi35xxInfo *info = cntrl->priv;
269     OSAL_WRITEL(value, info->regBase + HI35XX_TIMERx_LOAD);
270 
271     HDF_LOGD("%s: timer[%u] [%d][%d][%d] ", __func__, info->number, maxSeconds, value, cntrl->info.useconds);
272 
273     return HDF_SUCCESS;
274 }
275 
TimerHi35xxIrqRegister(struct TimerHi35xxInfo * info)276 static int32_t TimerHi35xxIrqRegister(struct TimerHi35xxInfo *info)
277 {
278     CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT);
279 
280     if (OsalRegisterIrq(info->irq, 0, TimerHi35xxIrqHandle, "timer_alarm", (void*)info) != HDF_SUCCESS) {
281         HDF_LOGE("%s: OsalRegisterIrq[%u][%u] fail!", __func__, info->irq, info->number);
282         return HDF_FAILURE;
283     }
284     info->isIrqReg = true;
285     return HDF_SUCCESS;
286 }
287 
TimerHi35xxIrqUnregister(struct TimerHi35xxInfo * info)288 static int32_t TimerHi35xxIrqUnregister(struct TimerHi35xxInfo *info)
289 {
290     CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT);
291 
292     (void)OsalUnregisterIrq(info->irq, (void *)info);
293     info->isIrqReg = false;
294     return HDF_SUCCESS;
295 }
296 
TimerHi35xxStart(struct TimerCntrl * cntrl)297 static int32_t TimerHi35xxStart(struct TimerCntrl *cntrl)
298 {
299     CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT);
300     CHECK_NULL_PTR_RETURN_VALUE(cntrl->priv, HDF_ERR_INVALID_OBJECT);
301     struct TimerHi35xxInfo *info = cntrl->priv;
302 
303     int ret = TimerHi35xxIrqRegister(info);
304     if (ret != HDF_SUCCESS) {
305         HDF_LOGE("%s: TimerHi35xxIrqRegister fail!", __func__);
306         return HDF_FAILURE;
307     }
308 
309     // not mask interrupt
310     ret = TimerHi35xxIntEnable(info, true);
311     if (ret != HDF_SUCCESS) {
312         HDF_LOGE("%s: TimerHi35xxIntEnable fail!", __func__);
313         return HDF_FAILURE;
314     }
315 
316     ret = TimerHi35xxSetTimeout(cntrl);
317     if (ret != HDF_SUCCESS) {
318         HDF_LOGE("%s: TimerHi35xxSetTimeout fail!", __func__);
319         return HDF_FAILURE;
320     }
321 
322     ret = TimerHi35xxEnable(info, true);
323     if (ret != HDF_SUCCESS) {
324         HDF_LOGE("%s: TimerHi35xxEnable fail!", __func__);
325         return HDF_FAILURE;
326     }
327     TimerHi35xxTimerGetAllReg(info);
328     return HDF_SUCCESS;
329 }
330 
TimerHi35xxStop(struct TimerCntrl * cntrl)331 static int32_t TimerHi35xxStop(struct TimerCntrl *cntrl)
332 {
333     CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT);
334     CHECK_NULL_PTR_RETURN_VALUE(cntrl->priv, HDF_ERR_INVALID_OBJECT);
335     struct TimerHi35xxInfo *info = cntrl->priv;
336     int ret = TimerHi35xxEnable(info, false);
337     if (ret != HDF_SUCCESS) {
338         HDF_LOGE("%s: TimerHi35xxEnable fail!", __func__);
339         return HDF_FAILURE;
340     }
341 
342     ret = TimerHi35xxIntEnable(info, false);
343     if (ret != HDF_SUCCESS) {
344         HDF_LOGE("%s: TimerHi35xxIntEnable fail!", __func__);
345         return HDF_FAILURE;
346     }
347 
348     ret = TimerHi35xxIrqUnregister(info);
349     if (ret != HDF_SUCCESS) {
350         HDF_LOGE("%s: TimerHi35xxIrqUnregister fail!", __func__);
351         return HDF_FAILURE;
352     }
353     return HDF_SUCCESS;
354 }
355 
TimerHi35xxOpen(struct TimerCntrl * cntrl)356 static int32_t TimerHi35xxOpen(struct TimerCntrl *cntrl)
357 {
358     CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT);
359     return HDF_SUCCESS;
360 }
361 
TimerHi35xxClose(struct TimerCntrl * cntrl)362 static int32_t TimerHi35xxClose(struct TimerCntrl *cntrl)
363 {
364     CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT);
365     TimerHi35xxStop(cntrl);
366     return HDF_SUCCESS;
367 }
368 
TimerHi35xxRemove(struct TimerCntrl * cntrl)369 static int32_t TimerHi35xxRemove(struct TimerCntrl *cntrl)
370 {
371     CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT);
372     CHECK_NULL_PTR_RETURN_VALUE(cntrl->priv, HDF_ERR_INVALID_OBJECT);
373     struct TimerHi35xxInfo *info = cntrl->priv;
374 
375     TimerHi35xxStop(cntrl);
376     if (info->regBase != NULL) {
377         OsalIoUnmap((void*)info->regBase);
378         info->regBase = NULL;
379     }
380 
381     OsalMemFree(cntrl->priv);
382     cntrl->priv = NULL;
383     return HDF_SUCCESS;
384 }
385 
386 static struct TimerCntrlMethod g_timerCntlrMethod = {
387     .Remove = TimerHi35xxRemove,
388     .Open = TimerHi35xxOpen,
389     .Close = TimerHi35xxClose,
390     .Set = TimerHi35xxSet,
391     .SetOnce = TimerHi35xxSetOnce,
392     .Start = TimerHi35xxStart,
393     .Stop = TimerHi35xxStop,
394 };
395 
TimerHi35xxInitRegSet(struct TimerHi35xxInfo * info)396 static int32_t TimerHi35xxInitRegSet(struct TimerHi35xxInfo *info)
397 {
398     CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT);
399     TimerHi35xxScCtrlSet();
400     TimerHi35xxEnable(info, false);
401     TimerHi35xxSetMode(info, TIMERx_CONTROL_TIMERMODE_PERIOD);
402     TimerHi35xxIntEnable(info, false);
403     TimerHi35xxSetPre(info, TIMERx_CONTROL_TIMERPRE_NOT);
404     TimerHi35xxTimerSize(info, true);
405     TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_CONTROL);
406 
407     TimerHi35xxTimerLoadSet(info, HI35XX_TIMERx_LOAD_INIT_VAL);
408     return HDF_SUCCESS;
409 }
410 
TimerHi35xxReadHcs(struct TimerHi35xxInfo * info,const struct DeviceResourceNode * node)411 static int32_t TimerHi35xxReadHcs(struct TimerHi35xxInfo *info, const struct DeviceResourceNode *node)
412 {
413     int32_t ret;
414     uint32_t tmp;
415     struct DeviceResourceIface *iface = NULL;
416 
417     iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
418     if (iface == NULL || iface->GetUint32 == NULL) {
419         HDF_LOGE("%s: invalid drs ops fail!", __func__);
420         return HDF_FAILURE;
421     }
422 
423     ret = iface->GetUint32(node, "number", &info->number, 0);
424     if (ret != HDF_SUCCESS) {
425         HDF_LOGE("%s: read id fail!", __func__);
426         return HDF_FAILURE;
427     }
428 
429     ret = iface->GetUint32(node, "bus_clock", &info->busClock, 0);
430     if (ret != HDF_SUCCESS) {
431         HDF_LOGE("%s: read [%u] bus_clock fail!", __func__, info->number);
432         return HDF_FAILURE;
433     }
434 
435     ret = iface->GetUint32(node, "mode", &info->mode, 0);
436     if (ret != HDF_SUCCESS) {
437         HDF_LOGE("%s: read [%u] mode fail!", __func__, info->number);
438         return HDF_FAILURE;
439     }
440 
441     ret = iface->GetUint32(node, "init_count_val", &info->initCountVal, 0);
442     if (ret != HDF_SUCCESS) {
443         HDF_LOGE("%s: read [%u] init_count_val fail!", __func__, info->number);
444         return HDF_FAILURE;
445     }
446 
447     ret = iface->GetUint32(node, "irq", &info->irq, 0);
448     if (ret != HDF_SUCCESS) {
449         HDF_LOGE("%s: read [%u] irq fail!", __func__, info->number);
450         return HDF_FAILURE;
451     }
452 
453     if (iface->GetUint32(node, "reg_base", &tmp, 0) != HDF_SUCCESS) {
454         HDF_LOGE("%s: read [%u] reg_base fail", __func__, info->number);
455         return HDF_FAILURE;
456     }
457     info->regBase = OsalIoRemap(tmp, TIMER_MAX_REG_SIZE);
458     if (info->regBase == NULL) {
459         HDF_LOGE("%s:OsalIoRemap fail", __func__);
460         return HDF_FAILURE;
461     }
462     HDF_LOGD("%s:regBase[0x%x][%px]", __func__, tmp, info->regBase);
463 
464     HDF_LOGD("%s:number[%u], bus_clock[%d], mode[%d], init_count_val[%d] irq[%u]", __func__,
465         info->number, info->busClock, info->mode, info->initCountVal, info->irq);
466 
467     return HDF_SUCCESS;
468 }
469 
TimerHi35xxInitHandle(const struct DeviceResourceNode * node,struct TimerHi35xxInfo * info)470 static int32_t TimerHi35xxInitHandle(const struct DeviceResourceNode *node, struct TimerHi35xxInfo *info)
471 {
472     CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_OBJECT);
473     CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT);
474 
475     int32_t ret = TimerHi35xxReadHcs(info, node);
476     if (ret != HDF_SUCCESS) {
477         HDF_LOGE("%s: TimerHi35xxReadHcs fail!", __func__);
478         return ret;
479     }
480 
481     ret = TimerHi35xxInitRegSet(info);
482     if (ret != HDF_SUCCESS) {
483         HDF_LOGE("%s: TimerHi35xxInitRegSet fail!", __func__);
484         return ret;
485     }
486     info->isIrqReg = false;
487 
488     return HDF_SUCCESS;
489 }
490 
TimerHi35xxInfoFree(struct TimerCntrl * cntrl)491 static void TimerHi35xxInfoFree(struct TimerCntrl *cntrl)
492 {
493     CHECK_NULL_PTR_RETURN(cntrl);
494     if (cntrl->priv != NULL) {
495         OsalMemFree(cntrl->priv);
496         cntrl->priv = NULL;
497     }
498 
499     if (cntrl != NULL) {
500         OsalMemFree(cntrl);
501     }
502 }
TimerHi35xxParseAndInit(struct HdfDeviceObject * device,const struct DeviceResourceNode * node)503 static int32_t TimerHi35xxParseAndInit(struct HdfDeviceObject *device, const struct DeviceResourceNode *node)
504 {
505     int32_t ret;
506     struct TimerCntrl *cntrl = NULL;
507     struct TimerHi35xxInfo *info = NULL;
508     (void)device;
509 
510     cntrl = (struct TimerCntrl *)OsalMemCalloc(sizeof(*cntrl));
511     CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT);
512 
513     info = (struct TimerHi35xxInfo *)OsalMemCalloc(sizeof(*info));
514     if (cntrl == NULL) {
515         HDF_LOGE("%s: malloc info fail!", __func__);
516         TimerHi35xxInfoFree(cntrl);
517         return HDF_ERR_MALLOC_FAIL;
518     }
519     cntrl->priv = (void *)info;
520 
521     ret = TimerHi35xxInitHandle(node, info);
522     if (ret != HDF_SUCCESS) {
523         HDF_LOGE("%s: TimerHi35xxInitHandle fail!", __func__);
524         TimerHi35xxInfoFree(cntrl);
525         return ret;
526     }
527 
528     cntrl->info.number = info->number;
529     cntrl->ops = &g_timerCntlrMethod;
530     ret = TimerCntrlAdd(cntrl);
531     if (ret != HDF_SUCCESS) {
532         HDF_LOGE("%s: TimerCntrlAdd fail!", __func__);
533         TimerHi35xxInfoFree(cntrl);
534         return ret;
535     }
536     return HDF_SUCCESS;
537 }
538 
TimerHi35xxDeviceInit(struct HdfDeviceObject * device)539 static int32_t TimerHi35xxDeviceInit(struct HdfDeviceObject *device)
540 {
541     int32_t ret;
542     const struct DeviceResourceNode *childNode = NULL;
543     if (device == NULL || device->property == NULL) {
544         HDF_LOGE("%s: device or property is NULL", __func__);
545         return HDF_ERR_INVALID_OBJECT;
546     }
547 
548     DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) {
549         ret = TimerHi35xxParseAndInit(device, childNode);
550         if (ret != HDF_SUCCESS) {
551             HDF_LOGE("%s:TimerHi35xxParseAndInit fail", __func__);
552             return HDF_FAILURE;
553         }
554     }
555     HDF_LOGD("%s: success", __func__);
556     return HDF_SUCCESS;
557 }
558 
TimerHi35xxDeviceBind(struct HdfDeviceObject * device)559 static int32_t TimerHi35xxDeviceBind(struct HdfDeviceObject *device)
560 {
561     CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_OBJECT);
562     HDF_LOGD("%s: success", __func__);
563     return HDF_SUCCESS;
564 }
565 
TimerHi35xxRemoveById(const struct DeviceResourceNode * node)566 static void TimerHi35xxRemoveById(const struct DeviceResourceNode *node)
567 {
568     int32_t ret;
569     uint32_t timerId;
570     struct DeviceResourceIface *drsOps = NULL;
571 
572     drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
573     if (drsOps == NULL || drsOps->GetUint32 == NULL) {
574         HDF_LOGE("%s: invalid drs ops fail!", __func__);
575         return;
576     }
577 
578     ret = drsOps->GetUint32(node, "id", (uint32_t *)&timerId, 0);
579     if (ret != HDF_SUCCESS) {
580         HDF_LOGE("%s: read id fail!", __func__);
581         return;
582     }
583 
584     TimerCntrlRemoveByNumber(timerId);
585     return;
586 }
587 
TimerHi35xxDeviceRelease(struct HdfDeviceObject * device)588 static void TimerHi35xxDeviceRelease(struct HdfDeviceObject *device)
589 {
590     const struct DeviceResourceNode *childNode = NULL;
591     HDF_LOGD("%s: in", __func__);
592     if (device == NULL || device->property == NULL) {
593         HDF_LOGE("%s: device is NULL", __func__);
594         return;
595     }
596 
597     DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) {
598         TimerHi35xxRemoveById(childNode);
599     }
600 
601     HDF_LOGD("%s: success", __func__);
602 }
603 
604 struct HdfDriverEntry g_hdfTimerDevice = {
605     .moduleVersion = 1,
606     .moduleName = "hi35xx_timer_driver",
607     .Bind = TimerHi35xxDeviceBind,
608     .Init = TimerHi35xxDeviceInit,
609     .Release = TimerHi35xxDeviceRelease,
610 };
611 
612 HDF_INIT(g_hdfTimerDevice);
613