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