11bd4fe43Sopenharmony_ci/* 21bd4fe43Sopenharmony_ci * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED. 31bd4fe43Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 41bd4fe43Sopenharmony_ci * you may not use this file except in compliance with the License. 51bd4fe43Sopenharmony_ci * You may obtain a copy of the License at 61bd4fe43Sopenharmony_ci * 71bd4fe43Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 81bd4fe43Sopenharmony_ci * 91bd4fe43Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 101bd4fe43Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 111bd4fe43Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 121bd4fe43Sopenharmony_ci * See the License for the specific language governing permissions and 131bd4fe43Sopenharmony_ci * limitations under the License. 141bd4fe43Sopenharmony_ci */ 151bd4fe43Sopenharmony_ci#include "timer_hi35xx.h" 161bd4fe43Sopenharmony_ci#include "device_resource_if.h" 171bd4fe43Sopenharmony_ci#include "hdf_base.h" 181bd4fe43Sopenharmony_ci#include "hdf_log.h" 191bd4fe43Sopenharmony_ci#include "osal_io.h" 201bd4fe43Sopenharmony_ci#include "osal_irq.h" 211bd4fe43Sopenharmony_ci#include "osal_mem.h" 221bd4fe43Sopenharmony_ci 231bd4fe43Sopenharmony_ci#define HDF_LOG_TAG timer_hi35xx 241bd4fe43Sopenharmony_ci 251bd4fe43Sopenharmony_cistatic int32_t TimerHi35xxRegWrite(uint32_t value, volatile uint8_t *addr) 261bd4fe43Sopenharmony_ci{ 271bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(addr, HDF_ERR_INVALID_OBJECT); 281bd4fe43Sopenharmony_ci 291bd4fe43Sopenharmony_ci OSAL_WRITEL(value, addr); 301bd4fe43Sopenharmony_ci return HDF_SUCCESS; 311bd4fe43Sopenharmony_ci} 321bd4fe43Sopenharmony_ci 331bd4fe43Sopenharmony_cistatic uint32_t TimerHi35xxRegRead(volatile uint8_t *addr) 341bd4fe43Sopenharmony_ci{ 351bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(addr, HDF_ERR_INVALID_OBJECT); 361bd4fe43Sopenharmony_ci 371bd4fe43Sopenharmony_ci uint32_t val = OSAL_READL(addr); 381bd4fe43Sopenharmony_ci return val; 391bd4fe43Sopenharmony_ci} 401bd4fe43Sopenharmony_ci 411bd4fe43Sopenharmony_cistatic int32_t TimerHi35xxEnable(struct TimerHi35xxInfo *info, bool enable) 421bd4fe43Sopenharmony_ci{ 431bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT); 441bd4fe43Sopenharmony_ci uint32_t value = TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_CONTROL); 451bd4fe43Sopenharmony_ci if (enable) { 461bd4fe43Sopenharmony_ci value &= ~TIMERx_CONTROL_TIMEREN; 471bd4fe43Sopenharmony_ci value |= (0x1 << TIMERx_CONTROL_TIMEREN_SHIFT); 481bd4fe43Sopenharmony_ci } else { 491bd4fe43Sopenharmony_ci value &= ~TIMERx_CONTROL_TIMEREN; 501bd4fe43Sopenharmony_ci value |= (0x0 << TIMERx_CONTROL_TIMEREN_SHIFT); 511bd4fe43Sopenharmony_ci } 521bd4fe43Sopenharmony_ci TimerHi35xxRegWrite(value, info->regBase + HI35XX_TIMERx_CONTROL); 531bd4fe43Sopenharmony_ci TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_CONTROL); 541bd4fe43Sopenharmony_ci return HDF_SUCCESS; 551bd4fe43Sopenharmony_ci} 561bd4fe43Sopenharmony_ci 571bd4fe43Sopenharmony_ci// once or period 581bd4fe43Sopenharmony_cistatic int32_t TimerHi35xxSetMode(struct TimerHi35xxInfo *info, uint16_t mode) 591bd4fe43Sopenharmony_ci{ 601bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT); 611bd4fe43Sopenharmony_ci uint32_t value = TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_CONTROL); 621bd4fe43Sopenharmony_ci if ((mode == TIMERx_CONTROL_TIMERMODE_PERIOD) || (mode == TIMERx_CONTROL_TIMERMODE_FREE)) { 631bd4fe43Sopenharmony_ci value &= ~TIMERx_CONTROL_TIMERMODE; 641bd4fe43Sopenharmony_ci value |= (mode << TIMERx_CONTROL_TIMERMODE_SHIFT); 651bd4fe43Sopenharmony_ci } else { // one shot 661bd4fe43Sopenharmony_ci value &= ~TIMERx_CONTROL_ONESHOT; 671bd4fe43Sopenharmony_ci value |= (TIMERx_CONTROL_TIMERMODE_ONESHOT_ONE << TIMERx_CONTROL_ONESHOT_SHIFT); 681bd4fe43Sopenharmony_ci } 691bd4fe43Sopenharmony_ci 701bd4fe43Sopenharmony_ci TimerHi35xxRegWrite(value, info->regBase + HI35XX_TIMERx_CONTROL); 711bd4fe43Sopenharmony_ci return HDF_SUCCESS; 721bd4fe43Sopenharmony_ci} 731bd4fe43Sopenharmony_ci 741bd4fe43Sopenharmony_ci// divide frequence 751bd4fe43Sopenharmony_cistatic int32_t TimerHi35xxSetPre(struct TimerHi35xxInfo *info, uint16_t pre) 761bd4fe43Sopenharmony_ci{ 771bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT); 781bd4fe43Sopenharmony_ci uint32_t value = TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_CONTROL); 791bd4fe43Sopenharmony_ci uint32_t tmpVal; 801bd4fe43Sopenharmony_ci switch (pre) { 811bd4fe43Sopenharmony_ci case TIMERx_CONTROL_TIMERPRE_NOT: 821bd4fe43Sopenharmony_ci tmpVal = TIMERx_CONTROL_TIMERPRE_NOT; 831bd4fe43Sopenharmony_ci break; 841bd4fe43Sopenharmony_ci case TIMERx_CONTROL_TIMERPRE_4_LEVEL: 851bd4fe43Sopenharmony_ci tmpVal = TIMERx_CONTROL_TIMERPRE_4_LEVEL; 861bd4fe43Sopenharmony_ci break; 871bd4fe43Sopenharmony_ci case TIMERx_CONTROL_TIMERPRE_8_LEVEL: 881bd4fe43Sopenharmony_ci case TIMERx_CONTROL_TIMERPRE_UNDEFINE: 891bd4fe43Sopenharmony_ci tmpVal = TIMERx_CONTROL_TIMERPRE_8_LEVEL; 901bd4fe43Sopenharmony_ci break; 911bd4fe43Sopenharmony_ci default: 921bd4fe43Sopenharmony_ci HDF_LOGE("%s: unsupported pre [%hu]", __func__, pre); 931bd4fe43Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 941bd4fe43Sopenharmony_ci } 951bd4fe43Sopenharmony_ci value &= ~TIMERx_CONTROL_TIMERPRE; 961bd4fe43Sopenharmony_ci value |= (tmpVal << TIMERx_CONTROL_TIMERPRE_SHIFT); 971bd4fe43Sopenharmony_ci TimerHi35xxRegWrite(value, info->regBase + HI35XX_TIMERx_CONTROL); 981bd4fe43Sopenharmony_ci TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_CONTROL); 991bd4fe43Sopenharmony_ci return HDF_SUCCESS; 1001bd4fe43Sopenharmony_ci} 1011bd4fe43Sopenharmony_ci 1021bd4fe43Sopenharmony_ci// mask interrupts true:not mask; false mask 1031bd4fe43Sopenharmony_cistatic int32_t TimerHi35xxIntEnable(struct TimerHi35xxInfo *info, bool enable) 1041bd4fe43Sopenharmony_ci{ 1051bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT); 1061bd4fe43Sopenharmony_ci uint32_t value = TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_CONTROL); 1071bd4fe43Sopenharmony_ci if (enable) { 1081bd4fe43Sopenharmony_ci value &= ~TIMERx_CONTROL_INTENABLE; 1091bd4fe43Sopenharmony_ci value |= (0x1 << TIMERx_CONTROL_INTENABLE_SHIFT); 1101bd4fe43Sopenharmony_ci } else { 1111bd4fe43Sopenharmony_ci value &= ~TIMERx_CONTROL_INTENABLE; 1121bd4fe43Sopenharmony_ci value |= (0x0 << TIMERx_CONTROL_INTENABLE_SHIFT); 1131bd4fe43Sopenharmony_ci } 1141bd4fe43Sopenharmony_ci TimerHi35xxRegWrite(value, info->regBase + HI35XX_TIMERx_CONTROL); 1151bd4fe43Sopenharmony_ci return HDF_SUCCESS; 1161bd4fe43Sopenharmony_ci} 1171bd4fe43Sopenharmony_ci 1181bd4fe43Sopenharmony_ci// clear timer interrupt 1191bd4fe43Sopenharmony_cistatic int32_t TimerHi35xxIntClear(struct TimerHi35xxInfo *info) 1201bd4fe43Sopenharmony_ci{ 1211bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT); 1221bd4fe43Sopenharmony_ci TimerHi35xxRegWrite(0x0, info->regBase + HI35XX_TIMERx_INTCLR); 1231bd4fe43Sopenharmony_ci return HDF_SUCCESS; 1241bd4fe43Sopenharmony_ci} 1251bd4fe43Sopenharmony_ci 1261bd4fe43Sopenharmony_cistatic int32_t TimerHi35xxTimerSize(struct TimerHi35xxInfo *info, bool is32Bit) 1271bd4fe43Sopenharmony_ci{ 1281bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT); 1291bd4fe43Sopenharmony_ci uint32_t value = TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_CONTROL); 1301bd4fe43Sopenharmony_ci if (is32Bit) { // 1:32 bit 1311bd4fe43Sopenharmony_ci value &= ~TIMERx_CONTROL_TIMERSIZE; 1321bd4fe43Sopenharmony_ci value |= (0x1 << TIMERx_CONTROL_TIMERSIZE_SHIFT); 1331bd4fe43Sopenharmony_ci } else { // 0:16 bit 1341bd4fe43Sopenharmony_ci value &= ~TIMERx_CONTROL_TIMERSIZE; 1351bd4fe43Sopenharmony_ci value |= (0x0 << TIMERx_CONTROL_TIMERSIZE_SHIFT); 1361bd4fe43Sopenharmony_ci } 1371bd4fe43Sopenharmony_ci TimerHi35xxRegWrite(value, info->regBase + HI35XX_TIMERx_CONTROL); 1381bd4fe43Sopenharmony_ci return HDF_SUCCESS; 1391bd4fe43Sopenharmony_ci} 1401bd4fe43Sopenharmony_ci 1411bd4fe43Sopenharmony_ci// timer count value 1421bd4fe43Sopenharmony_cistatic int32_t TimerHi35xxTimerLoadSet(struct TimerHi35xxInfo *info, uint32_t value) 1431bd4fe43Sopenharmony_ci{ 1441bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT); 1451bd4fe43Sopenharmony_ci 1461bd4fe43Sopenharmony_ci TimerHi35xxRegWrite(value, info->regBase + HI35XX_TIMERx_LOAD); 1471bd4fe43Sopenharmony_ci return HDF_SUCCESS; 1481bd4fe43Sopenharmony_ci} 1491bd4fe43Sopenharmony_ci 1501bd4fe43Sopenharmony_cistatic void TimerHi35xxTimerGetAllReg(struct TimerHi35xxInfo *info) 1511bd4fe43Sopenharmony_ci{ 1521bd4fe43Sopenharmony_ci TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_LOAD); 1531bd4fe43Sopenharmony_ci TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_VALUE); 1541bd4fe43Sopenharmony_ci TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_CONTROL); 1551bd4fe43Sopenharmony_ci TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_INTCLR); 1561bd4fe43Sopenharmony_ci TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_RIS); 1571bd4fe43Sopenharmony_ci TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_MIS); 1581bd4fe43Sopenharmony_ci TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_BGLOAD); 1591bd4fe43Sopenharmony_ci} 1601bd4fe43Sopenharmony_ci 1611bd4fe43Sopenharmony_cistatic void TimerDumperAddDatas(struct TimerHi35xxInfo *info) 1621bd4fe43Sopenharmony_ci{ 1631bd4fe43Sopenharmony_ci struct PlatformDumperData datas[] = { 1641bd4fe43Sopenharmony_ci {"HI35XX_TIMERx_LOAD", PLATFORM_DUMPER_REGISTERB, (void *)(info->regBase + HI35XX_TIMERx_LOAD)}, 1651bd4fe43Sopenharmony_ci {"HI35XX_TIMERx_VALUE", PLATFORM_DUMPER_REGISTERB, (void *)(info->regBase + HI35XX_TIMERx_VALUE)}, 1661bd4fe43Sopenharmony_ci {"HI35XX_TIMERx_CONTROL", PLATFORM_DUMPER_REGISTERB, (void *)(info->regBase + HI35XX_TIMERx_CONTROL)}, 1671bd4fe43Sopenharmony_ci {"HI35XX_TIMERx_INTCLR", PLATFORM_DUMPER_REGISTERB, (void *)(info->regBase + HI35XX_TIMERx_INTCLR)}, 1681bd4fe43Sopenharmony_ci {"HI35XX_TIMERx_RIS", PLATFORM_DUMPER_REGISTERB, (void *)(info->regBase + HI35XX_TIMERx_RIS)}, 1691bd4fe43Sopenharmony_ci {"HI35XX_TIMERx_MIS", PLATFORM_DUMPER_REGISTERB, (void *)(info->regBase + HI35XX_TIMERx_MIS)}, 1701bd4fe43Sopenharmony_ci {"HI35XX_TIMERx_BGLOAD", PLATFORM_DUMPER_REGISTERB, (void *)(info->regBase + HI35XX_TIMERx_BGLOAD)}, 1711bd4fe43Sopenharmony_ci }; 1721bd4fe43Sopenharmony_ci if (info->dumper == NULL) { 1731bd4fe43Sopenharmony_ci return; 1741bd4fe43Sopenharmony_ci } 1751bd4fe43Sopenharmony_ci 1761bd4fe43Sopenharmony_ci PlatformDumperAddDatas(info->dumper, datas, sizeof(datas) / sizeof(struct PlatformDumperData)); 1771bd4fe43Sopenharmony_ci} 1781bd4fe43Sopenharmony_ci 1791bd4fe43Sopenharmony_ci// timer count clk 1801bd4fe43Sopenharmony_cistatic void TimerHi35xxScCtrlSet(void) 1811bd4fe43Sopenharmony_ci{ 1821bd4fe43Sopenharmony_ci volatile uint8_t *regBase = 1831bd4fe43Sopenharmony_ci (volatile void *)OsalIoRemap((uintptr_t)HI35XX_SC_CTRL_REG, TIMER_MAX_REG_SIZE); 1841bd4fe43Sopenharmony_ci if (regBase == NULL) { 1851bd4fe43Sopenharmony_ci HDF_LOGE("%s:OsalIoRemap fail", __func__); 1861bd4fe43Sopenharmony_ci return; 1871bd4fe43Sopenharmony_ci } 1881bd4fe43Sopenharmony_ci uint32_t value = TimerHi35xxRegRead(regBase); 1891bd4fe43Sopenharmony_ci value &= ~HI35XX_SC_CTRL_TIMEREN0OV; 1901bd4fe43Sopenharmony_ci value |= (0x0 << HI35XX_SC_CTRL_TIMEREN0OV_SHIFT); 1911bd4fe43Sopenharmony_ci value &= ~HI35XX_SC_CTRL_TIMEREN1OV; 1921bd4fe43Sopenharmony_ci value |= (0x0 << HI35XX_SC_CTRL_TIMEREN1OV_SHIFT); 1931bd4fe43Sopenharmony_ci value &= ~HI35XX_SC_CTRL_TIMEREN2OV; 1941bd4fe43Sopenharmony_ci value |= (0x0 << HI35XX_SC_CTRL_TIMEREN2OV_SHIFT); 1951bd4fe43Sopenharmony_ci value &= ~HI35XX_SC_CTRL_TIMEREN3OV; 1961bd4fe43Sopenharmony_ci value |= (0x0 << HI35XX_SC_CTRL_TIMEREN3OV_SHIFT); 1971bd4fe43Sopenharmony_ci value &= ~HI35XX_SC_CTRL_TIMEREN4OV; 1981bd4fe43Sopenharmony_ci value |= (0x0 << HI35XX_SC_CTRL_TIMEREN4OV_SHIFT); 1991bd4fe43Sopenharmony_ci value &= ~HI35XX_SC_CTRL_TIMEREN5OV; 2001bd4fe43Sopenharmony_ci value |= (0x0 << HI35XX_SC_CTRL_TIMEREN5OV_SHIFT); 2011bd4fe43Sopenharmony_ci value &= ~HI35XX_SC_CTRL_TIMEREN6OV; 2021bd4fe43Sopenharmony_ci value |= (0x0 << HI35XX_SC_CTRL_TIMEREN6OV_SHIFT); 2031bd4fe43Sopenharmony_ci value &= ~HI35XX_SC_CTRL_TIMEREN7OV; 2041bd4fe43Sopenharmony_ci value |= (0x0 << HI35XX_SC_CTRL_TIMEREN7OV_SHIFT); 2051bd4fe43Sopenharmony_ci TimerHi35xxRegWrite(value, regBase); 2061bd4fe43Sopenharmony_ci TimerHi35xxRegRead(regBase); 2071bd4fe43Sopenharmony_ci OsalIoUnmap((void *)regBase); 2081bd4fe43Sopenharmony_ci regBase = NULL; 2091bd4fe43Sopenharmony_ci} 2101bd4fe43Sopenharmony_ci 2111bd4fe43Sopenharmony_cistatic uint32_t TimerHi35xxIrqHandle(uint32_t irqId, void *data) 2121bd4fe43Sopenharmony_ci{ 2131bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_OBJECT); 2141bd4fe43Sopenharmony_ci struct TimerHi35xxInfo *info = NULL; 2151bd4fe43Sopenharmony_ci info = (struct TimerHi35xxInfo *)data; 2161bd4fe43Sopenharmony_ci 2171bd4fe43Sopenharmony_ci HDF_LOGD("------------->%s[%s]: timer[%u], irqId [%u] in ", 2181bd4fe43Sopenharmony_ci __func__, __TIME__, info->number, irqId); 2191bd4fe43Sopenharmony_ci 2201bd4fe43Sopenharmony_ci // clear interrupt 2211bd4fe43Sopenharmony_ci TimerHi35xxIntClear(info); 2221bd4fe43Sopenharmony_ci 2231bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(info->cb, HDF_ERR_INVALID_OBJECT); 2241bd4fe43Sopenharmony_ci info->cb(info->number); 2251bd4fe43Sopenharmony_ci HDF_LOGD("------------->%s: timer[%u], irqId [%u] process success", __func__, info->number, irqId); 2261bd4fe43Sopenharmony_ci return HDF_SUCCESS; 2271bd4fe43Sopenharmony_ci} 2281bd4fe43Sopenharmony_ci 2291bd4fe43Sopenharmony_cistatic int32_t TimerHi35xxSet(struct TimerCntrl *cntrl, uint32_t useconds, TimerHandleCb cb) 2301bd4fe43Sopenharmony_ci{ 2311bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT); 2321bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(cntrl->priv, HDF_ERR_INVALID_OBJECT); 2331bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(cb, HDF_ERR_INVALID_OBJECT); 2341bd4fe43Sopenharmony_ci 2351bd4fe43Sopenharmony_ci cntrl->info.useconds = useconds; 2361bd4fe43Sopenharmony_ci cntrl->info.cb = cb; 2371bd4fe43Sopenharmony_ci cntrl->info.isPeriod = true; 2381bd4fe43Sopenharmony_ci 2391bd4fe43Sopenharmony_ci struct TimerHi35xxInfo *info = cntrl->priv; 2401bd4fe43Sopenharmony_ci info->cb = cb; 2411bd4fe43Sopenharmony_ci info->isPeriod = true; 2421bd4fe43Sopenharmony_ci HDF_LOGD("%s: timer[%u][%u][%d] ", 2431bd4fe43Sopenharmony_ci __func__, info->number, cntrl->info.useconds, cntrl->info.isPeriod); 2441bd4fe43Sopenharmony_ci 2451bd4fe43Sopenharmony_ci if (TimerHi35xxSetMode(info, TIMERx_CONTROL_TIMERMODE_PERIOD) != HDF_SUCCESS) { 2461bd4fe43Sopenharmony_ci HDF_LOGE("%s: TimerHi35xxSetMode[%u] fail!", __func__, info->number); 2471bd4fe43Sopenharmony_ci return HDF_FAILURE; 2481bd4fe43Sopenharmony_ci } 2491bd4fe43Sopenharmony_ci return HDF_SUCCESS; 2501bd4fe43Sopenharmony_ci} 2511bd4fe43Sopenharmony_ci 2521bd4fe43Sopenharmony_cistatic int32_t TimerHi35xxSetOnce(struct TimerCntrl *cntrl, uint32_t useconds, TimerHandleCb cb) 2531bd4fe43Sopenharmony_ci{ 2541bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT); 2551bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(cntrl->priv, HDF_ERR_INVALID_OBJECT); 2561bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(cb, HDF_ERR_INVALID_OBJECT); 2571bd4fe43Sopenharmony_ci 2581bd4fe43Sopenharmony_ci cntrl->info.useconds = useconds; 2591bd4fe43Sopenharmony_ci cntrl->info.cb = cb; 2601bd4fe43Sopenharmony_ci cntrl->info.isPeriod = false; 2611bd4fe43Sopenharmony_ci 2621bd4fe43Sopenharmony_ci struct TimerHi35xxInfo *info = cntrl->priv; 2631bd4fe43Sopenharmony_ci info->cb = cb; 2641bd4fe43Sopenharmony_ci info->isPeriod = false; 2651bd4fe43Sopenharmony_ci if (TimerHi35xxSetMode(info, TIMERx_CONTROL_TIMERMODE_ONESHOT) != HDF_SUCCESS) { 2661bd4fe43Sopenharmony_ci HDF_LOGE("%s: TimerHi35xxSetMode[%u] fail!", __func__, info->number); 2671bd4fe43Sopenharmony_ci return HDF_FAILURE; 2681bd4fe43Sopenharmony_ci } 2691bd4fe43Sopenharmony_ci return HDF_SUCCESS; 2701bd4fe43Sopenharmony_ci} 2711bd4fe43Sopenharmony_ci 2721bd4fe43Sopenharmony_cistatic int32_t TimerHi35xxSetTimeout(struct TimerCntrl *cntrl) 2731bd4fe43Sopenharmony_ci{ 2741bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT); 2751bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(cntrl->priv, HDF_ERR_INVALID_OBJECT); 2761bd4fe43Sopenharmony_ci unsigned int value; 2771bd4fe43Sopenharmony_ci unsigned int maxCnt = ~0x00; /* 32 bit counter */ 2781bd4fe43Sopenharmony_ci unsigned int maxSeconds = maxCnt / HI35XX_TIMERx_CLOCK_HZ; 2791bd4fe43Sopenharmony_ci 2801bd4fe43Sopenharmony_ci if (cntrl->info.useconds == 0 || (cntrl->info.useconds / HI35XX_TIMERx_US_TRANS_S) > maxSeconds) { 2811bd4fe43Sopenharmony_ci value = maxCnt; 2821bd4fe43Sopenharmony_ci } else { 2831bd4fe43Sopenharmony_ci value = (cntrl->info.useconds / HI35XX_TIMERx_US_TRANS_S) * HI35XX_TIMERx_CLOCK_HZ; 2841bd4fe43Sopenharmony_ci } 2851bd4fe43Sopenharmony_ci 2861bd4fe43Sopenharmony_ci struct TimerHi35xxInfo *info = cntrl->priv; 2871bd4fe43Sopenharmony_ci OSAL_WRITEL(value, info->regBase + HI35XX_TIMERx_LOAD); 2881bd4fe43Sopenharmony_ci 2891bd4fe43Sopenharmony_ci HDF_LOGD("%s: timer[%u] [%u][%u][%u] ", __func__, info->number, maxSeconds, value, cntrl->info.useconds); 2901bd4fe43Sopenharmony_ci 2911bd4fe43Sopenharmony_ci return HDF_SUCCESS; 2921bd4fe43Sopenharmony_ci} 2931bd4fe43Sopenharmony_ci 2941bd4fe43Sopenharmony_cistatic int32_t TimerHi35xxIrqRegister(struct TimerHi35xxInfo *info) 2951bd4fe43Sopenharmony_ci{ 2961bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT); 2971bd4fe43Sopenharmony_ci 2981bd4fe43Sopenharmony_ci if (OsalRegisterIrq(info->irq, 0, TimerHi35xxIrqHandle, "timer_alarm", (void *)info) != HDF_SUCCESS) { 2991bd4fe43Sopenharmony_ci HDF_LOGE("%s: OsalRegisterIrq[%u][%u] fail!", __func__, info->irq, info->number); 3001bd4fe43Sopenharmony_ci return HDF_FAILURE; 3011bd4fe43Sopenharmony_ci } 3021bd4fe43Sopenharmony_ci info->isIrqReg = true; 3031bd4fe43Sopenharmony_ci return HDF_SUCCESS; 3041bd4fe43Sopenharmony_ci} 3051bd4fe43Sopenharmony_ci 3061bd4fe43Sopenharmony_cistatic int32_t TimerHi35xxIrqUnregister(struct TimerHi35xxInfo *info) 3071bd4fe43Sopenharmony_ci{ 3081bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT); 3091bd4fe43Sopenharmony_ci 3101bd4fe43Sopenharmony_ci (void)OsalUnregisterIrq(info->irq, (void *)info); 3111bd4fe43Sopenharmony_ci info->isIrqReg = false; 3121bd4fe43Sopenharmony_ci return HDF_SUCCESS; 3131bd4fe43Sopenharmony_ci} 3141bd4fe43Sopenharmony_ci 3151bd4fe43Sopenharmony_cistatic int32_t TimerHi35xxStart(struct TimerCntrl *cntrl) 3161bd4fe43Sopenharmony_ci{ 3171bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT); 3181bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(cntrl->priv, HDF_ERR_INVALID_OBJECT); 3191bd4fe43Sopenharmony_ci struct TimerHi35xxInfo *info = cntrl->priv; 3201bd4fe43Sopenharmony_ci 3211bd4fe43Sopenharmony_ci int ret = TimerHi35xxIrqRegister(info); 3221bd4fe43Sopenharmony_ci if (ret != HDF_SUCCESS) { 3231bd4fe43Sopenharmony_ci HDF_LOGE("%s: TimerHi35xxIrqRegister fail!", __func__); 3241bd4fe43Sopenharmony_ci return HDF_FAILURE; 3251bd4fe43Sopenharmony_ci } 3261bd4fe43Sopenharmony_ci 3271bd4fe43Sopenharmony_ci // not mask interrupt 3281bd4fe43Sopenharmony_ci ret = TimerHi35xxIntEnable(info, true); 3291bd4fe43Sopenharmony_ci if (ret != HDF_SUCCESS) { 3301bd4fe43Sopenharmony_ci HDF_LOGE("%s: TimerHi35xxIntEnable fail!", __func__); 3311bd4fe43Sopenharmony_ci return HDF_FAILURE; 3321bd4fe43Sopenharmony_ci } 3331bd4fe43Sopenharmony_ci 3341bd4fe43Sopenharmony_ci ret = TimerHi35xxSetTimeout(cntrl); 3351bd4fe43Sopenharmony_ci if (ret != HDF_SUCCESS) { 3361bd4fe43Sopenharmony_ci HDF_LOGE("%s: TimerHi35xxSetTimeout fail!", __func__); 3371bd4fe43Sopenharmony_ci return HDF_FAILURE; 3381bd4fe43Sopenharmony_ci } 3391bd4fe43Sopenharmony_ci 3401bd4fe43Sopenharmony_ci ret = TimerHi35xxEnable(info, true); 3411bd4fe43Sopenharmony_ci if (ret != HDF_SUCCESS) { 3421bd4fe43Sopenharmony_ci HDF_LOGE("%s: TimerHi35xxEnable fail!", __func__); 3431bd4fe43Sopenharmony_ci return HDF_FAILURE; 3441bd4fe43Sopenharmony_ci } 3451bd4fe43Sopenharmony_ci TimerHi35xxTimerGetAllReg(info); 3461bd4fe43Sopenharmony_ci TimerDumperAddDatas(info); 3471bd4fe43Sopenharmony_ci PlatformDumperDump(info->dumper); 3481bd4fe43Sopenharmony_ci return HDF_SUCCESS; 3491bd4fe43Sopenharmony_ci} 3501bd4fe43Sopenharmony_ci 3511bd4fe43Sopenharmony_cistatic int32_t TimerHi35xxStop(struct TimerCntrl *cntrl) 3521bd4fe43Sopenharmony_ci{ 3531bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT); 3541bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(cntrl->priv, HDF_ERR_INVALID_OBJECT); 3551bd4fe43Sopenharmony_ci struct TimerHi35xxInfo *info = cntrl->priv; 3561bd4fe43Sopenharmony_ci int ret = TimerHi35xxEnable(info, false); 3571bd4fe43Sopenharmony_ci if (ret != HDF_SUCCESS) { 3581bd4fe43Sopenharmony_ci HDF_LOGE("%s: TimerHi35xxEnable fail!", __func__); 3591bd4fe43Sopenharmony_ci return HDF_FAILURE; 3601bd4fe43Sopenharmony_ci } 3611bd4fe43Sopenharmony_ci 3621bd4fe43Sopenharmony_ci ret = TimerHi35xxIntEnable(info, false); 3631bd4fe43Sopenharmony_ci if (ret != HDF_SUCCESS) { 3641bd4fe43Sopenharmony_ci HDF_LOGE("%s: TimerHi35xxIntEnable fail!", __func__); 3651bd4fe43Sopenharmony_ci return HDF_FAILURE; 3661bd4fe43Sopenharmony_ci } 3671bd4fe43Sopenharmony_ci 3681bd4fe43Sopenharmony_ci ret = TimerHi35xxIrqUnregister(info); 3691bd4fe43Sopenharmony_ci if (ret != HDF_SUCCESS) { 3701bd4fe43Sopenharmony_ci HDF_LOGE("%s: TimerHi35xxIrqUnregister fail!", __func__); 3711bd4fe43Sopenharmony_ci return HDF_FAILURE; 3721bd4fe43Sopenharmony_ci } 3731bd4fe43Sopenharmony_ci PlatformDumperDump(info->dumper); 3741bd4fe43Sopenharmony_ci return HDF_SUCCESS; 3751bd4fe43Sopenharmony_ci} 3761bd4fe43Sopenharmony_ci 3771bd4fe43Sopenharmony_cistatic int32_t TimerHi35xxOpen(struct TimerCntrl *cntrl) 3781bd4fe43Sopenharmony_ci{ 3791bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT); 3801bd4fe43Sopenharmony_ci return HDF_SUCCESS; 3811bd4fe43Sopenharmony_ci} 3821bd4fe43Sopenharmony_ci 3831bd4fe43Sopenharmony_cistatic int32_t TimerHi35xxClose(struct TimerCntrl *cntrl) 3841bd4fe43Sopenharmony_ci{ 3851bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT); 3861bd4fe43Sopenharmony_ci TimerHi35xxStop(cntrl); 3871bd4fe43Sopenharmony_ci return HDF_SUCCESS; 3881bd4fe43Sopenharmony_ci} 3891bd4fe43Sopenharmony_ci 3901bd4fe43Sopenharmony_cistatic int32_t TimerHi35xxRemove(struct TimerCntrl *cntrl) 3911bd4fe43Sopenharmony_ci{ 3921bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT); 3931bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(cntrl->priv, HDF_ERR_INVALID_OBJECT); 3941bd4fe43Sopenharmony_ci struct TimerHi35xxInfo *info = cntrl->priv; 3951bd4fe43Sopenharmony_ci 3961bd4fe43Sopenharmony_ci TimerHi35xxStop(cntrl); 3971bd4fe43Sopenharmony_ci if (info->regBase != NULL) { 3981bd4fe43Sopenharmony_ci OsalIoUnmap((void *)info->regBase); 3991bd4fe43Sopenharmony_ci info->regBase = NULL; 4001bd4fe43Sopenharmony_ci } 4011bd4fe43Sopenharmony_ci PlatformDumperDestroy(info->dumper); 4021bd4fe43Sopenharmony_ci OsalMemFree(info->dumperName); 4031bd4fe43Sopenharmony_ci 4041bd4fe43Sopenharmony_ci OsalMemFree(cntrl->priv); 4051bd4fe43Sopenharmony_ci cntrl->priv = NULL; 4061bd4fe43Sopenharmony_ci return HDF_SUCCESS; 4071bd4fe43Sopenharmony_ci} 4081bd4fe43Sopenharmony_ci 4091bd4fe43Sopenharmony_cistatic struct TimerCntrlMethod g_timerCntlrMethod = { 4101bd4fe43Sopenharmony_ci .Remove = TimerHi35xxRemove, 4111bd4fe43Sopenharmony_ci .Open = TimerHi35xxOpen, 4121bd4fe43Sopenharmony_ci .Close = TimerHi35xxClose, 4131bd4fe43Sopenharmony_ci .Set = TimerHi35xxSet, 4141bd4fe43Sopenharmony_ci .SetOnce = TimerHi35xxSetOnce, 4151bd4fe43Sopenharmony_ci .Start = TimerHi35xxStart, 4161bd4fe43Sopenharmony_ci .Stop = TimerHi35xxStop, 4171bd4fe43Sopenharmony_ci}; 4181bd4fe43Sopenharmony_ci 4191bd4fe43Sopenharmony_cistatic int32_t TimerHi35xxInitRegSet(struct TimerHi35xxInfo *info) 4201bd4fe43Sopenharmony_ci{ 4211bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT); 4221bd4fe43Sopenharmony_ci TimerHi35xxScCtrlSet(); 4231bd4fe43Sopenharmony_ci TimerHi35xxEnable(info, false); 4241bd4fe43Sopenharmony_ci TimerHi35xxSetMode(info, TIMERx_CONTROL_TIMERMODE_PERIOD); 4251bd4fe43Sopenharmony_ci TimerHi35xxIntEnable(info, false); 4261bd4fe43Sopenharmony_ci TimerHi35xxSetPre(info, TIMERx_CONTROL_TIMERPRE_NOT); 4271bd4fe43Sopenharmony_ci TimerHi35xxTimerSize(info, true); 4281bd4fe43Sopenharmony_ci TimerHi35xxRegRead(info->regBase + HI35XX_TIMERx_CONTROL); 4291bd4fe43Sopenharmony_ci 4301bd4fe43Sopenharmony_ci TimerHi35xxTimerLoadSet(info, HI35XX_TIMERx_LOAD_INIT_VAL); 4311bd4fe43Sopenharmony_ci return HDF_SUCCESS; 4321bd4fe43Sopenharmony_ci} 4331bd4fe43Sopenharmony_ci 4341bd4fe43Sopenharmony_cistatic int32_t TimerHi35xxReadHcs(struct TimerHi35xxInfo *info, const struct DeviceResourceNode *node) 4351bd4fe43Sopenharmony_ci{ 4361bd4fe43Sopenharmony_ci int32_t ret; 4371bd4fe43Sopenharmony_ci uint32_t tmp; 4381bd4fe43Sopenharmony_ci struct DeviceResourceIface *iface = NULL; 4391bd4fe43Sopenharmony_ci 4401bd4fe43Sopenharmony_ci iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); 4411bd4fe43Sopenharmony_ci if (iface == NULL || iface->GetUint32 == NULL) { 4421bd4fe43Sopenharmony_ci HDF_LOGE("%s: invalid drs ops fail!", __func__); 4431bd4fe43Sopenharmony_ci return HDF_FAILURE; 4441bd4fe43Sopenharmony_ci } 4451bd4fe43Sopenharmony_ci 4461bd4fe43Sopenharmony_ci ret = iface->GetUint32(node, "number", &info->number, 0); 4471bd4fe43Sopenharmony_ci if (ret != HDF_SUCCESS) { 4481bd4fe43Sopenharmony_ci HDF_LOGE("%s: read id fail!", __func__); 4491bd4fe43Sopenharmony_ci return HDF_FAILURE; 4501bd4fe43Sopenharmony_ci } 4511bd4fe43Sopenharmony_ci 4521bd4fe43Sopenharmony_ci ret = iface->GetUint32(node, "bus_clock", &info->busClock, 0); 4531bd4fe43Sopenharmony_ci if (ret != HDF_SUCCESS) { 4541bd4fe43Sopenharmony_ci HDF_LOGE("%s: read [%u] bus_clock fail!", __func__, info->number); 4551bd4fe43Sopenharmony_ci return HDF_FAILURE; 4561bd4fe43Sopenharmony_ci } 4571bd4fe43Sopenharmony_ci 4581bd4fe43Sopenharmony_ci ret = iface->GetUint32(node, "mode", &info->mode, 0); 4591bd4fe43Sopenharmony_ci if (ret != HDF_SUCCESS) { 4601bd4fe43Sopenharmony_ci HDF_LOGE("%s: read [%u] mode fail!", __func__, info->number); 4611bd4fe43Sopenharmony_ci return HDF_FAILURE; 4621bd4fe43Sopenharmony_ci } 4631bd4fe43Sopenharmony_ci 4641bd4fe43Sopenharmony_ci ret = iface->GetUint32(node, "init_count_val", &info->initCountVal, 0); 4651bd4fe43Sopenharmony_ci if (ret != HDF_SUCCESS) { 4661bd4fe43Sopenharmony_ci HDF_LOGE("%s: read [%u] init_count_val fail!", __func__, info->number); 4671bd4fe43Sopenharmony_ci return HDF_FAILURE; 4681bd4fe43Sopenharmony_ci } 4691bd4fe43Sopenharmony_ci 4701bd4fe43Sopenharmony_ci ret = iface->GetUint32(node, "irq", &info->irq, 0); 4711bd4fe43Sopenharmony_ci if (ret != HDF_SUCCESS) { 4721bd4fe43Sopenharmony_ci HDF_LOGE("%s: read [%u] irq fail!", __func__, info->number); 4731bd4fe43Sopenharmony_ci return HDF_FAILURE; 4741bd4fe43Sopenharmony_ci } 4751bd4fe43Sopenharmony_ci 4761bd4fe43Sopenharmony_ci if (iface->GetUint32(node, "reg_base", &tmp, 0) != HDF_SUCCESS) { 4771bd4fe43Sopenharmony_ci HDF_LOGE("%s: read [%u] reg_base fail", __func__, info->number); 4781bd4fe43Sopenharmony_ci return HDF_FAILURE; 4791bd4fe43Sopenharmony_ci } 4801bd4fe43Sopenharmony_ci info->regBase = OsalIoRemap(tmp, TIMER_MAX_REG_SIZE); 4811bd4fe43Sopenharmony_ci if (info->regBase == NULL) { 4821bd4fe43Sopenharmony_ci HDF_LOGE("%s:OsalIoRemap fail", __func__); 4831bd4fe43Sopenharmony_ci return HDF_FAILURE; 4841bd4fe43Sopenharmony_ci } 4851bd4fe43Sopenharmony_ci 4861bd4fe43Sopenharmony_ci HDF_LOGD("%s:number[%u], bus_clock[%u], mode[%u], init_count_val[%u] irq[%u]", __func__, 4871bd4fe43Sopenharmony_ci info->number, info->busClock, info->mode, info->initCountVal, info->irq); 4881bd4fe43Sopenharmony_ci 4891bd4fe43Sopenharmony_ci return HDF_SUCCESS; 4901bd4fe43Sopenharmony_ci} 4911bd4fe43Sopenharmony_ci 4921bd4fe43Sopenharmony_cistatic int32_t TimerHi35xxInitHandle(const struct DeviceResourceNode *node, struct TimerHi35xxInfo *info) 4931bd4fe43Sopenharmony_ci{ 4941bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(node, HDF_ERR_INVALID_OBJECT); 4951bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(info, HDF_ERR_INVALID_OBJECT); 4961bd4fe43Sopenharmony_ci 4971bd4fe43Sopenharmony_ci int32_t ret = TimerHi35xxReadHcs(info, node); 4981bd4fe43Sopenharmony_ci if (ret != HDF_SUCCESS) { 4991bd4fe43Sopenharmony_ci HDF_LOGE("%s: TimerHi35xxReadHcs fail!", __func__); 5001bd4fe43Sopenharmony_ci return ret; 5011bd4fe43Sopenharmony_ci } 5021bd4fe43Sopenharmony_ci 5031bd4fe43Sopenharmony_ci ret = TimerHi35xxInitRegSet(info); 5041bd4fe43Sopenharmony_ci if (ret != HDF_SUCCESS) { 5051bd4fe43Sopenharmony_ci HDF_LOGE("%s: TimerHi35xxInitRegSet fail!", __func__); 5061bd4fe43Sopenharmony_ci return ret; 5071bd4fe43Sopenharmony_ci } 5081bd4fe43Sopenharmony_ci info->isIrqReg = false; 5091bd4fe43Sopenharmony_ci 5101bd4fe43Sopenharmony_ci return HDF_SUCCESS; 5111bd4fe43Sopenharmony_ci} 5121bd4fe43Sopenharmony_ci 5131bd4fe43Sopenharmony_cistatic void TimerHi35xxInfoFree(struct TimerCntrl *cntrl) 5141bd4fe43Sopenharmony_ci{ 5151bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN(cntrl); 5161bd4fe43Sopenharmony_ci if (cntrl->priv != NULL) { 5171bd4fe43Sopenharmony_ci OsalMemFree(cntrl->priv); 5181bd4fe43Sopenharmony_ci cntrl->priv = NULL; 5191bd4fe43Sopenharmony_ci } 5201bd4fe43Sopenharmony_ci 5211bd4fe43Sopenharmony_ci if (cntrl != NULL) { 5221bd4fe43Sopenharmony_ci OsalMemFree(cntrl); 5231bd4fe43Sopenharmony_ci } 5241bd4fe43Sopenharmony_ci} 5251bd4fe43Sopenharmony_ci 5261bd4fe43Sopenharmony_cistatic void TimerDumperGet(struct TimerHi35xxInfo *info) 5271bd4fe43Sopenharmony_ci{ 5281bd4fe43Sopenharmony_ci struct PlatformDumper *dumper = NULL; 5291bd4fe43Sopenharmony_ci char *name = (char *)OsalMemAlloc(TIMER_DUMPER_NAME_LEN); 5301bd4fe43Sopenharmony_ci if (name == NULL) { 5311bd4fe43Sopenharmony_ci return; 5321bd4fe43Sopenharmony_ci } 5331bd4fe43Sopenharmony_ci if (snprintf_s(name, TIMER_DUMPER_NAME_LEN, TIMER_DUMPER_NAME_LEN - 1, "%s%d", 5341bd4fe43Sopenharmony_ci TIMER_DUMPER_NAME_PREFIX, info->number) < 0) { 5351bd4fe43Sopenharmony_ci HDF_LOGE("%s: snprintf_s name fail!", __func__); 5361bd4fe43Sopenharmony_ci OsalMemFree(name); 5371bd4fe43Sopenharmony_ci return; 5381bd4fe43Sopenharmony_ci } 5391bd4fe43Sopenharmony_ci dumper = PlatformDumperCreate(name); 5401bd4fe43Sopenharmony_ci if (dumper == NULL) { 5411bd4fe43Sopenharmony_ci HDF_LOGE("%s: get dumper for %s fail!", __func__, name); 5421bd4fe43Sopenharmony_ci OsalMemFree(name); 5431bd4fe43Sopenharmony_ci return; 5441bd4fe43Sopenharmony_ci } 5451bd4fe43Sopenharmony_ci info->dumperName = name; 5461bd4fe43Sopenharmony_ci info->dumper = dumper; 5471bd4fe43Sopenharmony_ci} 5481bd4fe43Sopenharmony_ci 5491bd4fe43Sopenharmony_cistatic int32_t TimerHi35xxParseAndInit(struct HdfDeviceObject *device, const struct DeviceResourceNode *node) 5501bd4fe43Sopenharmony_ci{ 5511bd4fe43Sopenharmony_ci int32_t ret; 5521bd4fe43Sopenharmony_ci struct TimerCntrl *cntrl = NULL; 5531bd4fe43Sopenharmony_ci struct TimerHi35xxInfo *info = NULL; 5541bd4fe43Sopenharmony_ci (void)device; 5551bd4fe43Sopenharmony_ci 5561bd4fe43Sopenharmony_ci cntrl = (struct TimerCntrl *)OsalMemCalloc(sizeof(*cntrl)); 5571bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT); 5581bd4fe43Sopenharmony_ci 5591bd4fe43Sopenharmony_ci info = (struct TimerHi35xxInfo *)OsalMemCalloc(sizeof(*info)); 5601bd4fe43Sopenharmony_ci if (cntrl == NULL) { 5611bd4fe43Sopenharmony_ci HDF_LOGE("%s: malloc info fail!", __func__); 5621bd4fe43Sopenharmony_ci TimerHi35xxInfoFree(cntrl); 5631bd4fe43Sopenharmony_ci return HDF_ERR_MALLOC_FAIL; 5641bd4fe43Sopenharmony_ci } 5651bd4fe43Sopenharmony_ci cntrl->priv = (void *)info; 5661bd4fe43Sopenharmony_ci 5671bd4fe43Sopenharmony_ci ret = TimerHi35xxInitHandle(node, info); 5681bd4fe43Sopenharmony_ci if (ret != HDF_SUCCESS) { 5691bd4fe43Sopenharmony_ci HDF_LOGE("%s: TimerHi35xxInitHandle fail!", __func__); 5701bd4fe43Sopenharmony_ci TimerHi35xxInfoFree(cntrl); 5711bd4fe43Sopenharmony_ci return ret; 5721bd4fe43Sopenharmony_ci } 5731bd4fe43Sopenharmony_ci 5741bd4fe43Sopenharmony_ci cntrl->info.number = info->number; 5751bd4fe43Sopenharmony_ci cntrl->ops = &g_timerCntlrMethod; 5761bd4fe43Sopenharmony_ci TimerDumperGet(info); 5771bd4fe43Sopenharmony_ci ret = TimerCntrlAdd(cntrl); 5781bd4fe43Sopenharmony_ci if (ret != HDF_SUCCESS) { 5791bd4fe43Sopenharmony_ci HDF_LOGE("%s: TimerCntrlAdd fail!", __func__); 5801bd4fe43Sopenharmony_ci TimerHi35xxInfoFree(cntrl); 5811bd4fe43Sopenharmony_ci return ret; 5821bd4fe43Sopenharmony_ci } 5831bd4fe43Sopenharmony_ci return HDF_SUCCESS; 5841bd4fe43Sopenharmony_ci} 5851bd4fe43Sopenharmony_ci 5861bd4fe43Sopenharmony_cistatic int32_t TimerHi35xxDeviceInit(struct HdfDeviceObject *device) 5871bd4fe43Sopenharmony_ci{ 5881bd4fe43Sopenharmony_ci int32_t ret; 5891bd4fe43Sopenharmony_ci const struct DeviceResourceNode *childNode = NULL; 5901bd4fe43Sopenharmony_ci if (device == NULL || device->property == NULL) { 5911bd4fe43Sopenharmony_ci HDF_LOGE("%s: device or property is NULL", __func__); 5921bd4fe43Sopenharmony_ci return HDF_ERR_INVALID_OBJECT; 5931bd4fe43Sopenharmony_ci } 5941bd4fe43Sopenharmony_ci 5951bd4fe43Sopenharmony_ci DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) { 5961bd4fe43Sopenharmony_ci ret = TimerHi35xxParseAndInit(device, childNode); 5971bd4fe43Sopenharmony_ci if (ret != HDF_SUCCESS) { 5981bd4fe43Sopenharmony_ci HDF_LOGE("%s:TimerHi35xxParseAndInit fail", __func__); 5991bd4fe43Sopenharmony_ci return HDF_FAILURE; 6001bd4fe43Sopenharmony_ci } 6011bd4fe43Sopenharmony_ci } 6021bd4fe43Sopenharmony_ci HDF_LOGD("%s: success", __func__); 6031bd4fe43Sopenharmony_ci return HDF_SUCCESS; 6041bd4fe43Sopenharmony_ci} 6051bd4fe43Sopenharmony_ci 6061bd4fe43Sopenharmony_cistatic int32_t TimerHi35xxDeviceBind(struct HdfDeviceObject *device) 6071bd4fe43Sopenharmony_ci{ 6081bd4fe43Sopenharmony_ci CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_OBJECT); 6091bd4fe43Sopenharmony_ci HDF_LOGI("%s: success", __func__); 6101bd4fe43Sopenharmony_ci return HDF_SUCCESS; 6111bd4fe43Sopenharmony_ci} 6121bd4fe43Sopenharmony_ci 6131bd4fe43Sopenharmony_cistatic void TimerHi35xxRemoveById(const struct DeviceResourceNode *node) 6141bd4fe43Sopenharmony_ci{ 6151bd4fe43Sopenharmony_ci int32_t ret; 6161bd4fe43Sopenharmony_ci uint32_t timerId; 6171bd4fe43Sopenharmony_ci struct DeviceResourceIface *drsOps = NULL; 6181bd4fe43Sopenharmony_ci 6191bd4fe43Sopenharmony_ci drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); 6201bd4fe43Sopenharmony_ci if (drsOps == NULL || drsOps->GetUint32 == NULL) { 6211bd4fe43Sopenharmony_ci HDF_LOGE("%s: invalid drs ops fail!", __func__); 6221bd4fe43Sopenharmony_ci return; 6231bd4fe43Sopenharmony_ci } 6241bd4fe43Sopenharmony_ci 6251bd4fe43Sopenharmony_ci ret = drsOps->GetUint32(node, "id", (uint32_t *)&timerId, 0); 6261bd4fe43Sopenharmony_ci if (ret != HDF_SUCCESS) { 6271bd4fe43Sopenharmony_ci HDF_LOGE("%s: read id fail!", __func__); 6281bd4fe43Sopenharmony_ci return; 6291bd4fe43Sopenharmony_ci } 6301bd4fe43Sopenharmony_ci 6311bd4fe43Sopenharmony_ci TimerCntrlRemoveByNumber(timerId); 6321bd4fe43Sopenharmony_ci return; 6331bd4fe43Sopenharmony_ci} 6341bd4fe43Sopenharmony_ci 6351bd4fe43Sopenharmony_cistatic void TimerHi35xxDeviceRelease(struct HdfDeviceObject *device) 6361bd4fe43Sopenharmony_ci{ 6371bd4fe43Sopenharmony_ci const struct DeviceResourceNode *childNode = NULL; 6381bd4fe43Sopenharmony_ci 6391bd4fe43Sopenharmony_ci HDF_LOGD("%s: in", __func__); 6401bd4fe43Sopenharmony_ci if (device == NULL || device->property == NULL) { 6411bd4fe43Sopenharmony_ci HDF_LOGE("%s: device is NULL", __func__); 6421bd4fe43Sopenharmony_ci return; 6431bd4fe43Sopenharmony_ci } 6441bd4fe43Sopenharmony_ci 6451bd4fe43Sopenharmony_ci DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) { 6461bd4fe43Sopenharmony_ci TimerHi35xxRemoveById(childNode); 6471bd4fe43Sopenharmony_ci } 6481bd4fe43Sopenharmony_ci} 6491bd4fe43Sopenharmony_ci 6501bd4fe43Sopenharmony_cistruct HdfDriverEntry g_hdfTimerDevice = { 6511bd4fe43Sopenharmony_ci .moduleVersion = 1, 6521bd4fe43Sopenharmony_ci .moduleName = "hi35xx_timer_driver", 6531bd4fe43Sopenharmony_ci .Bind = TimerHi35xxDeviceBind, 6541bd4fe43Sopenharmony_ci .Init = TimerHi35xxDeviceInit, 6551bd4fe43Sopenharmony_ci .Release = TimerHi35xxDeviceRelease, 6561bd4fe43Sopenharmony_ci}; 6571bd4fe43Sopenharmony_ci 6581bd4fe43Sopenharmony_ciHDF_INIT(g_hdfTimerDevice); 659