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