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