1 #define USE_HW_I2C
2 #ifdef USE_HW_I2C
3 #include "ddk750_help.h"
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 
11 int sm750_hw_i2c_init(
12 unsigned char bus_speed_mode
13 )
14 {
15 	unsigned int value;
16 
17 	/* Enable GPIO 30 & 31 as IIC clock & data */
18 	value = PEEK32(GPIO_MUX);
19 
20 	value |= (GPIO_MUX_30 | GPIO_MUX_31);
21 	POKE32(GPIO_MUX, value);
22 
23 	/* Enable Hardware I2C power.
24 	 TODO: Check if we need to enable GPIO power?
25 	 */
26 	enableI2C(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, 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, value);
45 
46 	/* Disable I2C Power */
47 	enableI2C(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, 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(
84 	unsigned char addr,
85 	unsigned int length,
86 	unsigned char *buf
87 )
88 {
89 	unsigned char count, i;
90 	unsigned int total_bytes = 0;
91 
92 	/* Set the Device Address */
93 	POKE32(I2C_SLAVE_ADDRESS, addr & ~0x01);
94 
95 	/* Write data.
96 	 * Note:
97 	 *      Only 16 byte can be accessed per i2c start instruction.
98 	 */
99 	do {
100 		/*
101 		 * Reset I2C by writing 0 to I2C_RESET register to
102 		 * clear the previous status.
103 		 */
104 		POKE32(I2C_RESET, 0);
105 
106 		/* Set the number of bytes to be written */
107 		if (length < MAX_HWI2C_FIFO)
108 			count = length - 1;
109 		else
110 			count = MAX_HWI2C_FIFO - 1;
111 		POKE32(I2C_BYTE_COUNT, count);
112 
113 		/* Move the data to the I2C data register */
114 		for (i = 0; i <= count; i++)
115 			POKE32(I2C_DATA0 + i, *buf++);
116 
117 		/* Start the I2C */
118 		POKE32(I2C_CTRL, PEEK32(I2C_CTRL) | I2C_CTRL_CTRL);
119 
120 		/* Wait until the transfer is completed. */
121 		if (hw_i2c_wait_tx_done() != 0)
122 			break;
123 
124 		/* Subtract length */
125 		length -= (count + 1);
126 
127 		/* Total byte written */
128 		total_bytes += (count + 1);
129 
130 	} while (length > 0);
131 
132 	return total_bytes;
133 }
134 
135 /*
136  *  This function reads data from the slave device and stores them
137  *  in the given buffer
138  *
139  *  Parameters:
140  *      addr            - i2c Slave device address
141  *      length          - Total number of bytes to be read
142  *      buf             - Pointer to a buffer to be filled with the data read
143  *                     from the slave device. It has to be the same size as the
144  *                     length to make sure that it can keep all the data read.
145  *
146  *  Return Value:
147  *      Total number of actual bytes read from the slave device
148  */
149 static unsigned int hw_i2c_read_data(
150 	unsigned char addr,
151 	unsigned int length,
152 	unsigned char *buf
153 )
154 {
155 	unsigned char count, i;
156 	unsigned int total_bytes = 0;
157 
158 	/* Set the Device Address */
159 	POKE32(I2C_SLAVE_ADDRESS, addr | 0x01);
160 
161 	/* Read data and save them to the buffer.
162 	 * Note:
163 	 *      Only 16 byte can be accessed per i2c start instruction.
164 	 */
165 	do {
166 		/*
167 		 * Reset I2C by writing 0 to I2C_RESET register to
168 		 * clear all the status.
169 		 */
170 		POKE32(I2C_RESET, 0);
171 
172 		/* Set the number of bytes to be read */
173 		if (length <= MAX_HWI2C_FIFO)
174 			count = length - 1;
175 		else
176 			count = MAX_HWI2C_FIFO - 1;
177 		POKE32(I2C_BYTE_COUNT, count);
178 
179 		/* Start the I2C */
180 		POKE32(I2C_CTRL, PEEK32(I2C_CTRL) | I2C_CTRL_CTRL);
181 
182 		/* Wait until transaction done. */
183 		if (hw_i2c_wait_tx_done() != 0)
184 			break;
185 
186 		/* Save the data to the given buffer */
187 		for (i = 0; i <= count; i++)
188 			*buf++ = PEEK32(I2C_DATA0 + i);
189 
190 		/* Subtract length by 16 */
191 		length -= (count + 1);
192 
193 		/* Number of bytes read. */
194 		total_bytes += (count + 1);
195 
196 	} while (length > 0);
197 
198 	return total_bytes;
199 }
200 
201 /*
202  *  This function reads the slave device's register
203  *
204  *  Parameters:
205  *      deviceAddress   - i2c Slave device address which register
206  *                        to be read from
207  *      registerIndex   - Slave device's register to be read
208  *
209  *  Return Value:
210  *      Register value
211  */
212 unsigned char sm750_hw_i2c_read_reg(
213 	unsigned char addr,
214 	unsigned char reg
215 )
216 {
217 	unsigned char value = (0xFF);
218 
219 	if (hw_i2c_write_data(addr, 1, &reg) == 1)
220 		hw_i2c_read_data(addr, 1, &value);
221 
222 	return value;
223 }
224 
225 /*
226  *  This function writes a value to the slave device's register
227  *
228  *  Parameters:
229  *      deviceAddress   - i2c Slave device address which register
230  *                        to be written
231  *      registerIndex   - Slave device's register to be written
232  *      data            - Data to be written to the register
233  *
234  *  Result:
235  *          0   - Success
236  *         -1   - Fail
237  */
238 int sm750_hw_i2c_write_reg(
239 	unsigned char addr,
240 	unsigned char reg,
241 	unsigned char data
242 )
243 {
244 	unsigned char value[2];
245 
246 	value[0] = reg;
247 	value[1] = data;
248 	if (hw_i2c_write_data(addr, 2, value) == 2)
249 		return 0;
250 
251 	return -1;
252 }
253 
254 #endif
255