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