1f4f680aaSMarek Vasut /* 2f4f680aaSMarek Vasut * Freescale i.MX28 I2C Driver 3f4f680aaSMarek Vasut * 4f4f680aaSMarek Vasut * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> 5f4f680aaSMarek Vasut * on behalf of DENX Software Engineering GmbH 6f4f680aaSMarek Vasut * 7f4f680aaSMarek Vasut * Partly based on Linux kernel i2c-mxs.c driver: 8f4f680aaSMarek Vasut * Copyright (C) 2011 Wolfram Sang, Pengutronix e.K. 9f4f680aaSMarek Vasut * 10f4f680aaSMarek Vasut * Which was based on a (non-working) driver which was: 11f4f680aaSMarek Vasut * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved. 12f4f680aaSMarek Vasut * 13f4f680aaSMarek Vasut * This program is free software; you can redistribute it and/or modify 14f4f680aaSMarek Vasut * it under the terms of the GNU General Public License as published by 15f4f680aaSMarek Vasut * the Free Software Foundation; either version 2 of the License, or 16f4f680aaSMarek Vasut * (at your option) any later version. 17f4f680aaSMarek Vasut * 18f4f680aaSMarek Vasut * This program is distributed in the hope that it will be useful, 19f4f680aaSMarek Vasut * but WITHOUT ANY WARRANTY; without even the implied warranty of 20f4f680aaSMarek Vasut * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21f4f680aaSMarek Vasut * GNU General Public License for more details. 22f4f680aaSMarek Vasut * 23f4f680aaSMarek Vasut * You should have received a copy of the GNU General Public License 24f4f680aaSMarek Vasut * along with this program; if not, write to the Free Software 25f4f680aaSMarek Vasut * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 26f4f680aaSMarek Vasut * 27f4f680aaSMarek Vasut */ 28f4f680aaSMarek Vasut 29f4f680aaSMarek Vasut #include <common.h> 30f4f680aaSMarek Vasut #include <malloc.h> 31f4f680aaSMarek Vasut #include <asm/errno.h> 32f4f680aaSMarek Vasut #include <asm/io.h> 33f4f680aaSMarek Vasut #include <asm/arch/clock.h> 34f4f680aaSMarek Vasut #include <asm/arch/imx-regs.h> 35f4f680aaSMarek Vasut #include <asm/arch/sys_proto.h> 36f4f680aaSMarek Vasut 37f4f680aaSMarek Vasut #define MXS_I2C_MAX_TIMEOUT 1000000 38f4f680aaSMarek Vasut 39f4f680aaSMarek Vasut void mxs_i2c_reset(void) 40f4f680aaSMarek Vasut { 41f4f680aaSMarek Vasut struct mx28_i2c_regs *i2c_regs = (struct mx28_i2c_regs *)MXS_I2C0_BASE; 42f4f680aaSMarek Vasut int ret; 43f4f680aaSMarek Vasut 44f4f680aaSMarek Vasut ret = mx28_reset_block(&i2c_regs->hw_i2c_ctrl0_reg); 45f4f680aaSMarek Vasut if (ret) { 46f4f680aaSMarek Vasut debug("MXS I2C: Block reset timeout\n"); 47f4f680aaSMarek Vasut return; 48f4f680aaSMarek Vasut } 49f4f680aaSMarek Vasut 50f4f680aaSMarek Vasut writel(I2C_CTRL1_DATA_ENGINE_CMPLT_IRQ | I2C_CTRL1_NO_SLAVE_ACK_IRQ | 51f4f680aaSMarek Vasut I2C_CTRL1_EARLY_TERM_IRQ | I2C_CTRL1_MASTER_LOSS_IRQ | 52f4f680aaSMarek Vasut I2C_CTRL1_SLAVE_STOP_IRQ | I2C_CTRL1_SLAVE_IRQ, 53f4f680aaSMarek Vasut &i2c_regs->hw_i2c_ctrl1_clr); 54f4f680aaSMarek Vasut 55f4f680aaSMarek Vasut writel(I2C_QUEUECTRL_PIO_QUEUE_MODE, &i2c_regs->hw_i2c_queuectrl_set); 56f4f680aaSMarek Vasut } 57f4f680aaSMarek Vasut 58f4f680aaSMarek Vasut void mxs_i2c_setup_read(uint8_t chip, int len) 59f4f680aaSMarek Vasut { 60f4f680aaSMarek Vasut struct mx28_i2c_regs *i2c_regs = (struct mx28_i2c_regs *)MXS_I2C0_BASE; 61f4f680aaSMarek Vasut 62f4f680aaSMarek Vasut writel(I2C_QUEUECMD_RETAIN_CLOCK | I2C_QUEUECMD_PRE_SEND_START | 63f4f680aaSMarek Vasut I2C_QUEUECMD_MASTER_MODE | I2C_QUEUECMD_DIRECTION | 64f4f680aaSMarek Vasut (1 << I2C_QUEUECMD_XFER_COUNT_OFFSET), 65f4f680aaSMarek Vasut &i2c_regs->hw_i2c_queuecmd); 66f4f680aaSMarek Vasut 67f4f680aaSMarek Vasut writel((chip << 1) | 1, &i2c_regs->hw_i2c_data); 68f4f680aaSMarek Vasut 69f4f680aaSMarek Vasut writel(I2C_QUEUECMD_SEND_NAK_ON_LAST | I2C_QUEUECMD_MASTER_MODE | 70f4f680aaSMarek Vasut (len << I2C_QUEUECMD_XFER_COUNT_OFFSET) | 71f4f680aaSMarek Vasut I2C_QUEUECMD_POST_SEND_STOP, &i2c_regs->hw_i2c_queuecmd); 72f4f680aaSMarek Vasut 73f4f680aaSMarek Vasut writel(I2C_QUEUECTRL_QUEUE_RUN, &i2c_regs->hw_i2c_queuectrl_set); 74f4f680aaSMarek Vasut } 75f4f680aaSMarek Vasut 76f4f680aaSMarek Vasut void mxs_i2c_write(uchar chip, uint addr, int alen, 77f4f680aaSMarek Vasut uchar *buf, int blen, int stop) 78f4f680aaSMarek Vasut { 79f4f680aaSMarek Vasut struct mx28_i2c_regs *i2c_regs = (struct mx28_i2c_regs *)MXS_I2C0_BASE; 80f4f680aaSMarek Vasut uint32_t data; 81f4f680aaSMarek Vasut int i, remain, off; 82f4f680aaSMarek Vasut 83f4f680aaSMarek Vasut if ((alen > 4) || (alen == 0)) { 84f4f680aaSMarek Vasut debug("MXS I2C: Invalid address length\n"); 85f4f680aaSMarek Vasut return; 86f4f680aaSMarek Vasut } 87f4f680aaSMarek Vasut 88f4f680aaSMarek Vasut if (stop) 89f4f680aaSMarek Vasut stop = I2C_QUEUECMD_POST_SEND_STOP; 90f4f680aaSMarek Vasut 91f4f680aaSMarek Vasut writel(I2C_QUEUECMD_PRE_SEND_START | 92f4f680aaSMarek Vasut I2C_QUEUECMD_MASTER_MODE | I2C_QUEUECMD_DIRECTION | 93f4f680aaSMarek Vasut ((blen + alen + 1) << I2C_QUEUECMD_XFER_COUNT_OFFSET) | stop, 94f4f680aaSMarek Vasut &i2c_regs->hw_i2c_queuecmd); 95f4f680aaSMarek Vasut 96f4f680aaSMarek Vasut data = (chip << 1) << 24; 97f4f680aaSMarek Vasut 98f4f680aaSMarek Vasut for (i = 0; i < alen; i++) { 99f4f680aaSMarek Vasut data >>= 8; 100*fa86d1c0STorsten Fleischer data |= ((char *)&addr)[alen - i - 1] << 24; 101f4f680aaSMarek Vasut if ((i & 3) == 2) 102f4f680aaSMarek Vasut writel(data, &i2c_regs->hw_i2c_data); 103f4f680aaSMarek Vasut } 104f4f680aaSMarek Vasut 105f4f680aaSMarek Vasut off = i; 106f4f680aaSMarek Vasut for (; i < off + blen; i++) { 107f4f680aaSMarek Vasut data >>= 8; 108f4f680aaSMarek Vasut data |= buf[i - off] << 24; 109f4f680aaSMarek Vasut if ((i & 3) == 2) 110f4f680aaSMarek Vasut writel(data, &i2c_regs->hw_i2c_data); 111f4f680aaSMarek Vasut } 112f4f680aaSMarek Vasut 113f4f680aaSMarek Vasut remain = 24 - ((i & 3) * 8); 114f4f680aaSMarek Vasut if (remain) 115f4f680aaSMarek Vasut writel(data >> remain, &i2c_regs->hw_i2c_data); 116f4f680aaSMarek Vasut 117f4f680aaSMarek Vasut writel(I2C_QUEUECTRL_QUEUE_RUN, &i2c_regs->hw_i2c_queuectrl_set); 118f4f680aaSMarek Vasut } 119f4f680aaSMarek Vasut 120f4f680aaSMarek Vasut int mxs_i2c_wait_for_ack(void) 121f4f680aaSMarek Vasut { 122f4f680aaSMarek Vasut struct mx28_i2c_regs *i2c_regs = (struct mx28_i2c_regs *)MXS_I2C0_BASE; 123f4f680aaSMarek Vasut uint32_t tmp; 124f4f680aaSMarek Vasut int timeout = MXS_I2C_MAX_TIMEOUT; 125f4f680aaSMarek Vasut 126f4f680aaSMarek Vasut for (;;) { 127f4f680aaSMarek Vasut tmp = readl(&i2c_regs->hw_i2c_ctrl1); 128f4f680aaSMarek Vasut if (tmp & I2C_CTRL1_NO_SLAVE_ACK_IRQ) { 129f4f680aaSMarek Vasut debug("MXS I2C: No slave ACK\n"); 130f4f680aaSMarek Vasut goto err; 131f4f680aaSMarek Vasut } 132f4f680aaSMarek Vasut 133f4f680aaSMarek Vasut if (tmp & ( 134f4f680aaSMarek Vasut I2C_CTRL1_EARLY_TERM_IRQ | I2C_CTRL1_MASTER_LOSS_IRQ | 135f4f680aaSMarek Vasut I2C_CTRL1_SLAVE_STOP_IRQ | I2C_CTRL1_SLAVE_IRQ)) { 136f4f680aaSMarek Vasut debug("MXS I2C: Error (CTRL1 = %08x)\n", tmp); 137f4f680aaSMarek Vasut goto err; 138f4f680aaSMarek Vasut } 139f4f680aaSMarek Vasut 140f4f680aaSMarek Vasut if (tmp & I2C_CTRL1_DATA_ENGINE_CMPLT_IRQ) 141f4f680aaSMarek Vasut break; 142f4f680aaSMarek Vasut 143f4f680aaSMarek Vasut if (!timeout--) { 144f4f680aaSMarek Vasut debug("MXS I2C: Operation timed out\n"); 145f4f680aaSMarek Vasut goto err; 146f4f680aaSMarek Vasut } 147f4f680aaSMarek Vasut 148f4f680aaSMarek Vasut udelay(1); 149f4f680aaSMarek Vasut } 150f4f680aaSMarek Vasut 151f4f680aaSMarek Vasut return 0; 152f4f680aaSMarek Vasut 153f4f680aaSMarek Vasut err: 154f4f680aaSMarek Vasut mxs_i2c_reset(); 155f4f680aaSMarek Vasut return 1; 156f4f680aaSMarek Vasut } 157f4f680aaSMarek Vasut 158f4f680aaSMarek Vasut int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) 159f4f680aaSMarek Vasut { 160f4f680aaSMarek Vasut struct mx28_i2c_regs *i2c_regs = (struct mx28_i2c_regs *)MXS_I2C0_BASE; 161f4f680aaSMarek Vasut uint32_t tmp = 0; 162f4f680aaSMarek Vasut int ret; 163f4f680aaSMarek Vasut int i; 164f4f680aaSMarek Vasut 165f4f680aaSMarek Vasut mxs_i2c_write(chip, addr, alen, NULL, 0, 0); 166f4f680aaSMarek Vasut ret = mxs_i2c_wait_for_ack(); 167f4f680aaSMarek Vasut if (ret) { 168f4f680aaSMarek Vasut debug("MXS I2C: Failed writing address\n"); 169f4f680aaSMarek Vasut return ret; 170f4f680aaSMarek Vasut } 171f4f680aaSMarek Vasut 172f4f680aaSMarek Vasut mxs_i2c_setup_read(chip, len); 173f4f680aaSMarek Vasut ret = mxs_i2c_wait_for_ack(); 174f4f680aaSMarek Vasut if (ret) { 175f4f680aaSMarek Vasut debug("MXS I2C: Failed reading address\n"); 176f4f680aaSMarek Vasut return ret; 177f4f680aaSMarek Vasut } 178f4f680aaSMarek Vasut 179f4f680aaSMarek Vasut for (i = 0; i < len; i++) { 180f4f680aaSMarek Vasut if (!(i & 3)) { 181f4f680aaSMarek Vasut while (readl(&i2c_regs->hw_i2c_queuestat) & 182f4f680aaSMarek Vasut I2C_QUEUESTAT_RD_QUEUE_EMPTY) 183f4f680aaSMarek Vasut ; 184f4f680aaSMarek Vasut tmp = readl(&i2c_regs->hw_i2c_queuedata); 185f4f680aaSMarek Vasut } 186f4f680aaSMarek Vasut buffer[i] = tmp & 0xff; 187f4f680aaSMarek Vasut tmp >>= 8; 188f4f680aaSMarek Vasut } 189f4f680aaSMarek Vasut 190f4f680aaSMarek Vasut return 0; 191f4f680aaSMarek Vasut } 192f4f680aaSMarek Vasut 193f4f680aaSMarek Vasut int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) 194f4f680aaSMarek Vasut { 195f4f680aaSMarek Vasut int ret; 196f4f680aaSMarek Vasut mxs_i2c_write(chip, addr, alen, buffer, len, 1); 197f4f680aaSMarek Vasut ret = mxs_i2c_wait_for_ack(); 198f4f680aaSMarek Vasut if (ret) 199f4f680aaSMarek Vasut debug("MXS I2C: Failed writing address\n"); 200f4f680aaSMarek Vasut 201f4f680aaSMarek Vasut return ret; 202f4f680aaSMarek Vasut } 203f4f680aaSMarek Vasut 204f4f680aaSMarek Vasut int i2c_probe(uchar chip) 205f4f680aaSMarek Vasut { 206f4f680aaSMarek Vasut int ret; 207f4f680aaSMarek Vasut mxs_i2c_write(chip, 0, 1, NULL, 0, 1); 208f4f680aaSMarek Vasut ret = mxs_i2c_wait_for_ack(); 209f4f680aaSMarek Vasut mxs_i2c_reset(); 210f4f680aaSMarek Vasut return ret; 211f4f680aaSMarek Vasut } 212f4f680aaSMarek Vasut 213f4f680aaSMarek Vasut void i2c_init(int speed, int slaveadd) 214f4f680aaSMarek Vasut { 215f4f680aaSMarek Vasut struct mx28_i2c_regs *i2c_regs = (struct mx28_i2c_regs *)MXS_I2C0_BASE; 216f4f680aaSMarek Vasut 217f4f680aaSMarek Vasut mxs_i2c_reset(); 218f4f680aaSMarek Vasut 219f4f680aaSMarek Vasut switch (speed) { 220f4f680aaSMarek Vasut case 100000: 221f4f680aaSMarek Vasut writel((0x0078 << I2C_TIMING0_HIGH_COUNT_OFFSET) | 222f4f680aaSMarek Vasut (0x0030 << I2C_TIMING0_RCV_COUNT_OFFSET), 223f4f680aaSMarek Vasut &i2c_regs->hw_i2c_timing0); 224f4f680aaSMarek Vasut writel((0x0080 << I2C_TIMING1_LOW_COUNT_OFFSET) | 225f4f680aaSMarek Vasut (0x0030 << I2C_TIMING1_XMIT_COUNT_OFFSET), 226f4f680aaSMarek Vasut &i2c_regs->hw_i2c_timing1); 227f4f680aaSMarek Vasut break; 228f4f680aaSMarek Vasut case 400000: 229f4f680aaSMarek Vasut writel((0x000f << I2C_TIMING0_HIGH_COUNT_OFFSET) | 230f4f680aaSMarek Vasut (0x0007 << I2C_TIMING0_RCV_COUNT_OFFSET), 231f4f680aaSMarek Vasut &i2c_regs->hw_i2c_timing0); 232f4f680aaSMarek Vasut writel((0x001f << I2C_TIMING1_LOW_COUNT_OFFSET) | 233f4f680aaSMarek Vasut (0x000f << I2C_TIMING1_XMIT_COUNT_OFFSET), 234f4f680aaSMarek Vasut &i2c_regs->hw_i2c_timing1); 235f4f680aaSMarek Vasut break; 236f4f680aaSMarek Vasut default: 237f4f680aaSMarek Vasut printf("MXS I2C: Invalid speed selected (%d Hz)\n", speed); 238f4f680aaSMarek Vasut return; 239f4f680aaSMarek Vasut } 240f4f680aaSMarek Vasut 241f4f680aaSMarek Vasut writel((0x0015 << I2C_TIMING2_BUS_FREE_OFFSET) | 242f4f680aaSMarek Vasut (0x000d << I2C_TIMING2_LEADIN_COUNT_OFFSET), 243f4f680aaSMarek Vasut &i2c_regs->hw_i2c_timing2); 244f4f680aaSMarek Vasut 245f4f680aaSMarek Vasut return; 246f4f680aaSMarek Vasut } 247