1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #define USE_HW_I2C |
3 | #ifdef USE_HW_I2C |
4 | #include "ddk750_chip.h" |
5 | #include "ddk750_reg.h" |
6 | #include "ddk750_hwi2c.h" |
7 | #include "ddk750_power.h" |
8 | |
9 | #define MAX_HWI2C_FIFO 16 |
10 | #define HWI2C_WAIT_TIMEOUT 0xF0000 |
11 | |
12 | int sm750_hw_i2c_init(unsigned char bus_speed_mode) |
13 | { |
14 | unsigned int value; |
15 | |
16 | /* Enable GPIO 30 & 31 as IIC clock & data */ |
17 | value = peek32(GPIO_MUX); |
18 | |
19 | value |= (GPIO_MUX_30 | GPIO_MUX_31); |
20 | poke32(GPIO_MUX, data: value); |
21 | |
22 | /* |
23 | * Enable Hardware I2C power. |
24 | * TODO: Check if we need to enable GPIO power? |
25 | */ |
26 | sm750_enable_i2c(enable: 1); |
27 | |
28 | /* Enable the I2C Controller and set the bus speed mode */ |
29 | value = peek32(I2C_CTRL) & ~(I2C_CTRL_MODE | I2C_CTRL_EN); |
30 | if (bus_speed_mode) |
31 | value |= I2C_CTRL_MODE; |
32 | value |= I2C_CTRL_EN; |
33 | poke32(I2C_CTRL, data: value); |
34 | |
35 | return 0; |
36 | } |
37 | |
38 | void sm750_hw_i2c_close(void) |
39 | { |
40 | unsigned int value; |
41 | |
42 | /* Disable I2C controller */ |
43 | value = peek32(I2C_CTRL) & ~I2C_CTRL_EN; |
44 | poke32(I2C_CTRL, data: value); |
45 | |
46 | /* Disable I2C Power */ |
47 | sm750_enable_i2c(enable: 0); |
48 | |
49 | /* Set GPIO 30 & 31 back as GPIO pins */ |
50 | value = peek32(GPIO_MUX); |
51 | value &= ~GPIO_MUX_30; |
52 | value &= ~GPIO_MUX_31; |
53 | poke32(GPIO_MUX, data: value); |
54 | } |
55 | |
56 | static long hw_i2c_wait_tx_done(void) |
57 | { |
58 | unsigned int timeout; |
59 | |
60 | /* Wait until the transfer is completed. */ |
61 | timeout = HWI2C_WAIT_TIMEOUT; |
62 | while (!(peek32(I2C_STATUS) & I2C_STATUS_TX) && (timeout != 0)) |
63 | timeout--; |
64 | |
65 | if (timeout == 0) |
66 | return -1; |
67 | |
68 | return 0; |
69 | } |
70 | |
71 | /* |
72 | * This function writes data to the i2c slave device registers. |
73 | * |
74 | * Parameters: |
75 | * addr - i2c Slave device address |
76 | * length - Total number of bytes to be written to the device |
77 | * buf - The buffer that contains the data to be written to the |
78 | * i2c device. |
79 | * |
80 | * Return Value: |
81 | * Total number of bytes those are actually written. |
82 | */ |
83 | static unsigned int hw_i2c_write_data(unsigned char addr, |
84 | unsigned int length, |
85 | unsigned char *buf) |
86 | { |
87 | unsigned char count, i; |
88 | unsigned int total_bytes = 0; |
89 | |
90 | /* Set the Device Address */ |
91 | poke32(I2C_SLAVE_ADDRESS, data: addr & ~0x01); |
92 | |
93 | /* |
94 | * Write data. |
95 | * Note: |
96 | * Only 16 byte can be accessed per i2c start instruction. |
97 | */ |
98 | do { |
99 | /* |
100 | * Reset I2C by writing 0 to I2C_RESET register to |
101 | * clear the previous status. |
102 | */ |
103 | poke32(I2C_RESET, data: 0); |
104 | |
105 | /* Set the number of bytes to be written */ |
106 | if (length < MAX_HWI2C_FIFO) |
107 | count = length - 1; |
108 | else |
109 | count = MAX_HWI2C_FIFO - 1; |
110 | poke32(I2C_BYTE_COUNT, data: count); |
111 | |
112 | /* Move the data to the I2C data register */ |
113 | for (i = 0; i <= count; i++) |
114 | poke32(I2C_DATA0 + i, data: *buf++); |
115 | |
116 | /* Start the I2C */ |
117 | poke32(I2C_CTRL, data: peek32(I2C_CTRL) | I2C_CTRL_CTRL); |
118 | |
119 | /* Wait until the transfer is completed. */ |
120 | if (hw_i2c_wait_tx_done() != 0) |
121 | break; |
122 | |
123 | /* Subtract length */ |
124 | length -= (count + 1); |
125 | |
126 | /* Total byte written */ |
127 | total_bytes += (count + 1); |
128 | |
129 | } while (length > 0); |
130 | |
131 | return total_bytes; |
132 | } |
133 | |
134 | /* |
135 | * This function reads data from the slave device and stores them |
136 | * in the given buffer |
137 | * |
138 | * Parameters: |
139 | * addr - i2c Slave device address |
140 | * length - Total number of bytes to be read |
141 | * buf - Pointer to a buffer to be filled with the data read |
142 | * from the slave device. It has to be the same size as the |
143 | * length to make sure that it can keep all the data read. |
144 | * |
145 | * Return Value: |
146 | * Total number of actual bytes read from the slave device |
147 | */ |
148 | static unsigned int hw_i2c_read_data(unsigned char addr, |
149 | unsigned int length, |
150 | unsigned char *buf) |
151 | { |
152 | unsigned char count, i; |
153 | unsigned int total_bytes = 0; |
154 | |
155 | /* Set the Device Address */ |
156 | poke32(I2C_SLAVE_ADDRESS, data: addr | 0x01); |
157 | |
158 | /* |
159 | * Read data and save them to the buffer. |
160 | * Note: |
161 | * Only 16 byte can be accessed per i2c start instruction. |
162 | */ |
163 | do { |
164 | /* |
165 | * Reset I2C by writing 0 to I2C_RESET register to |
166 | * clear all the status. |
167 | */ |
168 | poke32(I2C_RESET, data: 0); |
169 | |
170 | /* Set the number of bytes to be read */ |
171 | if (length <= MAX_HWI2C_FIFO) |
172 | count = length - 1; |
173 | else |
174 | count = MAX_HWI2C_FIFO - 1; |
175 | poke32(I2C_BYTE_COUNT, data: count); |
176 | |
177 | /* Start the I2C */ |
178 | poke32(I2C_CTRL, data: peek32(I2C_CTRL) | I2C_CTRL_CTRL); |
179 | |
180 | /* Wait until transaction done. */ |
181 | if (hw_i2c_wait_tx_done() != 0) |
182 | break; |
183 | |
184 | /* Save the data to the given buffer */ |
185 | for (i = 0; i <= count; i++) |
186 | *buf++ = peek32(I2C_DATA0 + i); |
187 | |
188 | /* Subtract length by 16 */ |
189 | length -= (count + 1); |
190 | |
191 | /* Number of bytes read. */ |
192 | total_bytes += (count + 1); |
193 | |
194 | } while (length > 0); |
195 | |
196 | return total_bytes; |
197 | } |
198 | |
199 | /* |
200 | * This function reads the slave device's register |
201 | * |
202 | * Parameters: |
203 | * deviceAddress - i2c Slave device address which register |
204 | * to be read from |
205 | * registerIndex - Slave device's register to be read |
206 | * |
207 | * Return Value: |
208 | * Register value |
209 | */ |
210 | unsigned char sm750_hw_i2c_read_reg(unsigned char addr, unsigned char reg) |
211 | { |
212 | unsigned char value = 0xFF; |
213 | |
214 | if (hw_i2c_write_data(addr, length: 1, buf: ®) == 1) |
215 | hw_i2c_read_data(addr, length: 1, buf: &value); |
216 | |
217 | return value; |
218 | } |
219 | |
220 | /* |
221 | * This function writes a value to the slave device's register |
222 | * |
223 | * Parameters: |
224 | * deviceAddress - i2c Slave device address which register |
225 | * to be written |
226 | * registerIndex - Slave device's register to be written |
227 | * data - Data to be written to the register |
228 | * |
229 | * Result: |
230 | * 0 - Success |
231 | * -1 - Fail |
232 | */ |
233 | int sm750_hw_i2c_write_reg(unsigned char addr, |
234 | unsigned char reg, |
235 | unsigned char data) |
236 | { |
237 | unsigned char value[2]; |
238 | |
239 | value[0] = reg; |
240 | value[1] = data; |
241 | if (hw_i2c_write_data(addr, length: 2, buf: value) == 2) |
242 | return 0; |
243 | |
244 | return -1; |
245 | } |
246 | |
247 | #endif |
248 | |