1942ba996SJean-Christophe PLAGNIOL-VILLARD /* 2942ba996SJean-Christophe PLAGNIOL-VILLARD * TI DaVinci (TMS320DM644x) I2C driver. 3942ba996SJean-Christophe PLAGNIOL-VILLARD * 4e8459dccSVitaly Andrianov * (C) Copyright 2012-2014 5e8459dccSVitaly Andrianov * Texas Instruments Incorporated, <www.ti.com> 6e8459dccSVitaly Andrianov * (C) Copyright 2007 Sergey Kubushyn <ksi@koi8.net> 7942ba996SJean-Christophe PLAGNIOL-VILLARD * -------------------------------------------------------- 8942ba996SJean-Christophe PLAGNIOL-VILLARD * 91a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 10*28527096SSimon Glass * 11*28527096SSimon Glass * NOTE: This driver should be converted to driver model before June 2017. 12*28527096SSimon Glass * Please see doc/driver-model/i2c-howto.txt for instructions. 13942ba996SJean-Christophe PLAGNIOL-VILLARD */ 14942ba996SJean-Christophe PLAGNIOL-VILLARD 15942ba996SJean-Christophe PLAGNIOL-VILLARD #include <common.h> 16942ba996SJean-Christophe PLAGNIOL-VILLARD #include <i2c.h> 17942ba996SJean-Christophe PLAGNIOL-VILLARD #include <asm/arch/hardware.h> 18942ba996SJean-Christophe PLAGNIOL-VILLARD #include <asm/arch/i2c_defs.h> 19e8459dccSVitaly Andrianov #include <asm/io.h> 20356d15ebSKaricheri, Muralidharan #include "davinci_i2c.h" 21942ba996SJean-Christophe PLAGNIOL-VILLARD 22942ba996SJean-Christophe PLAGNIOL-VILLARD #define CHECK_NACK() \ 23942ba996SJean-Christophe PLAGNIOL-VILLARD do {\ 24942ba996SJean-Christophe PLAGNIOL-VILLARD if (tmp & (I2C_TIMEOUT | I2C_STAT_NACK)) {\ 25e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = 0;\ 26e8459dccSVitaly Andrianov return 1;\ 27942ba996SJean-Christophe PLAGNIOL-VILLARD } \ 28942ba996SJean-Christophe PLAGNIOL-VILLARD } while (0) 29942ba996SJean-Christophe PLAGNIOL-VILLARD 30e8459dccSVitaly Andrianov static struct i2c_regs *davinci_get_base(struct i2c_adapter *adap); 31942ba996SJean-Christophe PLAGNIOL-VILLARD 32e8459dccSVitaly Andrianov static int wait_for_bus(struct i2c_adapter *adap) 33942ba996SJean-Christophe PLAGNIOL-VILLARD { 34e8459dccSVitaly Andrianov struct i2c_regs *i2c_base = davinci_get_base(adap); 35942ba996SJean-Christophe PLAGNIOL-VILLARD int stat, timeout; 36942ba996SJean-Christophe PLAGNIOL-VILLARD 37e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_stat)) = 0xffff; 38942ba996SJean-Christophe PLAGNIOL-VILLARD 39942ba996SJean-Christophe PLAGNIOL-VILLARD for (timeout = 0; timeout < 10; timeout++) { 40e8459dccSVitaly Andrianov stat = REG(&(i2c_base->i2c_stat)); 41e8459dccSVitaly Andrianov if (!((stat) & I2C_STAT_BB)) { 42e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_stat)) = 0xffff; 4349d6da60SHeiko Schocher return 0; 4449d6da60SHeiko Schocher } 45942ba996SJean-Christophe PLAGNIOL-VILLARD 46e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_stat)) = stat; 47e8459dccSVitaly Andrianov udelay(50000); 48e8459dccSVitaly Andrianov } 49e8459dccSVitaly Andrianov 50e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_stat)) = 0xffff; 51e8459dccSVitaly Andrianov return 1; 52e8459dccSVitaly Andrianov } 53e8459dccSVitaly Andrianov 54e8459dccSVitaly Andrianov 55e8459dccSVitaly Andrianov static int poll_i2c_irq(struct i2c_adapter *adap, int mask) 56942ba996SJean-Christophe PLAGNIOL-VILLARD { 57e8459dccSVitaly Andrianov struct i2c_regs *i2c_base = davinci_get_base(adap); 58e8459dccSVitaly Andrianov int stat, timeout; 59e8459dccSVitaly Andrianov 60e8459dccSVitaly Andrianov for (timeout = 0; timeout < 10; timeout++) { 61e8459dccSVitaly Andrianov udelay(1000); 62e8459dccSVitaly Andrianov stat = REG(&(i2c_base->i2c_stat)); 63e8459dccSVitaly Andrianov if (stat & mask) 64e8459dccSVitaly Andrianov return stat; 65e8459dccSVitaly Andrianov } 66e8459dccSVitaly Andrianov 67e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_stat)) = 0xffff; 68e8459dccSVitaly Andrianov return stat | I2C_TIMEOUT; 69e8459dccSVitaly Andrianov } 70e8459dccSVitaly Andrianov 71e8459dccSVitaly Andrianov static void flush_rx(struct i2c_adapter *adap) 72e8459dccSVitaly Andrianov { 73e8459dccSVitaly Andrianov struct i2c_regs *i2c_base = davinci_get_base(adap); 74e8459dccSVitaly Andrianov 75e8459dccSVitaly Andrianov while (1) { 76e8459dccSVitaly Andrianov if (!(REG(&(i2c_base->i2c_stat)) & I2C_STAT_RRDY)) 77e8459dccSVitaly Andrianov break; 78e8459dccSVitaly Andrianov 79e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_drr)); 80e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_stat)) = I2C_STAT_RRDY; 81e8459dccSVitaly Andrianov udelay(1000); 82e8459dccSVitaly Andrianov } 83e8459dccSVitaly Andrianov } 84e8459dccSVitaly Andrianov 85e8459dccSVitaly Andrianov static uint davinci_i2c_setspeed(struct i2c_adapter *adap, uint speed) 86e8459dccSVitaly Andrianov { 87e8459dccSVitaly Andrianov struct i2c_regs *i2c_base = davinci_get_base(adap); 88e8459dccSVitaly Andrianov uint32_t div, psc; 89e8459dccSVitaly Andrianov 90e8459dccSVitaly Andrianov psc = 2; 91e8459dccSVitaly Andrianov /* SCLL + SCLH */ 92e8459dccSVitaly Andrianov div = (CONFIG_SYS_HZ_CLOCK / ((psc + 1) * speed)) - 10; 93e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_psc)) = psc; /* 27MHz / (2 + 1) = 9MHz */ 94e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_scll)) = (div * 50) / 100; /* 50% Duty */ 95e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_sclh)) = div - REG(&(i2c_base->i2c_scll)); 96e8459dccSVitaly Andrianov 97e8459dccSVitaly Andrianov adap->speed = speed; 98e8459dccSVitaly Andrianov return 0; 99e8459dccSVitaly Andrianov } 100e8459dccSVitaly Andrianov 101e8459dccSVitaly Andrianov static void davinci_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) 102e8459dccSVitaly Andrianov { 103e8459dccSVitaly Andrianov struct i2c_regs *i2c_base = davinci_get_base(adap); 104e8459dccSVitaly Andrianov 105e8459dccSVitaly Andrianov if (REG(&(i2c_base->i2c_con)) & I2C_CON_EN) { 106e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = 0; 107e8459dccSVitaly Andrianov udelay(50000); 108e8459dccSVitaly Andrianov } 109e8459dccSVitaly Andrianov 110e8459dccSVitaly Andrianov davinci_i2c_setspeed(adap, speed); 111e8459dccSVitaly Andrianov 112e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_oa)) = slaveadd; 113e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_cnt)) = 0; 114e8459dccSVitaly Andrianov 115e8459dccSVitaly Andrianov /* Interrupts must be enabled or I2C module won't work */ 116e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_ie)) = I2C_IE_SCD_IE | I2C_IE_XRDY_IE | 117e8459dccSVitaly Andrianov I2C_IE_RRDY_IE | I2C_IE_ARDY_IE | I2C_IE_NACK_IE; 118e8459dccSVitaly Andrianov 119e8459dccSVitaly Andrianov /* Now enable I2C controller (get it out of reset) */ 120e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = I2C_CON_EN; 121e8459dccSVitaly Andrianov 122e8459dccSVitaly Andrianov udelay(1000); 123e8459dccSVitaly Andrianov } 124e8459dccSVitaly Andrianov 125e8459dccSVitaly Andrianov static int davinci_i2c_probe(struct i2c_adapter *adap, uint8_t chip) 126e8459dccSVitaly Andrianov { 127e8459dccSVitaly Andrianov struct i2c_regs *i2c_base = davinci_get_base(adap); 128942ba996SJean-Christophe PLAGNIOL-VILLARD int rc = 1; 129942ba996SJean-Christophe PLAGNIOL-VILLARD 130e8459dccSVitaly Andrianov if (chip == REG(&(i2c_base->i2c_oa))) 131e8459dccSVitaly Andrianov return rc; 132942ba996SJean-Christophe PLAGNIOL-VILLARD 133e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = 0; 134e8459dccSVitaly Andrianov if (wait_for_bus(adap)) 135e8459dccSVitaly Andrianov return 1; 136942ba996SJean-Christophe PLAGNIOL-VILLARD 137942ba996SJean-Christophe PLAGNIOL-VILLARD /* try to read one byte from current (or only) address */ 138e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_cnt)) = 1; 139e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_sa)) = chip; 140e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | 141e8459dccSVitaly Andrianov I2C_CON_STP); 142942ba996SJean-Christophe PLAGNIOL-VILLARD udelay(50000); 143942ba996SJean-Christophe PLAGNIOL-VILLARD 144e8459dccSVitaly Andrianov if (!(REG(&(i2c_base->i2c_stat)) & I2C_STAT_NACK)) { 145942ba996SJean-Christophe PLAGNIOL-VILLARD rc = 0; 146e8459dccSVitaly Andrianov flush_rx(adap); 147e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_stat)) = 0xffff; 148942ba996SJean-Christophe PLAGNIOL-VILLARD } else { 149e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_stat)) = 0xffff; 150e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) |= I2C_CON_STP; 151942ba996SJean-Christophe PLAGNIOL-VILLARD udelay(20000); 152e8459dccSVitaly Andrianov if (wait_for_bus(adap)) 153e8459dccSVitaly Andrianov return 1; 154942ba996SJean-Christophe PLAGNIOL-VILLARD } 155942ba996SJean-Christophe PLAGNIOL-VILLARD 156e8459dccSVitaly Andrianov flush_rx(adap); 157e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_stat)) = 0xffff; 158e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_cnt)) = 0; 159e8459dccSVitaly Andrianov return rc; 160942ba996SJean-Christophe PLAGNIOL-VILLARD } 161942ba996SJean-Christophe PLAGNIOL-VILLARD 162e8459dccSVitaly Andrianov static int davinci_i2c_read(struct i2c_adapter *adap, uint8_t chip, 163e8459dccSVitaly Andrianov uint32_t addr, int alen, uint8_t *buf, int len) 164942ba996SJean-Christophe PLAGNIOL-VILLARD { 165e8459dccSVitaly Andrianov struct i2c_regs *i2c_base = davinci_get_base(adap); 166e8459dccSVitaly Andrianov uint32_t tmp; 167942ba996SJean-Christophe PLAGNIOL-VILLARD int i; 168942ba996SJean-Christophe PLAGNIOL-VILLARD 169942ba996SJean-Christophe PLAGNIOL-VILLARD if ((alen < 0) || (alen > 2)) { 170e8459dccSVitaly Andrianov printf("%s(): bogus address length %x\n", __func__, alen); 171e8459dccSVitaly Andrianov return 1; 172942ba996SJean-Christophe PLAGNIOL-VILLARD } 173942ba996SJean-Christophe PLAGNIOL-VILLARD 174e8459dccSVitaly Andrianov if (wait_for_bus(adap)) 175e8459dccSVitaly Andrianov return 1; 176942ba996SJean-Christophe PLAGNIOL-VILLARD 177942ba996SJean-Christophe PLAGNIOL-VILLARD if (alen != 0) { 178942ba996SJean-Christophe PLAGNIOL-VILLARD /* Start address phase */ 179942ba996SJean-Christophe PLAGNIOL-VILLARD tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX; 180e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_cnt)) = alen; 181e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_sa)) = chip; 182e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = tmp; 183942ba996SJean-Christophe PLAGNIOL-VILLARD 184e8459dccSVitaly Andrianov tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK); 185942ba996SJean-Christophe PLAGNIOL-VILLARD 186942ba996SJean-Christophe PLAGNIOL-VILLARD CHECK_NACK(); 187942ba996SJean-Christophe PLAGNIOL-VILLARD 188942ba996SJean-Christophe PLAGNIOL-VILLARD switch (alen) { 189942ba996SJean-Christophe PLAGNIOL-VILLARD case 2: 190942ba996SJean-Christophe PLAGNIOL-VILLARD /* Send address MSByte */ 191942ba996SJean-Christophe PLAGNIOL-VILLARD if (tmp & I2C_STAT_XRDY) { 192e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_dxr)) = (addr >> 8) & 0xff; 193942ba996SJean-Christophe PLAGNIOL-VILLARD } else { 194e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = 0; 195e8459dccSVitaly Andrianov return 1; 196942ba996SJean-Christophe PLAGNIOL-VILLARD } 197942ba996SJean-Christophe PLAGNIOL-VILLARD 198e8459dccSVitaly Andrianov tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK); 199942ba996SJean-Christophe PLAGNIOL-VILLARD 200942ba996SJean-Christophe PLAGNIOL-VILLARD CHECK_NACK(); 201942ba996SJean-Christophe PLAGNIOL-VILLARD /* No break, fall through */ 202942ba996SJean-Christophe PLAGNIOL-VILLARD case 1: 203942ba996SJean-Christophe PLAGNIOL-VILLARD /* Send address LSByte */ 204942ba996SJean-Christophe PLAGNIOL-VILLARD if (tmp & I2C_STAT_XRDY) { 205e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_dxr)) = addr & 0xff; 206942ba996SJean-Christophe PLAGNIOL-VILLARD } else { 207e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = 0; 208e8459dccSVitaly Andrianov return 1; 209942ba996SJean-Christophe PLAGNIOL-VILLARD } 210942ba996SJean-Christophe PLAGNIOL-VILLARD 211e8459dccSVitaly Andrianov tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | 212e8459dccSVitaly Andrianov I2C_STAT_NACK | I2C_STAT_ARDY); 213942ba996SJean-Christophe PLAGNIOL-VILLARD 214942ba996SJean-Christophe PLAGNIOL-VILLARD CHECK_NACK(); 215942ba996SJean-Christophe PLAGNIOL-VILLARD 216942ba996SJean-Christophe PLAGNIOL-VILLARD if (!(tmp & I2C_STAT_ARDY)) { 217e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = 0; 218e8459dccSVitaly Andrianov return 1; 219942ba996SJean-Christophe PLAGNIOL-VILLARD } 220942ba996SJean-Christophe PLAGNIOL-VILLARD } 221942ba996SJean-Christophe PLAGNIOL-VILLARD } 222942ba996SJean-Christophe PLAGNIOL-VILLARD 223942ba996SJean-Christophe PLAGNIOL-VILLARD /* Address phase is over, now read 'len' bytes and stop */ 224942ba996SJean-Christophe PLAGNIOL-VILLARD tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP; 225e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_cnt)) = len & 0xffff; 226e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_sa)) = chip; 227e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = tmp; 228942ba996SJean-Christophe PLAGNIOL-VILLARD 229942ba996SJean-Christophe PLAGNIOL-VILLARD for (i = 0; i < len; i++) { 230e8459dccSVitaly Andrianov tmp = poll_i2c_irq(adap, I2C_STAT_RRDY | I2C_STAT_NACK | 231e8459dccSVitaly Andrianov I2C_STAT_ROVR); 232942ba996SJean-Christophe PLAGNIOL-VILLARD 233942ba996SJean-Christophe PLAGNIOL-VILLARD CHECK_NACK(); 234942ba996SJean-Christophe PLAGNIOL-VILLARD 235942ba996SJean-Christophe PLAGNIOL-VILLARD if (tmp & I2C_STAT_RRDY) { 236e8459dccSVitaly Andrianov buf[i] = REG(&(i2c_base->i2c_drr)); 237942ba996SJean-Christophe PLAGNIOL-VILLARD } else { 238e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = 0; 239e8459dccSVitaly Andrianov return 1; 240942ba996SJean-Christophe PLAGNIOL-VILLARD } 241942ba996SJean-Christophe PLAGNIOL-VILLARD } 242942ba996SJean-Christophe PLAGNIOL-VILLARD 243e8459dccSVitaly Andrianov tmp = poll_i2c_irq(adap, I2C_STAT_SCD | I2C_STAT_NACK); 244942ba996SJean-Christophe PLAGNIOL-VILLARD 245942ba996SJean-Christophe PLAGNIOL-VILLARD CHECK_NACK(); 246942ba996SJean-Christophe PLAGNIOL-VILLARD 247942ba996SJean-Christophe PLAGNIOL-VILLARD if (!(tmp & I2C_STAT_SCD)) { 248e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = 0; 249e8459dccSVitaly Andrianov return 1; 250942ba996SJean-Christophe PLAGNIOL-VILLARD } 251942ba996SJean-Christophe PLAGNIOL-VILLARD 252e8459dccSVitaly Andrianov flush_rx(adap); 253e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_stat)) = 0xffff; 254e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_cnt)) = 0; 255e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = 0; 256942ba996SJean-Christophe PLAGNIOL-VILLARD 257e8459dccSVitaly Andrianov return 0; 258942ba996SJean-Christophe PLAGNIOL-VILLARD } 259942ba996SJean-Christophe PLAGNIOL-VILLARD 260e8459dccSVitaly Andrianov static int davinci_i2c_write(struct i2c_adapter *adap, uint8_t chip, 261e8459dccSVitaly Andrianov uint32_t addr, int alen, uint8_t *buf, int len) 262942ba996SJean-Christophe PLAGNIOL-VILLARD { 263e8459dccSVitaly Andrianov struct i2c_regs *i2c_base = davinci_get_base(adap); 264e8459dccSVitaly Andrianov uint32_t tmp; 265942ba996SJean-Christophe PLAGNIOL-VILLARD int i; 266942ba996SJean-Christophe PLAGNIOL-VILLARD 267942ba996SJean-Christophe PLAGNIOL-VILLARD if ((alen < 0) || (alen > 2)) { 268e8459dccSVitaly Andrianov printf("%s(): bogus address length %x\n", __func__, alen); 269e8459dccSVitaly Andrianov return 1; 270942ba996SJean-Christophe PLAGNIOL-VILLARD } 271942ba996SJean-Christophe PLAGNIOL-VILLARD if (len < 0) { 272e8459dccSVitaly Andrianov printf("%s(): bogus length %x\n", __func__, len); 273e8459dccSVitaly Andrianov return 1; 274942ba996SJean-Christophe PLAGNIOL-VILLARD } 275942ba996SJean-Christophe PLAGNIOL-VILLARD 276e8459dccSVitaly Andrianov if (wait_for_bus(adap)) 277e8459dccSVitaly Andrianov return 1; 278942ba996SJean-Christophe PLAGNIOL-VILLARD 279942ba996SJean-Christophe PLAGNIOL-VILLARD /* Start address phase */ 280e8459dccSVitaly Andrianov tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | 281e8459dccSVitaly Andrianov I2C_CON_TRX | I2C_CON_STP; 282e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_cnt)) = (alen == 0) ? 283e8459dccSVitaly Andrianov len & 0xffff : (len & 0xffff) + alen; 284e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_sa)) = chip; 285e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = tmp; 286942ba996SJean-Christophe PLAGNIOL-VILLARD 287942ba996SJean-Christophe PLAGNIOL-VILLARD switch (alen) { 288942ba996SJean-Christophe PLAGNIOL-VILLARD case 2: 289942ba996SJean-Christophe PLAGNIOL-VILLARD /* Send address MSByte */ 290e8459dccSVitaly Andrianov tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK); 291942ba996SJean-Christophe PLAGNIOL-VILLARD 292942ba996SJean-Christophe PLAGNIOL-VILLARD CHECK_NACK(); 293942ba996SJean-Christophe PLAGNIOL-VILLARD 294942ba996SJean-Christophe PLAGNIOL-VILLARD if (tmp & I2C_STAT_XRDY) { 295e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_dxr)) = (addr >> 8) & 0xff; 296942ba996SJean-Christophe PLAGNIOL-VILLARD } else { 297e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = 0; 298e8459dccSVitaly Andrianov return 1; 299942ba996SJean-Christophe PLAGNIOL-VILLARD } 300942ba996SJean-Christophe PLAGNIOL-VILLARD /* No break, fall through */ 301942ba996SJean-Christophe PLAGNIOL-VILLARD case 1: 302942ba996SJean-Christophe PLAGNIOL-VILLARD /* Send address LSByte */ 303e8459dccSVitaly Andrianov tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK); 304942ba996SJean-Christophe PLAGNIOL-VILLARD 305942ba996SJean-Christophe PLAGNIOL-VILLARD CHECK_NACK(); 306942ba996SJean-Christophe PLAGNIOL-VILLARD 307942ba996SJean-Christophe PLAGNIOL-VILLARD if (tmp & I2C_STAT_XRDY) { 308e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_dxr)) = addr & 0xff; 309942ba996SJean-Christophe PLAGNIOL-VILLARD } else { 310e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = 0; 311e8459dccSVitaly Andrianov return 1; 312942ba996SJean-Christophe PLAGNIOL-VILLARD } 313942ba996SJean-Christophe PLAGNIOL-VILLARD } 314942ba996SJean-Christophe PLAGNIOL-VILLARD 315942ba996SJean-Christophe PLAGNIOL-VILLARD for (i = 0; i < len; i++) { 316e8459dccSVitaly Andrianov tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK); 317942ba996SJean-Christophe PLAGNIOL-VILLARD 318942ba996SJean-Christophe PLAGNIOL-VILLARD CHECK_NACK(); 319942ba996SJean-Christophe PLAGNIOL-VILLARD 320e8459dccSVitaly Andrianov if (tmp & I2C_STAT_XRDY) 321e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_dxr)) = buf[i]; 322e8459dccSVitaly Andrianov else 323e8459dccSVitaly Andrianov return 1; 324942ba996SJean-Christophe PLAGNIOL-VILLARD } 325942ba996SJean-Christophe PLAGNIOL-VILLARD 326e8459dccSVitaly Andrianov tmp = poll_i2c_irq(adap, I2C_STAT_SCD | I2C_STAT_NACK); 327942ba996SJean-Christophe PLAGNIOL-VILLARD 328942ba996SJean-Christophe PLAGNIOL-VILLARD CHECK_NACK(); 329942ba996SJean-Christophe PLAGNIOL-VILLARD 330942ba996SJean-Christophe PLAGNIOL-VILLARD if (!(tmp & I2C_STAT_SCD)) { 331e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = 0; 332e8459dccSVitaly Andrianov return 1; 333942ba996SJean-Christophe PLAGNIOL-VILLARD } 334942ba996SJean-Christophe PLAGNIOL-VILLARD 335e8459dccSVitaly Andrianov flush_rx(adap); 336e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_stat)) = 0xffff; 337e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_cnt)) = 0; 338e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = 0; 339942ba996SJean-Christophe PLAGNIOL-VILLARD 340e8459dccSVitaly Andrianov return 0; 341942ba996SJean-Christophe PLAGNIOL-VILLARD } 342e8459dccSVitaly Andrianov 343e8459dccSVitaly Andrianov static struct i2c_regs *davinci_get_base(struct i2c_adapter *adap) 344e8459dccSVitaly Andrianov { 345e8459dccSVitaly Andrianov switch (adap->hwadapnr) { 346e8459dccSVitaly Andrianov #if I2C_BUS_MAX >= 3 347e8459dccSVitaly Andrianov case 2: 348e8459dccSVitaly Andrianov return (struct i2c_regs *)I2C2_BASE; 349e8459dccSVitaly Andrianov #endif 350e8459dccSVitaly Andrianov #if I2C_BUS_MAX >= 2 351e8459dccSVitaly Andrianov case 1: 352e8459dccSVitaly Andrianov return (struct i2c_regs *)I2C1_BASE; 353e8459dccSVitaly Andrianov #endif 354e8459dccSVitaly Andrianov case 0: 355e8459dccSVitaly Andrianov return (struct i2c_regs *)I2C_BASE; 356e8459dccSVitaly Andrianov 357e8459dccSVitaly Andrianov default: 358e8459dccSVitaly Andrianov printf("wrong hwadapnr: %d\n", adap->hwadapnr); 359e8459dccSVitaly Andrianov } 360e8459dccSVitaly Andrianov 361e8459dccSVitaly Andrianov return NULL; 362e8459dccSVitaly Andrianov } 363e8459dccSVitaly Andrianov 364e8459dccSVitaly Andrianov U_BOOT_I2C_ADAP_COMPLETE(davinci_0, davinci_i2c_init, davinci_i2c_probe, 365e8459dccSVitaly Andrianov davinci_i2c_read, davinci_i2c_write, 366e8459dccSVitaly Andrianov davinci_i2c_setspeed, 367e8459dccSVitaly Andrianov CONFIG_SYS_DAVINCI_I2C_SPEED, 368e8459dccSVitaly Andrianov CONFIG_SYS_DAVINCI_I2C_SLAVE, 369e8459dccSVitaly Andrianov 0) 370e8459dccSVitaly Andrianov 371e8459dccSVitaly Andrianov #if I2C_BUS_MAX >= 2 372e8459dccSVitaly Andrianov U_BOOT_I2C_ADAP_COMPLETE(davinci_1, davinci_i2c_init, davinci_i2c_probe, 373e8459dccSVitaly Andrianov davinci_i2c_read, davinci_i2c_write, 374e8459dccSVitaly Andrianov davinci_i2c_setspeed, 375e8459dccSVitaly Andrianov CONFIG_SYS_DAVINCI_I2C_SPEED1, 376e8459dccSVitaly Andrianov CONFIG_SYS_DAVINCI_I2C_SLAVE1, 377e8459dccSVitaly Andrianov 1) 378e8459dccSVitaly Andrianov #endif 379e8459dccSVitaly Andrianov 380e8459dccSVitaly Andrianov #if I2C_BUS_MAX >= 3 381e8459dccSVitaly Andrianov U_BOOT_I2C_ADAP_COMPLETE(davinci_2, davinci_i2c_init, davinci_i2c_probe, 382e8459dccSVitaly Andrianov davinci_i2c_read, davinci_i2c_write, 383e8459dccSVitaly Andrianov davinci_i2c_setspeed, 384e8459dccSVitaly Andrianov CONFIG_SYS_DAVINCI_I2C_SPEED2, 385e8459dccSVitaly Andrianov CONFIG_SYS_DAVINCI_I2C_SLAVE2, 386e8459dccSVitaly Andrianov 2) 387e8459dccSVitaly Andrianov #endif 388