Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
81dee67e SM |
2 | #define USE_HW_I2C |
3 | #ifdef USE_HW_I2C | |
efe9bc08 | 4 | #include "ddk750_chip.h" |
81dee67e SM |
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 | ||
c9750456 | 12 | int sm750_hw_i2c_init(unsigned char bus_speed_mode) |
81dee67e | 13 | { |
78376535 | 14 | unsigned int value; |
81dee67e | 15 | |
78376535 | 16 | /* Enable GPIO 30 & 31 as IIC clock & data */ |
c075b6f2 | 17 | value = peek32(GPIO_MUX); |
81dee67e | 18 | |
2a5149e0 | 19 | value |= (GPIO_MUX_30 | GPIO_MUX_31); |
c075b6f2 | 20 | poke32(GPIO_MUX, value); |
81dee67e | 21 | |
f5016082 ES |
22 | /* |
23 | * Enable Hardware I2C power. | |
35e4d8ca | 24 | * TODO: Check if we need to enable GPIO power? |
78376535 | 25 | */ |
52d0744d | 26 | sm750_enable_i2c(1); |
78376535 JL |
27 | |
28 | /* Enable the I2C Controller and set the bus speed mode */ | |
c075b6f2 | 29 | value = peek32(I2C_CTRL) & ~(I2C_CTRL_MODE | I2C_CTRL_EN); |
b71413e0 MR |
30 | if (bus_speed_mode) |
31 | value |= I2C_CTRL_MODE; | |
32 | value |= I2C_CTRL_EN; | |
c075b6f2 | 33 | poke32(I2C_CTRL, value); |
78376535 JL |
34 | |
35 | return 0; | |
81dee67e SM |
36 | } |
37 | ||
ed7042ed | 38 | void sm750_hw_i2c_close(void) |
81dee67e | 39 | { |
78376535 | 40 | unsigned int value; |
81dee67e | 41 | |
78376535 | 42 | /* Disable I2C controller */ |
c075b6f2 MS |
43 | value = peek32(I2C_CTRL) & ~I2C_CTRL_EN; |
44 | poke32(I2C_CTRL, value); | |
81dee67e | 45 | |
78376535 | 46 | /* Disable I2C Power */ |
52d0744d | 47 | sm750_enable_i2c(0); |
81dee67e | 48 | |
78376535 | 49 | /* Set GPIO 30 & 31 back as GPIO pins */ |
c075b6f2 | 50 | value = peek32(GPIO_MUX); |
2a5149e0 MR |
51 | value &= ~GPIO_MUX_30; |
52 | value &= ~GPIO_MUX_31; | |
c075b6f2 | 53 | poke32(GPIO_MUX, value); |
81dee67e SM |
54 | } |
55 | ||
ac118951 | 56 | static long hw_i2c_wait_tx_done(void) |
81dee67e | 57 | { |
78376535 | 58 | unsigned int timeout; |
81dee67e | 59 | |
78376535 JL |
60 | /* Wait until the transfer is completed. */ |
61 | timeout = HWI2C_WAIT_TIMEOUT; | |
c075b6f2 | 62 | while (!(peek32(I2C_STATUS) & I2C_STATUS_TX) && (timeout != 0)) |
81dee67e SM |
63 | timeout--; |
64 | ||
65 | if (timeout == 0) | |
732053a0 | 66 | return -1; |
81dee67e | 67 | |
78376535 | 68 | return 0; |
81dee67e SM |
69 | } |
70 | ||
81dee67e SM |
71 | /* |
72 | * This function writes data to the i2c slave device registers. | |
73 | * | |
74 | * Parameters: | |
b3696b79 | 75 | * addr - i2c Slave device address |
81dee67e | 76 | * length - Total number of bytes to be written to the device |
b3696b79 | 77 | * buf - The buffer that contains the data to be written to the |
81dee67e SM |
78 | * i2c device. |
79 | * | |
80 | * Return Value: | |
81 | * Total number of bytes those are actually written. | |
82 | */ | |
c9750456 MD |
83 | static unsigned int hw_i2c_write_data(unsigned char addr, |
84 | unsigned int length, | |
85 | unsigned char *buf) | |
81dee67e | 86 | { |
78376535 | 87 | unsigned char count, i; |
b3696b79 | 88 | unsigned int total_bytes = 0; |
81dee67e | 89 | |
78376535 | 90 | /* Set the Device Address */ |
c075b6f2 | 91 | poke32(I2C_SLAVE_ADDRESS, addr & ~0x01); |
81dee67e | 92 | |
f5016082 ES |
93 | /* |
94 | * Write data. | |
78376535 JL |
95 | * Note: |
96 | * Only 16 byte can be accessed per i2c start instruction. | |
97 | */ | |
259fef35 | 98 | do { |
9137f812 MR |
99 | /* |
100 | * Reset I2C by writing 0 to I2C_RESET register to | |
101 | * clear the previous status. | |
102 | */ | |
c075b6f2 | 103 | poke32(I2C_RESET, 0); |
81dee67e | 104 | |
78376535 JL |
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; | |
c075b6f2 | 110 | poke32(I2C_BYTE_COUNT, count); |
81dee67e | 111 | |
78376535 JL |
112 | /* Move the data to the I2C data register */ |
113 | for (i = 0; i <= count; i++) | |
c075b6f2 | 114 | poke32(I2C_DATA0 + i, *buf++); |
81dee67e | 115 | |
78376535 | 116 | /* Start the I2C */ |
c075b6f2 | 117 | poke32(I2C_CTRL, peek32(I2C_CTRL) | I2C_CTRL_CTRL); |
81dee67e | 118 | |
78376535 | 119 | /* Wait until the transfer is completed. */ |
ac118951 | 120 | if (hw_i2c_wait_tx_done() != 0) |
78376535 | 121 | break; |
81dee67e | 122 | |
fbb8c963 | 123 | /* Subtract length */ |
78376535 | 124 | length -= (count + 1); |
81dee67e | 125 | |
78376535 | 126 | /* Total byte written */ |
b3696b79 | 127 | total_bytes += (count + 1); |
81dee67e | 128 | |
78376535 | 129 | } while (length > 0); |
81dee67e | 130 | |
b3696b79 | 131 | return total_bytes; |
81dee67e SM |
132 | } |
133 | ||
81dee67e SM |
134 | /* |
135 | * This function reads data from the slave device and stores them | |
136 | * in the given buffer | |
137 | * | |
138 | * Parameters: | |
b3696b79 | 139 | * addr - i2c Slave device address |
81dee67e | 140 | * length - Total number of bytes to be read |
b3696b79 | 141 | * buf - Pointer to a buffer to be filled with the data read |
81dee67e SM |
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 | */ | |
c9750456 MD |
148 | static unsigned int hw_i2c_read_data(unsigned char addr, |
149 | unsigned int length, | |
150 | unsigned char *buf) | |
81dee67e | 151 | { |
78376535 | 152 | unsigned char count, i; |
b3696b79 | 153 | unsigned int total_bytes = 0; |
81dee67e | 154 | |
78376535 | 155 | /* Set the Device Address */ |
c075b6f2 | 156 | poke32(I2C_SLAVE_ADDRESS, addr | 0x01); |
81dee67e | 157 | |
f5016082 ES |
158 | /* |
159 | * Read data and save them to the buffer. | |
78376535 JL |
160 | * Note: |
161 | * Only 16 byte can be accessed per i2c start instruction. | |
162 | */ | |
259fef35 | 163 | do { |
9137f812 MR |
164 | /* |
165 | * Reset I2C by writing 0 to I2C_RESET register to | |
166 | * clear all the status. | |
167 | */ | |
c075b6f2 | 168 | poke32(I2C_RESET, 0); |
81dee67e | 169 | |
78376535 JL |
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; | |
c075b6f2 | 175 | poke32(I2C_BYTE_COUNT, count); |
81dee67e | 176 | |
78376535 | 177 | /* Start the I2C */ |
c075b6f2 | 178 | poke32(I2C_CTRL, peek32(I2C_CTRL) | I2C_CTRL_CTRL); |
81dee67e | 179 | |
78376535 | 180 | /* Wait until transaction done. */ |
ac118951 | 181 | if (hw_i2c_wait_tx_done() != 0) |
78376535 | 182 | break; |
81dee67e | 183 | |
78376535 JL |
184 | /* Save the data to the given buffer */ |
185 | for (i = 0; i <= count; i++) | |
c075b6f2 | 186 | *buf++ = peek32(I2C_DATA0 + i); |
81dee67e | 187 | |
fbb8c963 | 188 | /* Subtract length by 16 */ |
78376535 | 189 | length -= (count + 1); |
81dee67e | 190 | |
78376535 | 191 | /* Number of bytes read. */ |
b3696b79 | 192 | total_bytes += (count + 1); |
81dee67e | 193 | |
78376535 | 194 | } while (length > 0); |
81dee67e | 195 | |
b3696b79 | 196 | return total_bytes; |
81dee67e SM |
197 | } |
198 | ||
81dee67e SM |
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 | */ | |
c9750456 | 210 | unsigned char sm750_hw_i2c_read_reg(unsigned char addr, unsigned char reg) |
81dee67e | 211 | { |
4e1c89de | 212 | unsigned char value = 0xFF; |
81dee67e | 213 | |
938ad7ed MR |
214 | if (hw_i2c_write_data(addr, 1, ®) == 1) |
215 | hw_i2c_read_data(addr, 1, &value); | |
81dee67e | 216 | |
78376535 | 217 | return value; |
81dee67e SM |
218 | } |
219 | ||
81dee67e SM |
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 | */ | |
c9750456 MD |
233 | int sm750_hw_i2c_write_reg(unsigned char addr, |
234 | unsigned char reg, | |
235 | unsigned char data) | |
81dee67e | 236 | { |
78376535 | 237 | unsigned char value[2]; |
81dee67e | 238 | |
938ad7ed | 239 | value[0] = reg; |
78376535 | 240 | value[1] = data; |
938ad7ed | 241 | if (hw_i2c_write_data(addr, 2, value) == 2) |
78376535 | 242 | return 0; |
81dee67e | 243 | |
732053a0 | 244 | return -1; |
81dee67e SM |
245 | } |
246 | ||
81dee67e | 247 | #endif |