1 /*
2 * Copyright (c) 2022 Chipsea Technologies (Shenzhen) Corp., 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 <securec.h>
10 #include "osal_mem.h"
11 #include "osal_io.h"
12 #include "sensor_ppg_config.h"
13
14 static struct PpgCfgData *g_ppgCfg = NULL;
15
16 #define HDF_LOG_TAG khdf_sensor_ppg_config_driver
17
InitPpgCfgData()18 static int32_t InitPpgCfgData()
19 {
20 g_ppgCfg = (struct PpgCfgData *)OsalMemCalloc(sizeof(*g_ppgCfg));
21 if (g_ppgCfg == NULL) {
22 HDF_LOGE("%s: malloc failed!", __func__);
23 return HDF_FAILURE;
24 }
25 (void)memset_s(g_ppgCfg, sizeof(*g_ppgCfg), 0, sizeof(*g_ppgCfg));
26 return HDF_SUCCESS;
27 }
28
GetPpgConfig(void)29 struct PpgCfgData *GetPpgConfig(void)
30 {
31 return g_ppgCfg;
32 }
33
ParsePpgPinMuxConfig(struct DeviceResourceIface * parser,const struct DeviceResourceNode * node,struct PpgPinCfg * pinCfg)34 static int32_t ParsePpgPinMuxConfig(struct DeviceResourceIface *parser,
35 const struct DeviceResourceNode *node, struct PpgPinCfg *pinCfg)
36 {
37 int32_t ret;
38 int32_t num;
39 struct MultiUsePinSetCfg *mutiPinConfig = NULL;
40
41 num = parser->GetElemNum(node, "multiUseSet");
42 if ((num <= 0) || (num > PPG_PIN_CONFIG_MAX_ITEM) || ((num % PPG_PIN_CFG_INDEX_MAX) != 0)) {
43 HDF_LOGW("%s: parser multiUseSet size overflow, ignore this config, num = %d", __func__, num);
44 return HDF_SUCCESS;
45 }
46
47 if (pinCfg->multiUsePin == NULL) {
48 pinCfg->multiUsePin = (struct MultiUsePinSetCfg *)OsalMemCalloc(sizeof(uint32_t) * num);
49 if (pinCfg->multiUsePin == NULL) {
50 HDF_LOGE("%s: malloc ppg multiUsePin config item failed", __func__);
51 return HDF_ERR_MALLOC_FAIL;
52 }
53 }
54
55 ret = parser->GetUint32Array(node, "multiUseSet", (uint32_t *)pinCfg->multiUsePin, num, 0);
56 if (ret != HDF_SUCCESS) {
57 HDF_LOGE("%s: parser multiUseSet reg array failed", __func__);
58 return HDF_FAILURE;
59 }
60
61 for (uint32_t index = 0; index < (num / PPG_PIN_CFG_INDEX_MAX); ++index) {
62 mutiPinConfig = &pinCfg->multiUsePin[index];
63 ret = SetSensorPinMux(mutiPinConfig->regAddr, mutiPinConfig->regLen, mutiPinConfig->regValue);
64 if (ret != HDF_SUCCESS) {
65 HDF_LOGE("%s: SetSensorPinMux failed, index %d, reg=0x%x, len=%d, val=0x%x", __func__, index,
66 mutiPinConfig->regAddr, mutiPinConfig->regLen, mutiPinConfig->regValue);
67 return HDF_FAILURE;
68 }
69 }
70
71 return HDF_SUCCESS;
72 }
73
ParsePpgGpiosConfig(struct DeviceResourceIface * parser,const struct DeviceResourceNode * node,struct PpgPinCfg * pinCfg)74 static int32_t ParsePpgGpiosConfig(struct DeviceResourceIface *parser,
75 const struct DeviceResourceNode *node, struct PpgPinCfg *pinCfg)
76 {
77 int32_t ret;
78 int32_t num;
79 struct GpiosPinSetCfg *gpioCfg = NULL;
80
81 num = parser->GetElemNum(node, "gipos");
82 if ((num <= 0) || (num > PPG_PIN_CONFIG_MAX_ITEM) || ((num % PPG_GPIOS_INDEX_MAX) != 0)) {
83 HDF_LOGE("%s: parser gipos size overflow, ignore this config, num = %d", __func__, num);
84 return HDF_SUCCESS;
85 }
86
87 if (pinCfg->gpios == NULL) {
88 pinCfg->gpios = (struct GpiosPinSetCfg *)OsalMemCalloc(sizeof(uint16_t) * num);
89 if (pinCfg->gpios == NULL) {
90 HDF_LOGE("%s: malloc ppg gipos config item failed", __func__);
91 return HDF_ERR_MALLOC_FAIL;
92 }
93 }
94
95 ret = parser->GetUint16Array(node, "gipos", (uint16_t *)pinCfg->gpios, num, 0);
96 if (ret != HDF_SUCCESS) {
97 HDF_LOGE("%s: parser gipos reg array failed", __func__);
98 return HDF_FAILURE;
99 }
100
101 pinCfg->gpioNum = 0;
102
103 for (uint32_t index = 0; index < (num / PPG_GPIOS_INDEX_MAX); ++index) {
104 gpioCfg = &pinCfg->gpios[index];
105 ret = GpioSetDir(gpioCfg->gpioNo, gpioCfg->dirType);
106 if (ret != HDF_SUCCESS) {
107 HDF_LOGE("%s: GpioSetDir is error, ret = %d!", __func__, ret);
108 return HDF_FAILURE;
109 }
110
111 if (pinCfg->gpios[index].gpioType == PPG_TYPE_GPIO) {
112 ret = GpioWrite(gpioCfg->gpioNo, gpioCfg->gpioValue);
113 if (ret != HDF_SUCCESS) {
114 HDF_LOGE("%s: GpioWrite is error, ret = %d!", __func__, ret);
115 return HDF_FAILURE;
116 }
117 }
118 pinCfg->gpioNum++;
119 }
120
121 return HDF_SUCCESS;
122 }
123
ParsePpgPinConfig(struct DeviceResourceIface * parser,const struct DeviceResourceNode * pinCfgNode,struct PpgPinCfg * config)124 int32_t ParsePpgPinConfig(struct DeviceResourceIface *parser,
125 const struct DeviceResourceNode *pinCfgNode, struct PpgPinCfg *config)
126 {
127 int32_t ret;
128
129 ret = ParsePpgPinMuxConfig(parser, pinCfgNode, config);
130 if (ret != HDF_SUCCESS) {
131 HDF_LOGE("%s: pin mux config failed!", __func__);
132 return HDF_FAILURE;
133 }
134
135 ret = ParsePpgGpiosConfig(parser, pinCfgNode, config);
136 if (ret != HDF_SUCCESS) {
137 HDF_LOGE("%s: gpios config failed!", __func__);
138 return HDF_FAILURE;
139 }
140
141 HDF_LOGI("%s: Parse and Set pin success!", __func__);
142 return HDF_SUCCESS;
143 }
144
EnablePpgIrq(uint16_t pinIndex)145 int32_t EnablePpgIrq(uint16_t pinIndex)
146 {
147 struct PpgCfgData *config = GetPpgConfig();
148 struct GpiosPinSetCfg *gpio = NULL;
149 CHECK_NULL_PTR_RETURN_VALUE(config, HDF_ERR_INVALID_PARAM);
150 CHECK_NULL_PTR_RETURN_VALUE(config->pinCfg.gpios, HDF_ERR_INVALID_PARAM);
151
152 for (uint16_t gpioIndex = 0; gpioIndex < config->pinCfg.gpioNum; gpioIndex++) {
153 gpio = &config->pinCfg.gpios[gpioIndex];
154 CHECK_NULL_PTR_RETURN_VALUE(gpio, HDF_ERR_INVALID_PARAM);
155 if ((gpio->gpioType == PPG_TYPE_IRQ) && (pinIndex == gpio->pinIndex)) {
156 if (GpioEnableIrq(gpio->gpioNo) != 0) {
157 break;
158 }
159 return HDF_SUCCESS;
160 }
161 }
162 HDF_LOGE("%s: failed!", __func__);
163 return HDF_FAILURE;
164 }
165
DisablePpgIrq(uint16_t pinIndex)166 int32_t DisablePpgIrq(uint16_t pinIndex)
167 {
168 struct PpgCfgData *config = GetPpgConfig();
169 struct GpiosPinSetCfg *gpio = NULL;
170 CHECK_NULL_PTR_RETURN_VALUE(config, HDF_ERR_INVALID_PARAM);
171 CHECK_NULL_PTR_RETURN_VALUE(config->pinCfg.gpios, HDF_ERR_INVALID_PARAM);
172
173 for (uint16_t gpioIndex = 0; gpioIndex < config->pinCfg.gpioNum; gpioIndex++) {
174 gpio = &config->pinCfg.gpios[gpioIndex];
175 CHECK_NULL_PTR_RETURN_VALUE(gpio, HDF_ERR_INVALID_PARAM);
176 if ((gpio->gpioType == PPG_TYPE_IRQ) && (pinIndex == gpio->pinIndex)) {
177 if (GpioDisableIrq(gpio->gpioNo) != 0) {
178 break;
179 }
180 return HDF_SUCCESS;
181 }
182 }
183 HDF_LOGE("%s: failed!", __func__);
184 return HDF_FAILURE;
185 }
186
SetPpgIrq(uint16_t pinIndex,GpioIrqFunc irqFunc)187 int32_t SetPpgIrq(uint16_t pinIndex, GpioIrqFunc irqFunc)
188 {
189 struct PpgCfgData *config = GetPpgConfig();
190 struct GpiosPinSetCfg *gpio = NULL;
191 CHECK_NULL_PTR_RETURN_VALUE(config, HDF_ERR_INVALID_PARAM);
192 CHECK_NULL_PTR_RETURN_VALUE(irqFunc, HDF_ERR_INVALID_PARAM);
193 CHECK_NULL_PTR_RETURN_VALUE(config->pinCfg.gpios, HDF_ERR_INVALID_PARAM);
194
195 for (uint16_t gpioIndex = 0; gpioIndex < config->pinCfg.gpioNum; gpioIndex++) {
196 gpio = &config->pinCfg.gpios[gpioIndex];
197 CHECK_NULL_PTR_RETURN_VALUE(gpio, HDF_ERR_INVALID_PARAM);
198 if ((gpio->pinIndex == pinIndex) && (gpio->gpioType == PPG_TYPE_IRQ)) {
199 if (GpioSetIrq(gpio->gpioNo, gpio->triggerMode, irqFunc, NULL) != 0) {
200 break;
201 }
202 return HDF_SUCCESS;
203 }
204 }
205
206 HDF_LOGE("%s: failed!", __func__);
207 return HDF_FAILURE;
208 }
209
GetPinConfigData(const struct DeviceResourceNode * node,struct PpgPinCfg * pinCfg)210 static int32_t GetPinConfigData(const struct DeviceResourceNode *node, struct PpgPinCfg *pinCfg)
211 {
212 int32_t ret = HDF_FAILURE;
213 struct DeviceResourceIface *parser = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
214 CHECK_NULL_PTR_RETURN_VALUE(parser, HDF_ERR_INVALID_PARAM);
215
216 const struct DeviceResourceNode *pinCfgNode = parser->GetChildNode(node, "ppgPinConfig");
217 if (pinCfgNode != NULL) {
218 ret = ParsePpgPinConfig(parser, pinCfgNode, pinCfg);
219 }
220
221 HDF_LOGI("%s: Parse and Set pin ret = %d!", __func__, ret);
222 return ret;
223 }
224
ReleasePpgCfgData(void)225 void ReleasePpgCfgData(void)
226 {
227 CHECK_NULL_PTR_RETURN(g_ppgCfg);
228
229 if (g_ppgCfg->pinCfg.multiUsePin != NULL) {
230 OsalMemFree(g_ppgCfg->pinCfg.multiUsePin);
231 }
232
233 if (g_ppgCfg->pinCfg.gpios != NULL) {
234 OsalMemFree(g_ppgCfg->pinCfg.gpios);
235 }
236
237 OsalMemFree(g_ppgCfg);
238 g_ppgCfg = NULL;
239 }
240
ParsePpgCfgData(const struct DeviceResourceNode * node,struct PpgCfgData ** cfgData)241 int32_t ParsePpgCfgData(const struct DeviceResourceNode *node, struct PpgCfgData **cfgData)
242 {
243 int32_t ret;
244
245 if (g_ppgCfg != NULL) {
246 HDF_LOGI("%s: ppg config already parsed.", __func__);
247 return HDF_SUCCESS;
248 }
249
250 ret = InitPpgCfgData();
251 if (ret != HDF_SUCCESS) {
252 HDF_LOGE("%s: Init ppg config failed.", __func__);
253 return HDF_FAILURE;
254 }
255
256 ret = GetSensorBaseConfigData(node, &g_ppgCfg->sensorCfg);
257 if (ret != HDF_SUCCESS) {
258 HDF_LOGE("%s: get sensor base config failed.", __func__);
259 ReleasePpgCfgData();
260 return HDF_FAILURE;
261 }
262
263 ret = GetPinConfigData(node, &g_ppgCfg->pinCfg);
264 if (ret != HDF_SUCCESS) {
265 HDF_LOGE("%s: get pin config failed.", __func__);
266 ReleasePpgCfgData();
267 return HDF_FAILURE;
268 }
269
270 *cfgData = g_ppgCfg;
271 return HDF_SUCCESS;
272 }
273