1 /*
2  * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdlib.h>
8 #include "esp_bit_defs.h"
9 #include "esp_rom_caps.h"
10 #include "esp_attr.h"
11 #include "sdkconfig.h"
12 
13 #include "soc/syscon_reg.h"
14 
15 #define I2C_RTC_WIFI_CLK_EN (SYSCON_WIFI_CLK_EN_REG)
16 
17 #define I2C_RTC_CLK_GATE_EN    (BIT(18))
18 #define I2C_RTC_CLK_GATE_EN_M  (BIT(18))
19 #define I2C_RTC_CLK_GATE_EN_V  0x1
20 #define I2C_RTC_CLK_GATE_EN_S  18
21 
22 #define I2C_RTC_CONFIG0  0x6000e048
23 
24 #define I2C_RTC_MAGIC_CTRL 0x00001FFF
25 #define I2C_RTC_MAGIC_CTRL_M  ((I2C_RTC_MAGIC_CTRL_V)<<(I2C_RTC_MAGIC_CTRL_S))
26 #define I2C_RTC_MAGIC_CTRL_V  0x1FFF
27 #define I2C_RTC_MAGIC_CTRL_S  4
28 
29 #define I2C_RTC_CONFIG1  0x6000e044
30 
31 #define I2C_RTC_BOD_MASK (BIT(22))
32 #define I2C_RTC_BOD_MASK_M  (BIT(22))
33 #define I2C_RTC_BOD_MASK_V  0x1
34 #define I2C_RTC_BOD_MASK_S  22
35 
36 #define I2C_RTC_SAR_MASK (BIT(18))
37 #define I2C_RTC_SAR_MASK_M  (BIT(18))
38 #define I2C_RTC_SAR_MASK_V  0x1
39 #define I2C_RTC_SAR_MASK_S  18
40 
41 #define I2C_RTC_BBPLL_MASK (BIT(17))
42 #define I2C_RTC_BBPLL_MASK_M  (BIT(17))
43 #define I2C_RTC_BBPLL_MASK_V  0x1
44 #define I2C_RTC_BBPLL_MASK_S  17
45 
46 #define I2C_RTC_APLL_MASK (BIT(14))
47 #define I2C_RTC_APLL_MASK_M  (BIT(14))
48 #define I2C_RTC_APLL_MASK_V  0x1
49 #define I2C_RTC_APLL_MASK_S  14
50 
51 #define I2C_RTC_ALL_MASK 0x00007FFF
52 #define I2C_RTC_ALL_MASK_M  ((I2C_RTC_ALL_MASK_V)<<(I2C_RTC_ALL_MASK_S))
53 #define I2C_RTC_ALL_MASK_V  0x7FFF
54 #define I2C_RTC_ALL_MASK_S  8
55 
56 #define I2C_RTC_CONFIG2  0x6000e000
57 
58 #define I2C_RTC_BUSY (BIT(25))
59 #define I2C_RTC_BUSY_M  (BIT(25))
60 #define I2C_RTC_BUSY_V  0x1
61 #define I2C_RTC_BUSY_S  25
62 
63 #define I2C_RTC_WR_CNTL (BIT(24))
64 #define I2C_RTC_WR_CNTL_M  (BIT(24))
65 #define I2C_RTC_WR_CNTL_V  0x1
66 #define I2C_RTC_WR_CNTL_S  24
67 
68 #define I2C_RTC_DATA 0x000000FF
69 #define I2C_RTC_DATA_M  ((I2C_RTC_DATA_V)<<(I2C_RTC_DATA_S))
70 #define I2C_RTC_DATA_V  0xFF
71 #define I2C_RTC_DATA_S  16
72 
73 #define I2C_RTC_ADDR 0x000000FF
74 #define I2C_RTC_ADDR_M  ((I2C_RTC_ADDR_V)<<(I2C_RTC_ADDR_S))
75 #define I2C_RTC_ADDR_V  0xFF
76 #define I2C_RTC_ADDR_S  8
77 
78 #define I2C_RTC_SLAVE_ID 0x000000FF
79 #define I2C_RTC_SLAVE_ID_M  ((I2C_RTC_SLAVE_ID_V)<<(I2C_RTC_SLAVE_ID_S))
80 #define I2C_RTC_SLAVE_ID_V  0xFF
81 #define I2C_RTC_SLAVE_ID_S  0
82 
83 #define I2C_RTC_MAGIC_DEFAULT (0x1c40)
84 
85 #define I2C_BOD     0x61
86 #define I2C_BBPLL   0x66
87 #define I2C_SAR_ADC 0X69
88 #define I2C_APLL    0X6D
89 
i2c_rtc_enable_block(uint8_t block)90 static IRAM_ATTR void i2c_rtc_enable_block(uint8_t block)
91 {
92     REG_SET_FIELD(I2C_RTC_CONFIG0, I2C_RTC_MAGIC_CTRL, I2C_RTC_MAGIC_DEFAULT);
93     REG_SET_FIELD(I2C_RTC_CONFIG1, I2C_RTC_ALL_MASK, I2C_RTC_ALL_MASK_V);
94     REG_SET_BIT(I2C_RTC_WIFI_CLK_EN, I2C_RTC_CLK_GATE_EN);
95     switch (block) {
96     case I2C_APLL:
97         REG_CLR_BIT(I2C_RTC_CONFIG1, I2C_RTC_APLL_MASK);
98         break;
99     case I2C_BBPLL:
100         REG_CLR_BIT(I2C_RTC_CONFIG1, I2C_RTC_BBPLL_MASK);
101         break;
102     case I2C_SAR_ADC:
103         REG_CLR_BIT(I2C_RTC_CONFIG1, I2C_RTC_SAR_MASK);
104         break;
105     case I2C_BOD:
106         REG_CLR_BIT(I2C_RTC_CONFIG1, I2C_RTC_BOD_MASK);
107         break;
108     }
109 }
110 
esp_rom_regi2c_read(uint8_t block,uint8_t host_id,uint8_t reg_add)111 uint8_t IRAM_ATTR esp_rom_regi2c_read(uint8_t block, uint8_t host_id, uint8_t reg_add)
112 {
113     i2c_rtc_enable_block(block);
114 
115     uint32_t temp = ((block & I2C_RTC_SLAVE_ID_V) << I2C_RTC_SLAVE_ID_S)
116                     | (reg_add & I2C_RTC_ADDR_V) << I2C_RTC_ADDR_S;
117     REG_WRITE(I2C_RTC_CONFIG2, temp);
118     while (REG_GET_BIT(I2C_RTC_CONFIG2, I2C_RTC_BUSY));
119     return REG_GET_FIELD(I2C_RTC_CONFIG2, I2C_RTC_DATA);
120 }
121 
esp_rom_regi2c_read_mask(uint8_t block,uint8_t host_id,uint8_t reg_add,uint8_t msb,uint8_t lsb)122 uint8_t IRAM_ATTR esp_rom_regi2c_read_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb)
123 {
124     assert(msb - lsb < 8);
125     i2c_rtc_enable_block(block);
126 
127     uint32_t temp = ((block & I2C_RTC_SLAVE_ID_V) << I2C_RTC_SLAVE_ID_S)
128                     | (reg_add & I2C_RTC_ADDR_V) << I2C_RTC_ADDR_S;
129     REG_WRITE(I2C_RTC_CONFIG2, temp);
130     while (REG_GET_BIT(I2C_RTC_CONFIG2, I2C_RTC_BUSY));
131     uint32_t data = REG_GET_FIELD(I2C_RTC_CONFIG2, I2C_RTC_DATA);
132     return (uint8_t)((data >> lsb) & (~(0xFFFFFFFF << (msb - lsb + 1))));
133 }
134 
esp_rom_regi2c_write(uint8_t block,uint8_t host_id,uint8_t reg_add,uint8_t data)135 void IRAM_ATTR esp_rom_regi2c_write(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data)
136 {
137     i2c_rtc_enable_block(block);
138 
139     uint32_t temp = ((block & I2C_RTC_SLAVE_ID_V) << I2C_RTC_SLAVE_ID_S)
140                     | ((reg_add & I2C_RTC_ADDR_V) << I2C_RTC_ADDR_S)
141                     | ((0x1 & I2C_RTC_WR_CNTL_V) << I2C_RTC_WR_CNTL_S)
142                     | (((uint32_t)data & I2C_RTC_DATA_V) << I2C_RTC_DATA_S);
143     REG_WRITE(I2C_RTC_CONFIG2, temp);
144     while (REG_GET_BIT(I2C_RTC_CONFIG2, I2C_RTC_BUSY));
145 }
146 
esp_rom_regi2c_write_mask(uint8_t block,uint8_t host_id,uint8_t reg_add,uint8_t msb,uint8_t lsb,uint8_t data)147 void IRAM_ATTR esp_rom_regi2c_write_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data)
148 {
149     assert(msb - lsb < 8);
150     i2c_rtc_enable_block(block);
151 
152     /*Read the i2c bus register*/
153     uint32_t temp = ((block & I2C_RTC_SLAVE_ID_V) << I2C_RTC_SLAVE_ID_S)
154                     | (reg_add & I2C_RTC_ADDR_V) << I2C_RTC_ADDR_S;
155     REG_WRITE(I2C_RTC_CONFIG2, temp);
156     while (REG_GET_BIT(I2C_RTC_CONFIG2, I2C_RTC_BUSY));
157     temp = REG_GET_FIELD(I2C_RTC_CONFIG2, I2C_RTC_DATA);
158     /*Write the i2c bus register*/
159     temp &= ((~(0xFFFFFFFF << lsb)) | (0xFFFFFFFF << (msb + 1)));
160     temp = (((uint32_t)data & (~(0xFFFFFFFF << (msb - lsb + 1)))) << lsb) | temp;
161     temp = ((block & I2C_RTC_SLAVE_ID_V) << I2C_RTC_SLAVE_ID_S)
162             | ((reg_add & I2C_RTC_ADDR_V) << I2C_RTC_ADDR_S)
163             | ((0x1 & I2C_RTC_WR_CNTL_V) << I2C_RTC_WR_CNTL_S)
164             | ((temp & I2C_RTC_DATA_V) << I2C_RTC_DATA_S);
165     REG_WRITE(I2C_RTC_CONFIG2, temp);
166     while (REG_GET_BIT(I2C_RTC_CONFIG2, I2C_RTC_BUSY));
167 }
168