1080c646dSJean-Christophe PLAGNIOL-VILLARD /* 2080c646dSJean-Christophe PLAGNIOL-VILLARD * Basic I2C functions 3080c646dSJean-Christophe PLAGNIOL-VILLARD * 4080c646dSJean-Christophe PLAGNIOL-VILLARD * Copyright (c) 2004 Texas Instruments 5080c646dSJean-Christophe PLAGNIOL-VILLARD * 6080c646dSJean-Christophe PLAGNIOL-VILLARD * This package is free software; you can redistribute it and/or 7080c646dSJean-Christophe PLAGNIOL-VILLARD * modify it under the terms of the license found in the file 8080c646dSJean-Christophe PLAGNIOL-VILLARD * named COPYING that should have accompanied this file. 9080c646dSJean-Christophe PLAGNIOL-VILLARD * 10080c646dSJean-Christophe PLAGNIOL-VILLARD * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 11080c646dSJean-Christophe PLAGNIOL-VILLARD * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 12080c646dSJean-Christophe PLAGNIOL-VILLARD * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 13080c646dSJean-Christophe PLAGNIOL-VILLARD * 14080c646dSJean-Christophe PLAGNIOL-VILLARD * Author: Jian Zhang jzhang@ti.com, Texas Instruments 15080c646dSJean-Christophe PLAGNIOL-VILLARD * 16080c646dSJean-Christophe PLAGNIOL-VILLARD * Copyright (c) 2003 Wolfgang Denk, wd@denx.de 17080c646dSJean-Christophe PLAGNIOL-VILLARD * Rewritten to fit into the current U-Boot framework 18080c646dSJean-Christophe PLAGNIOL-VILLARD * 19080c646dSJean-Christophe PLAGNIOL-VILLARD * Adapted for OMAP2420 I2C, r-woodruff2@ti.com 20080c646dSJean-Christophe PLAGNIOL-VILLARD * 21080c646dSJean-Christophe PLAGNIOL-VILLARD */ 22080c646dSJean-Christophe PLAGNIOL-VILLARD 23080c646dSJean-Christophe PLAGNIOL-VILLARD #include <common.h> 24080c646dSJean-Christophe PLAGNIOL-VILLARD 25080c646dSJean-Christophe PLAGNIOL-VILLARD #include <asm/arch/i2c.h> 26080c646dSJean-Christophe PLAGNIOL-VILLARD #include <asm/io.h> 27080c646dSJean-Christophe PLAGNIOL-VILLARD 28938717ceSSteve Sakoman #include "omap24xx_i2c.h" 29938717ceSSteve Sakoman 3029565326SJohn Rigby DECLARE_GLOBAL_DATA_PTR; 3129565326SJohn Rigby 32*2faa7619SPatil, Rachna #define I2C_STAT_TIMEO (1 << 31) 33*2faa7619SPatil, Rachna #define I2C_TIMEOUT 10 34d708395dSSteve Sakoman 35*2faa7619SPatil, Rachna static u32 wait_for_bb(void); 36*2faa7619SPatil, Rachna static u32 wait_for_status_mask(u16 mask); 37080c646dSJean-Christophe PLAGNIOL-VILLARD static void flush_fifo(void); 38080c646dSJean-Christophe PLAGNIOL-VILLARD 390b620ec9SAndreas Müller /* 400b620ec9SAndreas Müller * For SPL boot some boards need i2c before SDRAM is initialised so force 410b620ec9SAndreas Müller * variables to live in SRAM 420b620ec9SAndreas Müller */ 430b620ec9SAndreas Müller static struct i2c __attribute__((section (".data"))) *i2c_base = 440b620ec9SAndreas Müller (struct i2c *)I2C_DEFAULT_BASE; 450b620ec9SAndreas Müller static unsigned int __attribute__((section (".data"))) bus_initialized[I2C_BUS_MAX] = 460b620ec9SAndreas Müller { [0 ... (I2C_BUS_MAX-1)] = 0 }; 470b620ec9SAndreas Müller static unsigned int __attribute__((section (".data"))) current_bus = 0; 481d2e96deSDirk Behme 49080c646dSJean-Christophe PLAGNIOL-VILLARD void i2c_init(int speed, int slaveadd) 50080c646dSJean-Christophe PLAGNIOL-VILLARD { 517f79dfb4STom Rix int psc, fsscll, fssclh; 527f79dfb4STom Rix int hsscll = 0, hssclh = 0; 537f79dfb4STom Rix u32 scll, sclh; 547f79dfb4STom Rix 557f79dfb4STom Rix /* Only handle standard, fast and high speeds */ 567f79dfb4STom Rix if ((speed != OMAP_I2C_STANDARD) && 577f79dfb4STom Rix (speed != OMAP_I2C_FAST_MODE) && 587f79dfb4STom Rix (speed != OMAP_I2C_HIGH_SPEED)) { 597f79dfb4STom Rix printf("Error : I2C unsupported speed %d\n", speed); 607f79dfb4STom Rix return; 617f79dfb4STom Rix } 627f79dfb4STom Rix 637f79dfb4STom Rix psc = I2C_IP_CLK / I2C_INTERNAL_SAMPLING_CLK; 647f79dfb4STom Rix psc -= 1; 657f79dfb4STom Rix if (psc < I2C_PSC_MIN) { 667f79dfb4STom Rix printf("Error : I2C unsupported prescalar %d\n", psc); 677f79dfb4STom Rix return; 687f79dfb4STom Rix } 697f79dfb4STom Rix 707f79dfb4STom Rix if (speed == OMAP_I2C_HIGH_SPEED) { 717f79dfb4STom Rix /* High speed */ 727f79dfb4STom Rix 737f79dfb4STom Rix /* For first phase of HS mode */ 747f79dfb4STom Rix fsscll = fssclh = I2C_INTERNAL_SAMPLING_CLK / 757f79dfb4STom Rix (2 * OMAP_I2C_FAST_MODE); 767f79dfb4STom Rix 777f79dfb4STom Rix fsscll -= I2C_HIGHSPEED_PHASE_ONE_SCLL_TRIM; 787f79dfb4STom Rix fssclh -= I2C_HIGHSPEED_PHASE_ONE_SCLH_TRIM; 797f79dfb4STom Rix if (((fsscll < 0) || (fssclh < 0)) || 807f79dfb4STom Rix ((fsscll > 255) || (fssclh > 255))) { 8149e9b4bdSAndreas Müller puts("Error : I2C initializing first phase clock\n"); 827f79dfb4STom Rix return; 837f79dfb4STom Rix } 847f79dfb4STom Rix 857f79dfb4STom Rix /* For second phase of HS mode */ 867f79dfb4STom Rix hsscll = hssclh = I2C_INTERNAL_SAMPLING_CLK / (2 * speed); 877f79dfb4STom Rix 887f79dfb4STom Rix hsscll -= I2C_HIGHSPEED_PHASE_TWO_SCLL_TRIM; 897f79dfb4STom Rix hssclh -= I2C_HIGHSPEED_PHASE_TWO_SCLH_TRIM; 907f79dfb4STom Rix if (((fsscll < 0) || (fssclh < 0)) || 917f79dfb4STom Rix ((fsscll > 255) || (fssclh > 255))) { 9249e9b4bdSAndreas Müller puts("Error : I2C initializing second phase clock\n"); 937f79dfb4STom Rix return; 947f79dfb4STom Rix } 957f79dfb4STom Rix 967f79dfb4STom Rix scll = (unsigned int)hsscll << 8 | (unsigned int)fsscll; 977f79dfb4STom Rix sclh = (unsigned int)hssclh << 8 | (unsigned int)fssclh; 987f79dfb4STom Rix 997f79dfb4STom Rix } else { 1007f79dfb4STom Rix /* Standard and fast speed */ 1017f79dfb4STom Rix fsscll = fssclh = I2C_INTERNAL_SAMPLING_CLK / (2 * speed); 1027f79dfb4STom Rix 1037f79dfb4STom Rix fsscll -= I2C_FASTSPEED_SCLL_TRIM; 1047f79dfb4STom Rix fssclh -= I2C_FASTSPEED_SCLH_TRIM; 1057f79dfb4STom Rix if (((fsscll < 0) || (fssclh < 0)) || 1067f79dfb4STom Rix ((fsscll > 255) || (fssclh > 255))) { 10749e9b4bdSAndreas Müller puts("Error : I2C initializing clock\n"); 1087f79dfb4STom Rix return; 1097f79dfb4STom Rix } 1107f79dfb4STom Rix 1117f79dfb4STom Rix scll = (unsigned int)fsscll; 1127f79dfb4STom Rix sclh = (unsigned int)fssclh; 1137f79dfb4STom Rix } 114080c646dSJean-Christophe PLAGNIOL-VILLARD 115*2faa7619SPatil, Rachna if (gd->flags & GD_FLG_RELOC) 116*2faa7619SPatil, Rachna bus_initialized[current_bus] = 1; 117*2faa7619SPatil, Rachna 1181d2e96deSDirk Behme if (readw(&i2c_base->con) & I2C_CON_EN) { 1191d2e96deSDirk Behme writew(0, &i2c_base->con); 120080c646dSJean-Christophe PLAGNIOL-VILLARD udelay(50000); 121080c646dSJean-Christophe PLAGNIOL-VILLARD } 122080c646dSJean-Christophe PLAGNIOL-VILLARD 1231d2e96deSDirk Behme writew(psc, &i2c_base->psc); 1241d2e96deSDirk Behme writew(scll, &i2c_base->scll); 1251d2e96deSDirk Behme writew(sclh, &i2c_base->sclh); 1267f79dfb4STom Rix 127080c646dSJean-Christophe PLAGNIOL-VILLARD /* own address */ 1281d2e96deSDirk Behme writew(slaveadd, &i2c_base->oa); 1291d2e96deSDirk Behme writew(I2C_CON_EN, &i2c_base->con); 130080c646dSJean-Christophe PLAGNIOL-VILLARD 131080c646dSJean-Christophe PLAGNIOL-VILLARD /* have to enable intrrupts or OMAP i2c module doesn't work */ 132e23c7c95SDirk Behme writew(I2C_IE_XRDY_IE | I2C_IE_RRDY_IE | I2C_IE_ARDY_IE | 1331d2e96deSDirk Behme I2C_IE_NACK_IE | I2C_IE_AL_IE, &i2c_base->ie); 134080c646dSJean-Christophe PLAGNIOL-VILLARD udelay(1000); 135080c646dSJean-Christophe PLAGNIOL-VILLARD flush_fifo(); 1361d2e96deSDirk Behme writew(0xFFFF, &i2c_base->stat); 1371d2e96deSDirk Behme writew(0, &i2c_base->cnt); 138080c646dSJean-Christophe PLAGNIOL-VILLARD } 139080c646dSJean-Christophe PLAGNIOL-VILLARD 140080c646dSJean-Christophe PLAGNIOL-VILLARD static void flush_fifo(void) 141080c646dSJean-Christophe PLAGNIOL-VILLARD { u16 stat; 142080c646dSJean-Christophe PLAGNIOL-VILLARD 143080c646dSJean-Christophe PLAGNIOL-VILLARD /* note: if you try and read data when its not there or ready 144080c646dSJean-Christophe PLAGNIOL-VILLARD * you get a bus error 145080c646dSJean-Christophe PLAGNIOL-VILLARD */ 146080c646dSJean-Christophe PLAGNIOL-VILLARD while (1) { 1471d2e96deSDirk Behme stat = readw(&i2c_base->stat); 148080c646dSJean-Christophe PLAGNIOL-VILLARD if (stat == I2C_STAT_RRDY) { 149938717ceSSteve Sakoman #if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) || \ 150938717ceSSteve Sakoman defined(CONFIG_OMAP44XX) 1511d2e96deSDirk Behme readb(&i2c_base->data); 1527d264c1eSDirk Behme #else 1531d2e96deSDirk Behme readw(&i2c_base->data); 1547d264c1eSDirk Behme #endif 1551d2e96deSDirk Behme writew(I2C_STAT_RRDY, &i2c_base->stat); 156080c646dSJean-Christophe PLAGNIOL-VILLARD udelay(1000); 157080c646dSJean-Christophe PLAGNIOL-VILLARD } else 158080c646dSJean-Christophe PLAGNIOL-VILLARD break; 159080c646dSJean-Christophe PLAGNIOL-VILLARD } 160080c646dSJean-Christophe PLAGNIOL-VILLARD } 161080c646dSJean-Christophe PLAGNIOL-VILLARD 162080c646dSJean-Christophe PLAGNIOL-VILLARD int i2c_probe(uchar chip) 163080c646dSJean-Christophe PLAGNIOL-VILLARD { 164*2faa7619SPatil, Rachna u32 status; 165080c646dSJean-Christophe PLAGNIOL-VILLARD int res = 1; /* default = fail */ 166080c646dSJean-Christophe PLAGNIOL-VILLARD 16789677b27SMichael Jones if (chip == readw(&i2c_base->oa)) 168080c646dSJean-Christophe PLAGNIOL-VILLARD return res; 169080c646dSJean-Christophe PLAGNIOL-VILLARD 170080c646dSJean-Christophe PLAGNIOL-VILLARD /* wait until bus not busy */ 171*2faa7619SPatil, Rachna status = wait_for_bb(); 172*2faa7619SPatil, Rachna /* exit on BUS busy */ 173*2faa7619SPatil, Rachna if (status & I2C_STAT_TIMEO) 174*2faa7619SPatil, Rachna return res; 175080c646dSJean-Christophe PLAGNIOL-VILLARD 1760e57968aSNick Thompson /* try to write one byte */ 1771d2e96deSDirk Behme writew(1, &i2c_base->cnt); 178080c646dSJean-Christophe PLAGNIOL-VILLARD /* set slave address */ 1791d2e96deSDirk Behme writew(chip, &i2c_base->sa); 180080c646dSJean-Christophe PLAGNIOL-VILLARD /* stop bit needed here */ 181*2faa7619SPatil, Rachna writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT 182*2faa7619SPatil, Rachna | I2C_CON_STP, &i2c_base->con); 183*2faa7619SPatil, Rachna /* enough delay for the NACK bit set */ 184*2faa7619SPatil, Rachna udelay(9000); 185080c646dSJean-Christophe PLAGNIOL-VILLARD 186*2faa7619SPatil, Rachna if (!(readw(&i2c_base->stat) & I2C_STAT_NACK)) { 187*2faa7619SPatil, Rachna res = 0; /* success case */ 188*2faa7619SPatil, Rachna flush_fifo(); 189*2faa7619SPatil, Rachna writew(0xFFFF, &i2c_base->stat); 190*2faa7619SPatil, Rachna } else { 191*2faa7619SPatil, Rachna /* failure, clear sources*/ 192*2faa7619SPatil, Rachna writew(0xFFFF, &i2c_base->stat); 193*2faa7619SPatil, Rachna /* finish up xfer */ 194*2faa7619SPatil, Rachna writew(readw(&i2c_base->con) | I2C_CON_STP, &i2c_base->con); 195*2faa7619SPatil, Rachna status = wait_for_bb(); 196*2faa7619SPatil, Rachna /* exit on BUS busy */ 197*2faa7619SPatil, Rachna if (status & I2C_STAT_TIMEO) 198*2faa7619SPatil, Rachna return res; 199*2faa7619SPatil, Rachna } 200080c646dSJean-Christophe PLAGNIOL-VILLARD flush_fifo(); 20189677b27SMichael Jones /* don't allow any more data in... we don't want it. */ 20289677b27SMichael Jones writew(0, &i2c_base->cnt); 2031d2e96deSDirk Behme writew(0xFFFF, &i2c_base->stat); 204080c646dSJean-Christophe PLAGNIOL-VILLARD return res; 205080c646dSJean-Christophe PLAGNIOL-VILLARD } 206080c646dSJean-Christophe PLAGNIOL-VILLARD 207080c646dSJean-Christophe PLAGNIOL-VILLARD int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) 208080c646dSJean-Christophe PLAGNIOL-VILLARD { 209*2faa7619SPatil, Rachna int i2c_error = 0, i; 210*2faa7619SPatil, Rachna u32 status; 211080c646dSJean-Christophe PLAGNIOL-VILLARD 212*2faa7619SPatil, Rachna if ((alen > 2) || (alen < 0)) 213*2faa7619SPatil, Rachna return 1; 214*2faa7619SPatil, Rachna 215*2faa7619SPatil, Rachna if (alen < 2) { 216*2faa7619SPatil, Rachna if (addr + len > 256) 217*2faa7619SPatil, Rachna return 1; 218*2faa7619SPatil, Rachna } else if (addr + len > 0xFFFF) { 219080c646dSJean-Christophe PLAGNIOL-VILLARD return 1; 220080c646dSJean-Christophe PLAGNIOL-VILLARD } 221080c646dSJean-Christophe PLAGNIOL-VILLARD 222*2faa7619SPatil, Rachna /* wait until bus not busy */ 223*2faa7619SPatil, Rachna status = wait_for_bb(); 224*2faa7619SPatil, Rachna 225*2faa7619SPatil, Rachna /* exit on BUS busy */ 226*2faa7619SPatil, Rachna if (status & I2C_STAT_TIMEO) 227080c646dSJean-Christophe PLAGNIOL-VILLARD return 1; 228*2faa7619SPatil, Rachna 229*2faa7619SPatil, Rachna writew((alen & 0xFF), &i2c_base->cnt); 230*2faa7619SPatil, Rachna /* set slave address */ 231*2faa7619SPatil, Rachna writew(chip, &i2c_base->sa); 232*2faa7619SPatil, Rachna /* Clear the Tx & Rx FIFOs */ 233*2faa7619SPatil, Rachna writew((readw(&i2c_base->buf) | I2C_RXFIFO_CLEAR | 234*2faa7619SPatil, Rachna I2C_TXFIFO_CLEAR), &i2c_base->buf); 235*2faa7619SPatil, Rachna /* no stop bit needed here */ 236*2faa7619SPatil, Rachna writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_TRX | 237*2faa7619SPatil, Rachna I2C_CON_STT, &i2c_base->con); 238*2faa7619SPatil, Rachna 239*2faa7619SPatil, Rachna /* wait for Transmit ready condition */ 240*2faa7619SPatil, Rachna status = wait_for_status_mask(I2C_STAT_XRDY | I2C_STAT_NACK); 241*2faa7619SPatil, Rachna 242*2faa7619SPatil, Rachna if (status & (I2C_STAT_NACK | I2C_STAT_TIMEO)) 243*2faa7619SPatil, Rachna i2c_error = 1; 244*2faa7619SPatil, Rachna 245*2faa7619SPatil, Rachna if (!i2c_error) { 246*2faa7619SPatil, Rachna if (status & I2C_STAT_XRDY) { 247*2faa7619SPatil, Rachna switch (alen) { 248*2faa7619SPatil, Rachna case 2: 249*2faa7619SPatil, Rachna /* Send address MSByte */ 250*2faa7619SPatil, Rachna #if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) 251*2faa7619SPatil, Rachna writew(((addr >> 8) & 0xFF), &i2c_base->data); 252*2faa7619SPatil, Rachna 253*2faa7619SPatil, Rachna /* Clearing XRDY event */ 254*2faa7619SPatil, Rachna writew((status & I2C_STAT_XRDY), 255*2faa7619SPatil, Rachna &i2c_base->stat); 256*2faa7619SPatil, Rachna /* wait for Transmit ready condition */ 257*2faa7619SPatil, Rachna status = wait_for_status_mask(I2C_STAT_XRDY | 258*2faa7619SPatil, Rachna I2C_STAT_NACK); 259*2faa7619SPatil, Rachna 260*2faa7619SPatil, Rachna if (status & (I2C_STAT_NACK | 261*2faa7619SPatil, Rachna I2C_STAT_TIMEO)) { 262*2faa7619SPatil, Rachna i2c_error = 1; 263*2faa7619SPatil, Rachna break; 264080c646dSJean-Christophe PLAGNIOL-VILLARD } 265*2faa7619SPatil, Rachna #endif 266*2faa7619SPatil, Rachna case 1: 267*2faa7619SPatil, Rachna #if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) 268*2faa7619SPatil, Rachna /* Send address LSByte */ 269*2faa7619SPatil, Rachna writew((addr & 0xFF), &i2c_base->data); 270*2faa7619SPatil, Rachna #else 271*2faa7619SPatil, Rachna /* Send address Short word */ 272*2faa7619SPatil, Rachna writew((addr & 0xFFFF), &i2c_base->data); 273*2faa7619SPatil, Rachna #endif 274*2faa7619SPatil, Rachna /* Clearing XRDY event */ 275*2faa7619SPatil, Rachna writew((status & I2C_STAT_XRDY), 276*2faa7619SPatil, Rachna &i2c_base->stat); 277*2faa7619SPatil, Rachna /*wait for Transmit ready condition */ 278*2faa7619SPatil, Rachna status = wait_for_status_mask(I2C_STAT_ARDY | 279*2faa7619SPatil, Rachna I2C_STAT_NACK); 280*2faa7619SPatil, Rachna 281*2faa7619SPatil, Rachna if (status & (I2C_STAT_NACK | 282*2faa7619SPatil, Rachna I2C_STAT_TIMEO)) { 283*2faa7619SPatil, Rachna i2c_error = 1; 284*2faa7619SPatil, Rachna break; 285*2faa7619SPatil, Rachna } 286*2faa7619SPatil, Rachna } 287*2faa7619SPatil, Rachna } else 288*2faa7619SPatil, Rachna i2c_error = 1; 289*2faa7619SPatil, Rachna } 290*2faa7619SPatil, Rachna 291*2faa7619SPatil, Rachna /* Wait for ARDY to set */ 292*2faa7619SPatil, Rachna status = wait_for_status_mask(I2C_STAT_ARDY | I2C_STAT_NACK 293*2faa7619SPatil, Rachna | I2C_STAT_AL); 294*2faa7619SPatil, Rachna 295*2faa7619SPatil, Rachna if (!i2c_error) { 296*2faa7619SPatil, Rachna /* set slave address */ 297*2faa7619SPatil, Rachna writew(chip, &i2c_base->sa); 298*2faa7619SPatil, Rachna writew((len & 0xFF), &i2c_base->cnt); 299*2faa7619SPatil, Rachna /* Clear the Tx & Rx FIFOs */ 300*2faa7619SPatil, Rachna writew((readw(&i2c_base->buf) | I2C_RXFIFO_CLEAR | 301*2faa7619SPatil, Rachna I2C_TXFIFO_CLEAR), &i2c_base->buf); 302*2faa7619SPatil, Rachna /* need stop bit here */ 303*2faa7619SPatil, Rachna writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, 304*2faa7619SPatil, Rachna &i2c_base->con); 305080c646dSJean-Christophe PLAGNIOL-VILLARD 306080c646dSJean-Christophe PLAGNIOL-VILLARD for (i = 0; i < len; i++) { 307*2faa7619SPatil, Rachna /* wait for Receive condition */ 308*2faa7619SPatil, Rachna status = wait_for_status_mask(I2C_STAT_RRDY | 309*2faa7619SPatil, Rachna I2C_STAT_NACK); 310*2faa7619SPatil, Rachna if (status & (I2C_STAT_NACK | I2C_STAT_TIMEO)) { 311*2faa7619SPatil, Rachna i2c_error = 1; 312*2faa7619SPatil, Rachna break; 313*2faa7619SPatil, Rachna } 314*2faa7619SPatil, Rachna 315*2faa7619SPatil, Rachna if (status & I2C_STAT_RRDY) { 316*2faa7619SPatil, Rachna #if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) 317*2faa7619SPatil, Rachna buffer[i] = readb(&i2c_base->data); 318*2faa7619SPatil, Rachna #else 319*2faa7619SPatil, Rachna *((u16 *)&buffer[i]) = 320*2faa7619SPatil, Rachna readw(&i2c_base->data) & 0xFFFF; 321*2faa7619SPatil, Rachna i++; 322*2faa7619SPatil, Rachna #endif 323*2faa7619SPatil, Rachna writew((status & I2C_STAT_RRDY), 324*2faa7619SPatil, Rachna &i2c_base->stat); 325*2faa7619SPatil, Rachna udelay(1000); 326*2faa7619SPatil, Rachna } else { 327*2faa7619SPatil, Rachna i2c_error = 1; 328*2faa7619SPatil, Rachna } 329*2faa7619SPatil, Rachna } 330*2faa7619SPatil, Rachna } 331*2faa7619SPatil, Rachna 332*2faa7619SPatil, Rachna /* Wait for ARDY to set */ 333*2faa7619SPatil, Rachna status = wait_for_status_mask(I2C_STAT_ARDY | I2C_STAT_NACK 334*2faa7619SPatil, Rachna | I2C_STAT_AL); 335*2faa7619SPatil, Rachna 336*2faa7619SPatil, Rachna if (i2c_error) { 337*2faa7619SPatil, Rachna writew(0, &i2c_base->con); 338080c646dSJean-Christophe PLAGNIOL-VILLARD return 1; 339080c646dSJean-Christophe PLAGNIOL-VILLARD } 340*2faa7619SPatil, Rachna 341*2faa7619SPatil, Rachna writew(I2C_CON_EN, &i2c_base->con); 342*2faa7619SPatil, Rachna 343*2faa7619SPatil, Rachna while (readw(&i2c_base->stat) 344*2faa7619SPatil, Rachna || (readw(&i2c_base->con) & I2C_CON_MST)) { 345*2faa7619SPatil, Rachna udelay(10000); 346*2faa7619SPatil, Rachna writew(0xFFFF, &i2c_base->stat); 347080c646dSJean-Christophe PLAGNIOL-VILLARD } 348080c646dSJean-Christophe PLAGNIOL-VILLARD 349*2faa7619SPatil, Rachna writew(I2C_CON_EN, &i2c_base->con); 350*2faa7619SPatil, Rachna flush_fifo(); 351*2faa7619SPatil, Rachna writew(0xFFFF, &i2c_base->stat); 352*2faa7619SPatil, Rachna writew(0, &i2c_base->cnt); 353*2faa7619SPatil, Rachna 354080c646dSJean-Christophe PLAGNIOL-VILLARD return 0; 355080c646dSJean-Christophe PLAGNIOL-VILLARD } 356080c646dSJean-Christophe PLAGNIOL-VILLARD 357080c646dSJean-Christophe PLAGNIOL-VILLARD int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) 358080c646dSJean-Christophe PLAGNIOL-VILLARD { 359080c646dSJean-Christophe PLAGNIOL-VILLARD 360*2faa7619SPatil, Rachna int i, i2c_error = 0; 361*2faa7619SPatil, Rachna u32 status; 362*2faa7619SPatil, Rachna u16 writelen; 363*2faa7619SPatil, Rachna 364*2faa7619SPatil, Rachna if (alen > 2) 365080c646dSJean-Christophe PLAGNIOL-VILLARD return 1; 366080c646dSJean-Christophe PLAGNIOL-VILLARD 367*2faa7619SPatil, Rachna if (alen < 2) { 368*2faa7619SPatil, Rachna if (addr + len > 256) 369*2faa7619SPatil, Rachna return 1; 370*2faa7619SPatil, Rachna } else if (addr + len > 0xFFFF) { 371080c646dSJean-Christophe PLAGNIOL-VILLARD return 1; 372080c646dSJean-Christophe PLAGNIOL-VILLARD } 373080c646dSJean-Christophe PLAGNIOL-VILLARD 3740607e2b9SMichael Jones /* wait until bus not busy */ 375*2faa7619SPatil, Rachna status = wait_for_bb(); 3760607e2b9SMichael Jones 377*2faa7619SPatil, Rachna /* exiting on BUS busy */ 378*2faa7619SPatil, Rachna if (status & I2C_STAT_TIMEO) 379*2faa7619SPatil, Rachna return 1; 380*2faa7619SPatil, Rachna 381*2faa7619SPatil, Rachna writelen = (len & 0xFFFF) + alen; 382*2faa7619SPatil, Rachna 383*2faa7619SPatil, Rachna /* two bytes */ 384*2faa7619SPatil, Rachna writew((writelen & 0xFFFF), &i2c_base->cnt); 385*2faa7619SPatil, Rachna /* Clear the Tx & Rx FIFOs */ 386*2faa7619SPatil, Rachna writew((readw(&i2c_base->buf) | I2C_RXFIFO_CLEAR | 387*2faa7619SPatil, Rachna I2C_TXFIFO_CLEAR), &i2c_base->buf); 3880607e2b9SMichael Jones /* set slave address */ 3890607e2b9SMichael Jones writew(chip, &i2c_base->sa); 3900607e2b9SMichael Jones /* stop bit needed here */ 3910607e2b9SMichael Jones writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | 3920607e2b9SMichael Jones I2C_CON_STP, &i2c_base->con); 3930607e2b9SMichael Jones 394*2faa7619SPatil, Rachna /* wait for Transmit ready condition */ 395*2faa7619SPatil, Rachna status = wait_for_status_mask(I2C_STAT_XRDY | I2C_STAT_NACK); 3960607e2b9SMichael Jones 397*2faa7619SPatil, Rachna if (status & (I2C_STAT_NACK | I2C_STAT_TIMEO)) 3980607e2b9SMichael Jones i2c_error = 1; 3990607e2b9SMichael Jones 400*2faa7619SPatil, Rachna if (!i2c_error) { 4010607e2b9SMichael Jones if (status & I2C_STAT_XRDY) { 402*2faa7619SPatil, Rachna switch (alen) { 403*2faa7619SPatil, Rachna #if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) 404*2faa7619SPatil, Rachna case 2: 405*2faa7619SPatil, Rachna /* send out MSB byte */ 406*2faa7619SPatil, Rachna writeb(((addr >> 8) & 0xFF), &i2c_base->data); 407*2faa7619SPatil, Rachna #else 408*2faa7619SPatil, Rachna writeb((addr & 0xFFFF), &i2c_base->data); 409*2faa7619SPatil, Rachna break; 410*2faa7619SPatil, Rachna #endif 411*2faa7619SPatil, Rachna /* Clearing XRDY event */ 412*2faa7619SPatil, Rachna writew((status & I2C_STAT_XRDY), 413*2faa7619SPatil, Rachna &i2c_base->stat); 414*2faa7619SPatil, Rachna /*waiting for Transmit ready * condition */ 415*2faa7619SPatil, Rachna status = wait_for_status_mask(I2C_STAT_XRDY | 416*2faa7619SPatil, Rachna I2C_STAT_NACK); 417*2faa7619SPatil, Rachna 418*2faa7619SPatil, Rachna if (status & (I2C_STAT_NACK | I2C_STAT_TIMEO)) { 4190607e2b9SMichael Jones i2c_error = 1; 420*2faa7619SPatil, Rachna break; 421*2faa7619SPatil, Rachna } 422*2faa7619SPatil, Rachna case 1: 423*2faa7619SPatil, Rachna #if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) 424*2faa7619SPatil, Rachna /* send out MSB byte */ 425*2faa7619SPatil, Rachna writeb((addr & 0xFF), &i2c_base->data); 426*2faa7619SPatil, Rachna #else 427*2faa7619SPatil, Rachna writew(((buffer[0] << 8) | (addr & 0xFF)), 428*2faa7619SPatil, Rachna &i2c_base->data); 429*2faa7619SPatil, Rachna #endif 4300607e2b9SMichael Jones } 4310607e2b9SMichael Jones 432*2faa7619SPatil, Rachna /* Clearing XRDY event */ 433*2faa7619SPatil, Rachna writew((status & I2C_STAT_XRDY), &i2c_base->stat); 4340607e2b9SMichael Jones } 4350607e2b9SMichael Jones 436*2faa7619SPatil, Rachna /* waiting for Transmit ready condition */ 437*2faa7619SPatil, Rachna status = wait_for_status_mask(I2C_STAT_XRDY | I2C_STAT_NACK); 438*2faa7619SPatil, Rachna 439*2faa7619SPatil, Rachna if (status & (I2C_STAT_NACK | I2C_STAT_TIMEO)) 440*2faa7619SPatil, Rachna i2c_error = 1; 441*2faa7619SPatil, Rachna 442*2faa7619SPatil, Rachna if (!i2c_error) { 443*2faa7619SPatil, Rachna for (i = ((alen > 1) ? 0 : 1); i < len; i++) { 4440607e2b9SMichael Jones if (status & I2C_STAT_XRDY) { 445*2faa7619SPatil, Rachna #if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) 446*2faa7619SPatil, Rachna writeb((buffer[i] & 0xFF), 447*2faa7619SPatil, Rachna &i2c_base->data); 448*2faa7619SPatil, Rachna #else 449*2faa7619SPatil, Rachna writew((((buffer[i] << 8) | 450*2faa7619SPatil, Rachna buffer[i + 1]) & 0xFFFF), 451*2faa7619SPatil, Rachna &i2c_base->data); 452*2faa7619SPatil, Rachna i++; 453*2faa7619SPatil, Rachna #endif 454*2faa7619SPatil, Rachna } else 4550607e2b9SMichael Jones i2c_error = 1; 456*2faa7619SPatil, Rachna /* Clearing XRDY event */ 457*2faa7619SPatil, Rachna writew((status & I2C_STAT_XRDY), 458*2faa7619SPatil, Rachna &i2c_base->stat); 459*2faa7619SPatil, Rachna /* waiting for XRDY condition */ 460*2faa7619SPatil, Rachna status = wait_for_status_mask( 461*2faa7619SPatil, Rachna I2C_STAT_XRDY | 462*2faa7619SPatil, Rachna I2C_STAT_ARDY | 463*2faa7619SPatil, Rachna I2C_STAT_NACK); 464*2faa7619SPatil, Rachna if (status & (I2C_STAT_NACK | 465*2faa7619SPatil, Rachna I2C_STAT_TIMEO)) { 466*2faa7619SPatil, Rachna i2c_error = 1; 467*2faa7619SPatil, Rachna break; 468*2faa7619SPatil, Rachna } 469*2faa7619SPatil, Rachna if (status & I2C_STAT_ARDY) 470*2faa7619SPatil, Rachna break; 471*2faa7619SPatil, Rachna } 472080c646dSJean-Christophe PLAGNIOL-VILLARD } 473080c646dSJean-Christophe PLAGNIOL-VILLARD } 474080c646dSJean-Christophe PLAGNIOL-VILLARD 475*2faa7619SPatil, Rachna status = wait_for_status_mask(I2C_STAT_ARDY | I2C_STAT_NACK | 476*2faa7619SPatil, Rachna I2C_STAT_AL); 477*2faa7619SPatil, Rachna 478*2faa7619SPatil, Rachna if (status & (I2C_STAT_NACK | I2C_STAT_TIMEO)) 479*2faa7619SPatil, Rachna i2c_error = 1; 480*2faa7619SPatil, Rachna 481*2faa7619SPatil, Rachna if (i2c_error) { 482*2faa7619SPatil, Rachna writew(0, &i2c_base->con); 483*2faa7619SPatil, Rachna return 1; 484*2faa7619SPatil, Rachna } 485*2faa7619SPatil, Rachna 486*2faa7619SPatil, Rachna if (!i2c_error) { 487*2faa7619SPatil, Rachna int eout = 200; 488*2faa7619SPatil, Rachna 489*2faa7619SPatil, Rachna writew(I2C_CON_EN, &i2c_base->con); 490*2faa7619SPatil, Rachna while ((status = readw(&i2c_base->stat)) || 491*2faa7619SPatil, Rachna (readw(&i2c_base->con) & I2C_CON_MST)) { 492*2faa7619SPatil, Rachna udelay(1000); 493*2faa7619SPatil, Rachna /* have to read to clear intrrupt */ 494*2faa7619SPatil, Rachna writew(0xFFFF, &i2c_base->stat); 495*2faa7619SPatil, Rachna if (--eout == 0) 496*2faa7619SPatil, Rachna /* better leave with error than hang */ 497*2faa7619SPatil, Rachna break; 498*2faa7619SPatil, Rachna } 499*2faa7619SPatil, Rachna } 500*2faa7619SPatil, Rachna 5010607e2b9SMichael Jones flush_fifo(); 5020607e2b9SMichael Jones writew(0xFFFF, &i2c_base->stat); 503*2faa7619SPatil, Rachna writew(0, &i2c_base->cnt); 504*2faa7619SPatil, Rachna return 0; 505080c646dSJean-Christophe PLAGNIOL-VILLARD } 506080c646dSJean-Christophe PLAGNIOL-VILLARD 507*2faa7619SPatil, Rachna static u32 wait_for_bb(void) 508080c646dSJean-Christophe PLAGNIOL-VILLARD { 50973e8747fSSteve Sakoman int timeout = I2C_TIMEOUT; 510*2faa7619SPatil, Rachna u32 stat; 511080c646dSJean-Christophe PLAGNIOL-VILLARD 5121d2e96deSDirk Behme while ((stat = readw(&i2c_base->stat) & I2C_STAT_BB) && timeout--) { 5131d2e96deSDirk Behme writew(stat, &i2c_base->stat); 51473e8747fSSteve Sakoman udelay(1000); 515080c646dSJean-Christophe PLAGNIOL-VILLARD } 516080c646dSJean-Christophe PLAGNIOL-VILLARD 517080c646dSJean-Christophe PLAGNIOL-VILLARD if (timeout <= 0) { 518080c646dSJean-Christophe PLAGNIOL-VILLARD printf("timed out in wait_for_bb: I2C_STAT=%x\n", 5191d2e96deSDirk Behme readw(&i2c_base->stat)); 520*2faa7619SPatil, Rachna stat |= I2C_STAT_TIMEO; 521080c646dSJean-Christophe PLAGNIOL-VILLARD } 5221d2e96deSDirk Behme writew(0xFFFF, &i2c_base->stat); /* clear delayed stuff*/ 523*2faa7619SPatil, Rachna return stat; 524080c646dSJean-Christophe PLAGNIOL-VILLARD } 525080c646dSJean-Christophe PLAGNIOL-VILLARD 526*2faa7619SPatil, Rachna static u32 wait_for_status_mask(u16 mask) 527080c646dSJean-Christophe PLAGNIOL-VILLARD { 528*2faa7619SPatil, Rachna u32 status; 52973e8747fSSteve Sakoman int timeout = I2C_TIMEOUT; 530080c646dSJean-Christophe PLAGNIOL-VILLARD 531080c646dSJean-Christophe PLAGNIOL-VILLARD do { 532080c646dSJean-Christophe PLAGNIOL-VILLARD udelay(1000); 5331d2e96deSDirk Behme status = readw(&i2c_base->stat); 534*2faa7619SPatil, Rachna } while (!(status & mask) && timeout--); 535080c646dSJean-Christophe PLAGNIOL-VILLARD 536080c646dSJean-Christophe PLAGNIOL-VILLARD if (timeout <= 0) { 537*2faa7619SPatil, Rachna printf("timed out in wait_for_status_mask: I2C_STAT=%x\n", 5381d2e96deSDirk Behme readw(&i2c_base->stat)); 5391d2e96deSDirk Behme writew(0xFFFF, &i2c_base->stat); 540*2faa7619SPatil, Rachna status |= I2C_STAT_TIMEO; 541080c646dSJean-Christophe PLAGNIOL-VILLARD } 542080c646dSJean-Christophe PLAGNIOL-VILLARD return status; 543080c646dSJean-Christophe PLAGNIOL-VILLARD } 5441d2e96deSDirk Behme 5451d2e96deSDirk Behme int i2c_set_bus_num(unsigned int bus) 5461d2e96deSDirk Behme { 5471d2e96deSDirk Behme if ((bus < 0) || (bus >= I2C_BUS_MAX)) { 5481d2e96deSDirk Behme printf("Bad bus: %d\n", bus); 5491d2e96deSDirk Behme return -1; 5501d2e96deSDirk Behme } 5511d2e96deSDirk Behme 5521d2e96deSDirk Behme #if I2C_BUS_MAX == 3 5531d2e96deSDirk Behme if (bus == 2) 5541d2e96deSDirk Behme i2c_base = (struct i2c *)I2C_BASE3; 5551d2e96deSDirk Behme else 5561d2e96deSDirk Behme #endif 5571d2e96deSDirk Behme if (bus == 1) 5581d2e96deSDirk Behme i2c_base = (struct i2c *)I2C_BASE2; 5591d2e96deSDirk Behme else 5601d2e96deSDirk Behme i2c_base = (struct i2c *)I2C_BASE1; 5611d2e96deSDirk Behme 5621d2e96deSDirk Behme current_bus = bus; 5631d2e96deSDirk Behme 5641d2e96deSDirk Behme if (!bus_initialized[current_bus]) 5651d2e96deSDirk Behme i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); 5661d2e96deSDirk Behme 5671d2e96deSDirk Behme return 0; 5681d2e96deSDirk Behme } 569938717ceSSteve Sakoman 570938717ceSSteve Sakoman int i2c_get_bus_num(void) 571938717ceSSteve Sakoman { 572938717ceSSteve Sakoman return (int) current_bus; 573938717ceSSteve Sakoman } 574