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_temperature_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_temperature_driver
20
21 #define HDF_TEMPERATURE_WORK_QUEUE_NAME "hdf_temperature_work_queue"
22
23 static struct TemperatureDrvData *g_temperatureDrvData = NULL;
24
TemperatureGetDrvData(void)25 static struct TemperatureDrvData *TemperatureGetDrvData(void)
26 {
27 return g_temperatureDrvData;
28 }
29
30 static struct SensorRegCfgGroupNode *g_regCfgGroup[SENSOR_GROUP_MAX] = { NULL };
31
TemperatureRegisterChipOps(const struct TemperatureOpsCall * ops)32 int32_t TemperatureRegisterChipOps(const struct TemperatureOpsCall *ops)
33 {
34 struct TemperatureDrvData *drvData = TemperatureGetDrvData();
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
TemperatureDataWorkEntry(void * arg)44 static void TemperatureDataWorkEntry(void *arg)
45 {
46 struct TemperatureDrvData *drvData = NULL;
47
48 drvData = (struct TemperatureDrvData *)arg;
49 CHECK_NULL_PTR_RETURN(drvData);
50
51 if (drvData->ops.ReadData == NULL) {
52 HDF_LOGE("%s: Temperature readdata function NULL", __func__);
53 return;
54 }
55 if (drvData->ops.ReadData(drvData->temperatureCfg) != HDF_SUCCESS) {
56 HDF_LOGE("%s: Temperature read data failed", __func__);
57 }
58 }
59
TemperatureTimerEntry(uintptr_t arg)60 static void TemperatureTimerEntry(uintptr_t arg)
61 {
62 int64_t interval;
63 int32_t ret;
64 struct TemperatureDrvData *drvData = (struct TemperatureDrvData *)arg;
65 CHECK_NULL_PTR_RETURN(drvData);
66
67 if (!HdfAddWork(&drvData->temperatureWorkQueue, &drvData->temperatureWork)) {
68 HDF_LOGE("%s: Temperature 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->temperatureTimer, interval);
74 if (ret != HDF_SUCCESS) {
75 HDF_LOGE("%s: Temperature modify time failed", __func__);
76 }
77 }
78
InitTemperatureData(struct TemperatureDrvData * drvData)79 static int32_t InitTemperatureData(struct TemperatureDrvData *drvData)
80 {
81 if (HdfWorkQueueInit(&drvData->temperatureWorkQueue, HDF_TEMPERATURE_WORK_QUEUE_NAME) != HDF_SUCCESS) {
82 HDF_LOGE("%s: Temperature init work queue failed", __func__);
83 return HDF_FAILURE;
84 }
85
86 if (HdfWorkInit(&drvData->temperatureWork, TemperatureDataWorkEntry, drvData) != HDF_SUCCESS) {
87 HDF_LOGE("%s: Temperature 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
SetTemperatureEnable(void)98 static int32_t SetTemperatureEnable(void)
99 {
100 int32_t ret;
101 struct TemperatureDrvData *drvData = TemperatureGetDrvData();
102
103 CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
104 CHECK_NULL_PTR_RETURN_VALUE(drvData->temperatureCfg, HDF_ERR_INVALID_PARAM);
105
106 if (drvData->enable) {
107 HDF_LOGE("%s: Temperature sensor is enabled", __func__);
108 return HDF_SUCCESS;
109 }
110
111 ret = SetSensorRegCfgArray(&drvData->temperatureCfg->busCfg, \
112 drvData->temperatureCfg->regCfgGroup[SENSOR_ENABLE_GROUP]);
113 if (ret != HDF_SUCCESS) {
114 HDF_LOGE("%s: Temperature sensor enable config failed", __func__);
115 return ret;
116 }
117
118 ret = OsalTimerCreate(&drvData->temperatureTimer, SENSOR_TIMER_MIN_TIME, TemperatureTimerEntry, (uintptr_t)drvData);
119 if (ret != HDF_SUCCESS) {
120 HDF_LOGE("%s: Temperature create timer failed[%d]", __func__, ret);
121 return ret;
122 }
123
124 ret = OsalTimerStartLoop(&drvData->temperatureTimer);
125 if (ret != HDF_SUCCESS) {
126 HDF_LOGE("%s: Temperature start timer failed[%d]", __func__, ret);
127 return ret;
128 }
129 drvData->enable = true;
130
131 return HDF_SUCCESS;
132 }
133
SetTemperatureDisable(void)134 static int32_t SetTemperatureDisable(void)
135 {
136 int32_t ret;
137 struct TemperatureDrvData *drvData = TemperatureGetDrvData();
138
139 CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
140 CHECK_NULL_PTR_RETURN_VALUE(drvData->temperatureCfg, HDF_ERR_INVALID_PARAM);
141
142 if (!drvData->enable) {
143 HDF_LOGE("%s: Temperature sensor had disable", __func__);
144 return HDF_SUCCESS;
145 }
146
147 ret = SetSensorRegCfgArray(&drvData->temperatureCfg->busCfg, \
148 drvData->temperatureCfg->regCfgGroup[SENSOR_DISABLE_GROUP]);
149 if (ret != HDF_SUCCESS) {
150 HDF_LOGE("%s: Temperature sensor disable config failed", __func__);
151 return ret;
152 }
153
154 ret = OsalTimerDelete(&drvData->temperatureTimer);
155 if (ret != HDF_SUCCESS) {
156 HDF_LOGE("%s: Temperature delete timer failed", __func__);
157 return ret;
158 }
159 drvData->enable = false;
160
161 return HDF_SUCCESS;
162 }
163
SetTemperatureBatch(int64_t samplingInterval,int64_t interval)164 static int32_t SetTemperatureBatch(int64_t samplingInterval, int64_t interval)
165 {
166 (void)interval;
167
168 struct TemperatureDrvData *drvData = NULL;
169
170 drvData = TemperatureGetDrvData();
171 CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
172
173 drvData->interval = samplingInterval;
174
175 return HDF_SUCCESS;
176 }
177
SetTemperatureMode(int32_t mode)178 static int32_t SetTemperatureMode(int32_t mode)
179 {
180 if (mode <= SENSOR_WORK_MODE_DEFAULT || mode >= SENSOR_WORK_MODE_MAX) {
181 HDF_LOGE("%s: The current mode is not supported", __func__);
182 return HDF_FAILURE;
183 }
184
185 return HDF_SUCCESS;
186 }
187
SetTemperatureOption(uint32_t option)188 static int32_t SetTemperatureOption(uint32_t option)
189 {
190 (void)option;
191
192 return HDF_SUCCESS;
193 }
194
DispatchTemperature(struct HdfDeviceIoClient * client,int cmd,struct HdfSBuf * data,struct HdfSBuf * reply)195 static int32_t DispatchTemperature(struct HdfDeviceIoClient *client,
196 int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
197 {
198 (void)client;
199 (void)cmd;
200 (void)data;
201 (void)reply;
202
203 return HDF_SUCCESS;
204 }
205
TemperatureBindDriver(struct HdfDeviceObject * device)206 int32_t TemperatureBindDriver(struct HdfDeviceObject *device)
207 {
208 CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
209
210 struct TemperatureDrvData *drvData = (struct TemperatureDrvData *)OsalMemCalloc(sizeof(*drvData));
211 if (drvData == NULL) {
212 HDF_LOGE("%s: Malloc Temperature drv data fail!", __func__);
213 return HDF_ERR_MALLOC_FAIL;
214 }
215
216 drvData->ioService.Dispatch = DispatchTemperature;
217 drvData->device = device;
218 device->service = &drvData->ioService;
219 g_temperatureDrvData = drvData;
220
221 return HDF_SUCCESS;
222 }
223
InitTemperatureOps(struct SensorCfgData * config,struct SensorDeviceInfo * deviceInfo)224 static int32_t InitTemperatureOps(struct SensorCfgData *config, struct SensorDeviceInfo *deviceInfo)
225 {
226 CHECK_NULL_PTR_RETURN_VALUE(config, HDF_ERR_INVALID_PARAM);
227
228 deviceInfo->ops.Enable = SetTemperatureEnable;
229 deviceInfo->ops.Disable = SetTemperatureDisable;
230 deviceInfo->ops.SetBatch = SetTemperatureBatch;
231 deviceInfo->ops.SetMode = SetTemperatureMode;
232 deviceInfo->ops.SetOption = SetTemperatureOption;
233
234 if (memcpy_s(&deviceInfo->sensorInfo, sizeof(deviceInfo->sensorInfo),
235 &config->sensorInfo, sizeof(config->sensorInfo)) != EOK) {
236 HDF_LOGE("%s: Copy sensor info failed", __func__);
237 return HDF_FAILURE;
238 }
239
240 return HDF_SUCCESS;
241 }
242
InitTemperatureAfterDetected(struct SensorCfgData * config)243 static int32_t InitTemperatureAfterDetected(struct SensorCfgData *config)
244 {
245 struct SensorDeviceInfo deviceInfo;
246 CHECK_NULL_PTR_RETURN_VALUE(config, HDF_ERR_INVALID_PARAM);
247
248 if (InitTemperatureOps(config, &deviceInfo) != HDF_SUCCESS) {
249 HDF_LOGE("%s: Init Temperature ops failed", __func__);
250 return HDF_FAILURE;
251 }
252
253 if (AddSensorDevice(&deviceInfo) != HDF_SUCCESS) {
254 HDF_LOGE("%s: Add Temperature device failed", __func__);
255 return HDF_FAILURE;
256 }
257
258 if (ParseSensorRegConfig(config) != HDF_SUCCESS) {
259 HDF_LOGE("%s: Parse sensor register failed", __func__);
260 (void)DeleteSensorDevice(&config->sensorInfo);
261 ReleaseSensorAllRegConfig(config);
262 ReleaseSensorDirectionConfig(config);
263 return HDF_FAILURE;
264 }
265
266 return HDF_SUCCESS;
267 }
268
TemperatureCreateCfgData(const struct DeviceResourceNode * node)269 struct SensorCfgData *TemperatureCreateCfgData(const struct DeviceResourceNode *node)
270 {
271 struct TemperatureDrvData *drvData = TemperatureGetDrvData();
272
273 if (drvData == NULL || node == NULL) {
274 HDF_LOGE("%s: Temperature node pointer NULL", __func__);
275 return NULL;
276 }
277
278 if (drvData->detectFlag) {
279 HDF_LOGE("%s: Temperature sensor have detected", __func__);
280 return NULL;
281 }
282
283 if (drvData->temperatureCfg == NULL) {
284 HDF_LOGE("%s: Temperature TemperatureCfg pointer NULL", __func__);
285 return NULL;
286 }
287
288 if (GetSensorBaseConfigData(node, drvData->temperatureCfg) != HDF_SUCCESS) {
289 HDF_LOGE("%s: Get sensor base config failed", __func__);
290 goto BASE_CONFIG_EXIT;
291 }
292
293 if ((drvData->temperatureCfg->sensorAttr.chipName != NULL) && \
294 (DetectSensorDevice(drvData->temperatureCfg) != HDF_SUCCESS)) {
295 HDF_LOGI("%s: Temperature sensor detect device no exist", __func__);
296 drvData->detectFlag = false;
297 goto BASE_CONFIG_EXIT;
298 } else {
299 if (GetSensorBusHandle(&drvData->temperatureCfg->busCfg) != HDF_SUCCESS) {
300 HDF_LOGE("%s: get sensor bus handle failed", __func__);
301 (void)ReleaseSensorBusHandle(&drvData->temperatureCfg->busCfg);
302 drvData->detectFlag = false;
303 goto BASE_CONFIG_EXIT;
304 }
305 }
306
307 drvData->detectFlag = true;
308 if (InitTemperatureAfterDetected(drvData->temperatureCfg) != HDF_SUCCESS) {
309 HDF_LOGI("%s: Temperature sensor detect device no exist", __func__);
310 goto INIT_EXIT;
311 }
312
313 return drvData->temperatureCfg;
314
315 INIT_EXIT:
316 (void)ReleaseSensorBusHandle(&drvData->temperatureCfg->busCfg);
317 BASE_CONFIG_EXIT:
318 drvData->temperatureCfg->root = NULL;
319 (void)memset_s(&drvData->temperatureCfg->sensorInfo,
320 sizeof(struct SensorBasicInfo), 0, sizeof(struct SensorBasicInfo));
321 (void)memset_s(&drvData->temperatureCfg->busCfg, sizeof(struct SensorBusCfg), 0, sizeof(struct SensorBusCfg));
322 (void)memset_s(&drvData->temperatureCfg->sensorAttr, sizeof(struct SensorAttr), 0, sizeof(struct SensorAttr));
323
324 return drvData->temperatureCfg;
325 }
326
TemperatureReleaseCfgData(struct SensorCfgData * temperatureCfg)327 void TemperatureReleaseCfgData(struct SensorCfgData *temperatureCfg)
328 {
329 CHECK_NULL_PTR_RETURN(temperatureCfg);
330
331 (void)DeleteSensorDevice(&temperatureCfg->sensorInfo);
332 ReleaseSensorAllRegConfig(temperatureCfg);
333 (void)ReleaseSensorBusHandle(&temperatureCfg->busCfg);
334 ReleaseSensorDirectionConfig(temperatureCfg);
335
336 temperatureCfg->root = NULL;
337 (void)memset_s(&temperatureCfg->sensorInfo, sizeof(struct SensorBasicInfo), 0, sizeof(struct SensorBasicInfo));
338 (void)memset_s(&temperatureCfg->busCfg, sizeof(struct SensorBusCfg), 0, sizeof(struct SensorBusCfg));
339 (void)memset_s(&temperatureCfg->sensorAttr, sizeof(struct SensorAttr), 0, sizeof(struct SensorAttr));
340 }
341
TemperatureInitDriver(struct HdfDeviceObject * device)342 int32_t TemperatureInitDriver(struct HdfDeviceObject *device)
343 {
344 CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
345 struct TemperatureDrvData *drvData = (struct TemperatureDrvData *)device->service;
346 CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
347
348 if (InitTemperatureData(drvData) != HDF_SUCCESS) {
349 HDF_LOGE("%s: Init Temperature config failed", __func__);
350 return HDF_FAILURE;
351 }
352
353 drvData->temperatureCfg = (struct SensorCfgData *)OsalMemCalloc(sizeof(*drvData->temperatureCfg));
354 if (drvData->temperatureCfg == NULL) {
355 HDF_LOGE("%s: Malloc Temperature config data failed", __func__);
356 return HDF_FAILURE;
357 }
358
359 drvData->temperatureCfg->regCfgGroup = &g_regCfgGroup[0];
360
361 HDF_LOGI("%s: Init Temperature driver success", __func__);
362 return HDF_SUCCESS;
363 }
364
TemperatureReleaseDriver(struct HdfDeviceObject * device)365 void TemperatureReleaseDriver(struct HdfDeviceObject *device)
366 {
367 CHECK_NULL_PTR_RETURN(device);
368
369 struct TemperatureDrvData *drvData = (struct TemperatureDrvData *)device->service;
370 CHECK_NULL_PTR_RETURN(drvData);
371
372 if (drvData->detectFlag && drvData->temperatureCfg != NULL) {
373 TemperatureReleaseCfgData(drvData->temperatureCfg);
374 }
375
376 OsalMemFree(drvData->temperatureCfg);
377 drvData->temperatureCfg = NULL;
378
379 HdfWorkDestroy(&drvData->temperatureWork);
380 HdfWorkQueueDestroy(&drvData->temperatureWorkQueue);
381 OsalMemFree(drvData);
382 }
383
384 struct HdfDriverEntry g_sensorTemperatureDevEntry = {
385 .moduleVersion = 1,
386 .moduleName = "HDF_SENSOR_TEMPERATURE",
387 .Bind = TemperatureBindDriver,
388 .Init = TemperatureInitDriver,
389 .Release = TemperatureReleaseDriver,
390 };
391
392 HDF_INIT(g_sensorTemperatureDevEntry);
393