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 "adc_hi35xx.h"
171bd4fe43Sopenharmony_ci#include "adc_core.h"
181bd4fe43Sopenharmony_ci#include "asm/platform.h"
191bd4fe43Sopenharmony_ci#include "device_resource_if.h"
201bd4fe43Sopenharmony_ci#include "hdf_device_desc.h"
211bd4fe43Sopenharmony_ci#include "hdf_log.h"
221bd4fe43Sopenharmony_ci#include "los_hwi.h"
231bd4fe43Sopenharmony_ci#include "osal_io.h"
241bd4fe43Sopenharmony_ci#include "osal_mem.h"
251bd4fe43Sopenharmony_ci#include "osal_time.h"
261bd4fe43Sopenharmony_ci
271bd4fe43Sopenharmony_ci#define HDF_LOG_TAG adc_hi35xx
281bd4fe43Sopenharmony_ci#define HI35XX_ADC_READ_DELAY    10
291bd4fe43Sopenharmony_ci
301bd4fe43Sopenharmony_cistruct Hi35xxAdcDevice {
311bd4fe43Sopenharmony_ci    struct AdcDevice device;
321bd4fe43Sopenharmony_ci    volatile unsigned char *regBase;
331bd4fe43Sopenharmony_ci    volatile unsigned char *pinCtrlBase;
341bd4fe43Sopenharmony_ci    uint32_t regBasePhy;
351bd4fe43Sopenharmony_ci    uint32_t regSize;
361bd4fe43Sopenharmony_ci    uint32_t deviceNum;
371bd4fe43Sopenharmony_ci    uint32_t dataWidth;
381bd4fe43Sopenharmony_ci    uint32_t validChannel;
391bd4fe43Sopenharmony_ci    uint32_t scanMode;
401bd4fe43Sopenharmony_ci    uint32_t delta;
411bd4fe43Sopenharmony_ci    uint32_t deglitch;
421bd4fe43Sopenharmony_ci    uint32_t glitchSample;
431bd4fe43Sopenharmony_ci    uint32_t rate;
441bd4fe43Sopenharmony_ci};
451bd4fe43Sopenharmony_ci
461bd4fe43Sopenharmony_cistatic inline void Hi35xxAdcSetIrq(const struct Hi35xxAdcDevice *hi35xx)
471bd4fe43Sopenharmony_ci{
481bd4fe43Sopenharmony_ci    OSAL_WRITEL(0, hi35xx->regBase + HI35XX_ADC_INTR_EN);
491bd4fe43Sopenharmony_ci}
501bd4fe43Sopenharmony_ci
511bd4fe43Sopenharmony_cistatic void Hi35xxAdcSetAccuracy(const struct Hi35xxAdcDevice *hi35xx)
521bd4fe43Sopenharmony_ci{
531bd4fe43Sopenharmony_ci    uint32_t dataWidth;
541bd4fe43Sopenharmony_ci    uint32_t val;
551bd4fe43Sopenharmony_ci
561bd4fe43Sopenharmony_ci    if (hi35xx->dataWidth != 0 && hi35xx->dataWidth <= MAX_DATA_WIDTH) {
571bd4fe43Sopenharmony_ci        dataWidth = hi35xx->dataWidth;
581bd4fe43Sopenharmony_ci    } else {
591bd4fe43Sopenharmony_ci        dataWidth = DEFAULT_DATA_WIDTH;
601bd4fe43Sopenharmony_ci    }
611bd4fe43Sopenharmony_ci
621bd4fe43Sopenharmony_ci    val = ((DATA_WIDTH_MASK << (MAX_DATA_WIDTH - dataWidth)) & DATA_WIDTH_MASK);
631bd4fe43Sopenharmony_ci    OSAL_WRITEL(val, hi35xx->regBase + HI35XX_ADC_ACCURACY);
641bd4fe43Sopenharmony_ci}
651bd4fe43Sopenharmony_ci
661bd4fe43Sopenharmony_cistatic void Hi35xxAdcSetGlitchSample(const struct Hi35xxAdcDevice *hi35xx)
671bd4fe43Sopenharmony_ci{
681bd4fe43Sopenharmony_ci    uint32_t val;
691bd4fe43Sopenharmony_ci
701bd4fe43Sopenharmony_ci    if (hi35xx->scanMode == CYCLE_MODE) {
711bd4fe43Sopenharmony_ci        val = (hi35xx->glitchSample == CYCLE_MODE) ? DEFAULT_GLITCHSAMPLE : hi35xx->glitchSample;
721bd4fe43Sopenharmony_ci        OSAL_WRITEL(val, hi35xx->regBase + HI35XX_ADC_START);
731bd4fe43Sopenharmony_ci        val = OSAL_READL(hi35xx->regBase + HI35XX_ADC_START);
741bd4fe43Sopenharmony_ci        HDF_LOGD("%s: glichSample reg val:%x", __func__, val);
751bd4fe43Sopenharmony_ci    }
761bd4fe43Sopenharmony_ci}
771bd4fe43Sopenharmony_ci
781bd4fe43Sopenharmony_cistatic void Hi35xxAdcSetTimeScan(const struct Hi35xxAdcDevice *hi35xx)
791bd4fe43Sopenharmony_ci{
801bd4fe43Sopenharmony_ci    uint32_t timeScan;
811bd4fe43Sopenharmony_ci    uint32_t rate;
821bd4fe43Sopenharmony_ci
831bd4fe43Sopenharmony_ci    rate = hi35xx->rate;
841bd4fe43Sopenharmony_ci    if (hi35xx->scanMode == CYCLE_MODE) {
851bd4fe43Sopenharmony_ci        timeScan = (TIME_SCAN_CALCULATOR / rate);
861bd4fe43Sopenharmony_ci        if (timeScan < TIME_SCAN_MINIMUM) {
871bd4fe43Sopenharmony_ci            timeScan = TIME_SCAN_MINIMUM;
881bd4fe43Sopenharmony_ci        }
891bd4fe43Sopenharmony_ci        OSAL_WRITEL(timeScan, hi35xx->regBase + HI35XX_ADC_START);
901bd4fe43Sopenharmony_ci        timeScan = OSAL_READL(hi35xx->regBase + HI35XX_ADC_START);
911bd4fe43Sopenharmony_ci        HDF_LOGD("%s: tiemScan reg val:%x", __func__, timeScan);
921bd4fe43Sopenharmony_ci    }
931bd4fe43Sopenharmony_ci}
941bd4fe43Sopenharmony_ci
951bd4fe43Sopenharmony_cistatic void Hi35xxAdcConfig(const struct Hi35xxAdcDevice *hi35xx)
961bd4fe43Sopenharmony_ci{
971bd4fe43Sopenharmony_ci    uint32_t validChannel;
981bd4fe43Sopenharmony_ci    uint32_t scanMode;
991bd4fe43Sopenharmony_ci    uint32_t delta;
1001bd4fe43Sopenharmony_ci    uint32_t deglitch;
1011bd4fe43Sopenharmony_ci    uint32_t val;
1021bd4fe43Sopenharmony_ci
1031bd4fe43Sopenharmony_ci    validChannel = hi35xx->validChannel;
1041bd4fe43Sopenharmony_ci    scanMode = hi35xx->scanMode;
1051bd4fe43Sopenharmony_ci    delta = hi35xx->delta;
1061bd4fe43Sopenharmony_ci    deglitch = hi35xx->deglitch;
1071bd4fe43Sopenharmony_ci
1081bd4fe43Sopenharmony_ci    if (scanMode == CYCLE_MODE) {
1091bd4fe43Sopenharmony_ci        val = (delta & DELTA_MASK) << DELTA_OFFSET;
1101bd4fe43Sopenharmony_ci        val |= ((~deglitch) & 1) << DEGLITCH_OFFSET;
1111bd4fe43Sopenharmony_ci    }
1121bd4fe43Sopenharmony_ci    val = ((~scanMode) & 1) << SCAN_MODE_OFFSET;
1131bd4fe43Sopenharmony_ci    val |= (validChannel & VALID_CHANNEL_MASK) << VALID_CHANNEL_OFFSET;
1141bd4fe43Sopenharmony_ci    OSAL_WRITEL(val, hi35xx->regBase + HI35XX_ADC_CONFIG);
1151bd4fe43Sopenharmony_ci}
1161bd4fe43Sopenharmony_ci
1171bd4fe43Sopenharmony_cistatic inline void Hi35xxAdcStartScan(const struct Hi35xxAdcDevice *hi35xx)
1181bd4fe43Sopenharmony_ci{
1191bd4fe43Sopenharmony_ci    OSAL_WRITEL(1, hi35xx->regBase + HI35XX_ADC_START);
1201bd4fe43Sopenharmony_ci}
1211bd4fe43Sopenharmony_ci
1221bd4fe43Sopenharmony_cistatic inline void Hi35xxAdcReset(const struct Hi35xxAdcDevice *hi35xx)
1231bd4fe43Sopenharmony_ci{
1241bd4fe43Sopenharmony_ci    OSAL_WRITEL(CONFIG_REG_RESET_VALUE, hi35xx->regBase + HI35XX_ADC_CONFIG);
1251bd4fe43Sopenharmony_ci}
1261bd4fe43Sopenharmony_ci
1271bd4fe43Sopenharmony_cistatic void Hi35xxAdcSetPinCtrl(const struct Hi35xxAdcDevice *hi35xx)
1281bd4fe43Sopenharmony_ci{
1291bd4fe43Sopenharmony_ci    uint32_t val;
1301bd4fe43Sopenharmony_ci    uint32_t validChannel;
1311bd4fe43Sopenharmony_ci
1321bd4fe43Sopenharmony_ci    validChannel = (hi35xx->validChannel & VALID_CHANNEL_MASK);
1331bd4fe43Sopenharmony_ci    if ((validChannel & 0x1) == 1) {
1341bd4fe43Sopenharmony_ci        val = OSAL_READL(hi35xx->pinCtrlBase + HI35XX_ADC_IO_CONFIG_0);
1351bd4fe43Sopenharmony_ci        val &= ~PINCTRL_MASK;
1361bd4fe43Sopenharmony_ci        OSAL_WRITEL(val, hi35xx->pinCtrlBase + HI35XX_ADC_IO_CONFIG_0);
1371bd4fe43Sopenharmony_ci    }
1381bd4fe43Sopenharmony_ci    validChannel = validChannel >> 1;
1391bd4fe43Sopenharmony_ci    if ((validChannel & 0x1) == 1) {
1401bd4fe43Sopenharmony_ci        val = OSAL_READL(hi35xx->pinCtrlBase + HI35XX_ADC_IO_CONFIG_1);
1411bd4fe43Sopenharmony_ci        val &= ~PINCTRL_MASK;
1421bd4fe43Sopenharmony_ci        OSAL_WRITEL(val, hi35xx->pinCtrlBase + HI35XX_ADC_IO_CONFIG_1);
1431bd4fe43Sopenharmony_ci    }
1441bd4fe43Sopenharmony_ci}
1451bd4fe43Sopenharmony_ci
1461bd4fe43Sopenharmony_cistatic inline int32_t Hi35xxAdcStart(struct AdcDevice *device)
1471bd4fe43Sopenharmony_ci{
1481bd4fe43Sopenharmony_ci    struct Hi35xxAdcDevice *hi35xx = NULL;
1491bd4fe43Sopenharmony_ci
1501bd4fe43Sopenharmony_ci    if (device == NULL || device->priv == NULL) {
1511bd4fe43Sopenharmony_ci        HDF_LOGE("%s: device or priv is null", __func__);
1521bd4fe43Sopenharmony_ci        return HDF_ERR_INVALID_OBJECT;
1531bd4fe43Sopenharmony_ci    }
1541bd4fe43Sopenharmony_ci    hi35xx = (struct Hi35xxAdcDevice *)device;
1551bd4fe43Sopenharmony_ci    if (hi35xx->scanMode == CYCLE_MODE) {
1561bd4fe43Sopenharmony_ci        Hi35xxAdcStartScan(hi35xx);
1571bd4fe43Sopenharmony_ci    }
1581bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
1591bd4fe43Sopenharmony_ci}
1601bd4fe43Sopenharmony_ci
1611bd4fe43Sopenharmony_cistatic int32_t Hi35xxAdcRead(struct AdcDevice *device, uint32_t channel, uint32_t *val)
1621bd4fe43Sopenharmony_ci{
1631bd4fe43Sopenharmony_ci    uint32_t value;
1641bd4fe43Sopenharmony_ci    uint32_t dataWidth;
1651bd4fe43Sopenharmony_ci    struct Hi35xxAdcDevice *hi35xx = NULL;
1661bd4fe43Sopenharmony_ci
1671bd4fe43Sopenharmony_ci    if (device == NULL || device->priv == NULL) {
1681bd4fe43Sopenharmony_ci        HDF_LOGE("%s: device or priv is null", __func__);
1691bd4fe43Sopenharmony_ci        return HDF_ERR_INVALID_OBJECT;
1701bd4fe43Sopenharmony_ci    }
1711bd4fe43Sopenharmony_ci    hi35xx = (struct Hi35xxAdcDevice *)device;
1721bd4fe43Sopenharmony_ci    Hi35xxAdcStartScan(hi35xx);
1731bd4fe43Sopenharmony_ci
1741bd4fe43Sopenharmony_ci    if (hi35xx->scanMode != CYCLE_MODE) {
1751bd4fe43Sopenharmony_ci        OsalUDelay(HI35XX_ADC_READ_DELAY);
1761bd4fe43Sopenharmony_ci    }
1771bd4fe43Sopenharmony_ci
1781bd4fe43Sopenharmony_ci    switch (channel) {
1791bd4fe43Sopenharmony_ci        case 0:
1801bd4fe43Sopenharmony_ci            value = OSAL_READL(hi35xx->regBase + HI35XX_ADC_DATA0);
1811bd4fe43Sopenharmony_ci            break;
1821bd4fe43Sopenharmony_ci        case 1:
1831bd4fe43Sopenharmony_ci            value = OSAL_READL(hi35xx->regBase + HI35XX_ADC_DATA1);
1841bd4fe43Sopenharmony_ci            break;
1851bd4fe43Sopenharmony_ci        default:
1861bd4fe43Sopenharmony_ci            value = 0;
1871bd4fe43Sopenharmony_ci            HDF_LOGE("%s: invalid channel:%u", __func__, channel);
1881bd4fe43Sopenharmony_ci            return HDF_ERR_INVALID_PARAM;
1891bd4fe43Sopenharmony_ci    }
1901bd4fe43Sopenharmony_ci
1911bd4fe43Sopenharmony_ci    dataWidth = hi35xx->dataWidth;
1921bd4fe43Sopenharmony_ci    value = value >> (MAX_DATA_WIDTH - dataWidth);
1931bd4fe43Sopenharmony_ci    *val = value;
1941bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
1951bd4fe43Sopenharmony_ci}
1961bd4fe43Sopenharmony_ci
1971bd4fe43Sopenharmony_cistatic inline int32_t Hi35xxAdcStop(struct AdcDevice *device)
1981bd4fe43Sopenharmony_ci{
1991bd4fe43Sopenharmony_ci    struct Hi35xxAdcDevice *hi35xx = NULL;
2001bd4fe43Sopenharmony_ci
2011bd4fe43Sopenharmony_ci    if (device == NULL || device->priv == NULL) {
2021bd4fe43Sopenharmony_ci        HDF_LOGE("%s: device or priv is null", __func__);
2031bd4fe43Sopenharmony_ci        return HDF_ERR_INVALID_OBJECT;
2041bd4fe43Sopenharmony_ci    }
2051bd4fe43Sopenharmony_ci    hi35xx = (struct Hi35xxAdcDevice *)device;
2061bd4fe43Sopenharmony_ci    if (hi35xx->scanMode == CYCLE_MODE) {
2071bd4fe43Sopenharmony_ci        OSAL_WRITEL(1, hi35xx->regBase + HI35XX_ADC_STOP);
2081bd4fe43Sopenharmony_ci    }
2091bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
2101bd4fe43Sopenharmony_ci}
2111bd4fe43Sopenharmony_ci
2121bd4fe43Sopenharmony_cistatic const struct AdcMethod g_method = {
2131bd4fe43Sopenharmony_ci    .read = Hi35xxAdcRead,
2141bd4fe43Sopenharmony_ci    .stop = Hi35xxAdcStop,
2151bd4fe43Sopenharmony_ci    .start = Hi35xxAdcStart,
2161bd4fe43Sopenharmony_ci};
2171bd4fe43Sopenharmony_ci
2181bd4fe43Sopenharmony_cistatic void Hi35xxAdcDeviceInit(struct Hi35xxAdcDevice *hi35xx)
2191bd4fe43Sopenharmony_ci{
2201bd4fe43Sopenharmony_ci    Hi35xxAdcReset(hi35xx);
2211bd4fe43Sopenharmony_ci    Hi35xxAdcConfig(hi35xx);
2221bd4fe43Sopenharmony_ci    Hi35xxAdcSetAccuracy(hi35xx);
2231bd4fe43Sopenharmony_ci    Hi35xxAdcSetIrq(hi35xx);
2241bd4fe43Sopenharmony_ci    Hi35xxAdcSetGlitchSample(hi35xx);
2251bd4fe43Sopenharmony_ci    Hi35xxAdcSetTimeScan(hi35xx);
2261bd4fe43Sopenharmony_ci    Hi35xxAdcSetPinCtrl(hi35xx);
2271bd4fe43Sopenharmony_ci    HDF_LOGI("%s: device:%u init done", __func__, hi35xx->deviceNum);
2281bd4fe43Sopenharmony_ci}
2291bd4fe43Sopenharmony_ci
2301bd4fe43Sopenharmony_cistatic int32_t Hi35xxAdcReadDrs(struct Hi35xxAdcDevice *hi35xx, const struct DeviceResourceNode *node)
2311bd4fe43Sopenharmony_ci{
2321bd4fe43Sopenharmony_ci    int32_t ret;
2331bd4fe43Sopenharmony_ci    struct DeviceResourceIface *drsOps = NULL;
2341bd4fe43Sopenharmony_ci
2351bd4fe43Sopenharmony_ci    drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
2361bd4fe43Sopenharmony_ci    if (drsOps == NULL || drsOps->GetUint32 == NULL) {
2371bd4fe43Sopenharmony_ci        HDF_LOGE("%s: invalid drs ops", __func__);
2381bd4fe43Sopenharmony_ci        return HDF_ERR_NOT_SUPPORT;
2391bd4fe43Sopenharmony_ci    }
2401bd4fe43Sopenharmony_ci
2411bd4fe43Sopenharmony_ci    ret = drsOps->GetUint32(node, "regBasePhy", &hi35xx->regBasePhy, 0);
2421bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
2431bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read regBasePhy failed", __func__);
2441bd4fe43Sopenharmony_ci        return ret;
2451bd4fe43Sopenharmony_ci    }
2461bd4fe43Sopenharmony_ci
2471bd4fe43Sopenharmony_ci    ret = drsOps->GetUint32(node, "regSize", &hi35xx->regSize, 0);
2481bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
2491bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read regSize failed", __func__);
2501bd4fe43Sopenharmony_ci        return ret;
2511bd4fe43Sopenharmony_ci    }
2521bd4fe43Sopenharmony_ci
2531bd4fe43Sopenharmony_ci    ret = drsOps->GetUint32(node, "deviceNum", &hi35xx->deviceNum, 0);
2541bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
2551bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read deviceNum failed", __func__);
2561bd4fe43Sopenharmony_ci        return ret;
2571bd4fe43Sopenharmony_ci    }
2581bd4fe43Sopenharmony_ci
2591bd4fe43Sopenharmony_ci    ret = drsOps->GetUint32(node, "dataWidth", &hi35xx->dataWidth, 0);
2601bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
2611bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read dataWidth failed", __func__);
2621bd4fe43Sopenharmony_ci        return ret;
2631bd4fe43Sopenharmony_ci    }
2641bd4fe43Sopenharmony_ci
2651bd4fe43Sopenharmony_ci    ret = drsOps->GetUint32(node, "validChannel", &hi35xx->validChannel, 0);
2661bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
2671bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read validChannel failed", __func__);
2681bd4fe43Sopenharmony_ci        return ret;
2691bd4fe43Sopenharmony_ci    }
2701bd4fe43Sopenharmony_ci
2711bd4fe43Sopenharmony_ci    ret = drsOps->GetUint32(node, "scanMode", &hi35xx->scanMode, 0);
2721bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
2731bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read scanMode failed", __func__);
2741bd4fe43Sopenharmony_ci        return ret;
2751bd4fe43Sopenharmony_ci    }
2761bd4fe43Sopenharmony_ci
2771bd4fe43Sopenharmony_ci    ret = drsOps->GetUint32(node, "delta", &hi35xx->delta, 0);
2781bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
2791bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read delta failed", __func__);
2801bd4fe43Sopenharmony_ci        return ret;
2811bd4fe43Sopenharmony_ci    }
2821bd4fe43Sopenharmony_ci
2831bd4fe43Sopenharmony_ci    ret = drsOps->GetUint32(node, "deglitch", &hi35xx->deglitch, 0);
2841bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
2851bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read deglitch failed", __func__);
2861bd4fe43Sopenharmony_ci        return ret;
2871bd4fe43Sopenharmony_ci    }
2881bd4fe43Sopenharmony_ci
2891bd4fe43Sopenharmony_ci    ret = drsOps->GetUint32(node, "glitchSample", &hi35xx->glitchSample, 0);
2901bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
2911bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read glitchSample failed", __func__);
2921bd4fe43Sopenharmony_ci        return ret;
2931bd4fe43Sopenharmony_ci    }
2941bd4fe43Sopenharmony_ci
2951bd4fe43Sopenharmony_ci    ret = drsOps->GetUint32(node, "rate", &hi35xx->rate, 0);
2961bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
2971bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read rate failed", __func__);
2981bd4fe43Sopenharmony_ci        return ret;
2991bd4fe43Sopenharmony_ci    }
3001bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
3011bd4fe43Sopenharmony_ci}
3021bd4fe43Sopenharmony_ci
3031bd4fe43Sopenharmony_cistatic int32_t Hi35xxAdcParseInit(struct HdfDeviceObject *device, struct DeviceResourceNode *node)
3041bd4fe43Sopenharmony_ci{
3051bd4fe43Sopenharmony_ci    int32_t ret;
3061bd4fe43Sopenharmony_ci    struct Hi35xxAdcDevice *hi35xx = NULL;
3071bd4fe43Sopenharmony_ci
3081bd4fe43Sopenharmony_ci    (void)device;
3091bd4fe43Sopenharmony_ci    hi35xx = (struct Hi35xxAdcDevice *)OsalMemCalloc(sizeof(*hi35xx));
3101bd4fe43Sopenharmony_ci    if (hi35xx == NULL) {
3111bd4fe43Sopenharmony_ci        HDF_LOGE("%s: alloc hi35xx failed", __func__);
3121bd4fe43Sopenharmony_ci        return HDF_ERR_MALLOC_FAIL;
3131bd4fe43Sopenharmony_ci    }
3141bd4fe43Sopenharmony_ci
3151bd4fe43Sopenharmony_ci    ret = Hi35xxAdcReadDrs(hi35xx, node);
3161bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
3171bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read drs failed:%d", __func__, ret);
3181bd4fe43Sopenharmony_ci        goto __ERR__;
3191bd4fe43Sopenharmony_ci    }
3201bd4fe43Sopenharmony_ci
3211bd4fe43Sopenharmony_ci    hi35xx->regBase = OsalIoRemap(hi35xx->regBasePhy, hi35xx->regSize);
3221bd4fe43Sopenharmony_ci    if (hi35xx->regBase == NULL) {
3231bd4fe43Sopenharmony_ci        HDF_LOGE("%s: remap regbase failed", __func__);
3241bd4fe43Sopenharmony_ci        ret = HDF_ERR_IO;
3251bd4fe43Sopenharmony_ci        goto __ERR__;
3261bd4fe43Sopenharmony_ci    }
3271bd4fe43Sopenharmony_ci
3281bd4fe43Sopenharmony_ci    hi35xx->pinCtrlBase = OsalIoRemap(HI35XX_ADC_IO_CONFIG_BASE, HI35XX_ADC_IO_CONFIG_SIZE);
3291bd4fe43Sopenharmony_ci    if (hi35xx->pinCtrlBase == NULL) {
3301bd4fe43Sopenharmony_ci        HDF_LOGE("%s: remap pinctrl base failed", __func__);
3311bd4fe43Sopenharmony_ci        ret = HDF_ERR_IO;
3321bd4fe43Sopenharmony_ci        goto __ERR__;
3331bd4fe43Sopenharmony_ci    }
3341bd4fe43Sopenharmony_ci
3351bd4fe43Sopenharmony_ci    Hi35xxAdcDeviceInit(hi35xx);
3361bd4fe43Sopenharmony_ci    hi35xx->device.priv = (void *)node;
3371bd4fe43Sopenharmony_ci    hi35xx->device.devNum = hi35xx->deviceNum;
3381bd4fe43Sopenharmony_ci    hi35xx->device.ops = &g_method;
3391bd4fe43Sopenharmony_ci    ret = AdcDeviceAdd(&hi35xx->device);
3401bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
3411bd4fe43Sopenharmony_ci        HDF_LOGE("%s: add adc device:%u failed", __func__, hi35xx->deviceNum);
3421bd4fe43Sopenharmony_ci        goto __ERR__;
3431bd4fe43Sopenharmony_ci    }
3441bd4fe43Sopenharmony_ci    return HDF_SUCCESS;
3451bd4fe43Sopenharmony_ci
3461bd4fe43Sopenharmony_ci__ERR__:
3471bd4fe43Sopenharmony_ci    if (hi35xx != NULL) {
3481bd4fe43Sopenharmony_ci        if (hi35xx->regBase != NULL) {
3491bd4fe43Sopenharmony_ci            OsalIoUnmap((void *)hi35xx->regBase);
3501bd4fe43Sopenharmony_ci            hi35xx->regBase = NULL;
3511bd4fe43Sopenharmony_ci        }
3521bd4fe43Sopenharmony_ci        AdcDeviceRemove(&hi35xx->device);
3531bd4fe43Sopenharmony_ci        OsalMemFree(hi35xx);
3541bd4fe43Sopenharmony_ci    }
3551bd4fe43Sopenharmony_ci    return ret;
3561bd4fe43Sopenharmony_ci}
3571bd4fe43Sopenharmony_ci
3581bd4fe43Sopenharmony_cistatic int32_t Hi35xxAdcInit(struct HdfDeviceObject *device)
3591bd4fe43Sopenharmony_ci{
3601bd4fe43Sopenharmony_ci    int32_t ret;
3611bd4fe43Sopenharmony_ci    struct DeviceResourceNode *childNode = NULL;
3621bd4fe43Sopenharmony_ci
3631bd4fe43Sopenharmony_ci    if (device == NULL || device->property == NULL) {
3641bd4fe43Sopenharmony_ci        HDF_LOGE("%s: device or property is null", __func__);
3651bd4fe43Sopenharmony_ci        return HDF_ERR_INVALID_OBJECT;
3661bd4fe43Sopenharmony_ci    }
3671bd4fe43Sopenharmony_ci
3681bd4fe43Sopenharmony_ci    ret = HDF_SUCCESS;
3691bd4fe43Sopenharmony_ci    DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) {
3701bd4fe43Sopenharmony_ci        ret = Hi35xxAdcParseInit(device, childNode);
3711bd4fe43Sopenharmony_ci        if (ret != HDF_SUCCESS) {
3721bd4fe43Sopenharmony_ci            break;
3731bd4fe43Sopenharmony_ci        }
3741bd4fe43Sopenharmony_ci    }
3751bd4fe43Sopenharmony_ci    HDF_LOGI("%s: adc init success.", __func__);
3761bd4fe43Sopenharmony_ci    return ret;
3771bd4fe43Sopenharmony_ci}
3781bd4fe43Sopenharmony_ci
3791bd4fe43Sopenharmony_cistatic void Hi35xxAdcRemoveByNode(const struct DeviceResourceNode *node)
3801bd4fe43Sopenharmony_ci{
3811bd4fe43Sopenharmony_ci    int32_t ret;
3821bd4fe43Sopenharmony_ci    int32_t deviceNum;
3831bd4fe43Sopenharmony_ci    struct AdcDevice *device = NULL;
3841bd4fe43Sopenharmony_ci    struct Hi35xxAdcDevice *hi35xx = NULL;
3851bd4fe43Sopenharmony_ci    struct DeviceResourceIface *drsOps = NULL;
3861bd4fe43Sopenharmony_ci
3871bd4fe43Sopenharmony_ci    drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
3881bd4fe43Sopenharmony_ci    if (drsOps == NULL || drsOps->GetUint32 == NULL) {
3891bd4fe43Sopenharmony_ci        HDF_LOGE("%s: invalid drs ops", __func__);
3901bd4fe43Sopenharmony_ci        return;
3911bd4fe43Sopenharmony_ci    }
3921bd4fe43Sopenharmony_ci
3931bd4fe43Sopenharmony_ci    ret = drsOps->GetUint32(node, "deviceNum", (uint32_t *)&deviceNum, 0);
3941bd4fe43Sopenharmony_ci    if (ret != HDF_SUCCESS) {
3951bd4fe43Sopenharmony_ci        HDF_LOGE("%s: read deviceNum failed", __func__);
3961bd4fe43Sopenharmony_ci        return;
3971bd4fe43Sopenharmony_ci    }
3981bd4fe43Sopenharmony_ci
3991bd4fe43Sopenharmony_ci    device = AdcDeviceGet(deviceNum);
4001bd4fe43Sopenharmony_ci    if (device != NULL && device->priv == node) {
4011bd4fe43Sopenharmony_ci        AdcDevicePut(device);
4021bd4fe43Sopenharmony_ci        AdcDeviceRemove(device);
4031bd4fe43Sopenharmony_ci        hi35xx = (struct Hi35xxAdcDevice *)device;
4041bd4fe43Sopenharmony_ci        OsalIoUnmap((void *)hi35xx->regBase);
4051bd4fe43Sopenharmony_ci        OsalMemFree(hi35xx);
4061bd4fe43Sopenharmony_ci    }
4071bd4fe43Sopenharmony_ci    return;
4081bd4fe43Sopenharmony_ci}
4091bd4fe43Sopenharmony_ci
4101bd4fe43Sopenharmony_cistatic void Hi35xxAdcRelease(struct HdfDeviceObject *device)
4111bd4fe43Sopenharmony_ci{
4121bd4fe43Sopenharmony_ci    const struct DeviceResourceNode *childNode = NULL;
4131bd4fe43Sopenharmony_ci
4141bd4fe43Sopenharmony_ci    HDF_LOGI("%s: enter", __func__);
4151bd4fe43Sopenharmony_ci    if (device == NULL || device->property == NULL) {
4161bd4fe43Sopenharmony_ci        HDF_LOGE("%s: device or property is null", __func__);
4171bd4fe43Sopenharmony_ci        return;
4181bd4fe43Sopenharmony_ci    }
4191bd4fe43Sopenharmony_ci    DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) {
4201bd4fe43Sopenharmony_ci        Hi35xxAdcRemoveByNode(childNode);
4211bd4fe43Sopenharmony_ci    }
4221bd4fe43Sopenharmony_ci}
4231bd4fe43Sopenharmony_ci
4241bd4fe43Sopenharmony_cistatic struct HdfDriverEntry g_hi35xxAdcDriverEntry = {
4251bd4fe43Sopenharmony_ci    .moduleVersion = 1,
4261bd4fe43Sopenharmony_ci    .Init = Hi35xxAdcInit,
4271bd4fe43Sopenharmony_ci    .Release = Hi35xxAdcRelease,
4281bd4fe43Sopenharmony_ci    .moduleName = "hi35xx_adc_driver",
4291bd4fe43Sopenharmony_ci};
4301bd4fe43Sopenharmony_ciHDF_INIT(g_hi35xxAdcDriverEntry);
431