• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 
9 #include "hdf_power.h"
10 #include "gpio_if.h"
11 #include "hdf_base.h"
12 #include "hdf_chip.h"
13 #include "hdf_chip_config.h"
14 
15 #define MAX_POWER_COUNT 4
16 
17 struct NoManagablePower {
18     struct HdfPower base;
19     uint8_t powerSeqDelay;
20 };
21 
22 struct GpioBasedPower {
23     struct HdfPower base;
24     uint8_t powerSeqDelay;
25     uint16_t gpioId;
26     uint8_t activeLevel;
27 };
28 
29 struct MutiPowers {
30     struct HdfPower base;
31     uint8_t innerPowerCount;
32     struct HdfPower *powers[0];
33 };
34 
NotManagablePowerOn(struct HdfPower * power)35 static int32_t NotManagablePowerOn(struct HdfPower *power)
36 {
37     (void)power;
38     return HDF_SUCCESS;
39 }
40 
NotManagablePowerOff(struct HdfPower * power)41 static int32_t NotManagablePowerOff(struct HdfPower *power)
42 {
43     (void)power;
44     return HDF_FAILURE;
45 }
46 
ReleasePower(struct HdfPower * power)47 static void ReleasePower(struct HdfPower *power)
48 {
49     if (power == NULL) {
50         return;
51     }
52     OsalMemFree(power);
53 }
54 
CreateNoManagablePower(const struct HdfPowerConfig * power)55 static struct NoManagablePower *CreateNoManagablePower(const struct HdfPowerConfig *power)
56 {
57     struct NoManagablePower *result = NULL;
58     static const struct HdfPowerOps notManagablePowerOps = {.On = NotManagablePowerOn,
59                                                             .Off = NotManagablePowerOff,
60                                                             .Release = ReleasePower};
61     result = (struct NoManagablePower *)OsalMemCalloc(sizeof(struct NoManagablePower));
62     if (result == NULL) {
63         return NULL;
64     }
65     result->base.ops = &notManagablePowerOps;
66     result->powerSeqDelay = power->powerSeqDelay;
67     return result;
68 }
69 
GpioPowerOn(struct HdfPower * power)70 static int32_t GpioPowerOn(struct HdfPower *power)
71 {
72     int32_t ret;
73     struct GpioBasedPower *gpioPower = (struct GpioBasedPower *)power;
74     if (power == NULL) {
75         HDF_LOGE("%s:nullptr", __func__);
76         return HDF_FAILURE;
77     }
78     ret = GpioSetDir(gpioPower->gpioId, 1);
79     if (ret != HDF_SUCCESS) {
80         HDF_LOGE("%s:set dir fail! ret=%d\n", __func__, ret);
81         return HDF_FAILURE;
82     }
83     ret = GpioWrite(gpioPower->gpioId, gpioPower->activeLevel);
84     if (ret != HDF_SUCCESS) {
85         HDF_LOGE("%s:set power on fail! ret=%d\n", __func__, ret);
86         return HDF_FAILURE;
87     }
88     return HDF_SUCCESS;
89 }
90 
GpioPowerOff(struct HdfPower * power)91 static int32_t GpioPowerOff(struct HdfPower *power)
92 {
93     int32_t ret;
94     struct GpioBasedPower *gpioPower = (struct GpioBasedPower *)power;
95     if (power == NULL) {
96         HDF_LOGE("%s:nullptr", __func__);
97         return HDF_FAILURE;
98     }
99     ret = GpioSetDir(gpioPower->gpioId, 1);
100     if (ret != HDF_SUCCESS) {
101         HDF_LOGE("%s:set dir fail! ret=%d\n", __func__, ret);
102         return HDF_FAILURE;
103     }
104     ret = GpioWrite(gpioPower->gpioId, !gpioPower->activeLevel);
105     if (ret != HDF_SUCCESS) {
106         HDF_LOGE("%s:set power on fail! ret=%d\n", __func__, ret);
107         return HDF_FAILURE;
108     }
109     return HDF_SUCCESS;
110 }
111 
CreateGpioBasedPower(const struct HdfPowerConfig * power)112 static struct GpioBasedPower *CreateGpioBasedPower(const struct HdfPowerConfig *power)
113 {
114     struct GpioBasedPower *result = NULL;
115     result = (struct GpioBasedPower *)OsalMemCalloc(sizeof(struct GpioBasedPower));
116     if (result == NULL) {
117         return NULL;
118     }
119     static const struct HdfPowerOps notManagablePowerOps = {.On = GpioPowerOn,
120                                                             .Off = GpioPowerOff,
121                                                             .Release = ReleasePower};
122     result->base.ops = &notManagablePowerOps;
123     result->powerSeqDelay = power->powerSeqDelay;
124     result->gpioId = power->gpio.gpioId;
125     result->activeLevel = power->gpio.activeLevel;
126     return result;
127 }
128 
CreatePower(const struct HdfPowerConfig * power)129 static struct HdfPower *CreatePower(const struct HdfPowerConfig *power)
130 {
131     if (power == NULL) {
132         return NULL;
133     }
134     if (power->type == POWER_TYPE_ALWAYS_ON) {
135         return (struct HdfPower *)CreateNoManagablePower(power);
136     } else if (power->type == POWER_TYPE_GPIO) {
137         return (struct HdfPower *)CreateGpioBasedPower(power);
138     } else {
139         HDF_LOGE("%s:not supported power type %d", __func__, power->type);
140         return NULL;
141     }
142 }
143 
ActiveMutiPower(struct HdfPower * power)144 static int32_t ActiveMutiPower(struct HdfPower *power)
145 {
146     struct MutiPowers *mutiPower = (struct MutiPowers *)power;
147     int ret;
148     if (power == NULL) {
149         HDF_LOGE("%s:nullptr", __func__);
150         return HDF_FAILURE;
151     }
152     for (uint8_t i = 0; i < mutiPower->innerPowerCount; i++) {
153         if (mutiPower->powers[i] == NULL || mutiPower->powers[i]->ops == NULL ||
154             mutiPower->powers[i]->ops->On == NULL) {
155             HDF_LOGW("%s:bad power!index=%d", __func__, i);
156             ret = HDF_FAILURE;
157             break;
158         }
159         if (i > 0) {
160             struct NoManagablePower *innerPower = (struct NoManagablePower *)mutiPower->powers[i];
161             OsalMSleep(innerPower->powerSeqDelay);
162         }
163         ret = mutiPower->powers[i]->ops->On(mutiPower->powers[i]);
164         if (ret != HDF_SUCCESS) {
165             break;
166         }
167     }
168     return ret;
169 }
170 
DeactiveMutiPower(struct HdfPower * power)171 static int32_t DeactiveMutiPower(struct HdfPower *power)
172 {
173     struct MutiPowers *mutiPower = (struct MutiPowers *)power;
174     int ret;
175     if (power == NULL) {
176         HDF_LOGE("%s:nullptr", __func__);
177         return HDF_FAILURE;
178     }
179     for (uint8_t i = 0; i < mutiPower->innerPowerCount; i++) {
180         if (mutiPower->powers[i] == NULL || mutiPower->powers[i]->ops == NULL ||
181             mutiPower->powers[i]->ops->Off == NULL) {
182             HDF_LOGW("%s:bad power!index=%d", __func__, i);
183             ret = HDF_FAILURE;
184             break;
185         }
186         ret = mutiPower->powers[i]->ops->Off(mutiPower->powers[i]);
187         if (ret != HDF_SUCCESS) {
188             break;
189         }
190     }
191     return ret;
192 }
193 
ReleaseMutiPower(struct HdfPower * power)194 static void ReleaseMutiPower(struct HdfPower *power)
195 {
196     struct MutiPowers *mutiPower = (struct MutiPowers *)power;
197     if (power == NULL) {
198         HDF_LOGE("%s:nullptr", __func__);
199         return;
200     }
201     for (uint8_t i = 0; i < mutiPower->innerPowerCount; i++) {
202         if (mutiPower->powers[i] == NULL || mutiPower->powers[i]->ops == NULL ||
203             mutiPower->powers[i]->ops->Release == NULL) {
204             HDF_LOGW("%s:bad power!index=%d", __func__, i);
205         } else {
206             mutiPower->powers[i]->ops->Release(mutiPower->powers[i]);
207         }
208         mutiPower->powers[i] = NULL;
209     }
210     OsalMemFree(power);
211 }
212 
CreateMutiPower(const struct HdfPowersConfig * powersConfig)213 static struct MutiPowers *CreateMutiPower(const struct HdfPowersConfig *powersConfig) {
214     int ret = HDF_SUCCESS;
215     struct MutiPowers *mutiPower =
216         OsalMemCalloc(sizeof(struct MutiPowers) + sizeof(struct HdfPower *) * powersConfig->powerCount);
217     static const struct HdfPowerOps mutiPowerOps = {.On = ActiveMutiPower,
218                                                     .Off = DeactiveMutiPower,
219                                                     .Release = ReleaseMutiPower};
220     for (uint8_t i = 0; i < powersConfig->powerCount; i++) {
221         mutiPower->powers[i] = CreatePower(powersConfig->power + i);
222         if (mutiPower->powers[i] == NULL) {
223             OsalMemFree(mutiPower);
224             ret = HDF_FAILURE;
225             break;
226         }
227     }
228     mutiPower->innerPowerCount = powersConfig->powerCount;
229     if (ret != HDF_SUCCESS) {
230         ReleaseMutiPower((struct HdfPower *)mutiPower);
231         return NULL;
232     }
233     mutiPower->base.ops = &mutiPowerOps;
234     return mutiPower;
235 }
236 
CreateVirtualPower(const struct HdfPowersConfig * powers)237 struct HdfPower *CreateVirtualPower(const struct HdfPowersConfig *powers)
238 {
239     if (powers == NULL) {
240         HDF_LOGE("%s:nullptr", __func__);
241         return NULL;
242     }
243     if (powers->powerCount > MAX_POWER_COUNT) {
244         HDF_LOGE("%s:too many power in config!count=%d", __func__, powers->powerCount);
245         return NULL;
246     }
247     if (powers->powerCount == 1) {
248         return CreatePower(&powers->power[0]);
249     } else if (powers->powerCount > 1) {
250         return (struct HdfPower *)CreateMutiPower(powers);
251     } else {
252         return NULL;
253     }
254 }
255