• 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 "sensor_als_driver.h"
10 #include <securec.h>
11 #include "als_bh1745.h"
12 #include "osal_math.h"
13 #include "osal_mem.h"
14 #include "sensor_config_controller.h"
15 #include "sensor_device_manager.h"
16 #include "sensor_platform_if.h"
17 
18 #define HDF_LOG_TAG    hdf_sensor_als_driver
19 
20 #define HDF_ALS_WORK_QUEUE_NAME    "hdf_als_work_queue"
21 
22 static struct AlsDrvData *g_alsDrvData = NULL;
23 
AlsGetDrvData(void)24 static struct AlsDrvData *AlsGetDrvData(void)
25 {
26     return g_alsDrvData;
27 }
28 
29 static struct SensorRegCfgGroupNode *g_regCfgGroup[SENSOR_GROUP_MAX] = { NULL };
30 static struct SensorRegCfgGroupNode *g_extendAlsRegCfgGroup[EXTENDED_ALS_GROUP_MAX] = { NULL };
31 static char *g_extendedAlsGroupName[EXTENDED_ALS_GROUP_MAX] = {
32     "time",
33     "gain",
34 };
35 
GetTimeByRegValue(uint8_t regValue,struct TimeRegAddrValueMap * map,int32_t itemNum)36 int32_t GetTimeByRegValue(uint8_t regValue, struct TimeRegAddrValueMap *map, int32_t itemNum)
37 {
38     int32_t i;
39 
40     CHECK_NULL_PTR_RETURN_VALUE(map, INVALID_VALUE);
41 
42     for (i = 0; i < itemNum; i++) {
43         if (regValue == map[i].timeRegKey) {
44             return map[i].timeValue;
45         }
46     }
47 
48     return INVALID_VALUE;
49 }
50 
GetRegGroupIndexByTime(uint32_t timeValue,struct TimeRegAddrValueMap * map,int32_t itemNum)51 int32_t GetRegGroupIndexByTime(uint32_t timeValue, struct TimeRegAddrValueMap *map, int32_t itemNum)
52 {
53     int32_t i;
54 
55     CHECK_NULL_PTR_RETURN_VALUE(map, INVALID_VALUE);
56 
57     for (i = 0; i < itemNum; i++) {
58         if (timeValue == map[i].timeValue) {
59             return i;
60         }
61     }
62 
63     return INVALID_VALUE;
64 }
65 
GetGainByRegValue(uint8_t regValue,struct GainRegAddrValueMap * map,int32_t itemNum)66 int32_t GetGainByRegValue(uint8_t regValue, struct GainRegAddrValueMap *map, int32_t itemNum)
67 {
68     int32_t i;
69 
70     CHECK_NULL_PTR_RETURN_VALUE(map, INVALID_VALUE);
71 
72     for (i = 0; i < itemNum; i++) {
73         if (regValue == map[i].gainRegKey) {
74             return map[i].gainValue;
75         }
76     }
77 
78     return INVALID_VALUE;
79 }
80 
GetExtendedAlsRegGroupNameIndex(const char * name)81 static int32_t GetExtendedAlsRegGroupNameIndex(const char *name)
82 {
83     int32_t index;
84 
85     CHECK_NULL_PTR_RETURN_VALUE(name, EXTENDED_ALS_GROUP_MAX);
86 
87     for (index = 0; index < EXTENDED_ALS_GROUP_MAX; ++index) {
88         if ((g_extendedAlsGroupName[index] != NULL) && (strcmp(name, g_extendedAlsGroupName[index]) == 0)) {
89             break;
90         }
91     }
92 
93     return index;
94 }
95 
ReleaseExtendedAlsRegConfig(struct SensorCfgData * config)96 void ReleaseExtendedAlsRegConfig(struct SensorCfgData *config)
97 {
98     int32_t index;
99 
100     CHECK_NULL_PTR_RETURN(config);
101     CHECK_NULL_PTR_RETURN(config->extendedRegCfgGroup);
102 
103     for (index = 0; index < EXTENDED_ALS_GROUP_MAX; ++index) {
104         if (config->extendedRegCfgGroup[index] != NULL) {
105             if (config->extendedRegCfgGroup[index]->regCfgItem != NULL) {
106                 OsalMemFree(config->extendedRegCfgGroup[index]->regCfgItem);
107                 config->extendedRegCfgGroup[index]->regCfgItem = NULL;
108             }
109 
110             OsalMemFree(config->extendedRegCfgGroup[index]);
111             config->extendedRegCfgGroup[index] = NULL;
112         }
113     }
114 }
115 
ParseExtendedAlsRegConfig(struct SensorCfgData * config)116 int32_t ParseExtendedAlsRegConfig(struct SensorCfgData *config)
117 {
118     int32_t index;
119     struct DeviceResourceIface *parser = NULL;
120     const struct DeviceResourceNode *extendedRegCfgNode = NULL;
121     const struct DeviceResourceAttr *extendedRegAttr = NULL;
122 
123     CHECK_NULL_PTR_RETURN_VALUE(config->root, HDF_ERR_INVALID_PARAM);
124     parser = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
125     CHECK_NULL_PTR_RETURN_VALUE(parser, HDF_ERR_INVALID_PARAM);
126 
127     extendedRegCfgNode = parser->GetChildNode(config->root, "extendAlsRegConfig");
128     CHECK_NULL_PTR_RETURN_VALUE(extendedRegCfgNode, HDF_ERR_INVALID_PARAM);
129 
130     DEV_RES_NODE_FOR_EACH_ATTR(extendedRegCfgNode, extendedRegAttr) {
131         if (extendedRegAttr == NULL || extendedRegAttr->name == NULL) {
132             HDF_LOGE("%s:sensor reg node attr is null", __func__);
133             break;
134         }
135 
136         index = GetExtendedAlsRegGroupNameIndex(extendedRegAttr->name);
137         if (index >= EXTENDED_ALS_GROUP_MAX) {
138             HDF_LOGE("%s: get sensor register group index failed", __func__);
139             goto ERROR;
140         }
141 
142         if (ParseSensorRegGroup(parser, extendedRegCfgNode, extendedRegAttr->name,
143             &config->extendedRegCfgGroup[index]) != HDF_SUCCESS) {
144             HDF_LOGE("%s: parse sensor register group failed", __func__);
145             goto ERROR;
146         }
147     }
148 
149     return HDF_SUCCESS;
150 
151 ERROR:
152     ReleaseExtendedAlsRegConfig(config);
153     HDF_LOGE("%s: parse sensor extend register config failed", __func__);
154 
155     return HDF_FAILURE;
156 }
157 
AlsRegisterChipOps(const struct AlsOpsCall * ops)158 int32_t AlsRegisterChipOps(const struct AlsOpsCall *ops)
159 {
160     struct AlsDrvData *drvData = AlsGetDrvData();
161 
162     CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
163     CHECK_NULL_PTR_RETURN_VALUE(ops, HDF_ERR_INVALID_PARAM);
164 
165     drvData->ops.Init = ops->Init;
166     drvData->ops.ReadData = ops->ReadData;
167     return HDF_SUCCESS;
168 }
169 
AlsDataWorkEntry(void * arg)170 static void AlsDataWorkEntry(void *arg)
171 {
172     struct AlsDrvData *drvData = NULL;
173 
174     drvData = (struct AlsDrvData *)arg;
175     CHECK_NULL_PTR_RETURN(drvData);
176 
177     if (drvData->ops.ReadData == NULL) {
178         HDF_LOGI("%s: Als ReadData function NULl", __func__);
179         return;
180     }
181     if (drvData->ops.ReadData(drvData->alsCfg) != HDF_SUCCESS) {
182         HDF_LOGE("%s: Als read data failed", __func__);
183     }
184 }
185 
AlsTimerEntry(uintptr_t arg)186 static void AlsTimerEntry(uintptr_t arg)
187 {
188     int64_t interval;
189     int32_t ret;
190     struct AlsDrvData *drvData = (struct AlsDrvData *)arg;
191     CHECK_NULL_PTR_RETURN(drvData);
192 
193     if (!HdfAddWork(&drvData->alsWorkQueue, &drvData->alsWork)) {
194         HDF_LOGE("%s: Als add work queue failed", __func__);
195     }
196 
197     interval = OsalDivS64(drvData->interval, (SENSOR_CONVERT_UNIT * SENSOR_CONVERT_UNIT));
198     interval = (interval < SENSOR_TIMER_MIN_TIME) ? SENSOR_TIMER_MIN_TIME : interval;
199     ret = OsalTimerSetTimeout(&drvData->alsTimer, interval);
200     if (ret != HDF_SUCCESS) {
201         HDF_LOGE("%s: Als modify time failed", __func__);
202     }
203 }
204 
InitAlsData(struct AlsDrvData * drvData)205 static int32_t InitAlsData(struct AlsDrvData *drvData)
206 {
207     if (HdfWorkQueueInit(&drvData->alsWorkQueue, HDF_ALS_WORK_QUEUE_NAME) != HDF_SUCCESS) {
208         HDF_LOGE("%s: Als init work queue failed", __func__);
209         return HDF_FAILURE;
210     }
211 
212     if (HdfWorkInit(&drvData->alsWork, AlsDataWorkEntry, drvData) != HDF_SUCCESS) {
213         HDF_LOGE("%s: Als create thread failed", __func__);
214         return HDF_FAILURE;
215     }
216 
217     drvData->interval = SENSOR_TIMER_MIN_TIME;
218     drvData->enable = false;
219     drvData->detectFlag = false;
220 
221     return HDF_SUCCESS;
222 }
223 
SetAlsEnable(void)224 static int32_t SetAlsEnable(void)
225 {
226     int32_t ret;
227     struct AlsDrvData *drvData = AlsGetDrvData();
228 
229     CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
230     CHECK_NULL_PTR_RETURN_VALUE(drvData->alsCfg, HDF_ERR_INVALID_PARAM);
231 
232     if (drvData->enable) {
233         HDF_LOGE("%s: Als sensor is enabled", __func__);
234         return HDF_SUCCESS;
235     }
236 
237     ret = SetSensorRegCfgArray(&drvData->alsCfg->busCfg, drvData->alsCfg->regCfgGroup[SENSOR_ENABLE_GROUP]);
238     if (ret != HDF_SUCCESS) {
239         HDF_LOGE("%s: Als sensor enable config failed", __func__);
240         return ret;
241     }
242 
243     ret = OsalTimerCreate(&drvData->alsTimer, SENSOR_TIMER_MIN_TIME, AlsTimerEntry, (uintptr_t)drvData);
244     if (ret != HDF_SUCCESS) {
245         HDF_LOGE("%s: Als create timer failed[%d]", __func__, ret);
246         return ret;
247     }
248 
249     ret = OsalTimerStartLoop(&drvData->alsTimer);
250     if (ret != HDF_SUCCESS) {
251         HDF_LOGE("%s: Als start timer failed[%d]", __func__, ret);
252         return ret;
253     }
254     drvData->enable = true;
255 
256     return HDF_SUCCESS;
257 }
258 
SetAlsDisable(void)259 static int32_t SetAlsDisable(void)
260 {
261     int32_t ret;
262     struct AlsDrvData *drvData = AlsGetDrvData();
263 
264     CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
265     CHECK_NULL_PTR_RETURN_VALUE(drvData->alsCfg, HDF_ERR_INVALID_PARAM);
266 
267     if (!drvData->enable) {
268         HDF_LOGE("%s: Als sensor had disable", __func__);
269         return HDF_SUCCESS;
270     }
271 
272     ret = SetSensorRegCfgArray(&drvData->alsCfg->busCfg, drvData->alsCfg->regCfgGroup[SENSOR_DISABLE_GROUP]);
273     if (ret != HDF_SUCCESS) {
274         HDF_LOGE("%s: Als sensor disable config failed", __func__);
275         return ret;
276     }
277 
278     ret = OsalTimerDelete(&drvData->alsTimer);
279     if (ret != HDF_SUCCESS) {
280         HDF_LOGE("%s: Als delete timer failed", __func__);
281         return ret;
282     }
283     drvData->enable = false;
284 
285     return HDF_SUCCESS;
286 }
287 
SetAlsBatch(int64_t samplingInterval,int64_t interval)288 static int32_t SetAlsBatch(int64_t samplingInterval, int64_t interval)
289 {
290     (void)interval;
291 
292     struct AlsDrvData *drvData = NULL;
293 
294     drvData = AlsGetDrvData();
295     CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
296 
297     drvData->interval = samplingInterval;
298 
299     return HDF_SUCCESS;
300 }
301 
SetAlsMode(int32_t mode)302 static int32_t SetAlsMode(int32_t mode)
303 {
304     if (mode <= SENSOR_WORK_MODE_DEFAULT || mode >= SENSOR_WORK_MODE_MAX) {
305         HDF_LOGE("%s: The current mode is not supported", __func__);
306         return HDF_FAILURE;
307     }
308 
309     return HDF_SUCCESS;
310 }
311 
SetAlsOption(uint32_t option)312 static int32_t SetAlsOption(uint32_t option)
313 {
314     (void)option;
315     return HDF_SUCCESS;
316 }
317 
DispatchAls(struct HdfDeviceIoClient * client,int32_t cmd,struct HdfSBuf * data,struct HdfSBuf * reply)318 static int32_t DispatchAls(struct HdfDeviceIoClient *client,
319     int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
320 {
321     (void)client;
322     (void)cmd;
323     (void)data;
324     (void)reply;
325 
326     return HDF_SUCCESS;
327 }
328 
AlsBindDriver(struct HdfDeviceObject * device)329 int32_t AlsBindDriver(struct HdfDeviceObject *device)
330 {
331     CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
332 
333     struct AlsDrvData *drvData = (struct AlsDrvData *)OsalMemCalloc(sizeof(*drvData));
334     if (drvData == NULL) {
335         HDF_LOGE("%s: Malloc als drv data fail!", __func__);
336         return HDF_ERR_MALLOC_FAIL;
337     }
338 
339     drvData->ioService.Dispatch = DispatchAls;
340     drvData->device = device;
341     device->service = &drvData->ioService;
342     g_alsDrvData = drvData;
343     return HDF_SUCCESS;
344 }
345 
InitAlsOps(struct SensorCfgData * config,struct SensorDeviceInfo * deviceInfo)346 static int32_t InitAlsOps(struct SensorCfgData *config, struct SensorDeviceInfo *deviceInfo)
347 {
348     CHECK_NULL_PTR_RETURN_VALUE(config, HDF_ERR_INVALID_PARAM);
349 
350     deviceInfo->ops.Enable = SetAlsEnable;
351     deviceInfo->ops.Disable = SetAlsDisable;
352     deviceInfo->ops.SetBatch = SetAlsBatch;
353     deviceInfo->ops.SetMode = SetAlsMode;
354     deviceInfo->ops.SetOption = SetAlsOption;
355 
356     if (memcpy_s(&deviceInfo->sensorInfo, sizeof(deviceInfo->sensorInfo),
357         &config->sensorInfo, sizeof(config->sensorInfo)) != EOK) {
358         HDF_LOGE("%s: Copy sensor info failed", __func__);
359         return HDF_FAILURE;
360     }
361 
362     return HDF_SUCCESS;
363 }
364 
InitAlsAfterDetected(struct SensorCfgData * config)365 static int32_t InitAlsAfterDetected(struct SensorCfgData *config)
366 {
367     struct SensorDeviceInfo deviceInfo;
368     CHECK_NULL_PTR_RETURN_VALUE(config, HDF_ERR_INVALID_PARAM);
369 
370     if (InitAlsOps(config, &deviceInfo) != HDF_SUCCESS) {
371         HDF_LOGE("%s: Init als ops failed", __func__);
372         return HDF_FAILURE;
373     }
374 
375     if (AddSensorDevice(&deviceInfo) != HDF_SUCCESS) {
376         HDF_LOGE("%s: Add als device failed", __func__);
377         return HDF_FAILURE;
378     }
379 
380     if (ParseSensorRegConfig(config) != HDF_SUCCESS) {
381         HDF_LOGE("%s: Parse sensor register failed", __func__);
382         goto SENSOR_REG_CONFIG_EXIT;
383     }
384 
385     if (ParseExtendedAlsRegConfig(config) != HDF_SUCCESS) {
386         HDF_LOGE("%s: Parse sensor extendedRegCfgGroup register failed", __func__);
387         goto EXTENDED_ALS_REG_CONFIG_EXIT;
388     }
389 
390     return HDF_SUCCESS;
391 
392 EXTENDED_ALS_REG_CONFIG_EXIT:
393     ReleaseSensorAllRegConfig(config);
394 SENSOR_REG_CONFIG_EXIT:
395     (void)DeleteSensorDevice(&config->sensorInfo);
396 
397     return HDF_FAILURE;
398 }
399 
AlsCreateCfgData(const struct DeviceResourceNode * node)400 struct SensorCfgData *AlsCreateCfgData(const struct DeviceResourceNode *node)
401 {
402     struct AlsDrvData *drvData = AlsGetDrvData();
403 
404     if (drvData == NULL || node == NULL) {
405         HDF_LOGE("%s: Als node pointer NULL", __func__);
406         return NULL;
407     }
408 
409     if (drvData->detectFlag) {
410         HDF_LOGE("%s: Als sensor have detected", __func__);
411         return NULL;
412     }
413 
414     if (drvData->alsCfg == NULL) {
415         HDF_LOGE("%s: Als alsCfg pointer NULL", __func__);
416         return NULL;
417     }
418 
419     if (GetSensorBaseConfigData(node, drvData->alsCfg) != HDF_SUCCESS) {
420         HDF_LOGE("%s: Get sensor base config failed", __func__);
421         goto BASE_CONFIG_EXIT;
422     }
423 
424     if (DetectSensorDevice(drvData->alsCfg) != HDF_SUCCESS) {
425         HDF_LOGI("%s: Als sensor detect device no exist", __func__);
426         drvData->detectFlag = false;
427         goto BASE_CONFIG_EXIT;
428     }
429 
430     drvData->detectFlag = true;
431     if (InitAlsAfterDetected(drvData->alsCfg) != HDF_SUCCESS) {
432         HDF_LOGE("%s: Als sensor detect device no exist", __func__);
433         goto INIT_EXIT;
434     }
435 
436     return drvData->alsCfg;
437 
438 INIT_EXIT:
439     (void)ReleaseSensorBusHandle(&drvData->alsCfg->busCfg);
440 BASE_CONFIG_EXIT:
441     drvData->alsCfg->root = NULL;
442     (void)memset_s(&drvData->alsCfg->sensorInfo, sizeof(struct SensorBasicInfo), 0, sizeof(struct SensorBasicInfo));
443     (void)memset_s(&drvData->alsCfg->busCfg, sizeof(struct SensorBusCfg), 0, sizeof(struct SensorBusCfg));
444     (void)memset_s(&drvData->alsCfg->sensorAttr, sizeof(struct SensorAttr), 0, sizeof(struct SensorAttr));
445     return drvData->alsCfg;
446 }
447 
AlsReleaseCfgData(struct SensorCfgData * alsCfg)448 void AlsReleaseCfgData(struct SensorCfgData *alsCfg)
449 {
450     CHECK_NULL_PTR_RETURN(alsCfg);
451 
452     (void)DeleteSensorDevice(&alsCfg->sensorInfo);
453     ReleaseSensorAllRegConfig(alsCfg);
454     ReleaseExtendedAlsRegConfig(alsCfg);
455     (void)ReleaseSensorBusHandle(&alsCfg->busCfg);
456 
457     alsCfg->root = NULL;
458     (void)memset_s(&alsCfg->sensorInfo, sizeof(struct SensorBasicInfo), 0, sizeof(struct SensorBasicInfo));
459     (void)memset_s(&alsCfg->busCfg, sizeof(struct SensorBusCfg), 0, sizeof(struct SensorBusCfg));
460     (void)memset_s(&alsCfg->sensorAttr, sizeof(struct SensorAttr), 0, sizeof(struct SensorAttr));
461 }
462 
AlsInitDriver(struct HdfDeviceObject * device)463 int32_t AlsInitDriver(struct HdfDeviceObject *device)
464 {
465     CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
466     struct AlsDrvData *drvData = (struct AlsDrvData *)device->service;
467     CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
468 
469     if (InitAlsData(drvData) != HDF_SUCCESS) {
470         HDF_LOGE("%s: Init als config failed", __func__);
471         return HDF_FAILURE;
472     }
473 
474     drvData->alsCfg = (struct SensorCfgData *)OsalMemCalloc(sizeof(*drvData->alsCfg));
475     if (drvData->alsCfg == NULL) {
476         HDF_LOGE("%s: Malloc als config data failed", __func__);
477         return HDF_FAILURE;
478     }
479 
480     drvData->alsCfg->regCfgGroup = &g_regCfgGroup[0];
481     drvData->alsCfg->extendedRegCfgGroup = &g_extendAlsRegCfgGroup[0];
482 
483     return HDF_SUCCESS;
484 }
485 
AlsReleaseDriver(struct HdfDeviceObject * device)486 void AlsReleaseDriver(struct HdfDeviceObject *device)
487 {
488     CHECK_NULL_PTR_RETURN(device);
489 
490     struct AlsDrvData *drvData = (struct AlsDrvData *)device->service;
491     CHECK_NULL_PTR_RETURN(drvData);
492 
493     if (drvData->detectFlag && drvData->alsCfg != NULL) {
494         AlsReleaseCfgData(drvData->alsCfg);
495     }
496 
497     OsalMemFree(drvData->alsCfg);
498     drvData->alsCfg = NULL;
499 
500     HdfWorkDestroy(&drvData->alsWork);
501     HdfWorkQueueDestroy(&drvData->alsWorkQueue);
502     OsalMemFree(drvData);
503 }
504 
505 struct HdfDriverEntry g_sensorAlsDevEntry = {
506     .moduleVersion = 1,
507     .moduleName = "HDF_SENSOR_ALS",
508     .Bind = AlsBindDriver,
509     .Init = AlsInitDriver,
510     .Release = AlsReleaseDriver,
511 };
512 
513 HDF_INIT(g_sensorAlsDevEntry);
514