uboot/drivers/i2c/zynq_i2c.c
<<
>>
Prefs
   1/*
   2 * Driver for the Zynq-7000 PS I2C controller
   3 * IP from Cadence (ID T-CS-PE-0007-100, Version R1p10f2)
   4 *
   5 * Author: Joe Hershberger <joe.hershberger@ni.com>
   6 * Copyright (c) 2012 Joe Hershberger.
   7 *
   8 * Copyright (c) 2012-2013 Xilinx, Michal Simek
   9 *
  10 * See file CREDITS for list of people who contributed to this
  11 * project.
  12 *
  13 * This program is free software; you can redistribute it and/or
  14 * modify it under the terms of the GNU General Public License as
  15 * published by the Free Software Foundation; either version 2 of
  16 * the License, or (at your option) any later version.
  17 *
  18 * This program is distributed in the hope that it will be useful,
  19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21 * GNU General Public License for more details.
  22 *
  23 * You should have received a copy of the GNU General Public License
  24 * along with this program; if not, write to the Free Software
  25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  26 * MA 02110-1301 USA
  27 */
  28
  29#include <common.h>
  30#include <asm/io.h>
  31#include <i2c.h>
  32#include <asm/errno.h>
  33#include <asm/arch/hardware.h>
  34
  35/* i2c register set */
  36struct zynq_i2c_registers {
  37        u32 control;
  38        u32 status;
  39        u32 address;
  40        u32 data;
  41        u32 interrupt_status;
  42        u32 transfer_size;
  43        u32 slave_mon_pause;
  44        u32 time_out;
  45        u32 interrupt_mask;
  46        u32 interrupt_enable;
  47        u32 interrupt_disable;
  48};
  49
  50/* Control register fields */
  51#define ZYNQ_I2C_CONTROL_RW             0x00000001
  52#define ZYNQ_I2C_CONTROL_MS             0x00000002
  53#define ZYNQ_I2C_CONTROL_NEA            0x00000004
  54#define ZYNQ_I2C_CONTROL_ACKEN          0x00000008
  55#define ZYNQ_I2C_CONTROL_HOLD           0x00000010
  56#define ZYNQ_I2C_CONTROL_SLVMON         0x00000020
  57#define ZYNQ_I2C_CONTROL_CLR_FIFO       0x00000040
  58#define ZYNQ_I2C_CONTROL_DIV_B_SHIFT    8
  59#define ZYNQ_I2C_CONTROL_DIV_B_MASK     0x00003F00
  60#define ZYNQ_I2C_CONTROL_DIV_A_SHIFT    14
  61#define ZYNQ_I2C_CONTROL_DIV_A_MASK     0x0000C000
  62
  63/* Status register values */
  64#define ZYNQ_I2C_STATUS_RXDV    0x00000020
  65#define ZYNQ_I2C_STATUS_TXDV    0x00000040
  66#define ZYNQ_I2C_STATUS_RXOVF   0x00000080
  67#define ZYNQ_I2C_STATUS_BA      0x00000100
  68
  69/* Interrupt register fields */
  70#define ZYNQ_I2C_INTERRUPT_COMP         0x00000001
  71#define ZYNQ_I2C_INTERRUPT_DATA         0x00000002
  72#define ZYNQ_I2C_INTERRUPT_NACK         0x00000004
  73#define ZYNQ_I2C_INTERRUPT_TO           0x00000008
  74#define ZYNQ_I2C_INTERRUPT_SLVRDY       0x00000010
  75#define ZYNQ_I2C_INTERRUPT_RXOVF        0x00000020
  76#define ZYNQ_I2C_INTERRUPT_TXOVF        0x00000040
  77#define ZYNQ_I2C_INTERRUPT_RXUNF        0x00000080
  78#define ZYNQ_I2C_INTERRUPT_ARBLOST      0x00000200
  79
  80#define ZYNQ_I2C_FIFO_DEPTH             16
  81#define ZYNQ_I2C_TRANSFERT_SIZE_MAX     255 /* Controller transfer limit */
  82
  83#if defined(CONFIG_ZYNQ_I2C0)
  84# define ZYNQ_I2C_BASE  ZYNQ_I2C_BASEADDR0
  85#else
  86# define ZYNQ_I2C_BASE  ZYNQ_I2C_BASEADDR1
  87#endif
  88
  89static struct zynq_i2c_registers *zynq_i2c =
  90        (struct zynq_i2c_registers *)ZYNQ_I2C_BASE;
  91
  92/* I2C init called by cmd_i2c when doing 'i2c reset'. */
  93void i2c_init(int requested_speed, int slaveadd)
  94{
  95        /* 111MHz / ( (3 * 17) * 22 ) = ~100KHz */
  96        writel((16 << ZYNQ_I2C_CONTROL_DIV_B_SHIFT) |
  97                (2 << ZYNQ_I2C_CONTROL_DIV_A_SHIFT), &zynq_i2c->control);
  98
  99        /* Enable master mode, ack, and 7-bit addressing */
 100        setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_MS |
 101                ZYNQ_I2C_CONTROL_ACKEN | ZYNQ_I2C_CONTROL_NEA);
 102}
 103
 104#ifdef DEBUG
 105static void zynq_i2c_debug_status(void)
 106{
 107        int int_status;
 108        int status;
 109        int_status = readl(&zynq_i2c->interrupt_status);
 110
 111        status = readl(&zynq_i2c->status);
 112        if (int_status || status) {
 113                debug("Status: ");
 114                if (int_status & ZYNQ_I2C_INTERRUPT_COMP)
 115                        debug("COMP ");
 116                if (int_status & ZYNQ_I2C_INTERRUPT_DATA)
 117                        debug("DATA ");
 118                if (int_status & ZYNQ_I2C_INTERRUPT_NACK)
 119                        debug("NACK ");
 120                if (int_status & ZYNQ_I2C_INTERRUPT_TO)
 121                        debug("TO ");
 122                if (int_status & ZYNQ_I2C_INTERRUPT_SLVRDY)
 123                        debug("SLVRDY ");
 124                if (int_status & ZYNQ_I2C_INTERRUPT_RXOVF)
 125                        debug("RXOVF ");
 126                if (int_status & ZYNQ_I2C_INTERRUPT_TXOVF)
 127                        debug("TXOVF ");
 128                if (int_status & ZYNQ_I2C_INTERRUPT_RXUNF)
 129                        debug("RXUNF ");
 130                if (int_status & ZYNQ_I2C_INTERRUPT_ARBLOST)
 131                        debug("ARBLOST ");
 132                if (status & ZYNQ_I2C_STATUS_RXDV)
 133                        debug("RXDV ");
 134                if (status & ZYNQ_I2C_STATUS_TXDV)
 135                        debug("TXDV ");
 136                if (status & ZYNQ_I2C_STATUS_RXOVF)
 137                        debug("RXOVF ");
 138                if (status & ZYNQ_I2C_STATUS_BA)
 139                        debug("BA ");
 140                debug("TS%d ", readl(&zynq_i2c->transfer_size));
 141                debug("\n");
 142        }
 143}
 144#endif
 145
 146/* Wait for an interrupt */
 147static u32 zynq_i2c_wait(u32 mask)
 148{
 149        int timeout, int_status;
 150
 151        for (timeout = 0; timeout < 100; timeout++) {
 152                udelay(100);
 153                int_status = readl(&zynq_i2c->interrupt_status);
 154                if (int_status & mask)
 155                        break;
 156        }
 157#ifdef DEBUG
 158        zynq_i2c_debug_status();
 159#endif
 160        /* Clear interrupt status flags */
 161        writel(int_status & mask, &zynq_i2c->interrupt_status);
 162
 163        return int_status & mask;
 164}
 165
 166/*
 167 * I2C probe called by cmd_i2c when doing 'i2c probe'.
 168 * Begin read, nak data byte, end.
 169 */
 170int i2c_probe(u8 dev)
 171{
 172        /* Attempt to read a byte */
 173        setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO |
 174                ZYNQ_I2C_CONTROL_RW);
 175        clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
 176        writel(0xFF, &zynq_i2c->interrupt_status);
 177        writel(dev, &zynq_i2c->address);
 178        writel(1, &zynq_i2c->transfer_size);
 179
 180        return (zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP |
 181                ZYNQ_I2C_INTERRUPT_NACK) &
 182                ZYNQ_I2C_INTERRUPT_COMP) ? 0 : -ETIMEDOUT;
 183}
 184
 185/*
 186 * I2C read called by cmd_i2c when doing 'i2c read' and by cmd_eeprom.c
 187 * Begin write, send address byte(s), begin read, receive data bytes, end.
 188 */
 189int i2c_read(u8 dev, uint addr, int alen, u8 *data, int length)
 190{
 191        u32 status;
 192        u32 i = 0;
 193        u8 *cur_data = data;
 194
 195        /* Check the hardware can handle the requested bytes */
 196        if ((length < 0) || (length > ZYNQ_I2C_TRANSFERT_SIZE_MAX))
 197                return -EINVAL;
 198
 199        /* Write the register address */
 200        setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO |
 201                ZYNQ_I2C_CONTROL_HOLD);
 202        /*
 203         * Temporarily disable restart (by clearing hold)
 204         * It doesn't seem to work.
 205         */
 206        clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_RW |
 207                ZYNQ_I2C_CONTROL_HOLD);
 208        writel(0xFF, &zynq_i2c->interrupt_status);
 209        while (alen--)
 210                writel(addr >> (8*alen), &zynq_i2c->data);
 211        writel(dev, &zynq_i2c->address);
 212
 213        /* Wait for the address to be sent */
 214        if (!zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP)) {
 215                /* Release the bus */
 216                clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
 217                return -ETIMEDOUT;
 218        }
 219        debug("Device acked address\n");
 220
 221        setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO |
 222                ZYNQ_I2C_CONTROL_RW);
 223        /* Start reading data */
 224        writel(dev, &zynq_i2c->address);
 225        writel(length, &zynq_i2c->transfer_size);
 226
 227        /* Wait for data */
 228        do {
 229                status = zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP |
 230                        ZYNQ_I2C_INTERRUPT_DATA);
 231                if (!status) {
 232                        /* Release the bus */
 233                        clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
 234                        return -ETIMEDOUT;
 235                }
 236                debug("Read %d bytes\n",
 237                      length - readl(&zynq_i2c->transfer_size));
 238                for (; i < length - readl(&zynq_i2c->transfer_size); i++)
 239                        *(cur_data++) = readl(&zynq_i2c->data);
 240        } while (readl(&zynq_i2c->transfer_size) != 0);
 241        /* All done... release the bus */
 242        clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
 243
 244#ifdef DEBUG
 245        zynq_i2c_debug_status();
 246#endif
 247        return 0;
 248}
 249
 250/*
 251 * I2C write called by cmd_i2c when doing 'i2c write' and by cmd_eeprom.c
 252 * Begin write, send address byte(s), send data bytes, end.
 253 */
 254int i2c_write(u8 dev, uint addr, int alen, u8 *data, int length)
 255{
 256        u8 *cur_data = data;
 257
 258        /* Write the register address */
 259        setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO |
 260                ZYNQ_I2C_CONTROL_HOLD);
 261        clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_RW);
 262        writel(0xFF, &zynq_i2c->interrupt_status);
 263        while (alen--)
 264                writel(addr >> (8*alen), &zynq_i2c->data);
 265        /* Start the tranfer */
 266        writel(dev, &zynq_i2c->address);
 267        if (!zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP)) {
 268                /* Release the bus */
 269                clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
 270                return -ETIMEDOUT;
 271        }
 272
 273        debug("Device acked address\n");
 274        while (length--) {
 275                writel(*(cur_data++), &zynq_i2c->data);
 276                if (readl(&zynq_i2c->transfer_size) == ZYNQ_I2C_FIFO_DEPTH) {
 277                        if (!zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP)) {
 278                                /* Release the bus */
 279                                clrbits_le32(&zynq_i2c->control,
 280                                             ZYNQ_I2C_CONTROL_HOLD);
 281                                return -ETIMEDOUT;
 282                        }
 283                }
 284        }
 285
 286        /* All done... release the bus */
 287        clrbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_HOLD);
 288        /* Wait for the address and data to be sent */
 289        if (!zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP))
 290                return -ETIMEDOUT;
 291        return 0;
 292}
 293
 294int i2c_set_bus_num(unsigned int bus)
 295{
 296        /* Only support bus 0 */
 297        if (bus > 0)
 298                return -1;
 299        return 0;
 300}
 301
 302unsigned int i2c_get_bus_num(void)
 303{
 304        /* Only support bus 0 */
 305        return 0;
 306}
 307