11bd4fe43Sopenharmony_ci/*
21bd4fe43Sopenharmony_ci * Copyright (c) 2021 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
161bd4fe43Sopenharmony_ci#include "pin_hi35xx.h"
171bd4fe43Sopenharmony_ci#include "device_resource_if.h"
181bd4fe43Sopenharmony_ci#include "hdf_log.h"
191bd4fe43Sopenharmony_ci#include "osal_io.h"
201bd4fe43Sopenharmony_ci#include "osal_mem.h"
211bd4fe43Sopenharmony_ci#include "pin_core.h"
221bd4fe43Sopenharmony_ci#include "platform_dumper.h"
231bd4fe43Sopenharmony_ci
241bd4fe43Sopenharmony_ci#define HDF_LOG_TAG pin_hi35xx
251bd4fe43Sopenharmony_ci
261bd4fe43Sopenharmony_ci#define HI35XX_PIN_FUNC_MAX  6
271bd4fe43Sopenharmony_ci#define HI35XX_PIN_REG_SIZE  4
281bd4fe43Sopenharmony_ci
291bd4fe43Sopenharmony_cistruct Hi35xxPinDesc {
301bd4fe43Sopenharmony_ci    const char *pinName;
311bd4fe43Sopenharmony_ci    uint32_t init;
321bd4fe43Sopenharmony_ci    uint32_t index;
331bd4fe43Sopenharmony_ci    int32_t pullType;
341bd4fe43Sopenharmony_ci    int32_t strength;
351bd4fe43Sopenharmony_ci    const char *func[HI35XX_PIN_FUNC_MAX];
361bd4fe43Sopenharmony_ci};
371bd4fe43Sopenharmony_ci
381bd4fe43Sopenharmony_cistruct Hi35xxPinCntlr {
391bd4fe43Sopenharmony_ci    struct PinCntlr cntlr;
401bd4fe43Sopenharmony_ci    struct Hi35xxPinDesc *desc;
411bd4fe43Sopenharmony_ci    volatile unsigned char *regBase;
421bd4fe43Sopenharmony_ci    uint16_t number;
431bd4fe43Sopenharmony_ci    uint32_t regStartBasePhy;
441bd4fe43Sopenharmony_ci    uint32_t regSize;
451bd4fe43Sopenharmony_ci    uint32_t pinCount;
461bd4fe43Sopenharmony_ci    struct PlatformDumper *dumper;
471bd4fe43Sopenharmony_ci    char *dumperName;
481bd4fe43Sopenharmony_ci};
491bd4fe43Sopenharmony_ci
501bd4fe43Sopenharmony_cistatic int32_t PinDumperCreate(struct Hi35xxPinCntlr *hi35xx)
511bd4fe43Sopenharmony_ci{
521bd4fe43Sopenharmony_ci    struct PlatformDumper *dumper = NULL;
531bd4fe43Sopenharmony_ci    char *name = NULL;
541bd4fe43Sopenharmony_ci
551bd4fe43Sopenharmony_ci    name = (char *)OsalMemCalloc(PIN_DUMPER_NAME_LEN);
561bd4fe43Sopenharmony_ci    if (name == NULL) {
571bd4fe43Sopenharmony_ci        HDF_LOGE("%s: alloc name fail", __func__);
581bd4fe43Sopenharmony_ci        return HDF_ERR_MALLOC_FAIL;
591bd4fe43Sopenharmony_ci    }
601bd4fe43Sopenharmony_ci
611bd4fe43Sopenharmony_ci    if (snprintf_s(name, PIN_DUMPER_NAME_LEN, PIN_DUMPER_NAME_LEN - 1, "%s%hu",
621bd4fe43Sopenharmony_ci        PIN_DUMPER_NAME_PREFIX, hi35xx->number) < 0) {
631bd4fe43Sopenharmony_ci        HDF_LOGE("%s: snprintf_s name fail!", __func__);
641bd4fe43Sopenharmony_ci        OsalMemFree(name);
651bd4fe43Sopenharmony_ci        return HDF_ERR_IO;
661bd4fe43Sopenharmony_ci    }
671bd4fe43Sopenharmony_ci    dumper = PlatformDumperCreate(name);
681bd4fe43Sopenharmony_ci    if (dumper == NULL) {
691bd4fe43Sopenharmony_ci        HDF_LOGE("%s: get dumper for %s fail!", __func__, name);
701bd4fe43Sopenharmony_ci        OsalMemFree(name);
711bd4fe43Sopenharmony_ci        return HDF_ERR_IO;
721bd4fe43Sopenharmony_ci    }
731bd4fe43Sopenharmony_ci    hi35xx->dumper = dumper;
741bd4fe43Sopenharmony_ci    hi35xx->dumperName = name;
751bd4fe43Sopenharmony_ci
761bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
771bd4fe43Sopenharmony_ci}
781bd4fe43Sopenharmony_ci
791bd4fe43Sopenharmony_cistatic void PinDumperDump(struct Hi35xxPinCntlr *hi35xx, uint32_t index)
801bd4fe43Sopenharmony_ci{
811bd4fe43Sopenharmony_ci    int32_t ret;
821bd4fe43Sopenharmony_ci    struct PlatformDumperData data[] = {
831bd4fe43Sopenharmony_ci        {"PIN_REGISTER", PLATFORM_DUMPER_REGISTERL, (void *)(hi35xx->regBase + index * HI35XX_PIN_REG_SIZE)},
841bd4fe43Sopenharmony_ci    };
851bd4fe43Sopenharmony_ci
861bd4fe43Sopenharmony_ci    if (hi35xx->dumper == NULL) {
871bd4fe43Sopenharmony_ci        return;
881bd4fe43Sopenharmony_ci    }
891bd4fe43Sopenharmony_ci
901bd4fe43Sopenharmony_ci    ret = PlatformDumperAddDatas(hi35xx->dumper, data, sizeof(data) / sizeof(struct PlatformDumperData));
911bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
921bd4fe43Sopenharmony_ci        return;
931bd4fe43Sopenharmony_ci    }
941bd4fe43Sopenharmony_ci    (void)PlatformDumperDump(hi35xx->dumper);
951bd4fe43Sopenharmony_ci    (void)PlatformDumperClearDatas(hi35xx->dumper);
961bd4fe43Sopenharmony_ci}
971bd4fe43Sopenharmony_ci
981bd4fe43Sopenharmony_cistatic inline void PinDumperDestroy(struct Hi35xxPinCntlr *hi35xx)
991bd4fe43Sopenharmony_ci{
1001bd4fe43Sopenharmony_ci    PlatformDumperDestroy(hi35xx->dumper);
1011bd4fe43Sopenharmony_ci    OsalMemFree(hi35xx->dumperName);
1021bd4fe43Sopenharmony_ci}
1031bd4fe43Sopenharmony_ci
1041bd4fe43Sopenharmony_cistatic int32_t Hi35xxPinSetPull(struct PinCntlr *cntlr, uint32_t index, enum PinPullType pullType)
1051bd4fe43Sopenharmony_ci{
1061bd4fe43Sopenharmony_ci    uint32_t value;
1071bd4fe43Sopenharmony_ci    struct Hi35xxPinCntlr *hi35xx = NULL;
1081bd4fe43Sopenharmony_ci
1091bd4fe43Sopenharmony_ci    hi35xx = (struct Hi35xxPinCntlr *)cntlr;
1101bd4fe43Sopenharmony_ci    value = OSAL_READL(hi35xx->regBase + index * HI35XX_PIN_REG_SIZE);
1111bd4fe43Sopenharmony_ci    value = (value & ~PIN_PULL_TYPE_MASK) | ((uint32_t)pullType << PIN_PULL_TYPE_OFFSET);
1121bd4fe43Sopenharmony_ci    OSAL_WRITEL(value, hi35xx->regBase + index * HI35XX_PIN_REG_SIZE);
1131bd4fe43Sopenharmony_ci    HDF_LOGD("%s: set pin Pull success.", __func__);
1141bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
1151bd4fe43Sopenharmony_ci}
1161bd4fe43Sopenharmony_ci
1171bd4fe43Sopenharmony_cistatic int32_t Hi35xxPinGetPull(struct PinCntlr *cntlr, uint32_t index, enum PinPullType *pullType)
1181bd4fe43Sopenharmony_ci{
1191bd4fe43Sopenharmony_ci    uint32_t value;
1201bd4fe43Sopenharmony_ci    struct Hi35xxPinCntlr *hi35xx = NULL;
1211bd4fe43Sopenharmony_ci    hi35xx = (struct Hi35xxPinCntlr *)cntlr;
1221bd4fe43Sopenharmony_ci
1231bd4fe43Sopenharmony_ci    value = OSAL_READL(hi35xx->regBase + index * HI35XX_PIN_REG_SIZE);
1241bd4fe43Sopenharmony_ci    *pullType = (enum PinPullType)((value & PIN_PULL_TYPE_MASK) >> PIN_PULL_TYPE_OFFSET);
1251bd4fe43Sopenharmony_ci    HDF_LOGD("%s: get pin Pull success.", __func__);
1261bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
1271bd4fe43Sopenharmony_ci}
1281bd4fe43Sopenharmony_ci
1291bd4fe43Sopenharmony_cistatic int32_t Hi35xxPinSetStrength(struct PinCntlr *cntlr, uint32_t index, uint32_t strength)
1301bd4fe43Sopenharmony_ci{
1311bd4fe43Sopenharmony_ci    uint32_t value;
1321bd4fe43Sopenharmony_ci    struct Hi35xxPinCntlr *hi35xx = NULL;
1331bd4fe43Sopenharmony_ci
1341bd4fe43Sopenharmony_ci    hi35xx = (struct Hi35xxPinCntlr *)cntlr;
1351bd4fe43Sopenharmony_ci    value = OSAL_READL(hi35xx->regBase + index * HI35XX_PIN_REG_SIZE);
1361bd4fe43Sopenharmony_ci    value = (value & ~PIN_STRENGTH_MASK) | (strength << PIN_STRENGTH_OFFSET);
1371bd4fe43Sopenharmony_ci    OSAL_WRITEL(value, hi35xx->regBase + index * HI35XX_PIN_REG_SIZE);
1381bd4fe43Sopenharmony_ci    HDF_LOGD("%s: set pin Strength success.", __func__);
1391bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
1401bd4fe43Sopenharmony_ci}
1411bd4fe43Sopenharmony_ci
1421bd4fe43Sopenharmony_cistatic int32_t Hi35xxPinGetStrength(struct PinCntlr *cntlr, uint32_t index, uint32_t *strength)
1431bd4fe43Sopenharmony_ci{
1441bd4fe43Sopenharmony_ci    uint32_t value;
1451bd4fe43Sopenharmony_ci    struct Hi35xxPinCntlr *hi35xx = NULL;
1461bd4fe43Sopenharmony_ci    hi35xx = (struct Hi35xxPinCntlr *)cntlr;
1471bd4fe43Sopenharmony_ci
1481bd4fe43Sopenharmony_ci    value = OSAL_READL(hi35xx->regBase + index * HI35XX_PIN_REG_SIZE);
1491bd4fe43Sopenharmony_ci    *strength = (value & PIN_STRENGTH_MASK) >> PIN_STRENGTH_OFFSET;
1501bd4fe43Sopenharmony_ci    HDF_LOGD("%s: get pin Strength success.", __func__);
1511bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
1521bd4fe43Sopenharmony_ci}
1531bd4fe43Sopenharmony_ci
1541bd4fe43Sopenharmony_cistatic int32_t Hi35xxPinSetFunc(struct PinCntlr *cntlr, uint32_t index, const char *funcName)
1551bd4fe43Sopenharmony_ci{
1561bd4fe43Sopenharmony_ci    uint32_t value;
1571bd4fe43Sopenharmony_ci    int ret;
1581bd4fe43Sopenharmony_ci    uint32_t funcNum;
1591bd4fe43Sopenharmony_ci    struct Hi35xxPinCntlr *hi35xx = NULL;
1601bd4fe43Sopenharmony_ci
1611bd4fe43Sopenharmony_ci    hi35xx = (struct Hi35xxPinCntlr *)cntlr;
1621bd4fe43Sopenharmony_ci
1631bd4fe43Sopenharmony_ci    for (funcNum = 0; funcNum < HI35XX_PIN_FUNC_MAX; funcNum++) {
1641bd4fe43Sopenharmony_ci        ret = strcmp(funcName, hi35xx->desc[index].func[funcNum]);
1651bd4fe43Sopenharmony_ci        if (ret == 0) {
1661bd4fe43Sopenharmony_ci            value = OSAL_READL(hi35xx->regBase + index * HI35XX_PIN_REG_SIZE);
1671bd4fe43Sopenharmony_ci            value = (value & ~PIN_FUNC_MASK) | funcNum;
1681bd4fe43Sopenharmony_ci            OSAL_WRITEL(value, hi35xx->regBase + index * HI35XX_PIN_REG_SIZE);
1691bd4fe43Sopenharmony_ci            HDF_LOGD("%s: set pin function success.", __func__);
1701bd4fe43Sopenharmony_ci            return HDF_SUCCESS;
1711bd4fe43Sopenharmony_ci        }
1721bd4fe43Sopenharmony_ci    }
1731bd4fe43Sopenharmony_ci    HDF_LOGE("%s: set pin Function failed.", __func__);
1741bd4fe43Sopenharmony_ci    PinDumperDump(hi35xx, index);
1751bd4fe43Sopenharmony_ci    return HDF_ERR_IO;
1761bd4fe43Sopenharmony_ci}
1771bd4fe43Sopenharmony_ci
1781bd4fe43Sopenharmony_cistatic int32_t Hi35xxPinGetFunc(struct PinCntlr *cntlr, uint32_t index, const char **funcName)
1791bd4fe43Sopenharmony_ci{
1801bd4fe43Sopenharmony_ci    uint32_t value;
1811bd4fe43Sopenharmony_ci    uint32_t funcNum;
1821bd4fe43Sopenharmony_ci    struct Hi35xxPinCntlr *hi35xx = NULL;
1831bd4fe43Sopenharmony_ci
1841bd4fe43Sopenharmony_ci    hi35xx = (struct Hi35xxPinCntlr *)cntlr;
1851bd4fe43Sopenharmony_ci
1861bd4fe43Sopenharmony_ci    value = OSAL_READL(hi35xx->regBase + index * HI35XX_PIN_REG_SIZE);
1871bd4fe43Sopenharmony_ci    funcNum = value & PIN_FUNC_MASK;
1881bd4fe43Sopenharmony_ci    *funcName = hi35xx->desc[index].func[funcNum];
1891bd4fe43Sopenharmony_ci    HDF_LOGD("%s: get pin function success.", __func__);
1901bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
1911bd4fe43Sopenharmony_ci}
1921bd4fe43Sopenharmony_ci
1931bd4fe43Sopenharmony_cistatic struct PinCntlrMethod g_method = {
1941bd4fe43Sopenharmony_ci    .SetPinPull = Hi35xxPinSetPull,
1951bd4fe43Sopenharmony_ci    .GetPinPull = Hi35xxPinGetPull,
1961bd4fe43Sopenharmony_ci    .SetPinStrength = Hi35xxPinSetStrength,
1971bd4fe43Sopenharmony_ci    .GetPinStrength = Hi35xxPinGetStrength,
1981bd4fe43Sopenharmony_ci    .SetPinFunc = Hi35xxPinSetFunc,
1991bd4fe43Sopenharmony_ci    .GetPinFunc = Hi35xxPinGetFunc,
2001bd4fe43Sopenharmony_ci};
2011bd4fe43Sopenharmony_ci
2021bd4fe43Sopenharmony_cistatic int32_t Hi35xxPinReadFunc(struct Hi35xxPinDesc *desc,
2031bd4fe43Sopenharmony_ci    const struct DeviceResourceNode *node, struct DeviceResourceIface *drsOps)
2041bd4fe43Sopenharmony_ci{
2051bd4fe43Sopenharmony_ci    int32_t ret;
2061bd4fe43Sopenharmony_ci    uint32_t funcNum = 0;
2071bd4fe43Sopenharmony_ci
2081bd4fe43Sopenharmony_ci    ret = drsOps->GetString(node, "F0", &desc->func[funcNum], "NULL");
2091bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
2101bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read F0 failed", __func__);
2111bd4fe43Sopenharmony_ci        return ret;
2121bd4fe43Sopenharmony_ci    }
2131bd4fe43Sopenharmony_ci
2141bd4fe43Sopenharmony_ci    funcNum++;
2151bd4fe43Sopenharmony_ci    ret = drsOps->GetString(node, "F1", &desc->func[funcNum], "NULL");
2161bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
2171bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read F1 failed", __func__);
2181bd4fe43Sopenharmony_ci        return ret;
2191bd4fe43Sopenharmony_ci    }
2201bd4fe43Sopenharmony_ci
2211bd4fe43Sopenharmony_ci    funcNum++;
2221bd4fe43Sopenharmony_ci    ret = drsOps->GetString(node, "F2", &desc->func[funcNum], "NULL");
2231bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
2241bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read F2 failed", __func__);
2251bd4fe43Sopenharmony_ci        return ret;
2261bd4fe43Sopenharmony_ci    }
2271bd4fe43Sopenharmony_ci
2281bd4fe43Sopenharmony_ci    funcNum++;
2291bd4fe43Sopenharmony_ci    ret = drsOps->GetString(node, "F3", &desc->func[funcNum], "NULL");
2301bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
2311bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read F3 failed", __func__);
2321bd4fe43Sopenharmony_ci        return ret;
2331bd4fe43Sopenharmony_ci    }
2341bd4fe43Sopenharmony_ci
2351bd4fe43Sopenharmony_ci    funcNum++;
2361bd4fe43Sopenharmony_ci    ret = drsOps->GetString(node, "F4", &desc->func[funcNum], "NULL");
2371bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
2381bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read F4 failed", __func__);
2391bd4fe43Sopenharmony_ci        return ret;
2401bd4fe43Sopenharmony_ci    }
2411bd4fe43Sopenharmony_ci
2421bd4fe43Sopenharmony_ci    funcNum++;
2431bd4fe43Sopenharmony_ci    ret = drsOps->GetString(node, "F5", &desc->func[funcNum], "NULL");
2441bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
2451bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read F5 failed", __func__);
2461bd4fe43Sopenharmony_ci        return ret;
2471bd4fe43Sopenharmony_ci    }
2481bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
2491bd4fe43Sopenharmony_ci}
2501bd4fe43Sopenharmony_ci
2511bd4fe43Sopenharmony_cistatic int32_t Hi35xxPinParsePinNode(const struct DeviceResourceNode *node,
2521bd4fe43Sopenharmony_ci    struct Hi35xxPinCntlr *hi35xx, int32_t index)
2531bd4fe43Sopenharmony_ci{
2541bd4fe43Sopenharmony_ci    int32_t ret;
2551bd4fe43Sopenharmony_ci    struct DeviceResourceIface *drsOps = NULL;
2561bd4fe43Sopenharmony_ci
2571bd4fe43Sopenharmony_ci    drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
2581bd4fe43Sopenharmony_ci    if (drsOps == NULL || drsOps->GetUint32 == NULL || drsOps->GetString == NULL) {
2591bd4fe43Sopenharmony_ci        HDF_LOGE("%s: invalid drs ops fail!", __func__);
2601bd4fe43Sopenharmony_ci        return HDF_FAILURE;
2611bd4fe43Sopenharmony_ci    }
2621bd4fe43Sopenharmony_ci    ret = drsOps->GetString(node, "pinName", &hi35xx->desc[index].pinName, "NULL");
2631bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
2641bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read pinName failed", __func__);
2651bd4fe43Sopenharmony_ci        return ret;
2661bd4fe43Sopenharmony_ci    }
2671bd4fe43Sopenharmony_ci
2681bd4fe43Sopenharmony_ci    ret = drsOps->GetUint32(node, "init", &hi35xx->desc[index].init, 0);
2691bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
2701bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read init failed", __func__);
2711bd4fe43Sopenharmony_ci        return ret;
2721bd4fe43Sopenharmony_ci    }
2731bd4fe43Sopenharmony_ci
2741bd4fe43Sopenharmony_ci    ret = Hi35xxPinReadFunc(&hi35xx->desc[index], node, drsOps);
2751bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
2761bd4fe43Sopenharmony_ci        HDF_LOGE("%s:Pin read Func failed", __func__);
2771bd4fe43Sopenharmony_ci        return ret;
2781bd4fe43Sopenharmony_ci    }
2791bd4fe43Sopenharmony_ci    hi35xx->cntlr.pins[index].pinName = hi35xx->desc[index].pinName;
2801bd4fe43Sopenharmony_ci    hi35xx->cntlr.pins[index].priv = (void *)node;
2811bd4fe43Sopenharmony_ci
2821bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
2831bd4fe43Sopenharmony_ci}
2841bd4fe43Sopenharmony_ci
2851bd4fe43Sopenharmony_cistatic int32_t Hi35xxPinCntlrInit(struct HdfDeviceObject *device, struct Hi35xxPinCntlr *hi35xx)
2861bd4fe43Sopenharmony_ci{
2871bd4fe43Sopenharmony_ci    struct DeviceResourceIface *drsOps = NULL;
2881bd4fe43Sopenharmony_ci    int32_t ret;
2891bd4fe43Sopenharmony_ci
2901bd4fe43Sopenharmony_ci    drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
2911bd4fe43Sopenharmony_ci    if (drsOps == NULL || drsOps->GetUint32 == NULL || drsOps->GetUint16 == NULL) {
2921bd4fe43Sopenharmony_ci        HDF_LOGE("%s: invalid drs ops fail!", __func__);
2931bd4fe43Sopenharmony_ci        return HDF_FAILURE;
2941bd4fe43Sopenharmony_ci    }
2951bd4fe43Sopenharmony_ci    ret = drsOps->GetUint16(device->property, "number", &hi35xx->number, 0);
2961bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
2971bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read number failed", __func__);
2981bd4fe43Sopenharmony_ci        return ret;
2991bd4fe43Sopenharmony_ci    }
3001bd4fe43Sopenharmony_ci    ret = drsOps->GetUint32(device->property, "regStartBasePhy", &hi35xx->regStartBasePhy, 0);
3011bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
3021bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read regStartBasePhy failed", __func__);
3031bd4fe43Sopenharmony_ci        return ret;
3041bd4fe43Sopenharmony_ci    }
3051bd4fe43Sopenharmony_ci    ret = drsOps->GetUint32(device->property, "regSize", &hi35xx->regSize, 0);
3061bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
3071bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read regSize failed", __func__);
3081bd4fe43Sopenharmony_ci        return ret;
3091bd4fe43Sopenharmony_ci    }
3101bd4fe43Sopenharmony_ci    ret = drsOps->GetUint32(device->property, "pinCount", &hi35xx->pinCount, 0);
3111bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
3121bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read pinCount failed", __func__);
3131bd4fe43Sopenharmony_ci        return ret;
3141bd4fe43Sopenharmony_ci    }
3151bd4fe43Sopenharmony_ci    hi35xx->cntlr.pinCount = hi35xx->pinCount;
3161bd4fe43Sopenharmony_ci    hi35xx->cntlr.number = hi35xx->number;
3171bd4fe43Sopenharmony_ci    hi35xx->regBase = OsalIoRemap(hi35xx->regStartBasePhy, hi35xx->regSize);
3181bd4fe43Sopenharmony_ci    if (hi35xx->regBase == NULL) {
3191bd4fe43Sopenharmony_ci        HDF_LOGE("%s: remap Pin base failed", __func__);
3201bd4fe43Sopenharmony_ci        return HDF_ERR_IO;
3211bd4fe43Sopenharmony_ci    }
3221bd4fe43Sopenharmony_ci    hi35xx->desc = (struct Hi35xxPinDesc *)OsalMemCalloc(sizeof(struct Hi35xxPinDesc) * hi35xx->pinCount);
3231bd4fe43Sopenharmony_ci    if (hi35xx->desc == NULL) {
3241bd4fe43Sopenharmony_ci        HDF_LOGE("%s: malloc desc failed:%d", __func__, ret);
3251bd4fe43Sopenharmony_ci        return ret;
3261bd4fe43Sopenharmony_ci    }
3271bd4fe43Sopenharmony_ci    hi35xx->cntlr.pins = (struct PinDesc *)OsalMemCalloc(sizeof(struct PinDesc) * hi35xx->pinCount);
3281bd4fe43Sopenharmony_ci    if (hi35xx->cntlr.pins == NULL) {
3291bd4fe43Sopenharmony_ci        HDF_LOGE("%s: malloc pins failed:%d", __func__, ret);
3301bd4fe43Sopenharmony_ci        return ret;
3311bd4fe43Sopenharmony_ci    }
3321bd4fe43Sopenharmony_ci    ret = PinDumperCreate(hi35xx);
3331bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
3341bd4fe43Sopenharmony_ci        HDF_LOGE("%s: create dumper failed:%d", __func__, ret);
3351bd4fe43Sopenharmony_ci        return ret;
3361bd4fe43Sopenharmony_ci    }
3371bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
3381bd4fe43Sopenharmony_ci}
3391bd4fe43Sopenharmony_ci
3401bd4fe43Sopenharmony_cistatic int32_t Hi35xxPinBind(struct HdfDeviceObject *device)
3411bd4fe43Sopenharmony_ci{
3421bd4fe43Sopenharmony_ci    (void)device;
3431bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
3441bd4fe43Sopenharmony_ci}
3451bd4fe43Sopenharmony_ci
3461bd4fe43Sopenharmony_cistatic int32_t Hi35xxPinInit(struct HdfDeviceObject *device)
3471bd4fe43Sopenharmony_ci{
3481bd4fe43Sopenharmony_ci    int32_t ret;
3491bd4fe43Sopenharmony_ci    int32_t index;
3501bd4fe43Sopenharmony_ci    const struct DeviceResourceNode *childNode = NULL;
3511bd4fe43Sopenharmony_ci    struct Hi35xxPinCntlr *hi35xx = NULL;
3521bd4fe43Sopenharmony_ci
3531bd4fe43Sopenharmony_ci    hi35xx = (struct Hi35xxPinCntlr *)OsalMemCalloc(sizeof(*hi35xx));
3541bd4fe43Sopenharmony_ci    if (hi35xx == NULL) {
3551bd4fe43Sopenharmony_ci        HDF_LOGE("%s: alloc hi35xx failed", __func__);
3561bd4fe43Sopenharmony_ci        return HDF_ERR_MALLOC_FAIL;
3571bd4fe43Sopenharmony_ci    }
3581bd4fe43Sopenharmony_ci
3591bd4fe43Sopenharmony_ci    ret = Hi35xxPinCntlrInit(device, hi35xx);
3601bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
3611bd4fe43Sopenharmony_ci        HDF_LOGE("%s: init cntlr failed:%d", __func__, ret);
3621bd4fe43Sopenharmony_ci        return ret;
3631bd4fe43Sopenharmony_ci    }
3641bd4fe43Sopenharmony_ci    index = 0;
3651bd4fe43Sopenharmony_ci
3661bd4fe43Sopenharmony_ci    DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) {
3671bd4fe43Sopenharmony_ci        ret = Hi35xxPinParsePinNode(childNode, hi35xx, index);
3681bd4fe43Sopenharmony_ci        if (ret != HDF_SUCCESS) {
3691bd4fe43Sopenharmony_ci            PinDumperDestroy(hi35xx);
3701bd4fe43Sopenharmony_ci            return ret;
3711bd4fe43Sopenharmony_ci        }
3721bd4fe43Sopenharmony_ci        index++;
3731bd4fe43Sopenharmony_ci    }
3741bd4fe43Sopenharmony_ci
3751bd4fe43Sopenharmony_ci    hi35xx->cntlr.method = &g_method;
3761bd4fe43Sopenharmony_ci    ret = PinCntlrAdd(&hi35xx->cntlr);
3771bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
3781bd4fe43Sopenharmony_ci        HDF_LOGE("%s: add Pin cntlr failed", __func__);
3791bd4fe43Sopenharmony_ci        PinDumperDestroy(hi35xx);
3801bd4fe43Sopenharmony_ci        ret = HDF_FAILURE;
3811bd4fe43Sopenharmony_ci    }
3821bd4fe43Sopenharmony_ci    HDF_LOGI("%s: Pin Init success", __func__);
3831bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
3841bd4fe43Sopenharmony_ci}
3851bd4fe43Sopenharmony_ci
3861bd4fe43Sopenharmony_cistatic void Hi35xxPinRelease(struct HdfDeviceObject *device)
3871bd4fe43Sopenharmony_ci{
3881bd4fe43Sopenharmony_ci    int32_t ret;
3891bd4fe43Sopenharmony_ci    uint16_t number;
3901bd4fe43Sopenharmony_ci    struct PinCntlr *cntlr = NULL;
3911bd4fe43Sopenharmony_ci    struct Hi35xxPinCntlr *hi35xx = NULL;
3921bd4fe43Sopenharmony_ci    struct DeviceResourceIface *drsOps = NULL;
3931bd4fe43Sopenharmony_ci
3941bd4fe43Sopenharmony_ci    HDF_LOGI("%s: enter", __func__);
3951bd4fe43Sopenharmony_ci    if (device == NULL || device->property == NULL) {
3961bd4fe43Sopenharmony_ci        HDF_LOGE("%s: device or property is null", __func__);
3971bd4fe43Sopenharmony_ci        return;
3981bd4fe43Sopenharmony_ci    }
3991bd4fe43Sopenharmony_ci    drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
4001bd4fe43Sopenharmony_ci    if (drsOps == NULL || drsOps->GetUint32 == NULL || drsOps->GetString == NULL) {
4011bd4fe43Sopenharmony_ci        HDF_LOGE("%s: invalid drs ops", __func__);
4021bd4fe43Sopenharmony_ci        return;
4031bd4fe43Sopenharmony_ci    }
4041bd4fe43Sopenharmony_ci
4051bd4fe43Sopenharmony_ci    ret = drsOps->GetUint16(device->property, "number", &number, 0);
4061bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
4071bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read cntlr number failed", __func__);
4081bd4fe43Sopenharmony_ci        return;
4091bd4fe43Sopenharmony_ci    }
4101bd4fe43Sopenharmony_ci
4111bd4fe43Sopenharmony_ci    cntlr = PinCntlrGetByNumber(number);
4121bd4fe43Sopenharmony_ci    PinCntlrRemove(cntlr);
4131bd4fe43Sopenharmony_ci    hi35xx = (struct Hi35xxPinCntlr *)cntlr;
4141bd4fe43Sopenharmony_ci    if (hi35xx != NULL) {
4151bd4fe43Sopenharmony_ci        if (hi35xx->regBase != NULL) {
4161bd4fe43Sopenharmony_ci            OsalIoUnmap((void *)hi35xx->regBase);
4171bd4fe43Sopenharmony_ci        }
4181bd4fe43Sopenharmony_ci        PinDumperDestroy(hi35xx);
4191bd4fe43Sopenharmony_ci        OsalMemFree(hi35xx);
4201bd4fe43Sopenharmony_ci    }
4211bd4fe43Sopenharmony_ci}
4221bd4fe43Sopenharmony_ci
4231bd4fe43Sopenharmony_cistatic struct HdfDriverEntry g_hi35xxPinDriverEntry = {
4241bd4fe43Sopenharmony_ci    .moduleVersion = 1,
4251bd4fe43Sopenharmony_ci    .Bind = Hi35xxPinBind,
4261bd4fe43Sopenharmony_ci    .Init = Hi35xxPinInit,
4271bd4fe43Sopenharmony_ci    .Release = Hi35xxPinRelease,
4281bd4fe43Sopenharmony_ci    .moduleName = "hi35xx_pin_driver",
4291bd4fe43Sopenharmony_ci};
4301bd4fe43Sopenharmony_ciHDF_INIT(g_hi35xxPinDriverEntry);
431