1 /*******************************************************************
2 *
3 *         Copyright (c) 2007 by Silicon Motion, Inc. (SMI)
4 *
5 *  All rights are reserved. Reproduction or in part is prohibited
6 *  without the written consent of the copyright owner.
7 *
8 *  swi2c.c --- SM750/SM718 DDK
9 *  This file contains the source code for I2C using software
10 *  implementation.
11 *
12 *******************************************************************/
13 #include "ddk750_help.h"
14 #include "ddk750_reg.h"
15 #include "ddk750_swi2c.h"
16 #include "ddk750_power.h"
17 
18 
19 /*******************************************************************
20  * I2C Software Master Driver:
21  * ===========================
22  * Each i2c cycle is split into 4 sections. Each of these section marks
23  * a point in time where the SCL or SDA may be changed.
24  *
25  * 1 Cycle == |  Section I. |  Section 2. |  Section 3. |  Section 4. |
26  *            +-------------+-------------+-------------+-------------+
27  *            | SCL set LOW |SCL no change| SCL set HIGH|SCL no change|
28  *
29  *                                          ____________ _____________
30  * SCL == XXXX _____________ ____________ /
31  *
32  * I.e. the SCL may only be changed in section 1. and section 3. while
33  * the SDA may only be changed in section 2. and section 4. The table
34  * below gives the changes for these 2 lines in the varios sections.
35  *
36  * Section changes Table:
37  * ======================
38  * blank = no change, L = set bit LOW, H = set bit HIGH
39  *
40  *                                | 1.| 2.| 3.| 4.|
41  *                 ---------------+---+---+---+---+
42  *                 Tx Start   SDA |   | H |   | L |
43  *                            SCL | L |   | H |   |
44  *                 ---------------+---+---+---+---+
45  *                 Tx Stop    SDA |   | L |   | H |
46  *                            SCL | L |   | H |   |
47  *                 ---------------+---+---+---+---+
48  *                 Tx bit H   SDA |   | H |   |   |
49  *                            SCL | L |   | H |   |
50  *                 ---------------+---+---+---+---+
51  *                 Tx bit L   SDA |   | L |   |   |
52  *                            SCL | L |   | H |   |
53  *                 ---------------+---+---+---+---+
54  *
55  ******************************************************************/
56 
57 /* GPIO pins used for this I2C. It ranges from 0 to 63. */
58 static unsigned char g_i2cClockGPIO = DEFAULT_I2C_SCL;
59 static unsigned char g_i2cDataGPIO = DEFAULT_I2C_SDA;
60 
61 /*
62  *  Below is the variable declaration for the GPIO pin register usage
63  *  for the i2c Clock and i2c Data.
64  *
65  *  Note:
66  *      Notice that the GPIO usage for the i2c clock and i2c Data are
67  *      separated. This is to make this code flexible enough when
68  *      two separate GPIO pins for the clock and data are located
69  *      in two different GPIO register set (worst case).
70  */
71 
72 /* i2c Clock GPIO Register usage */
73 static unsigned long g_i2cClkGPIOMuxReg = GPIO_MUX;
74 static unsigned long g_i2cClkGPIODataReg = GPIO_DATA;
75 static unsigned long g_i2cClkGPIODataDirReg = GPIO_DATA_DIRECTION;
76 
77 /* i2c Data GPIO Register usage */
78 static unsigned long g_i2cDataGPIOMuxReg = GPIO_MUX;
79 static unsigned long g_i2cDataGPIODataReg = GPIO_DATA;
80 static unsigned long g_i2cDataGPIODataDirReg = GPIO_DATA_DIRECTION;
81 
82 /*
83  *  This function puts a delay between command
84  */
85 static void swI2CWait(void)
86 {
87 	/* find a bug:
88 	 * peekIO method works well before suspend/resume
89 	 * but after suspend, peekIO(0x3ce,0x61) & 0x10
90 	 * always be non-zero,which makes the while loop
91 	 * never finish.
92 	 * use non-ultimate for loop below is safe
93 	 * */
94 #if 0
95     /* Change wait algorithm to use PCI bus clock,
96        it's more reliable than counter loop ..
97        write 0x61 to 0x3ce and read from 0x3cf
98        */
99 	while(peekIO(0x3ce, 0x61) & 0x10);
100 #else
101 	int i, Temp;
102 
103 	for(i=0; i<600; i++)
104 	{
105 		Temp = i;
106 		Temp += i;
107 	}
108 #endif
109 }
110 
111 /*
112  *  This function set/reset the SCL GPIO pin
113  *
114  *  Parameters:
115  *      value    - Bit value to set to the SCL or SDA (0 = low, 1 = high)
116  *
117  *  Notes:
118  *      When setting SCL to high, just set the GPIO as input where the pull up
119  *      resistor will pull the signal up. Do not use software to pull up the
120  *      signal because the i2c will fail when other device try to drive the
121  *      signal due to SM50x will drive the signal to always high.
122  */
123 void swI2CSCL(unsigned char value)
124 {
125 	unsigned long ulGPIOData;
126 	unsigned long ulGPIODirection;
127 
128 	ulGPIODirection = PEEK32(g_i2cClkGPIODataDirReg);
129 	if (value)      /* High */
130 	{
131 		/* Set direction as input. This will automatically pull the signal up. */
132 		ulGPIODirection &= ~(1 << g_i2cClockGPIO);
133 		POKE32(g_i2cClkGPIODataDirReg, ulGPIODirection);
134 	}
135 	else            /* Low */
136 	{
137 		/* Set the signal down */
138 		ulGPIOData = PEEK32(g_i2cClkGPIODataReg);
139 		ulGPIOData &= ~(1 << g_i2cClockGPIO);
140 		POKE32(g_i2cClkGPIODataReg, ulGPIOData);
141 
142 		/* Set direction as output */
143 		ulGPIODirection |= (1 << g_i2cClockGPIO);
144 		POKE32(g_i2cClkGPIODataDirReg, ulGPIODirection);
145 	}
146 }
147 
148 /*
149  *  This function set/reset the SDA GPIO pin
150  *
151  *  Parameters:
152  *      value    - Bit value to set to the SCL or SDA (0 = low, 1 = high)
153  *
154  *  Notes:
155  *      When setting SCL to high, just set the GPIO as input where the pull up
156  *      resistor will pull the signal up. Do not use software to pull up the
157  *      signal because the i2c will fail when other device try to drive the
158  *      signal due to SM50x will drive the signal to always high.
159  */
160 void swI2CSDA(unsigned char value)
161 {
162 	unsigned long ulGPIOData;
163 	unsigned long ulGPIODirection;
164 
165 	ulGPIODirection = PEEK32(g_i2cDataGPIODataDirReg);
166 	if (value)      /* High */
167 	{
168 		/* Set direction as input. This will automatically pull the signal up. */
169 		ulGPIODirection &= ~(1 << g_i2cDataGPIO);
170 		POKE32(g_i2cDataGPIODataDirReg, ulGPIODirection);
171 	}
172 	else            /* Low */
173 	{
174 		/* Set the signal down */
175 		ulGPIOData = PEEK32(g_i2cDataGPIODataReg);
176 		ulGPIOData &= ~(1 << g_i2cDataGPIO);
177 		POKE32(g_i2cDataGPIODataReg, ulGPIOData);
178 
179 		/* Set direction as output */
180 		ulGPIODirection |= (1 << g_i2cDataGPIO);
181 		POKE32(g_i2cDataGPIODataDirReg, ulGPIODirection);
182 	}
183 }
184 
185 /*
186  *  This function read the data from the SDA GPIO pin
187  *
188  *  Return Value:
189  *      The SDA data bit sent by the Slave
190  */
191 static unsigned char swI2CReadSDA(void)
192 {
193 	unsigned long ulGPIODirection;
194 	unsigned long ulGPIOData;
195 
196 	/* Make sure that the direction is input (High) */
197 	ulGPIODirection = PEEK32(g_i2cDataGPIODataDirReg);
198 	if ((ulGPIODirection & (1 << g_i2cDataGPIO)) != (~(1 << g_i2cDataGPIO)))
199 	{
200 		ulGPIODirection &= ~(1 << g_i2cDataGPIO);
201 		POKE32(g_i2cDataGPIODataDirReg, ulGPIODirection);
202 	}
203 
204 	/* Now read the SDA line */
205 	ulGPIOData = PEEK32(g_i2cDataGPIODataReg);
206 	if (ulGPIOData & (1 << g_i2cDataGPIO))
207 		return 1;
208 	else
209 		return 0;
210 }
211 
212 /*
213  *  This function sends ACK signal
214  */
215 static void swI2CAck(void)
216 {
217 	return;  /* Single byte read is ok without it. */
218 }
219 
220 /*
221  *  This function sends the start command to the slave device
222  */
223 static void swI2CStart(void)
224 {
225 	/* Start I2C */
226 	swI2CSDA(1);
227 	swI2CSCL(1);
228 	swI2CSDA(0);
229 }
230 
231 /*
232  *  This function sends the stop command to the slave device
233  */
234 static void swI2CStop(void)
235 {
236 	/* Stop the I2C */
237 	swI2CSCL(1);
238 	swI2CSDA(0);
239 	swI2CSDA(1);
240 }
241 
242 /*
243  *  This function writes one byte to the slave device
244  *
245  *  Parameters:
246  *      data    - Data to be write to the slave device
247  *
248  *  Return Value:
249  *       0   - Success
250  *      -1   - Fail to write byte
251  */
252 static long swI2CWriteByte(unsigned char data)
253 {
254 	unsigned char value = data;
255 	int i;
256 
257 	/* Sending the data bit by bit */
258 	for (i=0; i<8; i++)
259 	{
260 		/* Set SCL to low */
261 		swI2CSCL(0);
262 
263 		/* Send data bit */
264 		if ((value & 0x80) != 0)
265 			swI2CSDA(1);
266 		else
267 			swI2CSDA(0);
268 
269 		swI2CWait();
270 
271 		/* Toggle clk line to one */
272 		swI2CSCL(1);
273 		swI2CWait();
274 
275 		/* Shift byte to be sent */
276 		value = value << 1;
277 	}
278 
279 	/* Set the SCL Low and SDA High (prepare to get input) */
280 	swI2CSCL(0);
281 	swI2CSDA(1);
282 
283 	/* Set the SCL High for ack */
284 	swI2CWait();
285 	swI2CSCL(1);
286 	swI2CWait();
287 
288 	/* Read SDA, until SDA==0 */
289 	for(i=0; i<0xff; i++)
290 	{
291 		if (!swI2CReadSDA())
292 			break;
293 
294 		swI2CSCL(0);
295 		swI2CWait();
296 		swI2CSCL(1);
297 		swI2CWait();
298 	}
299 
300 	/* Set the SCL Low and SDA High */
301 	swI2CSCL(0);
302 	swI2CSDA(1);
303 
304 	if (i<0xff)
305 		return 0;
306 	else
307 		return -1;
308 }
309 
310 /*
311  *  This function reads one byte from the slave device
312  *
313  *  Parameters:
314  *      ack    - Flag to indicate either to send the acknowledge
315  *            message to the slave device or not
316  *
317  *  Return Value:
318  *      One byte data read from the Slave device
319  */
320 static unsigned char swI2CReadByte(unsigned char ack)
321 {
322 	int i;
323 	unsigned char data = 0;
324 
325 	for(i=7; i>=0; i--)
326 	{
327 		/* Set the SCL to Low and SDA to High (Input) */
328 		swI2CSCL(0);
329 		swI2CSDA(1);
330 		swI2CWait();
331 
332 		/* Set the SCL High */
333 		swI2CSCL(1);
334 		swI2CWait();
335 
336 		/* Read data bits from SDA */
337 		data |= (swI2CReadSDA() << i);
338 	}
339 
340 	if (ack)
341 		swI2CAck();
342 
343 	/* Set the SCL Low and SDA High */
344 	swI2CSCL(0);
345 	swI2CSDA(1);
346 
347 	return data;
348 }
349 
350 /*
351  * This function initializes GPIO port for SW I2C communication.
352  *
353  * Parameters:
354  *      i2cClkGPIO      - The GPIO pin to be used as i2c SCL
355  *      i2cDataGPIO     - The GPIO pin to be used as i2c SDA
356  *
357  * Return Value:
358  *      -1   - Fail to initialize the i2c
359  *       0   - Success
360  */
361 static long swI2CInit_SM750LE(unsigned char i2cClkGPIO,
362 			      unsigned char i2cDataGPIO)
363 {
364 	int i;
365 
366 	/* Initialize the GPIO pin for the i2c Clock Register */
367 	g_i2cClkGPIODataReg = GPIO_DATA_SM750LE;
368 	g_i2cClkGPIODataDirReg = GPIO_DATA_DIRECTION_SM750LE;
369 
370 	/* Initialize the Clock GPIO Offset */
371 	g_i2cClockGPIO = i2cClkGPIO;
372 
373 	/* Initialize the GPIO pin for the i2c Data Register */
374 	g_i2cDataGPIODataReg = GPIO_DATA_SM750LE;
375 	g_i2cDataGPIODataDirReg = GPIO_DATA_DIRECTION_SM750LE;
376 
377 	/* Initialize the Data GPIO Offset */
378 	g_i2cDataGPIO = i2cDataGPIO;
379 
380 	/* Note that SM750LE don't have GPIO MUX and power is always on */
381 
382 	/* Clear the i2c lines. */
383 	for(i=0; i<9; i++)
384 		swI2CStop();
385 
386 	return 0;
387 }
388 
389 /*
390  * This function initializes the i2c attributes and bus
391  *
392  * Parameters:
393  *      i2cClkGPIO      - The GPIO pin to be used as i2c SCL
394  *      i2cDataGPIO     - The GPIO pin to be used as i2c SDA
395  *
396  * Return Value:
397  *      -1   - Fail to initialize the i2c
398  *       0   - Success
399  */
400 long swI2CInit(
401 	unsigned char i2cClkGPIO,
402 	unsigned char i2cDataGPIO
403 )
404 {
405 	int i;
406 
407 	/* Return 0 if the GPIO pins to be used is out of range. The range is only from [0..63] */
408 	if ((i2cClkGPIO > 31) || (i2cDataGPIO > 31))
409 		return -1;
410 
411 	if (getChipType() == SM750LE)
412 		return swI2CInit_SM750LE(i2cClkGPIO, i2cDataGPIO);
413 
414 	/* Initialize the GPIO pin for the i2c Clock Register */
415 	g_i2cClkGPIOMuxReg = GPIO_MUX;
416 	g_i2cClkGPIODataReg = GPIO_DATA;
417 	g_i2cClkGPIODataDirReg = GPIO_DATA_DIRECTION;
418 
419 	/* Initialize the Clock GPIO Offset */
420 	g_i2cClockGPIO = i2cClkGPIO;
421 
422 	/* Initialize the GPIO pin for the i2c Data Register */
423 	g_i2cDataGPIOMuxReg = GPIO_MUX;
424 	g_i2cDataGPIODataReg = GPIO_DATA;
425 	g_i2cDataGPIODataDirReg = GPIO_DATA_DIRECTION;
426 
427 	/* Initialize the Data GPIO Offset */
428 	g_i2cDataGPIO = i2cDataGPIO;
429 
430 	/* Enable the GPIO pins for the i2c Clock and Data (GPIO MUX) */
431 	POKE32(g_i2cClkGPIOMuxReg,
432 			PEEK32(g_i2cClkGPIOMuxReg) & ~(1 << g_i2cClockGPIO));
433 	POKE32(g_i2cDataGPIOMuxReg,
434 			PEEK32(g_i2cDataGPIOMuxReg) & ~(1 << g_i2cDataGPIO));
435 
436 	/* Enable GPIO power */
437 	enableGPIO(1);
438 
439 	/* Clear the i2c lines. */
440 	for(i=0; i<9; i++)
441 		swI2CStop();
442 
443 	return 0;
444 }
445 
446 /*
447  *  This function reads the slave device's register
448  *
449  *  Parameters:
450  *      deviceAddress   - i2c Slave device address which register
451  *                        to be read from
452  *      registerIndex   - Slave device's register to be read
453  *
454  *  Return Value:
455  *      Register value
456  */
457 unsigned char swI2CReadReg(
458 	unsigned char deviceAddress,
459 	unsigned char registerIndex
460 )
461 {
462 	unsigned char data;
463 
464 	/* Send the Start signal */
465 	swI2CStart();
466 
467 	/* Send the device address */
468 	swI2CWriteByte(deviceAddress);
469 
470 	/* Send the register index */
471 	swI2CWriteByte(registerIndex);
472 
473 	/* Get the bus again and get the data from the device read address */
474 	swI2CStart();
475 	swI2CWriteByte(deviceAddress + 1);
476 	data = swI2CReadByte(1);
477 
478 	/* Stop swI2C and release the bus */
479 	swI2CStop();
480 
481 	return data;
482 }
483 
484 /*
485  *  This function writes a value to the slave device's register
486  *
487  *  Parameters:
488  *      deviceAddress   - i2c Slave device address which register
489  *                        to be written
490  *      registerIndex   - Slave device's register to be written
491  *      data            - Data to be written to the register
492  *
493  *  Result:
494  *          0   - Success
495  *         -1   - Fail
496  */
497 long swI2CWriteReg(
498 	unsigned char deviceAddress,
499 	unsigned char registerIndex,
500 	unsigned char data
501 )
502 {
503 	long returnValue = 0;
504 
505 	/* Send the Start signal */
506 	swI2CStart();
507 
508 	/* Send the device address and read the data. All should return success
509 	   in order for the writing processed to be successful
510 	*/
511 	if ((swI2CWriteByte(deviceAddress) != 0) ||
512 	    (swI2CWriteByte(registerIndex) != 0) ||
513 	    (swI2CWriteByte(data) != 0))
514 	{
515 		returnValue = -1;
516 	}
517 
518 	/* Stop i2c and release the bus */
519 	swI2CStop();
520 
521 	return returnValue;
522 }
523