uboot/drivers/i2c/pca9564_i2c.c
<<
>>
Prefs
   1/*
   2 * File:         drivers/i2c/pca9564.c
   3 * Based on:     drivers/i2c/s3c44b0_i2c.c
   4 * Author:
   5 *
   6 * Created:      2009-06-23
   7 * Description:  PCA9564 i2c bridge driver
   8 *
   9 * Modified:
  10 *               Copyright 2009 CJSC "NII STT", http://www.niistt.ru/
  11 *
  12 * Bugs:
  13 *
  14 * This program is free software; you can redistribute it and/or modify
  15 * it under the terms of the GNU General Public License as published by
  16 * the Free Software Foundation; either version 2 of the License, or
  17 * (at your option) any later version.
  18 *
  19 * This program is distributed in the hope that it will be useful,
  20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22 * GNU General Public License for more details.
  23 *
  24 * You should have received a copy of the GNU General Public License
  25 * along with this program; if not, see the file COPYING, or write
  26 * to the Free Software Foundation, Inc.,
  27 * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  28 */
  29
  30#include <common.h>
  31#include <i2c.h>
  32#include <pca9564.h>
  33#include <asm/io.h>
  34
  35#define PCA_STA                 (CONFIG_PCA9564_BASE + 0)
  36#define PCA_TO                  (CONFIG_PCA9564_BASE + 0)
  37#define PCA_DAT                 (CONFIG_PCA9564_BASE + (1 << 2))
  38#define PCA_ADR                 (CONFIG_PCA9564_BASE + (2 << 2))
  39#define PCA_CON                 (CONFIG_PCA9564_BASE + (3 << 2))
  40
  41static unsigned char pca_read_reg(unsigned int reg)
  42{
  43        return readb((void *)reg);
  44}
  45
  46static void pca_write_reg(unsigned int reg, unsigned char value)
  47{
  48        writeb(value, (void *)reg);
  49}
  50
  51static int pca_wait_busy(void)
  52{
  53        unsigned int timeout = 10000;
  54
  55        while (!(pca_read_reg(PCA_CON) & PCA_CON_SI) && --timeout)
  56                udelay(1);
  57
  58        if (timeout == 0)
  59                debug("I2C timeout!\n");
  60
  61        debug("CON = 0x%02x, STA = 0x%02x\n", pca_read_reg(PCA_CON),
  62               pca_read_reg(PCA_STA));
  63
  64        return timeout ? 0 : 1;
  65}
  66
  67/*=====================================================================*/
  68/*                         Public Functions                            */
  69/*=====================================================================*/
  70
  71/*-----------------------------------------------------------------------
  72 * Initialization
  73 */
  74void i2c_init(int speed, int slaveaddr)
  75{
  76        pca_write_reg(PCA_CON, PCA_CON_ENSIO | speed);
  77}
  78
  79/*
  80 * Probe the given I2C chip address.  Returns 0 if a chip responded,
  81 * not 0 on failure.
  82 */
  83
  84int i2c_probe(uchar chip)
  85{
  86        unsigned char res;
  87
  88        pca_write_reg(PCA_CON, PCA_CON_STA | PCA_CON_ENSIO);
  89        pca_wait_busy();
  90
  91        pca_write_reg(PCA_CON, PCA_CON_STA | PCA_CON_ENSIO);
  92
  93        pca_write_reg(PCA_DAT, (chip << 1) | 1);
  94        res = pca_wait_busy();
  95
  96        if ((res == 0) && (pca_read_reg(PCA_STA) == 0x48))
  97                res = 1;
  98
  99        pca_write_reg(PCA_CON, PCA_CON_STO | PCA_CON_ENSIO);
 100
 101        return res;
 102}
 103
 104/*
 105 * Read/Write interface:
 106 *   chip:    I2C chip address, range 0..127
 107 *   addr:    Memory (register) address within the chip
 108 *   alen:    Number of bytes to use for addr (typically 1, 2 for larger
 109 *              memories, 0 for register type devices with only one
 110 *              register)
 111 *   buffer:  Where to read/write the data
 112 *   len:     How many bytes to read/write
 113 *
 114 *   Returns: 0 on success, not 0 on failure
 115 */
 116int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
 117{
 118        int i;
 119
 120        pca_write_reg(PCA_CON, PCA_CON_ENSIO | PCA_CON_STA);
 121        pca_wait_busy();
 122
 123        pca_write_reg(PCA_CON, PCA_CON_ENSIO);
 124
 125        pca_write_reg(PCA_DAT, (chip << 1));
 126        pca_wait_busy();
 127        pca_write_reg(PCA_CON, PCA_CON_ENSIO);
 128
 129        if (alen > 0) {
 130                pca_write_reg(PCA_DAT, addr);
 131                pca_wait_busy();
 132                pca_write_reg(PCA_CON, PCA_CON_ENSIO);
 133        }
 134
 135        pca_write_reg(PCA_CON, PCA_CON_ENSIO | PCA_CON_STO);
 136
 137        udelay(500);
 138
 139        pca_write_reg(PCA_CON, PCA_CON_ENSIO | PCA_CON_STA);
 140        pca_wait_busy();
 141        pca_write_reg(PCA_CON, PCA_CON_ENSIO);
 142
 143        pca_write_reg(PCA_DAT, (chip << 1) | 1);
 144        pca_wait_busy();
 145
 146        for (i = 0; i < len; ++i) {
 147                if (i == len - 1)
 148                        pca_write_reg(PCA_CON, PCA_CON_ENSIO);
 149                else
 150                        pca_write_reg(PCA_CON, PCA_CON_ENSIO | PCA_CON_AA);
 151
 152                pca_wait_busy();
 153                buffer[i] = pca_read_reg(PCA_DAT);
 154
 155        }
 156
 157        pca_write_reg(PCA_CON, PCA_CON_ENSIO | PCA_CON_STO);
 158
 159        return 0;
 160}
 161
 162int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
 163{
 164        int i;
 165
 166        pca_write_reg(PCA_CON, PCA_CON_ENSIO | PCA_CON_STA);
 167        pca_wait_busy();
 168        pca_write_reg(PCA_CON, PCA_CON_ENSIO);
 169
 170        pca_write_reg(PCA_DAT, chip << 1);
 171        pca_wait_busy();
 172        pca_write_reg(PCA_CON, PCA_CON_ENSIO);
 173
 174        if (alen > 0) {
 175                pca_write_reg(PCA_DAT, addr);
 176                pca_wait_busy();
 177                pca_write_reg(PCA_CON, PCA_CON_ENSIO);
 178        }
 179
 180        for (i = 0; i < len; ++i) {
 181                pca_write_reg(PCA_DAT, buffer[i]);
 182                pca_wait_busy();
 183                pca_write_reg(PCA_CON, PCA_CON_ENSIO);
 184        }
 185
 186        pca_write_reg(PCA_CON, PCA_CON_STO | PCA_CON_ENSIO);
 187
 188        return 0;
 189}
 190