linux/drivers/staging/sm750fb/ddk750_hwi2c.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#define USE_HW_I2C
   3#ifdef USE_HW_I2C
   4#include "ddk750_chip.h"
   5#include "ddk750_reg.h"
   6#include "ddk750_hwi2c.h"
   7#include "ddk750_power.h"
   8
   9#define MAX_HWI2C_FIFO                  16
  10#define HWI2C_WAIT_TIMEOUT              0xF0000
  11
  12int sm750_hw_i2c_init(unsigned char bus_speed_mode)
  13{
  14        unsigned int value;
  15
  16        /* Enable GPIO 30 & 31 as IIC clock & data */
  17        value = peek32(GPIO_MUX);
  18
  19        value |= (GPIO_MUX_30 | GPIO_MUX_31);
  20        poke32(GPIO_MUX, value);
  21
  22        /*
  23         * Enable Hardware I2C power.
  24         * TODO: Check if we need to enable GPIO power?
  25         */
  26        sm750_enable_i2c(1);
  27
  28        /* Enable the I2C Controller and set the bus speed mode */
  29        value = peek32(I2C_CTRL) & ~(I2C_CTRL_MODE | I2C_CTRL_EN);
  30        if (bus_speed_mode)
  31                value |= I2C_CTRL_MODE;
  32        value |= I2C_CTRL_EN;
  33        poke32(I2C_CTRL, value);
  34
  35        return 0;
  36}
  37
  38void sm750_hw_i2c_close(void)
  39{
  40        unsigned int value;
  41
  42        /* Disable I2C controller */
  43        value = peek32(I2C_CTRL) & ~I2C_CTRL_EN;
  44        poke32(I2C_CTRL, value);
  45
  46        /* Disable I2C Power */
  47        sm750_enable_i2c(0);
  48
  49        /* Set GPIO 30 & 31 back as GPIO pins */
  50        value = peek32(GPIO_MUX);
  51        value &= ~GPIO_MUX_30;
  52        value &= ~GPIO_MUX_31;
  53        poke32(GPIO_MUX, value);
  54}
  55
  56static long hw_i2c_wait_tx_done(void)
  57{
  58        unsigned int timeout;
  59
  60        /* Wait until the transfer is completed. */
  61        timeout = HWI2C_WAIT_TIMEOUT;
  62        while (!(peek32(I2C_STATUS) & I2C_STATUS_TX) && (timeout != 0))
  63                timeout--;
  64
  65        if (timeout == 0)
  66                return -1;
  67
  68        return 0;
  69}
  70
  71/*
  72 *  This function writes data to the i2c slave device registers.
  73 *
  74 *  Parameters:
  75 *      addr            - i2c Slave device address
  76 *      length          - Total number of bytes to be written to the device
  77 *      buf             - The buffer that contains the data to be written to the
  78 *                     i2c device.
  79 *
  80 *  Return Value:
  81 *      Total number of bytes those are actually written.
  82 */
  83static unsigned int hw_i2c_write_data(unsigned char addr,
  84                                      unsigned int length,
  85                                      unsigned char *buf)
  86{
  87        unsigned char count, i;
  88        unsigned int total_bytes = 0;
  89
  90        /* Set the Device Address */
  91        poke32(I2C_SLAVE_ADDRESS, addr & ~0x01);
  92
  93        /*
  94         * Write data.
  95         * Note:
  96         *      Only 16 byte can be accessed per i2c start instruction.
  97         */
  98        do {
  99                /*
 100                 * Reset I2C by writing 0 to I2C_RESET register to
 101                 * clear the previous status.
 102                 */
 103                poke32(I2C_RESET, 0);
 104
 105                /* Set the number of bytes to be written */
 106                if (length < MAX_HWI2C_FIFO)
 107                        count = length - 1;
 108                else
 109                        count = MAX_HWI2C_FIFO - 1;
 110                poke32(I2C_BYTE_COUNT, count);
 111
 112                /* Move the data to the I2C data register */
 113                for (i = 0; i <= count; i++)
 114                        poke32(I2C_DATA0 + i, *buf++);
 115
 116                /* Start the I2C */
 117                poke32(I2C_CTRL, peek32(I2C_CTRL) | I2C_CTRL_CTRL);
 118
 119                /* Wait until the transfer is completed. */
 120                if (hw_i2c_wait_tx_done() != 0)
 121                        break;
 122
 123                /* Subtract length */
 124                length -= (count + 1);
 125
 126                /* Total byte written */
 127                total_bytes += (count + 1);
 128
 129        } while (length > 0);
 130
 131        return total_bytes;
 132}
 133
 134/*
 135 *  This function reads data from the slave device and stores them
 136 *  in the given buffer
 137 *
 138 *  Parameters:
 139 *      addr            - i2c Slave device address
 140 *      length          - Total number of bytes to be read
 141 *      buf             - Pointer to a buffer to be filled with the data read
 142 *                     from the slave device. It has to be the same size as the
 143 *                     length to make sure that it can keep all the data read.
 144 *
 145 *  Return Value:
 146 *      Total number of actual bytes read from the slave device
 147 */
 148static unsigned int hw_i2c_read_data(unsigned char addr,
 149                                     unsigned int length,
 150                                     unsigned char *buf)
 151{
 152        unsigned char count, i;
 153        unsigned int total_bytes = 0;
 154
 155        /* Set the Device Address */
 156        poke32(I2C_SLAVE_ADDRESS, addr | 0x01);
 157
 158        /*
 159         * Read data and save them to the buffer.
 160         * Note:
 161         *      Only 16 byte can be accessed per i2c start instruction.
 162         */
 163        do {
 164                /*
 165                 * Reset I2C by writing 0 to I2C_RESET register to
 166                 * clear all the status.
 167                 */
 168                poke32(I2C_RESET, 0);
 169
 170                /* Set the number of bytes to be read */
 171                if (length <= MAX_HWI2C_FIFO)
 172                        count = length - 1;
 173                else
 174                        count = MAX_HWI2C_FIFO - 1;
 175                poke32(I2C_BYTE_COUNT, count);
 176
 177                /* Start the I2C */
 178                poke32(I2C_CTRL, peek32(I2C_CTRL) | I2C_CTRL_CTRL);
 179
 180                /* Wait until transaction done. */
 181                if (hw_i2c_wait_tx_done() != 0)
 182                        break;
 183
 184                /* Save the data to the given buffer */
 185                for (i = 0; i <= count; i++)
 186                        *buf++ = peek32(I2C_DATA0 + i);
 187
 188                /* Subtract length by 16 */
 189                length -= (count + 1);
 190
 191                /* Number of bytes read. */
 192                total_bytes += (count + 1);
 193
 194        } while (length > 0);
 195
 196        return total_bytes;
 197}
 198
 199/*
 200 *  This function reads the slave device's register
 201 *
 202 *  Parameters:
 203 *      deviceAddress   - i2c Slave device address which register
 204 *                        to be read from
 205 *      registerIndex   - Slave device's register to be read
 206 *
 207 *  Return Value:
 208 *      Register value
 209 */
 210unsigned char sm750_hw_i2c_read_reg(unsigned char addr, unsigned char reg)
 211{
 212        unsigned char value = 0xFF;
 213
 214        if (hw_i2c_write_data(addr, 1, &reg) == 1)
 215                hw_i2c_read_data(addr, 1, &value);
 216
 217        return value;
 218}
 219
 220/*
 221 *  This function writes a value to the slave device's register
 222 *
 223 *  Parameters:
 224 *      deviceAddress   - i2c Slave device address which register
 225 *                        to be written
 226 *      registerIndex   - Slave device's register to be written
 227 *      data            - Data to be written to the register
 228 *
 229 *  Result:
 230 *          0   - Success
 231 *         -1   - Fail
 232 */
 233int sm750_hw_i2c_write_reg(unsigned char addr,
 234                           unsigned char reg,
 235                           unsigned char data)
 236{
 237        unsigned char value[2];
 238
 239        value[0] = reg;
 240        value[1] = data;
 241        if (hw_i2c_write_data(addr, 2, value) == 2)
 242                return 0;
 243
 244        return -1;
 245}
 246
 247#endif
 248