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