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