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, &regRead, 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, &regTab);
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, &regRead, 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