1942ba996SJean-Christophe PLAGNIOL-VILLARD /* 2942ba996SJean-Christophe PLAGNIOL-VILLARD * TI DaVinci (TMS320DM644x) I2C driver. 3942ba996SJean-Christophe PLAGNIOL-VILLARD * 4*e8459dccSVitaly Andrianov * (C) Copyright 2012-2014 5*e8459dccSVitaly Andrianov * Texas Instruments Incorporated, <www.ti.com> 6*e8459dccSVitaly 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+ 10942ba996SJean-Christophe PLAGNIOL-VILLARD */ 11942ba996SJean-Christophe PLAGNIOL-VILLARD 12942ba996SJean-Christophe PLAGNIOL-VILLARD #include <common.h> 13942ba996SJean-Christophe PLAGNIOL-VILLARD #include <i2c.h> 14942ba996SJean-Christophe PLAGNIOL-VILLARD #include <asm/arch/hardware.h> 15942ba996SJean-Christophe PLAGNIOL-VILLARD #include <asm/arch/i2c_defs.h> 16*e8459dccSVitaly Andrianov #include <asm/io.h> 17356d15ebSKaricheri, Muralidharan #include "davinci_i2c.h" 18942ba996SJean-Christophe PLAGNIOL-VILLARD 19942ba996SJean-Christophe PLAGNIOL-VILLARD #define CHECK_NACK() \ 20942ba996SJean-Christophe PLAGNIOL-VILLARD do {\ 21942ba996SJean-Christophe PLAGNIOL-VILLARD if (tmp & (I2C_TIMEOUT | I2C_STAT_NACK)) {\ 22*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = 0;\ 23*e8459dccSVitaly Andrianov return 1;\ 24942ba996SJean-Christophe PLAGNIOL-VILLARD } \ 25942ba996SJean-Christophe PLAGNIOL-VILLARD } while (0) 26942ba996SJean-Christophe PLAGNIOL-VILLARD 27*e8459dccSVitaly Andrianov static struct i2c_regs *davinci_get_base(struct i2c_adapter *adap); 28942ba996SJean-Christophe PLAGNIOL-VILLARD 29*e8459dccSVitaly Andrianov static int wait_for_bus(struct i2c_adapter *adap) 30942ba996SJean-Christophe PLAGNIOL-VILLARD { 31*e8459dccSVitaly Andrianov struct i2c_regs *i2c_base = davinci_get_base(adap); 32942ba996SJean-Christophe PLAGNIOL-VILLARD int stat, timeout; 33942ba996SJean-Christophe PLAGNIOL-VILLARD 34*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_stat)) = 0xffff; 35942ba996SJean-Christophe PLAGNIOL-VILLARD 36942ba996SJean-Christophe PLAGNIOL-VILLARD for (timeout = 0; timeout < 10; timeout++) { 37*e8459dccSVitaly Andrianov stat = REG(&(i2c_base->i2c_stat)); 38*e8459dccSVitaly Andrianov if (!((stat) & I2C_STAT_BB)) { 39*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_stat)) = 0xffff; 4049d6da60SHeiko Schocher return 0; 4149d6da60SHeiko Schocher } 42942ba996SJean-Christophe PLAGNIOL-VILLARD 43*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_stat)) = stat; 44*e8459dccSVitaly Andrianov udelay(50000); 45*e8459dccSVitaly Andrianov } 46*e8459dccSVitaly Andrianov 47*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_stat)) = 0xffff; 48*e8459dccSVitaly Andrianov return 1; 49*e8459dccSVitaly Andrianov } 50*e8459dccSVitaly Andrianov 51*e8459dccSVitaly Andrianov 52*e8459dccSVitaly Andrianov static int poll_i2c_irq(struct i2c_adapter *adap, int mask) 53942ba996SJean-Christophe PLAGNIOL-VILLARD { 54*e8459dccSVitaly Andrianov struct i2c_regs *i2c_base = davinci_get_base(adap); 55*e8459dccSVitaly Andrianov int stat, timeout; 56*e8459dccSVitaly Andrianov 57*e8459dccSVitaly Andrianov for (timeout = 0; timeout < 10; timeout++) { 58*e8459dccSVitaly Andrianov udelay(1000); 59*e8459dccSVitaly Andrianov stat = REG(&(i2c_base->i2c_stat)); 60*e8459dccSVitaly Andrianov if (stat & mask) 61*e8459dccSVitaly Andrianov return stat; 62*e8459dccSVitaly Andrianov } 63*e8459dccSVitaly Andrianov 64*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_stat)) = 0xffff; 65*e8459dccSVitaly Andrianov return stat | I2C_TIMEOUT; 66*e8459dccSVitaly Andrianov } 67*e8459dccSVitaly Andrianov 68*e8459dccSVitaly Andrianov static void flush_rx(struct i2c_adapter *adap) 69*e8459dccSVitaly Andrianov { 70*e8459dccSVitaly Andrianov struct i2c_regs *i2c_base = davinci_get_base(adap); 71*e8459dccSVitaly Andrianov 72*e8459dccSVitaly Andrianov while (1) { 73*e8459dccSVitaly Andrianov if (!(REG(&(i2c_base->i2c_stat)) & I2C_STAT_RRDY)) 74*e8459dccSVitaly Andrianov break; 75*e8459dccSVitaly Andrianov 76*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_drr)); 77*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_stat)) = I2C_STAT_RRDY; 78*e8459dccSVitaly Andrianov udelay(1000); 79*e8459dccSVitaly Andrianov } 80*e8459dccSVitaly Andrianov } 81*e8459dccSVitaly Andrianov 82*e8459dccSVitaly Andrianov static uint davinci_i2c_setspeed(struct i2c_adapter *adap, uint speed) 83*e8459dccSVitaly Andrianov { 84*e8459dccSVitaly Andrianov struct i2c_regs *i2c_base = davinci_get_base(adap); 85*e8459dccSVitaly Andrianov uint32_t div, psc; 86*e8459dccSVitaly Andrianov 87*e8459dccSVitaly Andrianov psc = 2; 88*e8459dccSVitaly Andrianov /* SCLL + SCLH */ 89*e8459dccSVitaly Andrianov div = (CONFIG_SYS_HZ_CLOCK / ((psc + 1) * speed)) - 10; 90*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_psc)) = psc; /* 27MHz / (2 + 1) = 9MHz */ 91*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_scll)) = (div * 50) / 100; /* 50% Duty */ 92*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_sclh)) = div - REG(&(i2c_base->i2c_scll)); 93*e8459dccSVitaly Andrianov 94*e8459dccSVitaly Andrianov adap->speed = speed; 95*e8459dccSVitaly Andrianov return 0; 96*e8459dccSVitaly Andrianov } 97*e8459dccSVitaly Andrianov 98*e8459dccSVitaly Andrianov static void davinci_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) 99*e8459dccSVitaly Andrianov { 100*e8459dccSVitaly Andrianov struct i2c_regs *i2c_base = davinci_get_base(adap); 101*e8459dccSVitaly Andrianov 102*e8459dccSVitaly Andrianov if (REG(&(i2c_base->i2c_con)) & I2C_CON_EN) { 103*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = 0; 104*e8459dccSVitaly Andrianov udelay(50000); 105*e8459dccSVitaly Andrianov } 106*e8459dccSVitaly Andrianov 107*e8459dccSVitaly Andrianov davinci_i2c_setspeed(adap, speed); 108*e8459dccSVitaly Andrianov 109*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_oa)) = slaveadd; 110*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_cnt)) = 0; 111*e8459dccSVitaly Andrianov 112*e8459dccSVitaly Andrianov /* Interrupts must be enabled or I2C module won't work */ 113*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_ie)) = I2C_IE_SCD_IE | I2C_IE_XRDY_IE | 114*e8459dccSVitaly Andrianov I2C_IE_RRDY_IE | I2C_IE_ARDY_IE | I2C_IE_NACK_IE; 115*e8459dccSVitaly Andrianov 116*e8459dccSVitaly Andrianov /* Now enable I2C controller (get it out of reset) */ 117*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = I2C_CON_EN; 118*e8459dccSVitaly Andrianov 119*e8459dccSVitaly Andrianov udelay(1000); 120*e8459dccSVitaly Andrianov } 121*e8459dccSVitaly Andrianov 122*e8459dccSVitaly Andrianov static int davinci_i2c_probe(struct i2c_adapter *adap, uint8_t chip) 123*e8459dccSVitaly Andrianov { 124*e8459dccSVitaly Andrianov struct i2c_regs *i2c_base = davinci_get_base(adap); 125942ba996SJean-Christophe PLAGNIOL-VILLARD int rc = 1; 126942ba996SJean-Christophe PLAGNIOL-VILLARD 127*e8459dccSVitaly Andrianov if (chip == REG(&(i2c_base->i2c_oa))) 128*e8459dccSVitaly Andrianov return rc; 129942ba996SJean-Christophe PLAGNIOL-VILLARD 130*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = 0; 131*e8459dccSVitaly Andrianov if (wait_for_bus(adap)) 132*e8459dccSVitaly Andrianov return 1; 133942ba996SJean-Christophe PLAGNIOL-VILLARD 134942ba996SJean-Christophe PLAGNIOL-VILLARD /* try to read one byte from current (or only) address */ 135*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_cnt)) = 1; 136*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_sa)) = chip; 137*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | 138*e8459dccSVitaly Andrianov I2C_CON_STP); 139942ba996SJean-Christophe PLAGNIOL-VILLARD udelay(50000); 140942ba996SJean-Christophe PLAGNIOL-VILLARD 141*e8459dccSVitaly Andrianov if (!(REG(&(i2c_base->i2c_stat)) & I2C_STAT_NACK)) { 142942ba996SJean-Christophe PLAGNIOL-VILLARD rc = 0; 143*e8459dccSVitaly Andrianov flush_rx(adap); 144*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_stat)) = 0xffff; 145942ba996SJean-Christophe PLAGNIOL-VILLARD } else { 146*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_stat)) = 0xffff; 147*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) |= I2C_CON_STP; 148942ba996SJean-Christophe PLAGNIOL-VILLARD udelay(20000); 149*e8459dccSVitaly Andrianov if (wait_for_bus(adap)) 150*e8459dccSVitaly Andrianov return 1; 151942ba996SJean-Christophe PLAGNIOL-VILLARD } 152942ba996SJean-Christophe PLAGNIOL-VILLARD 153*e8459dccSVitaly Andrianov flush_rx(adap); 154*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_stat)) = 0xffff; 155*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_cnt)) = 0; 156*e8459dccSVitaly Andrianov return rc; 157942ba996SJean-Christophe PLAGNIOL-VILLARD } 158942ba996SJean-Christophe PLAGNIOL-VILLARD 159*e8459dccSVitaly Andrianov static int davinci_i2c_read(struct i2c_adapter *adap, uint8_t chip, 160*e8459dccSVitaly Andrianov uint32_t addr, int alen, uint8_t *buf, int len) 161942ba996SJean-Christophe PLAGNIOL-VILLARD { 162*e8459dccSVitaly Andrianov struct i2c_regs *i2c_base = davinci_get_base(adap); 163*e8459dccSVitaly Andrianov uint32_t tmp; 164942ba996SJean-Christophe PLAGNIOL-VILLARD int i; 165942ba996SJean-Christophe PLAGNIOL-VILLARD 166942ba996SJean-Christophe PLAGNIOL-VILLARD if ((alen < 0) || (alen > 2)) { 167*e8459dccSVitaly Andrianov printf("%s(): bogus address length %x\n", __func__, alen); 168*e8459dccSVitaly Andrianov return 1; 169942ba996SJean-Christophe PLAGNIOL-VILLARD } 170942ba996SJean-Christophe PLAGNIOL-VILLARD 171*e8459dccSVitaly Andrianov if (wait_for_bus(adap)) 172*e8459dccSVitaly Andrianov return 1; 173942ba996SJean-Christophe PLAGNIOL-VILLARD 174942ba996SJean-Christophe PLAGNIOL-VILLARD if (alen != 0) { 175942ba996SJean-Christophe PLAGNIOL-VILLARD /* Start address phase */ 176942ba996SJean-Christophe PLAGNIOL-VILLARD tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX; 177*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_cnt)) = alen; 178*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_sa)) = chip; 179*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = tmp; 180942ba996SJean-Christophe PLAGNIOL-VILLARD 181*e8459dccSVitaly Andrianov tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK); 182942ba996SJean-Christophe PLAGNIOL-VILLARD 183942ba996SJean-Christophe PLAGNIOL-VILLARD CHECK_NACK(); 184942ba996SJean-Christophe PLAGNIOL-VILLARD 185942ba996SJean-Christophe PLAGNIOL-VILLARD switch (alen) { 186942ba996SJean-Christophe PLAGNIOL-VILLARD case 2: 187942ba996SJean-Christophe PLAGNIOL-VILLARD /* Send address MSByte */ 188942ba996SJean-Christophe PLAGNIOL-VILLARD if (tmp & I2C_STAT_XRDY) { 189*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_dxr)) = (addr >> 8) & 0xff; 190942ba996SJean-Christophe PLAGNIOL-VILLARD } else { 191*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = 0; 192*e8459dccSVitaly Andrianov return 1; 193942ba996SJean-Christophe PLAGNIOL-VILLARD } 194942ba996SJean-Christophe PLAGNIOL-VILLARD 195*e8459dccSVitaly Andrianov tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK); 196942ba996SJean-Christophe PLAGNIOL-VILLARD 197942ba996SJean-Christophe PLAGNIOL-VILLARD CHECK_NACK(); 198942ba996SJean-Christophe PLAGNIOL-VILLARD /* No break, fall through */ 199942ba996SJean-Christophe PLAGNIOL-VILLARD case 1: 200942ba996SJean-Christophe PLAGNIOL-VILLARD /* Send address LSByte */ 201942ba996SJean-Christophe PLAGNIOL-VILLARD if (tmp & I2C_STAT_XRDY) { 202*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_dxr)) = addr & 0xff; 203942ba996SJean-Christophe PLAGNIOL-VILLARD } else { 204*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = 0; 205*e8459dccSVitaly Andrianov return 1; 206942ba996SJean-Christophe PLAGNIOL-VILLARD } 207942ba996SJean-Christophe PLAGNIOL-VILLARD 208*e8459dccSVitaly Andrianov tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | 209*e8459dccSVitaly Andrianov I2C_STAT_NACK | I2C_STAT_ARDY); 210942ba996SJean-Christophe PLAGNIOL-VILLARD 211942ba996SJean-Christophe PLAGNIOL-VILLARD CHECK_NACK(); 212942ba996SJean-Christophe PLAGNIOL-VILLARD 213942ba996SJean-Christophe PLAGNIOL-VILLARD if (!(tmp & I2C_STAT_ARDY)) { 214*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = 0; 215*e8459dccSVitaly Andrianov return 1; 216942ba996SJean-Christophe PLAGNIOL-VILLARD } 217942ba996SJean-Christophe PLAGNIOL-VILLARD } 218942ba996SJean-Christophe PLAGNIOL-VILLARD } 219942ba996SJean-Christophe PLAGNIOL-VILLARD 220942ba996SJean-Christophe PLAGNIOL-VILLARD /* Address phase is over, now read 'len' bytes and stop */ 221942ba996SJean-Christophe PLAGNIOL-VILLARD tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP; 222*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_cnt)) = len & 0xffff; 223*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_sa)) = chip; 224*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = tmp; 225942ba996SJean-Christophe PLAGNIOL-VILLARD 226942ba996SJean-Christophe PLAGNIOL-VILLARD for (i = 0; i < len; i++) { 227*e8459dccSVitaly Andrianov tmp = poll_i2c_irq(adap, I2C_STAT_RRDY | I2C_STAT_NACK | 228*e8459dccSVitaly Andrianov I2C_STAT_ROVR); 229942ba996SJean-Christophe PLAGNIOL-VILLARD 230942ba996SJean-Christophe PLAGNIOL-VILLARD CHECK_NACK(); 231942ba996SJean-Christophe PLAGNIOL-VILLARD 232942ba996SJean-Christophe PLAGNIOL-VILLARD if (tmp & I2C_STAT_RRDY) { 233*e8459dccSVitaly Andrianov buf[i] = REG(&(i2c_base->i2c_drr)); 234942ba996SJean-Christophe PLAGNIOL-VILLARD } else { 235*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = 0; 236*e8459dccSVitaly Andrianov return 1; 237942ba996SJean-Christophe PLAGNIOL-VILLARD } 238942ba996SJean-Christophe PLAGNIOL-VILLARD } 239942ba996SJean-Christophe PLAGNIOL-VILLARD 240*e8459dccSVitaly Andrianov tmp = poll_i2c_irq(adap, I2C_STAT_SCD | I2C_STAT_NACK); 241942ba996SJean-Christophe PLAGNIOL-VILLARD 242942ba996SJean-Christophe PLAGNIOL-VILLARD CHECK_NACK(); 243942ba996SJean-Christophe PLAGNIOL-VILLARD 244942ba996SJean-Christophe PLAGNIOL-VILLARD if (!(tmp & I2C_STAT_SCD)) { 245*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = 0; 246*e8459dccSVitaly Andrianov return 1; 247942ba996SJean-Christophe PLAGNIOL-VILLARD } 248942ba996SJean-Christophe PLAGNIOL-VILLARD 249*e8459dccSVitaly Andrianov flush_rx(adap); 250*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_stat)) = 0xffff; 251*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_cnt)) = 0; 252*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = 0; 253942ba996SJean-Christophe PLAGNIOL-VILLARD 254*e8459dccSVitaly Andrianov return 0; 255942ba996SJean-Christophe PLAGNIOL-VILLARD } 256942ba996SJean-Christophe PLAGNIOL-VILLARD 257*e8459dccSVitaly Andrianov static int davinci_i2c_write(struct i2c_adapter *adap, uint8_t chip, 258*e8459dccSVitaly Andrianov uint32_t addr, int alen, uint8_t *buf, int len) 259942ba996SJean-Christophe PLAGNIOL-VILLARD { 260*e8459dccSVitaly Andrianov struct i2c_regs *i2c_base = davinci_get_base(adap); 261*e8459dccSVitaly Andrianov uint32_t tmp; 262942ba996SJean-Christophe PLAGNIOL-VILLARD int i; 263942ba996SJean-Christophe PLAGNIOL-VILLARD 264942ba996SJean-Christophe PLAGNIOL-VILLARD if ((alen < 0) || (alen > 2)) { 265*e8459dccSVitaly Andrianov printf("%s(): bogus address length %x\n", __func__, alen); 266*e8459dccSVitaly Andrianov return 1; 267942ba996SJean-Christophe PLAGNIOL-VILLARD } 268942ba996SJean-Christophe PLAGNIOL-VILLARD if (len < 0) { 269*e8459dccSVitaly Andrianov printf("%s(): bogus length %x\n", __func__, len); 270*e8459dccSVitaly Andrianov return 1; 271942ba996SJean-Christophe PLAGNIOL-VILLARD } 272942ba996SJean-Christophe PLAGNIOL-VILLARD 273*e8459dccSVitaly Andrianov if (wait_for_bus(adap)) 274*e8459dccSVitaly Andrianov return 1; 275942ba996SJean-Christophe PLAGNIOL-VILLARD 276942ba996SJean-Christophe PLAGNIOL-VILLARD /* Start address phase */ 277*e8459dccSVitaly Andrianov tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | 278*e8459dccSVitaly Andrianov I2C_CON_TRX | I2C_CON_STP; 279*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_cnt)) = (alen == 0) ? 280*e8459dccSVitaly Andrianov len & 0xffff : (len & 0xffff) + alen; 281*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_sa)) = chip; 282*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = tmp; 283942ba996SJean-Christophe PLAGNIOL-VILLARD 284942ba996SJean-Christophe PLAGNIOL-VILLARD switch (alen) { 285942ba996SJean-Christophe PLAGNIOL-VILLARD case 2: 286942ba996SJean-Christophe PLAGNIOL-VILLARD /* Send address MSByte */ 287*e8459dccSVitaly Andrianov tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK); 288942ba996SJean-Christophe PLAGNIOL-VILLARD 289942ba996SJean-Christophe PLAGNIOL-VILLARD CHECK_NACK(); 290942ba996SJean-Christophe PLAGNIOL-VILLARD 291942ba996SJean-Christophe PLAGNIOL-VILLARD if (tmp & I2C_STAT_XRDY) { 292*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_dxr)) = (addr >> 8) & 0xff; 293942ba996SJean-Christophe PLAGNIOL-VILLARD } else { 294*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = 0; 295*e8459dccSVitaly Andrianov return 1; 296942ba996SJean-Christophe PLAGNIOL-VILLARD } 297942ba996SJean-Christophe PLAGNIOL-VILLARD /* No break, fall through */ 298942ba996SJean-Christophe PLAGNIOL-VILLARD case 1: 299942ba996SJean-Christophe PLAGNIOL-VILLARD /* Send address LSByte */ 300*e8459dccSVitaly Andrianov tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK); 301942ba996SJean-Christophe PLAGNIOL-VILLARD 302942ba996SJean-Christophe PLAGNIOL-VILLARD CHECK_NACK(); 303942ba996SJean-Christophe PLAGNIOL-VILLARD 304942ba996SJean-Christophe PLAGNIOL-VILLARD if (tmp & I2C_STAT_XRDY) { 305*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_dxr)) = addr & 0xff; 306942ba996SJean-Christophe PLAGNIOL-VILLARD } else { 307*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = 0; 308*e8459dccSVitaly Andrianov return 1; 309942ba996SJean-Christophe PLAGNIOL-VILLARD } 310942ba996SJean-Christophe PLAGNIOL-VILLARD } 311942ba996SJean-Christophe PLAGNIOL-VILLARD 312942ba996SJean-Christophe PLAGNIOL-VILLARD for (i = 0; i < len; i++) { 313*e8459dccSVitaly Andrianov tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK); 314942ba996SJean-Christophe PLAGNIOL-VILLARD 315942ba996SJean-Christophe PLAGNIOL-VILLARD CHECK_NACK(); 316942ba996SJean-Christophe PLAGNIOL-VILLARD 317*e8459dccSVitaly Andrianov if (tmp & I2C_STAT_XRDY) 318*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_dxr)) = buf[i]; 319*e8459dccSVitaly Andrianov else 320*e8459dccSVitaly Andrianov return 1; 321942ba996SJean-Christophe PLAGNIOL-VILLARD } 322942ba996SJean-Christophe PLAGNIOL-VILLARD 323*e8459dccSVitaly Andrianov tmp = poll_i2c_irq(adap, I2C_STAT_SCD | I2C_STAT_NACK); 324942ba996SJean-Christophe PLAGNIOL-VILLARD 325942ba996SJean-Christophe PLAGNIOL-VILLARD CHECK_NACK(); 326942ba996SJean-Christophe PLAGNIOL-VILLARD 327942ba996SJean-Christophe PLAGNIOL-VILLARD if (!(tmp & I2C_STAT_SCD)) { 328*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = 0; 329*e8459dccSVitaly Andrianov return 1; 330942ba996SJean-Christophe PLAGNIOL-VILLARD } 331942ba996SJean-Christophe PLAGNIOL-VILLARD 332*e8459dccSVitaly Andrianov flush_rx(adap); 333*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_stat)) = 0xffff; 334*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_cnt)) = 0; 335*e8459dccSVitaly Andrianov REG(&(i2c_base->i2c_con)) = 0; 336942ba996SJean-Christophe PLAGNIOL-VILLARD 337*e8459dccSVitaly Andrianov return 0; 338942ba996SJean-Christophe PLAGNIOL-VILLARD } 339*e8459dccSVitaly Andrianov 340*e8459dccSVitaly Andrianov static struct i2c_regs *davinci_get_base(struct i2c_adapter *adap) 341*e8459dccSVitaly Andrianov { 342*e8459dccSVitaly Andrianov switch (adap->hwadapnr) { 343*e8459dccSVitaly Andrianov #if I2C_BUS_MAX >= 3 344*e8459dccSVitaly Andrianov case 2: 345*e8459dccSVitaly Andrianov return (struct i2c_regs *)I2C2_BASE; 346*e8459dccSVitaly Andrianov #endif 347*e8459dccSVitaly Andrianov #if I2C_BUS_MAX >= 2 348*e8459dccSVitaly Andrianov case 1: 349*e8459dccSVitaly Andrianov return (struct i2c_regs *)I2C1_BASE; 350*e8459dccSVitaly Andrianov #endif 351*e8459dccSVitaly Andrianov case 0: 352*e8459dccSVitaly Andrianov return (struct i2c_regs *)I2C_BASE; 353*e8459dccSVitaly Andrianov 354*e8459dccSVitaly Andrianov default: 355*e8459dccSVitaly Andrianov printf("wrong hwadapnr: %d\n", adap->hwadapnr); 356*e8459dccSVitaly Andrianov } 357*e8459dccSVitaly Andrianov 358*e8459dccSVitaly Andrianov return NULL; 359*e8459dccSVitaly Andrianov } 360*e8459dccSVitaly Andrianov 361*e8459dccSVitaly Andrianov U_BOOT_I2C_ADAP_COMPLETE(davinci_0, davinci_i2c_init, davinci_i2c_probe, 362*e8459dccSVitaly Andrianov davinci_i2c_read, davinci_i2c_write, 363*e8459dccSVitaly Andrianov davinci_i2c_setspeed, 364*e8459dccSVitaly Andrianov CONFIG_SYS_DAVINCI_I2C_SPEED, 365*e8459dccSVitaly Andrianov CONFIG_SYS_DAVINCI_I2C_SLAVE, 366*e8459dccSVitaly Andrianov 0) 367*e8459dccSVitaly Andrianov 368*e8459dccSVitaly Andrianov #if I2C_BUS_MAX >= 2 369*e8459dccSVitaly Andrianov U_BOOT_I2C_ADAP_COMPLETE(davinci_1, davinci_i2c_init, davinci_i2c_probe, 370*e8459dccSVitaly Andrianov davinci_i2c_read, davinci_i2c_write, 371*e8459dccSVitaly Andrianov davinci_i2c_setspeed, 372*e8459dccSVitaly Andrianov CONFIG_SYS_DAVINCI_I2C_SPEED1, 373*e8459dccSVitaly Andrianov CONFIG_SYS_DAVINCI_I2C_SLAVE1, 374*e8459dccSVitaly Andrianov 1) 375*e8459dccSVitaly Andrianov #endif 376*e8459dccSVitaly Andrianov 377*e8459dccSVitaly Andrianov #if I2C_BUS_MAX >= 3 378*e8459dccSVitaly Andrianov U_BOOT_I2C_ADAP_COMPLETE(davinci_2, davinci_i2c_init, davinci_i2c_probe, 379*e8459dccSVitaly Andrianov davinci_i2c_read, davinci_i2c_write, 380*e8459dccSVitaly Andrianov davinci_i2c_setspeed, 381*e8459dccSVitaly Andrianov CONFIG_SYS_DAVINCI_I2C_SPEED2, 382*e8459dccSVitaly Andrianov CONFIG_SYS_DAVINCI_I2C_SLAVE2, 383*e8459dccSVitaly Andrianov 2) 384*e8459dccSVitaly Andrianov #endif 385