1 /*
2 * Copyright (c) 2022 Chipsea Technologies (Shenzhen) Corp., 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 "ppg_cs1262.h"
10 #include <securec.h>
11 #include "sensor_ppg_driver.h"
12 #include "sensor_device_if.h"
13 #include "osal_mem.h"
14 #include "osal_time.h"
15
16 #define HDF_LOG_TAG khdf_sensor_ppg_driver
17
18 static struct Cs1262DrvData *g_cs1262DrvData = NULL;
19
GetDrvData(void)20 static struct Cs1262DrvData *GetDrvData(void)
21 {
22 return g_cs1262DrvData;
23 }
24
ResetChip()25 static int32_t ResetChip()
26 {
27 uint8_t resetCmd[] = { CS1262_CHIP_REST_CMD, CS1262_SPI_DUMMY_DATA, CS1262_SPI_DUMMY_DATA };
28
29 if (Cs1262WriteData(resetCmd, HDF_ARRAY_SIZE(resetCmd)) != HDF_SUCCESS) {
30 HDF_LOGE("%s: Cs1262WriteData fail", __func__);
31 return HDF_FAILURE;
32 }
33
34 // delay 1 ms
35 OsalMDelay(1);
36 return HDF_SUCCESS;
37 }
38
ResetModule(uint16_t moduleOffset)39 static int32_t ResetModule(uint16_t moduleOffset)
40 {
41 uint8_t ret;
42
43 ret = Cs1262WriteRegbit(CS1262_RSTCON_REG, moduleOffset, CS1262_REG_BIT_SET);
44 if (ret != HDF_SUCCESS) {
45 HDF_LOGE("%s: CS1262_RST module fail CS1262_REG_BIT_SET", __func__);
46 return HDF_FAILURE;
47 }
48
49 ret = Cs1262WriteRegbit(CS1262_RSTCON_REG, moduleOffset, CS1262_REG_BIT_RESET);
50 if (ret != HDF_SUCCESS) {
51 HDF_LOGE("%s: CS1262_RST module fail CS1262_REG_BIT_RESET", __func__);
52 return HDF_FAILURE;
53 }
54
55 return HDF_SUCCESS;
56 }
57
RegLock(Cs1262LockStatus lockStatus)58 static int32_t RegLock(Cs1262LockStatus lockStatus)
59 {
60 int32_t ret;
61 uint16_t regRead = 0;
62 Cs1262RegGroup lockGroup[] = {
63 {.regAddr = CS1262_WRPROT_REG, .regVal = CS1262_LOCK, 1},
64 {.regAddr = CS1262_WRPROT_REG, .regVal = CS1262_UN_LOCK1, 1},
65 {.regAddr = CS1262_WRPROT_REG, .regVal = CS1262_UN_LOCK2, 1},
66 {.regAddr = CS1262_WRPROT_REG, .regVal = CS1262_UN_LOCK3, 1}
67 };
68 // lock write 1 byte 'CS1262_LOCK'; unlock need write 3 bytes
69 uint16_t lockGroupLen = (lockStatus == CS1262_REG_LOCK) ? 1 : 3;
70
71 ret = Cs1262WriteGroup(&lockGroup[lockStatus], lockGroupLen);
72 if (ret != HDF_SUCCESS) {
73 HDF_LOGE("%s: Cs1262WriteGroup fail", __func__);
74 return HDF_FAILURE;
75 }
76
77 ret = Cs1262ReadRegs(CS1262_SYS_STATE_REG, ®Read, 1);
78 if (ret != HDF_SUCCESS) {
79 HDF_LOGE("%s: Cs1262ReadRegs CS1262_SYS_STATE_REG fail", __func__);
80 return HDF_FAILURE;
81 }
82
83 if ((regRead & LOCK_REG_OFFSET) == lockStatus) {
84 return HDF_SUCCESS;
85 }
86
87 HDF_LOGE("%s: Cs1262 Lock fail status = %d", __func__, lockStatus);
88 return HDF_FAILURE;
89 }
90
ReadFifo(uint8_t * outBuf,uint16_t outBufMaxLen,uint16_t * outLen)91 static int32_t ReadFifo(uint8_t *outBuf, uint16_t outBufMaxLen, uint16_t *outLen)
92 {
93 uint8_t ret;
94 uint16_t fifoState = 0;
95 uint16_t fifoNum;
96
97 ret = Cs1262ReadRegs(CS1262_FIFO_STATE_REG, &fifoState, 1);
98 if (ret != HDF_SUCCESS) {
99 HDF_LOGE("%s: read reg %d fail", __func__, CS1262_FIFO_STATE_REG);
100 return HDF_FAILURE;
101 }
102
103 fifoNum = fifoState & FIFO_NUM_OFFSET;
104 // empty
105 if ((fifoNum == 0) || (fifoState & FIFO_EMPTY_OFFSET)) {
106 HDF_LOGI("%s: data FIFO is empty, no need read.", __func__);
107 return HDF_SUCCESS;
108 }
109
110 // full
111 if (fifoState & FIFO_FULL_OFFSET) {
112 fifoNum = CS1262_MAX_FIFO_READ_NUM;
113 }
114
115 // overflow
116 if ((fifoNum * sizeof(Cs1262FifoVal)) > outBufMaxLen) {
117 fifoNum = (outBufMaxLen / sizeof(Cs1262FifoVal));
118 }
119
120 (void)memset_s(outBuf, outBufMaxLen, 0, (fifoNum * sizeof(Cs1262FifoVal)));
121 ret = Cs1262ReadFifoReg((Cs1262FifoVal *)outBuf, fifoNum);
122 if (ret != HDF_SUCCESS) {
123 HDF_LOGE("%s: ReadFifoReg fail", __func__);
124 return HDF_FAILURE;
125 }
126
127 *outLen = fifoNum * sizeof(Cs1262FifoVal);
128
129 return HDF_SUCCESS;
130 }
131
SetIER(uint16_t it,uint8_t status)132 static inline int32_t SetIER(uint16_t it, uint8_t status)
133 {
134 return Cs1262WriteRegbit(CS1262_IER_REG, it, status);
135 }
136
ClearIFR(uint16_t it)137 static inline int32_t ClearIFR(uint16_t it)
138 {
139 return Cs1262WriteRegbit(CS1262_IFR_REG, it, CS1262_REG_BIT_SET);
140 }
141
Cs1262SetOption(uint32_t option)142 static int32_t Cs1262SetOption(uint32_t option)
143 {
144 HDF_LOGI("%s: cs1262 setOption :%d", __func__, option);
145 return HDF_SUCCESS;
146 }
147
Writefw(Cs1262RegConfigTab * regTab)148 static int32_t Writefw(Cs1262RegConfigTab *regTab)
149 {
150 int32_t ret;
151 Cs1262RegGroup regGroup[] = {
152 { .regAddr = CS1262_CLOCK_REG, .regVal = regTab->clock, 1 },
153 { .regAddr = CS1262_TL_BA, .regValGroup = regTab->tlTab, .regLen = TL_REGS_NUM },
154 { .regAddr = CS1262_TX_BA, .regValGroup = regTab->txTab, .regLen = TX_REGS_NUM },
155 { .regAddr = CS1262_RX_BA, .regValGroup = regTab->rxTab, .regLen = RX_REGS_NUM },
156 { .regAddr = CS1262_TE_BA, .regValGroup = regTab->teTab, .regLen = TE_REGS_NUM },
157 { .regAddr = CS1262_FIFO_OFFSET_REG, .regValGroup = (regTab->fifoTab + FIFO_WRITE_OFFSET),
158 .regLen = (FIFO_REGS_NUM - FIFO_WRITE_OFFSET)}
159 };
160
161 if (RegLock(CS1262_REG_UNLOCK) != HDF_SUCCESS) {
162 HDF_LOGE("%s: reg unlock failed", __func__);
163 return HDF_FAILURE;
164 }
165
166 ret = Cs1262WriteGroup(regGroup, HDF_ARRAY_SIZE(regGroup));
167 HDF_LOGI("%s: cs1262 init ret :%d", __func__, ret);
168
169 if (RegLock(CS1262_REG_LOCK) != HDF_SUCCESS) {
170 HDF_LOGE("%s: reg lock failed", __func__);
171 return HDF_FAILURE;
172 }
173 return ret;
174 }
175
Cs1262SetMode(uint32_t mode)176 static int32_t Cs1262SetMode(uint32_t mode)
177 {
178 int32_t ret;
179 Cs1262RegConfigTab *regTab = NULL;
180 struct Cs1262DrvData *drvData = GetDrvData();
181 CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
182
183 if ((mode == NONE_MODE) || (drvData->regMode == mode)) {
184 HDF_LOGI("%s: mode = %d, drvData->regMode = %d", __func__, mode, drvData->regMode);
185 drvData->regMode = mode;
186 return HDF_SUCCESS;
187 }
188
189 ret = Cs1262Loadfw(mode, ®Tab);
190 if ((ret != HDF_SUCCESS) || (regTab == NULL)) {
191 HDF_LOGE("%s: Cs1262Loadfw failed", __func__);
192 return HDF_FAILURE;
193 }
194
195 ret = Writefw(regTab);
196 if (ret != HDF_SUCCESS) {
197 HDF_LOGE("%s: Writefw failed", __func__);
198 return HDF_FAILURE;
199 }
200
201 drvData->regMode = mode;
202
203 HDF_LOGI("%s: set mode success", __func__);
204
205 return HDF_SUCCESS;
206 }
207
Cs1262ReadData(uint8_t * outBuf,uint16_t outBufMaxLen,uint16_t * outLen)208 static int32_t Cs1262ReadData(uint8_t *outBuf, uint16_t outBufMaxLen, uint16_t *outLen)
209 {
210 uint8_t ret;
211 uint16_t ifr = 0;
212 CHECK_NULL_PTR_RETURN_VALUE(outBuf, HDF_ERR_INVALID_PARAM);
213
214 ret = Cs1262ReadRegs(CS1262_IFR_REG, &ifr, 1);
215 if (ret != HDF_SUCCESS) {
216 HDF_LOGE("%s: Cs1262ReadRegs CS1262_IFR_REG fail", __func__);
217 return HDF_FAILURE;
218 }
219
220 if (ifr & IFR_RDY_FLAG) {
221 ret = ReadFifo(outBuf, outBufMaxLen, outLen);
222 if (ret != HDF_SUCCESS) {
223 HDF_LOGE("%s: ReadFifo fail", __func__);
224 }
225
226 ret = ClearIFR(FIFO_RDY_IFR_OFFSET);
227 if (ret != HDF_SUCCESS) {
228 HDF_LOGE("%s: ClearIFR fail", __func__);
229 return HDF_FAILURE;
230 }
231 }
232 return HDF_SUCCESS;
233 }
234
Cs1262Enable()235 static int32_t Cs1262Enable()
236 {
237 int32_t ret;
238 struct Cs1262DrvData *drvData = GetDrvData();
239 CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
240
241 if (drvData->regMode == NONE_MODE) {
242 HDF_LOGW("%s: drvData->regMode == NONE_MODE, need set default mode when enable", __func__);
243 if (Cs1262SetMode(DEFAULT_MODE) != HDF_SUCCESS) {
244 HDF_LOGE("%s: set default mode failed", __func__);
245 return HDF_FAILURE;
246 }
247 }
248
249 if (RegLock(CS1262_REG_UNLOCK) != HDF_SUCCESS) {
250 HDF_LOGE("%s: reg unlock failed", __func__);
251 return HDF_FAILURE;
252 }
253
254 ret = SetIER(FIFO_RDY_IER_OFFSET, CS1262_REG_BIT_SET);
255 if (ret != HDF_SUCCESS) {
256 HDF_LOGE("%s: Cs1262Enable fail", __func__);
257 return HDF_FAILURE;
258 }
259
260 ret = ResetModule(CS1262_TE_RST_OFFSET);
261 if (ret != HDF_SUCCESS) {
262 HDF_LOGE("%s: reset failed", __func__);
263 return HDF_FAILURE;
264 }
265
266 ret = Cs1262WriteRegbit(CS1262_TE_CTRL_REG, PRF_START_BIT, CS1262_REG_BIT_SET);
267 if (ret != HDF_SUCCESS) {
268 HDF_LOGE("%s: Cs1262WriteRegbit CS1262_TE_CTRL_REG fail", __func__);
269 return HDF_FAILURE;
270 }
271
272 if (RegLock(CS1262_REG_LOCK) != HDF_SUCCESS) {
273 HDF_LOGE("%s: reg lock failed", __func__);
274 return HDF_FAILURE;
275 }
276
277 return HDF_SUCCESS;
278 }
279
Cs1262Disable()280 static int32_t Cs1262Disable()
281 {
282 int32_t ret;
283
284 if (RegLock(CS1262_REG_UNLOCK) != HDF_SUCCESS) {
285 HDF_LOGE("%s: reg unlock failed", __func__);
286 return HDF_FAILURE;
287 }
288
289 ret = SetIER(FIFO_RDY_IER_OFFSET, CS1262_REG_BIT_RESET);
290 if (ret != HDF_SUCCESS) {
291 HDF_LOGE("%s: SetIER fail", __func__);
292 return HDF_FAILURE;
293 }
294
295 ret = Cs1262WriteRegbit(CS1262_TE_CTRL_REG, PRF_START_BIT, CS1262_REG_BIT_RESET);
296 HDF_LOGI("%s: Cs1262 disable ret = %d", __func__, ret);
297
298 if (RegLock(CS1262_REG_LOCK) != HDF_SUCCESS) {
299 HDF_LOGE("%s: reg unlock failed", __func__);
300 return HDF_FAILURE;
301 }
302
303 return ret;
304 }
305
InitChip()306 static int32_t InitChip()
307 {
308 (void)Cs1262SetMode(NONE_MODE);
309 return ResetChip();
310 }
311
CheckChipId(struct PpgCfgData * cfgData)312 static int32_t CheckChipId(struct PpgCfgData *cfgData)
313 {
314 uint16_t regRead = 0;
315 uint8_t cnt = 0;
316
317 uint16_t reg = cfgData->sensorCfg.sensorAttr.chipIdReg;
318 uint16_t val = cfgData->sensorCfg.sensorAttr.chipIdValue;
319
320 // retry 3 times
321 while (cnt++ < 3) {
322 if ((Cs1262ReadRegs(reg, ®Read, 1) == HDF_SUCCESS) && (regRead == val)) {
323 HDF_LOGI("%s: cs1262 read chip id success!", __func__);
324 return HDF_SUCCESS;
325 }
326 }
327
328 HDF_LOGE("%s: cs1262 read chip id fail, reg=%u!", __func__, reg);
329 return HDF_FAILURE;
330 }
331
DispatchCs1262(struct HdfDeviceIoClient * client,int cmd,struct HdfSBuf * data,struct HdfSBuf * reply)332 static int32_t DispatchCs1262(struct HdfDeviceIoClient *client,
333 int cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
334 {
335 (void)client;
336 (void)cmd;
337 (void)data;
338 (void)reply;
339
340 return HDF_SUCCESS;
341 }
342
Cs1262BindDriver(struct HdfDeviceObject * device)343 static int32_t Cs1262BindDriver(struct HdfDeviceObject *device)
344 {
345 CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
346
347 struct Cs1262DrvData *drvData = (struct Cs1262DrvData *)OsalMemCalloc(sizeof(*drvData));
348 CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_MALLOC_FAIL);
349 (void)memset_s(drvData, sizeof(struct Cs1262DrvData), 0, sizeof(struct Cs1262DrvData));
350
351 drvData->ioService.Dispatch = DispatchCs1262;
352 drvData->device = device;
353 device->service = &drvData->ioService;
354 g_cs1262DrvData = drvData;
355
356 return HDF_SUCCESS;
357 }
358
Cs1262InitDriver(struct HdfDeviceObject * device)359 static int32_t Cs1262InitDriver(struct HdfDeviceObject *device)
360 {
361 int32_t ret;
362 CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_PARAM);
363 struct Cs1262DrvData *drvData = (struct Cs1262DrvData *)device->service;
364 CHECK_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM);
365
366 ret = ParsePpgCfgData(device->property, &(drvData->ppgCfg));
367 if ((ret != HDF_SUCCESS) || (drvData->ppgCfg == NULL)) {
368 HDF_LOGE("%s: cs1262 construct fail!", __func__);
369 return HDF_FAILURE;
370 }
371
372 ret = Cs1262InitSpi(&drvData->ppgCfg->sensorCfg.busCfg);
373 if (ret != HDF_SUCCESS) {
374 HDF_LOGE("%s: cs1262 init spi!", __func__);
375 return HDF_FAILURE;
376 }
377
378 ret = CheckChipId(drvData->ppgCfg);
379 if (ret != HDF_SUCCESS) {
380 HDF_LOGE("%s: cs1262 check chip fail!", __func__);
381 return HDF_FAILURE;
382 }
383
384 ret = InitChip();
385 if (ret != HDF_SUCCESS) {
386 HDF_LOGE("%s: cs1262 init chip fail!", __func__);
387 return HDF_FAILURE;
388 }
389
390 struct PpgChipData chipData = {
391 .cfgData = drvData->ppgCfg,
392 .opsCall = {
393 .ReadData = Cs1262ReadData,
394 .Enable = Cs1262Enable,
395 .Disable = Cs1262Disable,
396 .SetOption = Cs1262SetOption,
397 .SetMode = Cs1262SetMode,
398 }
399 };
400
401 ret = RegisterPpgChip(&chipData);
402 if (ret != HDF_SUCCESS) {
403 HDF_LOGE("%s: Register CS1262 failed", __func__);
404 return HDF_FAILURE;
405 }
406
407 HDF_LOGI("%s: cs1262 init driver success", __func__);
408 return HDF_SUCCESS;
409 }
410
Cs1262ReleaseDriver(struct HdfDeviceObject * device)411 static void Cs1262ReleaseDriver(struct HdfDeviceObject *device)
412 {
413 CHECK_NULL_PTR_RETURN(device);
414 struct Cs1262DrvData *drvData = (struct Cs1262DrvData *)device->service;
415 CHECK_NULL_PTR_RETURN(drvData);
416 CHECK_NULL_PTR_RETURN(drvData->ppgCfg);
417
418 Cs1262ReleaseSpi(&drvData->ppgCfg->sensorCfg.busCfg);
419 (void)memset_s(drvData, sizeof(struct Cs1262DrvData), 0, sizeof(struct Cs1262DrvData));
420 OsalMemFree(drvData);
421 }
422
423 struct HdfDriverEntry g_ppgCs1262DevEntry = {
424 .moduleVersion = CS1262_MODULE_VER,
425 .moduleName = "HDF_SENSOR_PPG_CS1262",
426 .Bind = Cs1262BindDriver,
427 .Init = Cs1262InitDriver,
428 .Release = Cs1262ReleaseDriver,
429 };
430
431 HDF_INIT(g_ppgCs1262DevEntry);
432