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