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