1 /*
2 * Copyright (c) 2023 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 "sensor_humidity_driver.h"
10 #include <securec.h>
11 #include "hdf_base.h"
12 #include "hdf_device_desc.h"
13 #include "osal_math.h"
14 #include "osal_mem.h"
15 #include "sensor_config_controller.h"
16 #include "sensor_device_manager.h"
17 #include "sensor_platform_if.h"
18
19 #define HDF_LOG_TAG khdf_sensor_humidity_driver
20
21 #define HDF_HUMIDITY_WORK_QUEUE_NAME "hdf_humidity_work_queue"
22
23 static struct HumidityDrvData *g_humidityDrvData = NULL;
24
HumidityGetDrvData(void)25 static struct HumidityDrvData *HumidityGetDrvData(void)
26 {
27 return g_humidityDrvData;
28 }
29
30 static struct SensorRegCfgGroupNode *g_regCfgGroup[SENSOR_GROUP_MAX] = { NULL };
31
HumidityRegisterChipOps(const struct HumidityOpsCall * ops)32 int32_t HumidityRegisterChipOps(const struct HumidityOpsCall *ops)
33 {
34 struct HumidityDrvData *drvData = HumidityGetDrvData();
35
36 CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
37 CHECK_NULL_PTR_RETURN_VALUE(ops, HDF_ERR_INVALID_PARAM);
38
39 drvData->ops.Init = ops->Init;
40 drvData->ops.ReadData = ops->ReadData;
41 return HDF_SUCCESS;
42 }
43
HumidityDataWorkEntry(void * arg)44 static void HumidityDataWorkEntry(void *arg)
45 {
46 struct HumidityDrvData *drvData = NULL;
47
48 drvData = (struct HumidityDrvData *)arg;
49 CHECK_NULL_PTR_RETURN(drvData);
50
51 if (drvData->ops.ReadData == NULL) {
52 HDF_LOGE("%s: Humidity readdata function NULL", __func__);
53 return;
54 }
55 if (drvData->ops.ReadData(drvData->humidityCfg) != HDF_SUCCESS) {
56 HDF_LOGE("%s: Humidity read data failed", __func__);
57 }
58 }
59
HumidityTimerEntry(uintptr_t arg)60 static void HumidityTimerEntry(uintptr_t arg)
61 {
62 int64_t interval;
63 int32_t ret;
64 struct HumidityDrvData *drvData = (struct HumidityDrvData *)arg;
65 CHECK_NULL_PTR_RETURN(drvData);
66
67 if (!HdfAddWork(&drvData->humidityWorkQueue, &drvData->humidityWork)) {
68 HDF_LOGE("%s: Humidity add work queue failed", __func__);
69 }
70
71 interval = OsalDivS64(drvData->interval, (SENSOR_CONVERT_UNIT * SENSOR_CONVERT_UNIT));
72 interval = (interval < SENSOR_TIMER_MIN_TIME) ? SENSOR_TIMER_MIN_TIME : interval;
73 ret = OsalTimerSetTimeout(&drvData->humidityTimer, interval);
74 if (ret != HDF_SUCCESS) {
75 HDF_LOGE("%s: Humidity modify time failed", __func__);
76 }
77 }
78
InitHumidityData(struct HumidityDrvData * drvData)79 static int32_t InitHumidityData(struct HumidityDrvData *drvData)
80 {
81 if (HdfWorkQueueInit(&drvData->humidityWorkQueue, HDF_HUMIDITY_WORK_QUEUE_NAME) != HDF_SUCCESS) {
82 HDF_LOGE("%s: Humidity init work queue failed", __func__);
83 return HDF_FAILURE;
84 }
85
86 if (HdfWorkInit(&drvData->humidityWork, HumidityDataWorkEntry, drvData) != HDF_SUCCESS) {
87 HDF_LOGE("%s: Humidity create thread failed", __func__);
88 return HDF_FAILURE;
89 }
90
91 drvData->interval = SENSOR_TIMER_MIN_TIME;
92 drvData->enable = false;
93 drvData->detectFlag = false;
94
95 return HDF_SUCCESS;
96 }
97
SetHumidityEnable(void)98 static int32_t SetHumidityEnable(void)
99 {
100 int32_t ret;
101 struct HumidityDrvData *drvData = HumidityGetDrvData();
102
103 CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
104 CHECK_NULL_PTR_RETURN_VALUE(drvData->humidityCfg, HDF_ERR_INVALID_PARAM);
105
106 if (drvData->enable) {
107 HDF_LOGE("%s: Humidity sensor is enabled", __func__);
108 return HDF_SUCCESS;
109 }
110
111 ret = SetSensorRegCfgArray(&drvData->humidityCfg->busCfg, drvData->humidityCfg->regCfgGroup[SENSOR_ENABLE_GROUP]);
112 if (ret != HDF_SUCCESS) {
113 HDF_LOGE("%s: Humidity sensor enable config failed", __func__);
114 return ret;
115 }
116
117 ret = OsalTimerCreate(&drvData->humidityTimer, SENSOR_TIMER_MIN_TIME, HumidityTimerEntry, (uintptr_t)drvData);
118 if (ret != HDF_SUCCESS) {
119 HDF_LOGE("%s: Humidity create timer failed[%d]", __func__, ret);
120 return ret;
121 }
122
123 ret = OsalTimerStartLoop(&drvData->humidityTimer);
124 if (ret != HDF_SUCCESS) {
125 HDF_LOGE("%s: Humidity start timer failed[%d]", __func__, ret);
126 return ret;
127 }
128 drvData->enable = true;
129
130 return HDF_SUCCESS;
131 }
132
SetHumidityDisable(void)133 static int32_t SetHumidityDisable(void)
134 {
135 int32_t ret;
136 struct HumidityDrvData *drvData = HumidityGetDrvData();
137
138 CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
139 CHECK_NULL_PTR_RETURN_VALUE(drvData->humidityCfg, HDF_ERR_INVALID_PARAM);
140
141 if (!drvData->enable) {
142 HDF_LOGE("%s: Humidity sensor had disable", __func__);
143 return HDF_SUCCESS;
144 }
145
146 ret = SetSensorRegCfgArray(&drvData->humidityCfg->busCfg, drvData->humidityCfg->regCfgGroup[SENSOR_DISABLE_GROUP]);
147 if (ret != HDF_SUCCESS) {
148 HDF_LOGE("%s: Humidity sensor disable config failed", __func__);
149 return ret;
150 }
151
152 ret = OsalTimerDelete(&drvData->humidityTimer);
153 if (ret != HDF_SUCCESS) {
154 HDF_LOGE("%s: Humidity delete timer failed", __func__);
155 return ret;
156 }
157 drvData->enable = false;
158
159 return HDF_SUCCESS;
160 }
161
SetHumidityBatch(int64_t samplingInterval,int64_t interval)162 static int32_t SetHumidityBatch(int64_t samplingInterval, int64_t interval)
163 {
164 (void)interval;
165
166 struct HumidityDrvData *drvData = NULL;
167
168 drvData = HumidityGetDrvData();
169 CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
170
171 drvData->interval = samplingInterval;
172
173 return HDF_SUCCESS;
174 }
175
SetHumidityMode(int32_t mode)176 static int32_t SetHumidityMode(int32_t mode)
177 {
178 if (mode <= SENSOR_WORK_MODE_DEFAULT || mode >= SENSOR_WORK_MODE_MAX) {
179 HDF_LOGE("%s: The current mode is not supported", __func__);
180 return HDF_FAILURE;
181 }
182
183 return HDF_SUCCESS;
184 }
185
SetHumidityOption(uint32_t option)186 static int32_t SetHumidityOption(uint32_t option)
187 {
188 (void)option;
189
190 return HDF_SUCCESS;
191 }
192
DispatchHumidity(struct HdfDeviceIoClient * client,int cmd,struct HdfSBuf * data,struct HdfSBuf * reply)193 static int32_t DispatchHumidity(struct HdfDeviceIoClient *client,
194 int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
195 {
196 (void)client;
197 (void)cmd;
198 (void)data;
199 (void)reply;
200
201 return HDF_SUCCESS;
202 }
203
HumidityBindDriver(struct HdfDeviceObject * device)204 int32_t HumidityBindDriver(struct HdfDeviceObject *device)
205 {
206 CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
207
208 struct HumidityDrvData *drvData = (struct HumidityDrvData *)OsalMemCalloc(sizeof(*drvData));
209 if (drvData == NULL) {
210 HDF_LOGE("%s: Malloc Humidity drv data fail!", __func__);
211 return HDF_ERR_MALLOC_FAIL;
212 }
213
214 drvData->ioService.Dispatch = DispatchHumidity;
215 drvData->device = device;
216 device->service = &drvData->ioService;
217 g_humidityDrvData = drvData;
218
219 return HDF_SUCCESS;
220 }
221
InitHumidityOps(struct SensorCfgData * config,struct SensorDeviceInfo * deviceInfo)222 static int32_t InitHumidityOps(struct SensorCfgData *config, struct SensorDeviceInfo *deviceInfo)
223 {
224 CHECK_NULL_PTR_RETURN_VALUE(config, HDF_ERR_INVALID_PARAM);
225
226 deviceInfo->ops.Enable = SetHumidityEnable;
227 deviceInfo->ops.Disable = SetHumidityDisable;
228 deviceInfo->ops.SetBatch = SetHumidityBatch;
229 deviceInfo->ops.SetMode = SetHumidityMode;
230 deviceInfo->ops.SetOption = SetHumidityOption;
231
232 if (memcpy_s(&deviceInfo->sensorInfo, sizeof(deviceInfo->sensorInfo),
233 &config->sensorInfo, sizeof(config->sensorInfo)) != EOK) {
234 HDF_LOGE("%s: Copy sensor info failed", __func__);
235 return HDF_FAILURE;
236 }
237
238 return HDF_SUCCESS;
239 }
240
InitHumidityAfterDetected(struct SensorCfgData * config)241 static int32_t InitHumidityAfterDetected(struct SensorCfgData *config)
242 {
243 struct SensorDeviceInfo deviceInfo;
244 CHECK_NULL_PTR_RETURN_VALUE(config, HDF_ERR_INVALID_PARAM);
245
246 if (InitHumidityOps(config, &deviceInfo) != HDF_SUCCESS) {
247 HDF_LOGE("%s: Init Humidity ops failed", __func__);
248 return HDF_FAILURE;
249 }
250
251 if (AddSensorDevice(&deviceInfo) != HDF_SUCCESS) {
252 HDF_LOGE("%s: Add Humidity device failed", __func__);
253 return HDF_FAILURE;
254 }
255
256 if (ParseSensorRegConfig(config) != HDF_SUCCESS) {
257 HDF_LOGE("%s: Parse sensor register failed", __func__);
258 (void)DeleteSensorDevice(&config->sensorInfo);
259 ReleaseSensorAllRegConfig(config);
260 ReleaseSensorDirectionConfig(config);
261 return HDF_FAILURE;
262 }
263
264 return HDF_SUCCESS;
265 }
266
HumidityCreateCfgData(const struct DeviceResourceNode * node)267 struct SensorCfgData *HumidityCreateCfgData(const struct DeviceResourceNode *node)
268 {
269 struct HumidityDrvData *drvData = HumidityGetDrvData();
270
271 if (drvData == NULL || node == NULL) {
272 HDF_LOGE("%s: Humidity node pointer NULL", __func__);
273 return NULL;
274 }
275
276 if (drvData->detectFlag) {
277 HDF_LOGE("%s: Humidity sensor have detected", __func__);
278 return NULL;
279 }
280
281 if (drvData->humidityCfg == NULL) {
282 HDF_LOGE("%s: Humidity HumidityCfg pointer NULL", __func__);
283 return NULL;
284 }
285
286 if (GetSensorBaseConfigData(node, drvData->humidityCfg) != HDF_SUCCESS) {
287 HDF_LOGE("%s: Get sensor base config failed", __func__);
288 goto BASE_CONFIG_EXIT;
289 }
290
291 if ((drvData->humidityCfg->sensorAttr.chipName != NULL) && \
292 (DetectSensorDevice(drvData->humidityCfg) != HDF_SUCCESS)) {
293 HDF_LOGI("%s: Humidity sensor detect device no exist", __func__);
294 drvData->detectFlag = false;
295 goto BASE_CONFIG_EXIT;
296 } else {
297 if (GetSensorBusHandle(&drvData->humidityCfg->busCfg) != HDF_SUCCESS) {
298 HDF_LOGE("%s: get sensor bus handle failed", __func__);
299 (void)ReleaseSensorBusHandle(&drvData->humidityCfg->busCfg);
300 drvData->detectFlag = false;
301 goto BASE_CONFIG_EXIT;
302 }
303 }
304
305 drvData->detectFlag = true;
306 if (InitHumidityAfterDetected(drvData->humidityCfg) != HDF_SUCCESS) {
307 HDF_LOGI("%s: Humidity sensor detect device no exist", __func__);
308 goto INIT_EXIT;
309 }
310 return drvData->humidityCfg;
311
312 INIT_EXIT:
313 (void)ReleaseSensorBusHandle(&drvData->humidityCfg->busCfg);
314 BASE_CONFIG_EXIT:
315 drvData->humidityCfg->root = NULL;
316 (void)memset_s(&drvData->humidityCfg->sensorInfo,
317 sizeof(struct SensorBasicInfo), 0, sizeof(struct SensorBasicInfo));
318 (void)memset_s(&drvData->humidityCfg->busCfg, sizeof(struct SensorBusCfg), 0, sizeof(struct SensorBusCfg));
319 (void)memset_s(&drvData->humidityCfg->sensorAttr, sizeof(struct SensorAttr), 0, sizeof(struct SensorAttr));
320
321 return drvData->humidityCfg;
322 }
323
HumidityReleaseCfgData(struct SensorCfgData * humidityCfg)324 void HumidityReleaseCfgData(struct SensorCfgData *humidityCfg)
325 {
326 CHECK_NULL_PTR_RETURN(humidityCfg);
327
328 (void)DeleteSensorDevice(&humidityCfg->sensorInfo);
329 ReleaseSensorAllRegConfig(humidityCfg);
330 (void)ReleaseSensorBusHandle(&humidityCfg->busCfg);
331 ReleaseSensorDirectionConfig(humidityCfg);
332
333 humidityCfg->root = NULL;
334 (void)memset_s(&humidityCfg->sensorInfo, sizeof(struct SensorBasicInfo), 0, sizeof(struct SensorBasicInfo));
335 (void)memset_s(&humidityCfg->busCfg, sizeof(struct SensorBusCfg), 0, sizeof(struct SensorBusCfg));
336 (void)memset_s(&humidityCfg->sensorAttr, sizeof(struct SensorAttr), 0, sizeof(struct SensorAttr));
337 }
338
HumidityInitDriver(struct HdfDeviceObject * device)339 int32_t HumidityInitDriver(struct HdfDeviceObject *device)
340 {
341 CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
342 struct HumidityDrvData *drvData = (struct HumidityDrvData *)device->service;
343 CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
344
345 if (InitHumidityData(drvData) != HDF_SUCCESS) {
346 HDF_LOGE("%s: Init Humidity config failed", __func__);
347 return HDF_FAILURE;
348 }
349
350 drvData->humidityCfg = (struct SensorCfgData *)OsalMemCalloc(sizeof(*drvData->humidityCfg));
351 if (drvData->humidityCfg == NULL) {
352 HDF_LOGE("%s: Malloc Humidity config data failed", __func__);
353 return HDF_FAILURE;
354 }
355
356 drvData->humidityCfg->regCfgGroup = &g_regCfgGroup[0];
357
358 HDF_LOGI("%s: Init Humidity driver success", __func__);
359 return HDF_SUCCESS;
360 }
361
HumidityReleaseDriver(struct HdfDeviceObject * device)362 void HumidityReleaseDriver(struct HdfDeviceObject *device)
363 {
364 CHECK_NULL_PTR_RETURN(device);
365
366 struct HumidityDrvData *drvData = (struct HumidityDrvData *)device->service;
367 CHECK_NULL_PTR_RETURN(drvData);
368
369 if (drvData->detectFlag && drvData->humidityCfg != NULL) {
370 HumidityReleaseCfgData(drvData->humidityCfg);
371 }
372
373 OsalMemFree(drvData->humidityCfg);
374 drvData->humidityCfg = NULL;
375
376 HdfWorkDestroy(&drvData->humidityWork);
377 HdfWorkQueueDestroy(&drvData->humidityWorkQueue);
378 OsalMemFree(drvData);
379 }
380
381 struct HdfDriverEntry g_sensorHumidityDevEntry = {
382 .moduleVersion = 1,
383 .moduleName = "HDF_SENSOR_HUMIDITY",
384 .Bind = HumidityBindDriver,
385 .Init = HumidityInitDriver,
386 .Release = HumidityReleaseDriver,
387 };
388
389 HDF_INIT(g_sensorHumidityDevEntry);