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