1 /*******************************************************************
3 * Copyright (c) 2007 by Silicon Motion, Inc. (SMI)
5 * All rights are reserved. Reproduction or in part is prohibited
6 * without the written consent of the copyright owner.
8 * swi2c.c --- SM750/SM718 DDK
9 * This file contains the source code for I2C using software
12 *******************************************************************/
13 #include "ddk750_help.h"
14 #include "ddk750_reg.h"
15 #include "ddk750_swi2c.h"
16 #include "ddk750_power.h"
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.
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|
28 * ____________ _____________
29 * SCL == XXXX _____________ ____________ /
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.
35 * Section changes Table:
36 * ======================
37 * blank = no change, L = set bit LOW, H = set bit HIGH
40 * ---------------+---+---+---+---+
41 * Tx Start SDA | | H | | L |
43 * ---------------+---+---+---+---+
44 * Tx Stop SDA | | L | | H |
46 * ---------------+---+---+---+---+
47 * Tx bit H SDA | | H | | |
49 * ---------------+---+---+---+---+
50 * Tx bit L SDA | | L | | |
52 * ---------------+---+---+---+---+
54 ******************************************************************/
56 /* GPIO pins used for this I2C. It ranges from 0 to 63. */
57 static unsigned char sw_i2c_clk_gpio = DEFAULT_I2C_SCL;
58 static unsigned char sw_i2c_data_gpio = DEFAULT_I2C_SDA;
61 * Below is the variable declaration for the GPIO pin register usage
62 * for the i2c Clock and i2c Data.
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).
71 /* i2c Clock GPIO Register usage */
72 static unsigned long sw_i2c_clk_gpio_mux_reg = GPIO_MUX;
73 static unsigned long sw_i2c_clk_gpio_data_reg = GPIO_DATA;
74 static unsigned long sw_i2c_clk_gpio_data_dir_reg = GPIO_DATA_DIRECTION;
76 /* i2c Data GPIO Register usage */
77 static unsigned long sw_i2c_data_gpio_mux_reg = GPIO_MUX;
78 static unsigned long sw_i2c_data_gpio_data_reg = GPIO_DATA;
79 static unsigned long sw_i2c_data_gpio_data_dir_reg = GPIO_DATA_DIRECTION;
82 * This function puts a delay between command
84 static void sw_i2c_wait(void)
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
91 * use non-ultimate for loop below is safe
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
100 for (i = 0; i < 600; i++) {
107 * This function set/reset the SCL GPIO pin
110 * value - Bit value to set to the SCL or SDA (0 = low, 1 = high)
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.
118 static void sw_i2c_scl(unsigned char value)
120 unsigned long gpio_data;
121 unsigned long gpio_dir;
123 gpio_dir = PEEK32(sw_i2c_clk_gpio_data_dir_reg);
124 if (value) { /* High */
126 * Set direction as input. This will automatically
127 * pull the signal up.
129 gpio_dir &= ~(1 << sw_i2c_clk_gpio);
130 POKE32(sw_i2c_clk_gpio_data_dir_reg, gpio_dir);
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);
137 /* Set direction as output */
138 gpio_dir |= (1 << sw_i2c_clk_gpio);
139 POKE32(sw_i2c_clk_gpio_data_dir_reg, gpio_dir);
144 * This function set/reset the SDA GPIO pin
147 * value - Bit value to set to the SCL or SDA (0 = low, 1 = high)
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.
155 static void sw_i2c_sda(unsigned char value)
157 unsigned long gpio_data;
158 unsigned long gpio_dir;
160 gpio_dir = PEEK32(sw_i2c_data_gpio_data_dir_reg);
161 if (value) { /* High */
163 * Set direction as input. This will automatically
164 * pull the signal up.
166 gpio_dir &= ~(1 << sw_i2c_data_gpio);
167 POKE32(sw_i2c_data_gpio_data_dir_reg, gpio_dir);
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);
174 /* Set direction as output */
175 gpio_dir |= (1 << sw_i2c_data_gpio);
176 POKE32(sw_i2c_data_gpio_data_dir_reg, gpio_dir);
181 * This function read the data from the SDA GPIO pin
184 * The SDA data bit sent by the Slave
186 static unsigned char sw_i2c_read_sda(void)
188 unsigned long gpio_dir;
189 unsigned long gpio_data;
190 unsigned long dir_mask = 1 << sw_i2c_data_gpio;
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);
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))
208 * This function sends ACK signal
210 static void sw_i2c_ack(void)
212 return; /* Single byte read is ok without it. */
216 * This function sends the start command to the slave device
218 static void sw_i2c_start(void)
227 * This function sends the stop command to the slave device
229 static void sw_i2c_stop(void)
238 * This function writes one byte to the slave device
241 * data - Data to be write to the slave device
245 * -1 - Fail to write byte
247 static long sw_i2c_write_byte(unsigned char data)
249 unsigned char value = data;
252 /* Sending the data bit by bit */
253 for (i = 0; i < 8; i++) {
258 if ((value & 0x80) != 0)
265 /* Toggle clk line to one */
269 /* Shift byte to be sent */
273 /* Set the SCL Low and SDA High (prepare to get input) */
277 /* Set the SCL High for ack */
282 /* Read SDA, until SDA==0 */
283 for (i = 0; i < 0xff; i++) {
284 if (!sw_i2c_read_sda())
293 /* Set the SCL Low and SDA High */
304 * This function reads one byte from the slave device
307 * ack - Flag to indicate either to send the acknowledge
308 * message to the slave device or not
311 * One byte data read from the Slave device
313 static unsigned char sw_i2c_read_byte(unsigned char ack)
316 unsigned char data = 0;
318 for (i = 7; i >= 0; i--) {
319 /* Set the SCL to Low and SDA to High (Input) */
324 /* Set the SCL High */
328 /* Read data bits from SDA */
329 data |= (sw_i2c_read_sda() << i);
335 /* Set the SCL Low and SDA High */
343 * This function initializes GPIO port for SW I2C communication.
346 * clk_gpio - The GPIO pin to be used as i2c SCL
347 * data_gpio - The GPIO pin to be used as i2c SDA
350 * -1 - Fail to initialize the i2c
353 static long sm750le_i2c_init(unsigned char clk_gpio,
354 unsigned char data_gpio)
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;
362 /* Initialize the Clock GPIO Offset */
363 sw_i2c_clk_gpio = clk_gpio;
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;
369 /* Initialize the Data GPIO Offset */
370 sw_i2c_data_gpio = data_gpio;
372 /* Note that SM750LE don't have GPIO MUX and power is always on */
374 /* Clear the i2c lines. */
375 for (i = 0; i < 9; i++)
382 * This function initializes the i2c attributes and bus
385 * clk_gpio - The GPIO pin to be used as i2c SCL
386 * data_gpio - The GPIO pin to be used as i2c SDA
389 * -1 - Fail to initialize the i2c
392 long sm750_sw_i2c_init(
393 unsigned char clk_gpio,
394 unsigned char data_gpio
400 * Return 0 if the GPIO pins to be used is out of range. The
401 * range is only from [0..63]
403 if ((clk_gpio > 31) || (data_gpio > 31))
406 if (getChipType() == SM750LE)
407 return sm750le_i2c_init(clk_gpio, data_gpio);
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;
414 /* Initialize the Clock GPIO Offset */
415 sw_i2c_clk_gpio = clk_gpio;
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;
422 /* Initialize the Data GPIO Offset */
423 sw_i2c_data_gpio = data_gpio;
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));
431 /* Enable GPIO power */
434 /* Clear the i2c lines. */
435 for (i = 0; i < 9; i++)
442 * This function reads the slave device's register
445 * addr - i2c Slave device address which register
447 * reg - Slave device's register to be read
452 unsigned char sm750_sw_i2c_read_reg(
459 /* Send the Start signal */
462 /* Send the device address */
463 sw_i2c_write_byte(addr);
465 /* Send the register index */
466 sw_i2c_write_byte(reg);
468 /* Get the bus again and get the data from the device read address */
470 sw_i2c_write_byte(addr + 1);
471 data = sw_i2c_read_byte(1);
473 /* Stop swI2C and release the bus */
480 * This function writes a value to the slave device's register
483 * addr - i2c Slave device address which register
485 * reg - Slave device's register to be written
486 * data - Data to be written to the register
492 long sm750_sw_i2c_write_reg(
500 /* Send the Start signal */
503 /* Send the device address and read the data. All should return success
504 in order for the writing processed to be successful
506 if ((sw_i2c_write_byte(addr) != 0) ||
507 (sw_i2c_write_byte(reg) != 0) ||
508 (sw_i2c_write_byte(data) != 0)) {
512 /* Stop i2c and release the bus */