linux/drivers/staging/sm750fb/ddk750_swi2c.c
<<
>>
Prefs
   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