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