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. */ 56static unsigned char sw_i2c_clk_gpio = DEFAULT_I2C_SCL; 57static 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 */ 71static unsigned long sw_i2c_clk_gpio_mux_reg = GPIO_MUX; 72static unsigned long sw_i2c_clk_gpio_data_reg = GPIO_DATA; 73static unsigned long sw_i2c_clk_gpio_data_dir_reg = GPIO_DATA_DIRECTION; 74 75/* i2c Data GPIO Register usage */ 76static unsigned long sw_i2c_data_gpio_mux_reg = GPIO_MUX; 77static unsigned long sw_i2c_data_gpio_data_reg = GPIO_DATA; 78static unsigned long sw_i2c_data_gpio_data_dir_reg = GPIO_DATA_DIRECTION; 79 80/* 81 * This function puts a delay between command 82 */ 83static 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 */ 117static 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 */ 154static 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 */ 185static 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 */ 209static 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 */ 217static 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 */ 228static 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 */ 246static 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 */ 312static 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 */ 352static 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 */ 390long 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 */ 447unsigned 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 */ 484long 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