1 /*
2 * Copyright (c) 2023 Nanjing Xiaoxiongpai Intelligent Technology 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 "als_bh1750.h"
10 #include <securec.h>
11 #include "osal_mem.h"
12 #include "osal_time.h"
13 #include "sensor_als_driver.h"
14 #include "sensor_config_controller.h"
15 #include "sensor_device_manager.h"
16
17 #define HDF_LOG_TAG hdf_sensor_als
18
19 static struct Bh1750DrvData *g_bh1750DrvData = NULL;
20
Bh1750GetDrvData(void)21 static struct Bh1750DrvData *Bh1750GetDrvData(void)
22 {
23 return g_bh1750DrvData;
24 }
25
ReadBh1750RawData(struct SensorCfgData * data,struct BH1750AlsData * rawData,uint64_t * timestamp)26 static int32_t ReadBh1750RawData(struct SensorCfgData *data, struct BH1750AlsData *rawData, uint64_t *timestamp)
27 {
28 uint8_t reg[BH1750_TEMP_DATA_BUF_LEN] = { 0 };
29 OsalTimespec time;
30 int32_t ret = HDF_SUCCESS;
31 uint8_t measureCmdValue[] = {BH1750_CONTINUOUS_H_RES_MODE};
32 uint16_t tempValue;
33
34 (void)memset_s(&time, sizeof(time), 0, sizeof(time));
35
36 CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
37
38 if (OsalGetTime(&time) != HDF_SUCCESS) {
39 HDF_LOGE("%s: Get time failed", __func__);
40 return HDF_FAILURE;
41 }
42 *timestamp = time.sec * SENSOR_SECOND_CONVERT_NANOSECOND + time.usec * SENSOR_CONVERT_UNIT; /* unit nanosecond */
43
44 ret = WriteSensor(&data->busCfg, measureCmdValue, sizeof(measureCmdValue));
45 CHECK_PARSER_RESULT_RETURN_VALUE(ret, "write data");
46
47 OsalMDelay(BH1750_READ_VALUE_DELAY);
48
49 ret = ReadSensor(&data->busCfg, NULL, reg, sizeof(reg));
50
51 tempValue = reg[BH1750_TEMP_VALUE_IDX_ZERO];
52 tempValue <<= SENSOR_DATA_WIDTH_8_BIT;
53 tempValue |= reg[BH1750_TEMP_VALUE_IDX_ONE];
54
55 CHECK_PARSER_RESULT_RETURN_VALUE(ret, "read data");
56
57 rawData->als = (tempValue * BH1750_TEMP_CONSATNT_1) / BH1750_TEMP_CONSATNT_2;
58
59 return HDF_SUCCESS;
60 }
61
ReadBh1750Data(struct SensorCfgData * data)62 static int32_t ReadBh1750Data(struct SensorCfgData *data)
63 {
64 int32_t ret;
65 static int32_t als;
66 struct BH1750AlsData rawData = { 0 };
67 struct SensorReportEvent event;
68
69 (void)memset_s(&event, sizeof(event), 0, sizeof(event));
70 ret = ReadBh1750RawData(data, &rawData, &event.timestamp);
71 if (ret != HDF_SUCCESS) {
72 HDF_LOGE("%s: BH1750 read raw data failed", __func__);
73 return HDF_FAILURE;
74 }
75 als = rawData.als;
76 event.sensorId = SENSOR_TAG_AMBIENT_LIGHT;
77 event.option = 0;
78 event.mode = SENSOR_WORK_MODE_REALTIME;
79
80 event.dataLen = sizeof(als);
81 event.data = (uint8_t *)&als;
82
83 ret = ReportSensorEvent(&event);
84 if (ret != HDF_SUCCESS) {
85 HDF_LOGE("%s: BH1750 report data failed", __func__);
86 }
87 return ret;
88 }
89
InitBh1750(struct SensorCfgData * data)90 static int32_t InitBh1750(struct SensorCfgData *data)
91 {
92 int32_t ret;
93
94 CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
95 ret = SetSensorRegCfgArray(&data->busCfg, data->regCfgGroup[SENSOR_INIT_GROUP]);
96 if (ret != HDF_SUCCESS) {
97 HDF_LOGE("%s: BH1750 sensor init config failed", __func__);
98 return HDF_FAILURE;
99 }
100
101 return HDF_SUCCESS;
102 }
103
DispatchBH1750(struct HdfDeviceIoClient * client,int cmd,struct HdfSBuf * data,struct HdfSBuf * reply)104 static int32_t DispatchBH1750(struct HdfDeviceIoClient *client,
105 int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
106 {
107 (void)client;
108 (void)cmd;
109 (void)data;
110 (void)reply;
111
112 return HDF_SUCCESS;
113 }
114
Bh1750BindDriver(struct HdfDeviceObject * device)115 static int32_t Bh1750BindDriver(struct HdfDeviceObject *device)
116 {
117 CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
118
119 struct Bh1750DrvData *drvData = (struct Bh1750DrvData *)OsalMemCalloc(sizeof(*drvData));
120 if (drvData == NULL) {
121 HDF_LOGE("%s: Malloc Bh1750 drv data fail", __func__);
122 return HDF_ERR_MALLOC_FAIL;
123 }
124
125 drvData->ioService.Dispatch = DispatchBH1750;
126 drvData->device = device;
127 device->service = &drvData->ioService;
128 g_bh1750DrvData = drvData;
129
130 return HDF_SUCCESS;
131 }
132
Bh1750InitDriver(struct HdfDeviceObject * device)133 static int32_t Bh1750InitDriver(struct HdfDeviceObject *device)
134 {
135 int32_t ret;
136 struct AlsOpsCall ops;
137
138 CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
139 struct Bh1750DrvData *drvData = (struct Bh1750DrvData *)device->service;
140 CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
141
142 drvData->sensorCfg = AlsCreateCfgData(device->property);
143 if (drvData->sensorCfg == NULL || drvData->sensorCfg->root == NULL) {
144 HDF_LOGD("%s: Creating alscfg failed because detection failed", __func__);
145 return HDF_ERR_NOT_SUPPORT;
146 }
147
148 ops.Init = NULL;
149 ops.ReadData = ReadBh1750Data;
150 ret = AlsRegisterChipOps(&ops);
151 if (ret != HDF_SUCCESS) {
152 HDF_LOGE("%s: Register BH1750 als failed", __func__);
153 return HDF_FAILURE;
154 }
155
156 ret = InitBh1750(drvData->sensorCfg);
157 if (ret != HDF_SUCCESS) {
158 HDF_LOGE("%s: Init BH1750 als failed", __func__);
159 return HDF_FAILURE;
160 }
161
162 return HDF_SUCCESS;
163 }
164
Bh1750ReleaseDriver(struct HdfDeviceObject * device)165 static void Bh1750ReleaseDriver(struct HdfDeviceObject *device)
166 {
167 CHECK_NULL_PTR_RETURN(device);
168
169 struct Bh1750DrvData *drvData = (struct Bh1750DrvData *)device->service;
170 CHECK_NULL_PTR_RETURN(drvData);
171
172 if (drvData->sensorCfg != NULL) {
173 AlsReleaseCfgData(drvData->sensorCfg);
174 drvData->sensorCfg = NULL;
175 }
176 OsalMemFree(drvData);
177 }
178
179 struct HdfDriverEntry g_alsBh1750DevEntry = {
180 .moduleVersion = 1,
181 .moduleName = "HDF_SENSOR_ALS_BH1750",
182 .Bind = Bh1750BindDriver,
183 .Init = Bh1750InitDriver,
184 .Release = Bh1750ReleaseDriver,
185 };
186
187 HDF_INIT(g_alsBh1750DevEntry);
188