1094332d3Sopenharmony_ci/*
2094332d3Sopenharmony_ci * Copyright (c) 2022 Chipsea Technologies (Shenzhen) Corp., Ltd.
3094332d3Sopenharmony_ci *
4094332d3Sopenharmony_ci * HDF is dual licensed: you can use it either under the terms of
5094332d3Sopenharmony_ci * the GPL, or the BSD license, at your option.
6094332d3Sopenharmony_ci * See the LICENSE file in the root of this repository for complete details.
7094332d3Sopenharmony_ci */
8094332d3Sopenharmony_ci
9094332d3Sopenharmony_ci#include <securec.h>
10094332d3Sopenharmony_ci#include "osal_file.h"
11094332d3Sopenharmony_ci#include "hdf_log.h"
12094332d3Sopenharmony_ci#include "ppg_cs1262.h"
13094332d3Sopenharmony_ci
14094332d3Sopenharmony_ci#define PPG_CONFIG_START_MAGIC 0x1262
15094332d3Sopenharmony_ci#define HDF_LOG_TAG hdf_sensor_cs1262_fw
16094332d3Sopenharmony_ci#define REG_TAB_INDEX_HALF 2
17094332d3Sopenharmony_ci
18094332d3Sopenharmony_cistatic Cs1262RegConfigTab g_heartRegTab = {
19094332d3Sopenharmony_ci    0x1262,
20094332d3Sopenharmony_ci    0x0020,
21094332d3Sopenharmony_ci    {
22094332d3Sopenharmony_ci        0x0029, 0x473D, 0x003D, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
23094332d3Sopenharmony_ci        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
24094332d3Sopenharmony_ci        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
25094332d3Sopenharmony_ci        0x0000, 0x0000, 0x0000, 0x0000
26094332d3Sopenharmony_ci    },
27094332d3Sopenharmony_ci    {
28094332d3Sopenharmony_ci        0x02C2, 0x0040, 0x0080, 0x0020, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
29094332d3Sopenharmony_ci        0x0000, 0x00FF, 0xFFFF
30094332d3Sopenharmony_ci    },
31094332d3Sopenharmony_ci    {
32094332d3Sopenharmony_ci        0x4224, 0x2224, 0x2222, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
33094332d3Sopenharmony_ci        0x0600, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
34094332d3Sopenharmony_ci        0x7000, 0x0050, 0x70A0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
35094332d3Sopenharmony_ci        0x7028, 0x0050, 0x70C8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
36094332d3Sopenharmony_ci        0x7028, 0x0028, 0x00A0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
37094332d3Sopenharmony_ci        0x7000, 0x00F0, 0x70A0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
38094332d3Sopenharmony_ci        0x0010, 0x0000, 0x0000, 0x0000, 0x0000
39094332d3Sopenharmony_ci    },
40094332d3Sopenharmony_ci    {
41094332d3Sopenharmony_ci        0x0300, 0x0000, 0x0000, 0x0500, 0x000A, 0x0001, 0x0000, 0x0000, 0x0000, 0x1E0F, 0x0002, 0x0028,
42094332d3Sopenharmony_ci        0x579E, 0x579E, 0x579E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
43094332d3Sopenharmony_ci        0x0840, 0x0800, 0x0800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
44094332d3Sopenharmony_ci        0x0000, 0x0000
45094332d3Sopenharmony_ci    },
46094332d3Sopenharmony_ci    {
47094332d3Sopenharmony_ci        0x6160, 0x0020, 0x0202, 0x0000, 0x2200, 0x7FFF, 0x00C0, 0x01F4, 0x0000, 0x0000, 0x0000, 0x0000,
48094332d3Sopenharmony_ci        0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
49094332d3Sopenharmony_ci        0x0000
50094332d3Sopenharmony_ci    },
51094332d3Sopenharmony_ci    {
52094332d3Sopenharmony_ci        0x0429, 0x0000, 0x0064, 0x000A, 0x0002, 0x0882, 0x00DF, 0x0223, 0x0002, 0x0000,
53094332d3Sopenharmony_ci    },
54094332d3Sopenharmony_ci    0x00F9
55094332d3Sopenharmony_ci};
56094332d3Sopenharmony_ci
57094332d3Sopenharmony_cistatic struct PpgModeTab g_ppgModeTab[] = {
58094332d3Sopenharmony_ci    { .mode = HEART_RATE_MODE, .regTab = &g_heartRegTab },
59094332d3Sopenharmony_ci};
60094332d3Sopenharmony_ci
61094332d3Sopenharmony_cistatic int32_t validateTab(uint8_t *regTab, uint16_t valiSize)
62094332d3Sopenharmony_ci{
63094332d3Sopenharmony_ci    uint8_t checksum = 0;
64094332d3Sopenharmony_ci    uint16_t index = 0;
65094332d3Sopenharmony_ci
66094332d3Sopenharmony_ci    if (((uint16_t *)regTab)[0] != PPG_CONFIG_START_MAGIC) {
67094332d3Sopenharmony_ci        HDF_LOGE("%s: validateTab invalid", __func__);
68094332d3Sopenharmony_ci        return HDF_FAILURE;
69094332d3Sopenharmony_ci    }
70094332d3Sopenharmony_ci
71094332d3Sopenharmony_ci    /* real checksum stored in the last 2 bytes, needs to be removed during calculation */
72094332d3Sopenharmony_ci    for (index = 0; index < valiSize - 2; index++) {
73094332d3Sopenharmony_ci        checksum += regTab[index];
74094332d3Sopenharmony_ci    }
75094332d3Sopenharmony_ci
76094332d3Sopenharmony_ci    /* real checksum stored in the last 2 bytes, and one item of regTab has 2 bytes,
77094332d3Sopenharmony_ci     * needs to be divided by 2 when calculating the real checksum's index.
78094332d3Sopenharmony_ci     */
79094332d3Sopenharmony_ci    index = (valiSize / REG_TAB_INDEX_HALF) - 1;
80094332d3Sopenharmony_ci    return (checksum == ((uint16_t *)regTab)[index]) ? HDF_SUCCESS : HDF_FAILURE;
81094332d3Sopenharmony_ci}
82094332d3Sopenharmony_ci
83094332d3Sopenharmony_ciint32_t Cs1262Loadfw(enum PpgMode mode, Cs1262RegConfigTab **configTab)
84094332d3Sopenharmony_ci{
85094332d3Sopenharmony_ci    int32_t ret;
86094332d3Sopenharmony_ci
87094332d3Sopenharmony_ci    for (uint8_t index = 0; index < HDF_ARRAY_SIZE(g_ppgModeTab); index++) {
88094332d3Sopenharmony_ci        if (g_ppgModeTab[index].mode == mode) {
89094332d3Sopenharmony_ci            ret = validateTab((uint8_t *)(g_ppgModeTab[index].regTab), sizeof(*g_ppgModeTab[index].regTab));
90094332d3Sopenharmony_ci            if (ret != HDF_SUCCESS) {
91094332d3Sopenharmony_ci                HDF_LOGE("%s: validateTab fail mode = %d", __func__, mode);
92094332d3Sopenharmony_ci                return HDF_FAILURE;
93094332d3Sopenharmony_ci            }
94094332d3Sopenharmony_ci            *configTab = g_ppgModeTab[index].regTab;
95094332d3Sopenharmony_ci            HDF_LOGI("%s: load success", __func__);
96094332d3Sopenharmony_ci            return HDF_SUCCESS;
97094332d3Sopenharmony_ci        }
98094332d3Sopenharmony_ci    }
99094332d3Sopenharmony_ci    HDF_LOGE("%s: Cs1262Loadfw not match, mode = %d", __func__, mode);
100094332d3Sopenharmony_ci    return HDF_FAILURE;
101094332d3Sopenharmony_ci}
102