• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 xu
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 "proximity_apds9960.h"
10 #include <securec.h>
11 #include "osal_mem.h"
12 #include "osal_time.h"
13 #include "sensor_config_controller.h"
14 #include "sensor_device_manager.h"
15 #include "sensor_proximity_driver.h"
16 
17 #define HDF_LOG_TAG    hdf_sensor_proximity
18 
19 #define PROXIMITY_STATE_FAR    5
20 #define PROXIMITY_STATE_NEAR   0
21 
22 static struct Apds9960DrvData *g_apds9960DrvData = NULL;
23 
Apds9960GetDrvData(void)24 static struct Apds9960DrvData *Apds9960GetDrvData(void)
25 {
26     return g_apds9960DrvData;
27 }
28 
29 /* IO config for int-pin and I2C-pin */
30 #define SENSOR_I2C6_DATA_REG_ADDR 0x114f004c
31 #define SENSOR_I2C6_CLK_REG_ADDR  0x114f0048
32 #define SENSOR_I2C_REG_CFG        0x403
33 
ReadApds9960RawData(struct SensorCfgData * data,struct ProximityData * rawData,uint64_t * timestamp)34 static int32_t ReadApds9960RawData(struct SensorCfgData *data, struct ProximityData *rawData, uint64_t *timestamp)
35 {
36     OsalTimespec time;
37 
38     (void)memset_s(&time, sizeof(time), 0, sizeof(time));
39 
40     CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
41 
42     if (OsalGetTime(&time) != HDF_SUCCESS) {
43         HDF_LOGE("%s: Get time failed", __func__);
44         return HDF_FAILURE;
45     }
46     *timestamp = time.sec * SENSOR_SECOND_CONVERT_NANOSECOND + time.usec * SENSOR_CONVERT_UNIT; /* unit nanosecond */
47 
48     int32_t ret = ReadSensor(&data->busCfg, APDS9960_PROXIMITY_DATA_ADDR, &rawData->stateFlag, sizeof(uint8_t));
49     CHECK_PARSER_RESULT_RETURN_VALUE(ret, "read data");
50 
51     return ret;
52 }
53 
ReadApds9960Data(struct SensorCfgData * data)54 int32_t ReadApds9960Data(struct SensorCfgData *data)
55 {
56     int32_t ret;
57     int32_t tmp;
58     struct ProximityData rawData = { 5 };
59     struct SensorReportEvent event;
60 
61     (void)memset_s(&event, sizeof(event), 0, sizeof(event));
62 
63     ret = ReadApds9960RawData(data, &rawData, &event.timestamp);
64     if (ret != HDF_SUCCESS) {
65         return HDF_FAILURE;
66     }
67 
68     event.sensorId = SENSOR_TAG_PROXIMITY;
69     event.option = 0;
70     event.mode = SENSOR_WORK_MODE_ON_CHANGE;
71 
72     if (rawData.stateFlag <= APDS9960_PROXIMITY_THRESHOLD) {
73         tmp = PROXIMITY_STATE_FAR;
74     } else {
75         tmp = PROXIMITY_STATE_NEAR;
76     }
77 
78     event.dataLen = sizeof(tmp);
79     event.data = (uint8_t *)&tmp;
80     ret = ReportSensorEvent(&event);
81     if (ret != HDF_SUCCESS) {
82         HDF_LOGE("%s: APDS9960 report data failed", __func__);
83     }
84 
85     return ret;
86 }
87 
InitApda9960(struct SensorCfgData * data)88 static int32_t InitApda9960(struct SensorCfgData *data)
89 {
90     int32_t ret;
91 
92     CHECK_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM);
93     ret = SetSensorRegCfgArray(&data->busCfg, data->regCfgGroup[SENSOR_INIT_GROUP]);
94     if (ret != HDF_SUCCESS) {
95         HDF_LOGE("%s: APDS9960 sensor init config failed", __func__);
96         return HDF_FAILURE;
97     }
98     return HDF_SUCCESS;
99 }
100 
InitProximityPreConfig(void)101 static int32_t InitProximityPreConfig(void)
102 {
103     if (SetSensorPinMux(SENSOR_I2C6_DATA_REG_ADDR, SENSOR_ADDR_WIDTH_4_BYTE, SENSOR_I2C_REG_CFG) != HDF_SUCCESS) {
104         HDF_LOGE("%s: Data write mux pin failed", __func__);
105         return HDF_FAILURE;
106     }
107     if (SetSensorPinMux(SENSOR_I2C6_CLK_REG_ADDR, SENSOR_ADDR_WIDTH_4_BYTE, SENSOR_I2C_REG_CFG) != HDF_SUCCESS) {
108         HDF_LOGE("%s: Clk write mux pin failed", __func__);
109         return HDF_FAILURE;
110     }
111 
112     return HDF_SUCCESS;
113 }
114 
DispatchApds9960(struct HdfDeviceIoClient * client,int cmd,struct HdfSBuf * data,struct HdfSBuf * reply)115 static int32_t DispatchApds9960(struct HdfDeviceIoClient *client,
116     int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
117 {
118     (void)client;
119     (void)cmd;
120     (void)data;
121     (void)reply;
122 
123     return HDF_SUCCESS;
124 }
125 
Apds9960BindDriver(struct HdfDeviceObject * device)126 int32_t Apds9960BindDriver(struct HdfDeviceObject *device)
127 {
128     CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
129 
130     struct Apds9960DrvData *drvData = (struct Apds9960DrvData *)OsalMemCalloc(sizeof(*drvData));
131     if (drvData == NULL) {
132         HDF_LOGE("%s: Malloc Apds9960 drv data fail", __func__);
133         return HDF_ERR_MALLOC_FAIL;
134     }
135 
136     drvData->ioService.Dispatch = DispatchApds9960;
137     drvData->device = device;
138     device->service = &drvData->ioService;
139     g_apds9960DrvData = drvData;
140 
141     return HDF_SUCCESS;
142 }
143 
Apds996InitDriver(struct HdfDeviceObject * device)144 int32_t Apds996InitDriver(struct HdfDeviceObject *device)
145 {
146     int32_t ret;
147     struct ProximityOpsCall ops;
148 
149     CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
150     struct Apds9960DrvData *drvData = (struct Apds9960DrvData *)device->service;
151     CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
152 
153     ret = InitProximityPreConfig();
154     if (ret != HDF_SUCCESS) {
155         HDF_LOGE("%s: Init  APDS9960 bus mux config", __func__);
156         return HDF_FAILURE;
157     }
158 
159     drvData->sensorCfg = ProximityCreateCfgData(device->property);
160     if (drvData->sensorCfg == NULL || drvData->sensorCfg->root == NULL) {
161         HDF_LOGD("%s: Creating proximitycfg failed because detection failed", __func__);
162         return HDF_ERR_NOT_SUPPORT;
163     }
164 
165     ops.Init = NULL;
166     ops.ReadData = ReadApds9960Data;
167     ret = ProximityRegisterChipOps(&ops);
168     if (ret != HDF_SUCCESS) {
169         HDF_LOGE("%s: Register APDS9960 proximity failed", __func__);
170         return HDF_FAILURE;
171     }
172 
173     ret = InitApda9960(drvData->sensorCfg);
174     if (ret != HDF_SUCCESS) {
175         HDF_LOGE("%s: Init APDS9960 proximity failed", __func__);
176         return HDF_FAILURE;
177     }
178 
179     return HDF_SUCCESS;
180 }
181 
182 
Apds996ReleaseDriver(struct HdfDeviceObject * device)183 void Apds996ReleaseDriver(struct HdfDeviceObject *device)
184 {
185     CHECK_NULL_PTR_RETURN(device);
186 
187     struct Apds9960DrvData *drvData = (struct Apds9960DrvData *)device->service;
188     CHECK_NULL_PTR_RETURN(drvData);
189 
190     if (drvData->sensorCfg != NULL) {
191         ProximityReleaseCfgData(drvData->sensorCfg);
192         drvData->sensorCfg = NULL;
193     }
194     OsalMemFree(drvData);
195 }
196 
197 struct HdfDriverEntry g_proximityApds9960DevEntry = {
198     .moduleVersion = 1,
199     .moduleName = "HDF_SENSOR_PROXIMITY_APDS9960",
200     .Bind = Apds9960BindDriver,
201     .Init = Apds996InitDriver,
202     .Release = Apds996ReleaseDriver,
203 };
204 
205 HDF_INIT(g_proximityApds9960DevEntry);