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