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