1 /*
2  * Copyright (c) 2020-2022 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 #include "gpio_if.h"
9 #include "osal_mem.h"
10 #include "hdf_log.h"
11 #include "wifi_module.h"
12 #include "hdf_wlan_chipdriver_manager.h"
13 #include "securec.h"
14 
15 #define HDF_LOG_TAG HDF_WIFI_CORE
16 
17 /**
18  * @brief constant reset manage type
19  */
20 enum ResetType {
21     RESET_ALWAYS_ON = 0,
22     RESET_MANAGED_BY_GPIO = 1
23 };
24 
25 struct HdfWlanResetData {
26     struct HdfConfWlanRest resetCfg;
27     uint8_t bootUpHoldTime;
28 };
29 
30 struct ResetManagerImpl {
31     struct ResetManager base;
32     struct HdfWlanResetData resetData;
33 };
34 
35 /**
36  * @brief HdfChipReset
37  */
HdfChipReset(struct ResetManager * resetManager)38 static int32_t HdfChipReset(struct ResetManager *resetManager)
39 {
40     int32_t ret;
41     struct ResetManagerImpl *resetMgrImpl = NULL;
42     if (resetManager == NULL) {
43         HDF_LOGE("%s: resetManager is NULL", __func__);
44         return HDF_FAILURE;
45     }
46     resetMgrImpl = (struct ResetManagerImpl*)resetManager;
47     if (resetMgrImpl->resetData.resetCfg.resetType == RESET_ALWAYS_ON) {
48         HDF_LOGI("%s: the reset type is not managed", __func__);
49         return HDF_SUCCESS;
50     }
51     ret = GpioSetDir(resetMgrImpl->resetData.resetCfg.gpioId, GPIO_DIR_OUT);
52     if (ret != HDF_SUCCESS) {
53         HDF_LOGE("%s: set dir fail!", __func__);
54         return ret;
55     }
56     ret = GpioWrite(resetMgrImpl->resetData.resetCfg.gpioId, resetMgrImpl->resetData.resetCfg.activeLevel);
57     if (ret != HDF_SUCCESS) {
58         HDF_LOGE("%s: write active fail! ret=%d", __func__, ret);
59         return ret;
60     }
61     OsalMSleep(resetMgrImpl->resetData.resetCfg.resetHoldTime);
62 
63     ret = GpioWrite(resetMgrImpl->resetData.resetCfg.gpioId, !resetMgrImpl->resetData.resetCfg.activeLevel);
64     if (ret != HDF_SUCCESS) {
65         HDF_LOGE("%s: write deactivate fail! ret=%d", __func__, ret);
66         return ret;
67     }
68     OsalMSleep(resetMgrImpl->resetData.bootUpHoldTime);
69     HDF_LOGI("%s: HdfChipReset successful!", __func__);
70     return HDF_SUCCESS;
71 }
72 /* to release reset manager resource */
HdfWlanResetMgrRelease(struct ResetManager * resetMgr)73 static int32_t HdfWlanResetMgrRelease(struct ResetManager* resetMgr)
74 {
75     if (resetMgr == NULL) {
76         HDF_LOGE("%s: resetMgr already deinit or input para error ", __func__);
77         return HDF_FAILURE;
78     }
79     OsalMemFree(resetMgr);
80     return HDF_SUCCESS;
81 }
82 /* create power reset manager */
HdfWlanCreateResetManager(const struct HdfConfWlanRest * configReset,uint8_t bootUpTime)83 struct ResetManager* HdfWlanCreateResetManager(const struct HdfConfWlanRest *configReset, uint8_t bootUpTime)
84 {
85     struct ResetManagerImpl *resetMgrImpl = NULL;
86     if (configReset == NULL) {
87         HDF_LOGE("%s: configReset is NULL", __func__);
88         return NULL;
89     }
90     resetMgrImpl = (struct ResetManagerImpl *)OsalMemCalloc(sizeof(struct ResetManagerImpl));
91     if (resetMgrImpl == NULL) {
92         HDF_LOGE("%s: OsalMemCalloc fail! ", __func__);
93         return NULL;
94     }
95     if (memcpy_s(&resetMgrImpl->resetData.resetCfg, sizeof(struct HdfConfWlanRest),
96         configReset, sizeof(struct HdfConfWlanRest)) != EOK) {
97         HDF_LOGE("%s: memcpy_s is NULL", __func__);
98         OsalMemFree(resetMgrImpl);
99         return NULL;
100     }
101     resetMgrImpl->resetData.bootUpHoldTime = bootUpTime;
102     resetMgrImpl->base.Reset = HdfChipReset;
103     resetMgrImpl->base.Release = HdfWlanResetMgrRelease;
104     HDF_LOGD("%s: CreateResetManager finished!", __func__);
105     return (struct ResetManager*)resetMgrImpl;
106 }
107