• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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);