1 /*
2 * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include "esp_rom_sys.h"
7 #include "esp_attr.h"
8 #include "soc/i2c_ana_mst_reg.h"
9 #include "modem/modem_lpcon_reg.h"
10 /**
11 * BB - 0x67 - BIT0
12 * TXRF - 0x6B - BIT1
13 * SDM - 0x63 - BIT2
14 * PLL - 0x62 - BIT3
15 * BIAS - 0x6A - BIT4
16 * BBPLL - 0x66 - BIT5
17 * ULP - 0x61 - BIT6
18 * SAR - 0x69 - BIT7
19 * PMU - 0x6d - BIT8
20 */
21
22 #define REGI2C_BIAS_MST_SEL (BIT(8))
23 #define REGI2C_BBPLL_MST_SEL (BIT(9))
24 #define REGI2C_ULP_CAL_MST_SEL (BIT(10))
25 #define REGI2C_SAR_I2C_MST_SEL (BIT(11))
26 #define REGI2C_DIG_REG_MST_SEL (BIT(12))
27
28 #define REGI2C_BIAS_RD_MASK (~BIT(6) & I2C_ANA_MST_ANA_CONF1_M)
29 #define REGI2C_BBPLL_RD_MASK (~BIT(7) & I2C_ANA_MST_ANA_CONF1_M)
30 #define REGI2C_ULP_CAL_RD_MASK (~BIT(8) & I2C_ANA_MST_ANA_CONF1_M)
31 #define REGI2C_SAR_I2C_RD_MASK (~BIT(9) & I2C_ANA_MST_ANA_CONF1_M)
32 #define REGI2C_DIG_REG_RD_MASK (~BIT(10) & I2C_ANA_MST_ANA_CONF1_M)
33
34 #define I2C_ANA_MST_I2C_CTRL_REG(n) (I2C_ANA_MST_I2C0_CTRL_REG + n*4) // 0: I2C_ANA_MST_I2C0_CTRL_REG; 1: I2C_ANA_MST_I2C1_CTRL_REG
35
36 #define REGI2C_RTC_BUSY (BIT(25))
37 #define REGI2C_RTC_BUSY_M (BIT(25))
38 #define REGI2C_RTC_BUSY_V 0x1
39 #define REGI2C_RTC_BUSY_S 25
40
41 #define REGI2C_RTC_WR_CNTL (BIT(24))
42 #define REGI2C_RTC_WR_CNTL_M (BIT(24))
43 #define REGI2C_RTC_WR_CNTL_V 0x1
44 #define REGI2C_RTC_WR_CNTL_S 24
45
46 #define REGI2C_RTC_DATA 0x000000FF
47 #define REGI2C_RTC_DATA_M ((I2C_RTC_DATA_V)<<(I2C_RTC_DATA_S))
48 #define REGI2C_RTC_DATA_V 0xFF
49 #define REGI2C_RTC_DATA_S 16
50
51 #define REGI2C_RTC_ADDR 0x000000FF
52 #define REGI2C_RTC_ADDR_M ((I2C_RTC_ADDR_V)<<(I2C_RTC_ADDR_S))
53 #define REGI2C_RTC_ADDR_V 0xFF
54 #define REGI2C_RTC_ADDR_S 8
55
56 #define REGI2C_RTC_SLAVE_ID 0x000000FF
57 #define REGI2C_RTC_SLAVE_ID_M ((I2C_RTC_SLAVE_ID_V)<<(I2C_RTC_SLAVE_ID_S))
58 #define REGI2C_RTC_SLAVE_ID_V 0xFF
59 #define REGI2C_RTC_SLAVE_ID_S 0
60
61 /* SLAVE */
62
63 #define REGI2C_BBPLL (0x66)
64 #define REGI2C_BBPLL_HOSTID 0
65
66 #define REGI2C_BIAS (0x6a)
67 #define REGI2C_BIAS_HOSTID 0
68
69 #define REGI2C_DIG_REG (0x6d)
70 #define REGI2C_DIG_REG_HOSTID 0
71
72 #define REGI2C_ULP_CAL (0x61)
73 #define REGI2C_ULP_CAL_HOSTID 0
74
75 #define REGI2C_SAR_I2C (0x69)
76 #define REGI2C_SAR_I2C_HOSTID 0
77
78 /* SLAVE END */
79
80 uint8_t esp_rom_regi2c_read(uint8_t block, uint8_t host_id, uint8_t reg_add) __attribute__((alias("regi2c_read_impl")));
81 uint8_t esp_rom_regi2c_read_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb) __attribute__((alias("regi2c_read_mask_impl")));
82 void esp_rom_regi2c_write(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data) __attribute__((alias("regi2c_write_impl")));
83 void 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) __attribute__((alias("regi2c_write_mask_impl")));
84
regi2c_enable_block(uint8_t block)85 static IRAM_ATTR uint8_t regi2c_enable_block(uint8_t block)
86 {
87 uint32_t i2c_sel = 0;
88
89 REG_SET_BIT(MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN);
90 REG_SET_BIT(MODEM_LPCON_I2C_MST_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_SEL_160M);
91
92 /* Before config I2C register, enable corresponding slave. */
93 switch (block) {
94 case REGI2C_BBPLL :
95 i2c_sel = REG_GET_BIT(I2C_ANA_MST_ANA_CONF2_REG, REGI2C_BBPLL_MST_SEL);
96 REG_WRITE(I2C_ANA_MST_ANA_CONF1_REG, REGI2C_BBPLL_RD_MASK);
97 break;
98 case REGI2C_BIAS :
99 i2c_sel = REG_GET_BIT(I2C_ANA_MST_ANA_CONF2_REG, REGI2C_BIAS_MST_SEL);
100 REG_WRITE(I2C_ANA_MST_ANA_CONF1_REG, REGI2C_BIAS_RD_MASK);
101 break;
102 case REGI2C_DIG_REG:
103 i2c_sel = REG_GET_BIT(I2C_ANA_MST_ANA_CONF2_REG, REGI2C_DIG_REG_MST_SEL);
104 REG_WRITE(I2C_ANA_MST_ANA_CONF1_REG, REGI2C_DIG_REG_RD_MASK);
105 break;
106 case REGI2C_ULP_CAL:
107 i2c_sel = REG_GET_BIT(I2C_ANA_MST_ANA_CONF2_REG, REGI2C_ULP_CAL_MST_SEL);
108 REG_WRITE(I2C_ANA_MST_ANA_CONF1_REG, REGI2C_ULP_CAL_RD_MASK);
109 break;
110 case REGI2C_SAR_I2C:
111 i2c_sel = REG_GET_BIT(I2C_ANA_MST_ANA_CONF2_REG, REGI2C_SAR_I2C_MST_SEL);
112 REG_WRITE(I2C_ANA_MST_ANA_CONF1_REG, REGI2C_SAR_I2C_RD_MASK);
113 break;
114 }
115
116 return (uint8_t)(i2c_sel ? 0: 1);
117 }
118
regi2c_read_impl(uint8_t block,uint8_t host_id,uint8_t reg_add)119 uint8_t IRAM_ATTR regi2c_read_impl(uint8_t block, uint8_t host_id, uint8_t reg_add)
120 {
121 (void)host_id;
122 uint8_t i2c_sel = regi2c_enable_block(block);
123
124 while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); // wait i2c idle
125 uint32_t temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S)
126 | (reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S;
127 REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp);
128 while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY));
129 uint8_t ret = REG_GET_FIELD(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_DATA);
130
131 return ret;
132 }
133
regi2c_read_mask_impl(uint8_t block,uint8_t host_id,uint8_t reg_add,uint8_t msb,uint8_t lsb)134 uint8_t IRAM_ATTR regi2c_read_mask_impl(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb)
135 {
136 assert(msb - lsb < 8);
137 uint8_t i2c_sel = regi2c_enable_block(block);
138
139 (void)host_id;
140 while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); // wait i2c idle
141 uint32_t temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S)
142 | (reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S;
143 REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp);
144 while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY));
145 uint32_t data = REG_GET_FIELD(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_DATA);
146 uint8_t ret = (uint8_t)((data >> lsb) & (~(0xFFFFFFFF << (msb - lsb + 1))));
147
148 return ret;
149 }
150
regi2c_write_impl(uint8_t block,uint8_t host_id,uint8_t reg_add,uint8_t data)151 void IRAM_ATTR regi2c_write_impl(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data)
152 {
153 (void)host_id;
154 uint8_t i2c_sel = regi2c_enable_block(block);
155
156 while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); // wait i2c idle
157 uint32_t temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S)
158 | ((reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S)
159 | ((0x1 & REGI2C_RTC_WR_CNTL_V) << REGI2C_RTC_WR_CNTL_S) // 0: READ I2C register; 1: Write I2C register;
160 | (((uint32_t)data & REGI2C_RTC_DATA_V) << REGI2C_RTC_DATA_S);
161 REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp);
162 while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY));
163
164 }
165
regi2c_write_mask_impl(uint8_t block,uint8_t host_id,uint8_t reg_add,uint8_t msb,uint8_t lsb,uint8_t data)166 void IRAM_ATTR regi2c_write_mask_impl(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data)
167 {
168 (void)host_id;
169 assert(msb - lsb < 8);
170 uint8_t i2c_sel = regi2c_enable_block(block);
171
172 while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY));
173 /*Read the i2c bus register*/
174 uint32_t temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S)
175 | (reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S;
176 REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp);
177 while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY));
178 temp = REG_GET_FIELD(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_DATA);
179 /*Write the i2c bus register*/
180 temp &= ((~(0xFFFFFFFF << lsb)) | (0xFFFFFFFF << (msb + 1)));
181 temp = (((uint32_t)data & (~(0xFFFFFFFF << (msb - lsb + 1)))) << lsb) | temp;
182 temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S)
183 | ((reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S)
184 | ((0x1 & REGI2C_RTC_WR_CNTL_V) << REGI2C_RTC_WR_CNTL_S)
185 | ((temp & REGI2C_RTC_DATA_V) << REGI2C_RTC_DATA_S);
186 REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp);
187 while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY));
188 }
189