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