1 /******************************************************************************
2  *
3  * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
4  * Analog Devices, Inc.),
5  * Copyright (C) 2023-2024 Analog Devices, Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************************/
20 
21 /* **** Includes **** */
22 #include <stdint.h>
23 #include "mxc_sys.h"
24 #include "mxc_errors.h"
25 #include "mxc_device.h"
26 #include "mxc_assert.h"
27 #include "otp.h"
28 #include "otp_reva.h"
29 
30 /* **** Functions **** */
31 
MXC_OTP_Init(mxc_otp_clkdiv_t pclkdiv)32 int MXC_OTP_Init(mxc_otp_clkdiv_t pclkdiv)
33 {
34     int lowest_pclkdiv_int;
35     int lowest_pclkdiv_dec;
36 
37     // Divide by 16 is default divider value.
38     if (pclkdiv < MXC_OTP_CLK_DIV2 || pclkdiv > MXC_OTP_CLK_DIV32) {
39         pclkdiv = MXC_OTP_CLK_DIV16;
40     }
41 
42     MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_OTP);
43 
44     // Note: mxc_otp_clkdiv_t values based on predefined register definitions.
45 
46     // Verify minimum timing requirement for OTP Controller. (>=400ns) Check UG.
47     // Note: mxc_otp_clkdiv_t values based on predefined register definitions.
48     //  For example: pclkdiv = MXC_OTP_CLK_DIV2 = 0x01
49     //  Divider value = pclkdiv + 1
50     //  Divide by 2 = MXC_OTP_CLK_DIV2 + 1 = 0x01 + 1
51     lowest_pclkdiv_int = (PeripheralClock / 2500000); // (1 / (400ns)) = 2,500,000
52 
53     // Do not truncate down if equation above doesn't perfectly divide out.
54     lowest_pclkdiv_dec = (100 * PeripheralClock / 2500000) - lowest_pclkdiv_int;
55     if (lowest_pclkdiv_dec > 0) {
56         lowest_pclkdiv_int += 1;
57     }
58 
59     // Get raw clkdiv value. Divider value = pclkdiv + 1
60     lowest_pclkdiv_int -= 1;
61 
62     if (pclkdiv < lowest_pclkdiv_int) {
63         return E_BAD_PARAM;
64     }
65 
66     return MXC_OTP_RevA_Init((mxc_otp_reva_regs_t *)MXC_OTP, pclkdiv);
67 }
68 
MXC_OTP_IsLocked(void)69 int MXC_OTP_IsLocked(void)
70 {
71     return MXC_OTP_RevA_IsLocked((mxc_otp_reva_regs_t *)MXC_OTP);
72 }
73 
MXC_OTP_Unlock(void)74 void MXC_OTP_Unlock(void)
75 {
76     MXC_OTP_RevA_Unlock((mxc_otp_reva_regs_t *)MXC_OTP);
77 }
78 
MXC_OTP_Lock(void)79 void MXC_OTP_Lock(void)
80 {
81     MXC_OTP_RevA_Lock((mxc_otp_reva_regs_t *)MXC_OTP);
82 }
83 
MXC_OTP_Write(uint16_t addr,uint32_t * data,uint16_t size)84 int MXC_OTP_Write(uint16_t addr, uint32_t *data, uint16_t size)
85 {
86     return MXC_OTP_RevA_Write((mxc_otp_reva_regs_t *)MXC_OTP, addr, data, size);
87 }
88 
MXC_OTP_Write32(uint16_t addr,uint32_t data)89 int MXC_OTP_Write32(uint16_t addr, uint32_t data)
90 {
91     return MXC_OTP_RevA_Write32((mxc_otp_reva_regs_t *)MXC_OTP, addr, data);
92 }
93 
MXC_OTP_Read(uint16_t addr,uint32_t * data,uint16_t size)94 int MXC_OTP_Read(uint16_t addr, uint32_t *data, uint16_t size)
95 {
96     return MXC_OTP_RevA_Read((mxc_otp_reva_regs_t *)MXC_OTP, addr, data, size);
97 }
98 
MXC_OTP_Read32(uint16_t addr,uint32_t * data)99 int MXC_OTP_Read32(uint16_t addr, uint32_t *data)
100 {
101     return MXC_OTP_RevA_Read32((mxc_otp_reva_regs_t *)MXC_OTP, addr, data);
102 }
103