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 * 21960187ffSLubomir Popov * Copyright (c) 2013 Lubomir Popov <lpopov@mm-sol.com>, MM Solutions 22960187ffSLubomir Popov * New i2c_read, i2c_write and i2c_probe functions, tested on OMAP4 23960187ffSLubomir Popov * (4430/60/70), OMAP5 (5430) and AM335X (3359); should work on older 24960187ffSLubomir Popov * OMAPs and derivatives as well. The only anticipated exception would 25960187ffSLubomir Popov * be the OMAP2420, which shall require driver modification. 26960187ffSLubomir Popov * - Rewritten i2c_read to operate correctly with all types of chips 27960187ffSLubomir Popov * (old function could not read consistent data from some I2C slaves). 28960187ffSLubomir Popov * - Optimized i2c_write. 29960187ffSLubomir Popov * - New i2c_probe, performs write access vs read. The old probe could 30960187ffSLubomir Popov * hang the system under certain conditions (e.g. unconfigured pads). 31960187ffSLubomir Popov * - The read/write/probe functions try to identify unconfigured bus. 32960187ffSLubomir Popov * - Status functions now read irqstatus_raw as per TRM guidelines 33960187ffSLubomir Popov * (except for OMAP243X and OMAP34XX). 34960187ffSLubomir Popov * - Driver now supports up to I2C5 (OMAP5). 35d5243359SHannes Petermaier * 364c302b9aSHannes Schmelzer * Copyright (c) 2014 Hannes Schmelzer <oe5hpm@oevsv.at>, B&R 37d5243359SHannes Petermaier * - Added support for set_speed 38d5243359SHannes Petermaier * 39080c646dSJean-Christophe PLAGNIOL-VILLARD */ 40080c646dSJean-Christophe PLAGNIOL-VILLARD 41080c646dSJean-Christophe PLAGNIOL-VILLARD #include <common.h> 42*daa69ffeSMugunthan V N #include <dm.h> 436789e84eSHeiko Schocher #include <i2c.h> 44080c646dSJean-Christophe PLAGNIOL-VILLARD 45080c646dSJean-Christophe PLAGNIOL-VILLARD #include <asm/arch/i2c.h> 46080c646dSJean-Christophe PLAGNIOL-VILLARD #include <asm/io.h> 47080c646dSJean-Christophe PLAGNIOL-VILLARD 48938717ceSSteve Sakoman #include "omap24xx_i2c.h" 49938717ceSSteve Sakoman 5029565326SJohn Rigby DECLARE_GLOBAL_DATA_PTR; 5129565326SJohn Rigby 52cec487a4STom Rini #define I2C_TIMEOUT 1000 53d708395dSSteve Sakoman 54960187ffSLubomir Popov /* Absolutely safe for status update at 100 kHz I2C: */ 55960187ffSLubomir Popov #define I2C_WAIT 200 56960187ffSLubomir Popov 57*daa69ffeSMugunthan V N struct omap_i2c { 58*daa69ffeSMugunthan V N struct udevice *clk; 59*daa69ffeSMugunthan V N struct i2c *regs; 60*daa69ffeSMugunthan V N unsigned int speed; 61*daa69ffeSMugunthan V N int waitdelay; 62*daa69ffeSMugunthan V N int clk_id; 63*daa69ffeSMugunthan V N }; 64*daa69ffeSMugunthan V N 65d5243359SHannes Petermaier static int omap24_i2c_findpsc(u32 *pscl, u32 *psch, uint speed) 66d5243359SHannes Petermaier { 67d5243359SHannes Petermaier unsigned int sampleclk, prescaler; 68d5243359SHannes Petermaier int fsscll, fssclh; 69080c646dSJean-Christophe PLAGNIOL-VILLARD 70d5243359SHannes Petermaier speed <<= 1; 71d5243359SHannes Petermaier prescaler = 0; 72d5243359SHannes Petermaier /* 73d5243359SHannes Petermaier * some divisors may cause a precission loss, but shouldn't 74d5243359SHannes Petermaier * be a big thing, because i2c_clk is then allready very slow. 75d5243359SHannes Petermaier */ 76d5243359SHannes Petermaier while (prescaler <= 0xFF) { 77d5243359SHannes Petermaier sampleclk = I2C_IP_CLK / (prescaler+1); 78d5243359SHannes Petermaier 79d5243359SHannes Petermaier fsscll = sampleclk / speed; 80d5243359SHannes Petermaier fssclh = fsscll; 81d5243359SHannes Petermaier fsscll -= I2C_FASTSPEED_SCLL_TRIM; 82d5243359SHannes Petermaier fssclh -= I2C_FASTSPEED_SCLH_TRIM; 83d5243359SHannes Petermaier 84d5243359SHannes Petermaier if (((fsscll > 0) && (fssclh > 0)) && 85d5243359SHannes Petermaier ((fsscll <= (255-I2C_FASTSPEED_SCLL_TRIM)) && 86d5243359SHannes Petermaier (fssclh <= (255-I2C_FASTSPEED_SCLH_TRIM)))) { 87d5243359SHannes Petermaier if (pscl) 88d5243359SHannes Petermaier *pscl = fsscll; 89d5243359SHannes Petermaier if (psch) 90d5243359SHannes Petermaier *psch = fssclh; 91d5243359SHannes Petermaier 92d5243359SHannes Petermaier return prescaler; 93d5243359SHannes Petermaier } 94d5243359SHannes Petermaier prescaler++; 95d5243359SHannes Petermaier } 96d5243359SHannes Petermaier return -1; 97d5243359SHannes Petermaier } 98be243e41SMugunthan V N 99be243e41SMugunthan V N /* 100be243e41SMugunthan V N * Wait for the bus to be free by checking the Bus Busy (BB) 101be243e41SMugunthan V N * bit to become clear 102be243e41SMugunthan V N */ 103be243e41SMugunthan V N static int wait_for_bb(struct i2c *i2c_base, int waitdelay) 104080c646dSJean-Christophe PLAGNIOL-VILLARD { 105be243e41SMugunthan V N int timeout = I2C_TIMEOUT; 106be243e41SMugunthan V N u16 stat; 107be243e41SMugunthan V N 108be243e41SMugunthan V N writew(0xFFFF, &i2c_base->stat); /* clear current interrupts...*/ 109be243e41SMugunthan V N #if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) 110be243e41SMugunthan V N while ((stat = readw(&i2c_base->stat) & I2C_STAT_BB) && timeout--) { 111be243e41SMugunthan V N #else 112be243e41SMugunthan V N /* Read RAW status */ 113be243e41SMugunthan V N while ((stat = readw(&i2c_base->irqstatus_raw) & 114be243e41SMugunthan V N I2C_STAT_BB) && timeout--) { 115be243e41SMugunthan V N #endif 116be243e41SMugunthan V N writew(stat, &i2c_base->stat); 117be243e41SMugunthan V N udelay(waitdelay); 118be243e41SMugunthan V N } 119be243e41SMugunthan V N 120be243e41SMugunthan V N if (timeout <= 0) { 121be243e41SMugunthan V N printf("Timed out in wait_for_bb: status=%04x\n", 122be243e41SMugunthan V N stat); 123be243e41SMugunthan V N return 1; 124be243e41SMugunthan V N } 125be243e41SMugunthan V N writew(0xFFFF, &i2c_base->stat); /* clear delayed stuff*/ 126be243e41SMugunthan V N return 0; 127be243e41SMugunthan V N } 128be243e41SMugunthan V N 129be243e41SMugunthan V N /* 130be243e41SMugunthan V N * Wait for the I2C controller to complete current action 131be243e41SMugunthan V N * and update status 132be243e41SMugunthan V N */ 133be243e41SMugunthan V N static u16 wait_for_event(struct i2c *i2c_base, int waitdelay) 134be243e41SMugunthan V N { 135be243e41SMugunthan V N u16 status; 136be243e41SMugunthan V N int timeout = I2C_TIMEOUT; 137be243e41SMugunthan V N 138be243e41SMugunthan V N do { 139be243e41SMugunthan V N udelay(waitdelay); 140be243e41SMugunthan V N #if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) 141be243e41SMugunthan V N status = readw(&i2c_base->stat); 142be243e41SMugunthan V N #else 143be243e41SMugunthan V N /* Read RAW status */ 144be243e41SMugunthan V N status = readw(&i2c_base->irqstatus_raw); 145be243e41SMugunthan V N #endif 146be243e41SMugunthan V N } while (!(status & 147be243e41SMugunthan V N (I2C_STAT_ROVR | I2C_STAT_XUDF | I2C_STAT_XRDY | 148be243e41SMugunthan V N I2C_STAT_RRDY | I2C_STAT_ARDY | I2C_STAT_NACK | 149be243e41SMugunthan V N I2C_STAT_AL)) && timeout--); 150be243e41SMugunthan V N 151be243e41SMugunthan V N if (timeout <= 0) { 152be243e41SMugunthan V N printf("Timed out in wait_for_event: status=%04x\n", 153be243e41SMugunthan V N status); 154be243e41SMugunthan V N /* 155be243e41SMugunthan V N * If status is still 0 here, probably the bus pads have 156be243e41SMugunthan V N * not been configured for I2C, and/or pull-ups are missing. 157be243e41SMugunthan V N */ 158be243e41SMugunthan V N printf("Check if pads/pull-ups of bus are properly configured\n"); 159be243e41SMugunthan V N writew(0xFFFF, &i2c_base->stat); 160be243e41SMugunthan V N status = 0; 161be243e41SMugunthan V N } 162be243e41SMugunthan V N 163be243e41SMugunthan V N return status; 164be243e41SMugunthan V N } 165be243e41SMugunthan V N 166be243e41SMugunthan V N static void flush_fifo(struct i2c *i2c_base) 167be243e41SMugunthan V N { 168be243e41SMugunthan V N u16 stat; 169be243e41SMugunthan V N 170be243e41SMugunthan V N /* 171be243e41SMugunthan V N * note: if you try and read data when its not there or ready 172be243e41SMugunthan V N * you get a bus error 173be243e41SMugunthan V N */ 174be243e41SMugunthan V N while (1) { 175be243e41SMugunthan V N stat = readw(&i2c_base->stat); 176be243e41SMugunthan V N if (stat == I2C_STAT_RRDY) { 177be243e41SMugunthan V N readb(&i2c_base->data); 178be243e41SMugunthan V N writew(I2C_STAT_RRDY, &i2c_base->stat); 179be243e41SMugunthan V N udelay(1000); 180be243e41SMugunthan V N } else 181be243e41SMugunthan V N break; 182be243e41SMugunthan V N } 183be243e41SMugunthan V N } 184be243e41SMugunthan V N 185be243e41SMugunthan V N static int __omap24_i2c_setspeed(struct i2c *i2c_base, uint speed, 186be243e41SMugunthan V N int *waitdelay) 187be243e41SMugunthan V N { 188d5243359SHannes Petermaier int psc, fsscll = 0, fssclh = 0; 1897f79dfb4STom Rix int hsscll = 0, hssclh = 0; 190d5243359SHannes Petermaier u32 scll = 0, sclh = 0; 1917f79dfb4STom Rix 192d5243359SHannes Petermaier if (speed >= OMAP_I2C_HIGH_SPEED) { 193d5243359SHannes Petermaier /* High speed */ 1947f79dfb4STom Rix psc = I2C_IP_CLK / I2C_INTERNAL_SAMPLING_CLK; 1957f79dfb4STom Rix psc -= 1; 1967f79dfb4STom Rix if (psc < I2C_PSC_MIN) { 197d5243359SHannes Petermaier printf("Error : I2C unsupported prescaler %d\n", psc); 198d5243359SHannes Petermaier return -1; 1997f79dfb4STom Rix } 2007f79dfb4STom Rix 2017f79dfb4STom Rix /* For first phase of HS mode */ 202d5243359SHannes Petermaier fsscll = I2C_INTERNAL_SAMPLING_CLK / (2 * speed); 203d5243359SHannes Petermaier 204d5243359SHannes Petermaier fssclh = fsscll; 2057f79dfb4STom Rix 2067f79dfb4STom Rix fsscll -= I2C_HIGHSPEED_PHASE_ONE_SCLL_TRIM; 2077f79dfb4STom Rix fssclh -= I2C_HIGHSPEED_PHASE_ONE_SCLH_TRIM; 2087f79dfb4STom Rix if (((fsscll < 0) || (fssclh < 0)) || 2097f79dfb4STom Rix ((fsscll > 255) || (fssclh > 255))) { 21049e9b4bdSAndreas Müller puts("Error : I2C initializing first phase clock\n"); 211d5243359SHannes Petermaier return -1; 2127f79dfb4STom Rix } 2137f79dfb4STom Rix 2147f79dfb4STom Rix /* For second phase of HS mode */ 2157f79dfb4STom Rix hsscll = hssclh = I2C_INTERNAL_SAMPLING_CLK / (2 * speed); 2167f79dfb4STom Rix 2177f79dfb4STom Rix hsscll -= I2C_HIGHSPEED_PHASE_TWO_SCLL_TRIM; 2187f79dfb4STom Rix hssclh -= I2C_HIGHSPEED_PHASE_TWO_SCLH_TRIM; 2197f79dfb4STom Rix if (((fsscll < 0) || (fssclh < 0)) || 2207f79dfb4STom Rix ((fsscll > 255) || (fssclh > 255))) { 22149e9b4bdSAndreas Müller puts("Error : I2C initializing second phase clock\n"); 222d5243359SHannes Petermaier return -1; 2237f79dfb4STom Rix } 2247f79dfb4STom Rix 2257f79dfb4STom Rix scll = (unsigned int)hsscll << 8 | (unsigned int)fsscll; 2267f79dfb4STom Rix sclh = (unsigned int)hssclh << 8 | (unsigned int)fssclh; 2277f79dfb4STom Rix 2287f79dfb4STom Rix } else { 2297f79dfb4STom Rix /* Standard and fast speed */ 230d5243359SHannes Petermaier psc = omap24_i2c_findpsc(&scll, &sclh, speed); 231d5243359SHannes Petermaier if (0 > psc) { 23249e9b4bdSAndreas Müller puts("Error : I2C initializing clock\n"); 233d5243359SHannes Petermaier return -1; 234d5243359SHannes Petermaier } 2357f79dfb4STom Rix } 2367f79dfb4STom Rix 237be243e41SMugunthan V N *waitdelay = (10000000 / speed) * 2; /* wait for 20 clkperiods */ 238d5243359SHannes Petermaier writew(0, &i2c_base->con); 239d5243359SHannes Petermaier writew(psc, &i2c_base->psc); 240d5243359SHannes Petermaier writew(scll, &i2c_base->scll); 241d5243359SHannes Petermaier writew(sclh, &i2c_base->sclh); 242d5243359SHannes Petermaier writew(I2C_CON_EN, &i2c_base->con); 243d5243359SHannes Petermaier writew(0xFFFF, &i2c_base->stat); /* clear all pending status */ 244d5243359SHannes Petermaier 245d5243359SHannes Petermaier return 0; 2467f79dfb4STom Rix } 247f7c10535SHeiko Schocher 248be243e41SMugunthan V N static void omap24_i2c_deblock(struct i2c *i2c_base) 249f7c10535SHeiko Schocher { 250f7c10535SHeiko Schocher int i; 251f7c10535SHeiko Schocher u16 systest; 252f7c10535SHeiko Schocher u16 orgsystest; 253f7c10535SHeiko Schocher 254f7c10535SHeiko Schocher /* set test mode ST_EN = 1 */ 255f7c10535SHeiko Schocher orgsystest = readw(&i2c_base->systest); 256f7c10535SHeiko Schocher systest = orgsystest; 257f7c10535SHeiko Schocher /* enable testmode */ 258f7c10535SHeiko Schocher systest |= I2C_SYSTEST_ST_EN; 259f7c10535SHeiko Schocher writew(systest, &i2c_base->systest); 260f7c10535SHeiko Schocher systest &= ~I2C_SYSTEST_TMODE_MASK; 261f7c10535SHeiko Schocher systest |= 3 << I2C_SYSTEST_TMODE_SHIFT; 262f7c10535SHeiko Schocher writew(systest, &i2c_base->systest); 263f7c10535SHeiko Schocher 264f7c10535SHeiko Schocher /* set SCL, SDA = 1 */ 265f7c10535SHeiko Schocher systest |= I2C_SYSTEST_SCL_O | I2C_SYSTEST_SDA_O; 266f7c10535SHeiko Schocher writew(systest, &i2c_base->systest); 267f7c10535SHeiko Schocher udelay(10); 268f7c10535SHeiko Schocher 269f7c10535SHeiko Schocher /* toggle scl 9 clocks */ 270f7c10535SHeiko Schocher for (i = 0; i < 9; i++) { 271f7c10535SHeiko Schocher /* SCL = 0 */ 272f7c10535SHeiko Schocher systest &= ~I2C_SYSTEST_SCL_O; 273f7c10535SHeiko Schocher writew(systest, &i2c_base->systest); 274f7c10535SHeiko Schocher udelay(10); 275f7c10535SHeiko Schocher /* SCL = 1 */ 276f7c10535SHeiko Schocher systest |= I2C_SYSTEST_SCL_O; 277f7c10535SHeiko Schocher writew(systest, &i2c_base->systest); 278f7c10535SHeiko Schocher udelay(10); 279f7c10535SHeiko Schocher } 280f7c10535SHeiko Schocher 281f7c10535SHeiko Schocher /* send stop */ 282f7c10535SHeiko Schocher systest &= ~I2C_SYSTEST_SDA_O; 283f7c10535SHeiko Schocher writew(systest, &i2c_base->systest); 284f7c10535SHeiko Schocher udelay(10); 285f7c10535SHeiko Schocher systest |= I2C_SYSTEST_SCL_O | I2C_SYSTEST_SDA_O; 286f7c10535SHeiko Schocher writew(systest, &i2c_base->systest); 287f7c10535SHeiko Schocher udelay(10); 288f7c10535SHeiko Schocher 289f7c10535SHeiko Schocher /* restore original mode */ 290f7c10535SHeiko Schocher writew(orgsystest, &i2c_base->systest); 291f7c10535SHeiko Schocher } 292f7c10535SHeiko Schocher 293be243e41SMugunthan V N static void __omap24_i2c_init(struct i2c *i2c_base, int speed, int slaveadd, 294be243e41SMugunthan V N int *waitdelay) 295d5243359SHannes Petermaier { 296d5243359SHannes Petermaier int timeout = I2C_TIMEOUT; 297f7c10535SHeiko Schocher int deblock = 1; 298080c646dSJean-Christophe PLAGNIOL-VILLARD 299f7c10535SHeiko Schocher retry: 3001d2e96deSDirk Behme if (readw(&i2c_base->con) & I2C_CON_EN) { 3011d2e96deSDirk Behme writew(0, &i2c_base->con); 302080c646dSJean-Christophe PLAGNIOL-VILLARD udelay(50000); 303080c646dSJean-Christophe PLAGNIOL-VILLARD } 304080c646dSJean-Christophe PLAGNIOL-VILLARD 305cec487a4STom Rini writew(0x2, &i2c_base->sysc); /* for ES2 after soft reset */ 306cec487a4STom Rini udelay(1000); 307cec487a4STom Rini 308cec487a4STom Rini writew(I2C_CON_EN, &i2c_base->con); 309cec487a4STom Rini while (!(readw(&i2c_base->syss) & I2C_SYSS_RDONE) && timeout--) { 310cec487a4STom Rini if (timeout <= 0) { 311cec487a4STom Rini puts("ERROR: Timeout in soft-reset\n"); 312cec487a4STom Rini return; 313cec487a4STom Rini } 314cec487a4STom Rini udelay(1000); 315cec487a4STom Rini } 316cec487a4STom Rini 317be243e41SMugunthan V N if (0 != __omap24_i2c_setspeed(i2c_base, speed, waitdelay)) { 318d5243359SHannes Petermaier printf("ERROR: failed to setup I2C bus-speed!\n"); 319d5243359SHannes Petermaier return; 320d5243359SHannes Petermaier } 3217f79dfb4STom Rix 322080c646dSJean-Christophe PLAGNIOL-VILLARD /* own address */ 3231d2e96deSDirk Behme writew(slaveadd, &i2c_base->oa); 324d5243359SHannes Petermaier 325960187ffSLubomir Popov #if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) 326960187ffSLubomir Popov /* 327960187ffSLubomir Popov * Have to enable interrupts for OMAP2/3, these IPs don't have 328960187ffSLubomir Popov * an 'irqstatus_raw' register and we shall have to poll 'stat' 329960187ffSLubomir Popov */ 330e23c7c95SDirk Behme writew(I2C_IE_XRDY_IE | I2C_IE_RRDY_IE | I2C_IE_ARDY_IE | 3311d2e96deSDirk Behme I2C_IE_NACK_IE | I2C_IE_AL_IE, &i2c_base->ie); 332960187ffSLubomir Popov #endif 333080c646dSJean-Christophe PLAGNIOL-VILLARD udelay(1000); 334be243e41SMugunthan V N flush_fifo(i2c_base); 3351d2e96deSDirk Behme writew(0xFFFF, &i2c_base->stat); 336f7c10535SHeiko Schocher 337f7c10535SHeiko Schocher /* Handle possible failed I2C state */ 338be243e41SMugunthan V N if (wait_for_bb(i2c_base, *waitdelay)) 339f7c10535SHeiko Schocher if (deblock == 1) { 340be243e41SMugunthan V N omap24_i2c_deblock(i2c_base); 341f7c10535SHeiko Schocher deblock = 0; 342f7c10535SHeiko Schocher goto retry; 343f7c10535SHeiko Schocher } 344cec487a4STom Rini } 345cec487a4STom Rini 346960187ffSLubomir Popov /* 347960187ffSLubomir Popov * i2c_probe: Use write access. Allows to identify addresses that are 348960187ffSLubomir Popov * write-only (like the config register of dual-port EEPROMs) 349960187ffSLubomir Popov */ 350be243e41SMugunthan V N static int __omap24_i2c_probe(struct i2c *i2c_base, int waitdelay, uchar chip) 351080c646dSJean-Christophe PLAGNIOL-VILLARD { 352cec487a4STom Rini u16 status; 353080c646dSJean-Christophe PLAGNIOL-VILLARD int res = 1; /* default = fail */ 354080c646dSJean-Christophe PLAGNIOL-VILLARD 35589677b27SMichael Jones if (chip == readw(&i2c_base->oa)) 356080c646dSJean-Christophe PLAGNIOL-VILLARD return res; 357080c646dSJean-Christophe PLAGNIOL-VILLARD 358960187ffSLubomir Popov /* Wait until bus is free */ 359be243e41SMugunthan V N if (wait_for_bb(i2c_base, waitdelay)) 360febc4cd4SVincent Stehlé return res; 361080c646dSJean-Christophe PLAGNIOL-VILLARD 362960187ffSLubomir Popov /* No data transfer, slave addr only */ 363960187ffSLubomir Popov writew(chip, &i2c_base->sa); 364960187ffSLubomir Popov /* Stop bit needed here */ 365960187ffSLubomir Popov writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | 366960187ffSLubomir Popov I2C_CON_STP, &i2c_base->con); 367960187ffSLubomir Popov 368be243e41SMugunthan V N status = wait_for_event(i2c_base, waitdelay); 369960187ffSLubomir Popov 370960187ffSLubomir Popov if ((status & ~I2C_STAT_XRDY) == 0 || (status & I2C_STAT_AL)) { 371960187ffSLubomir Popov /* 372960187ffSLubomir Popov * With current high-level command implementation, notifying 373960187ffSLubomir Popov * the user shall flood the console with 127 messages. If 374960187ffSLubomir Popov * silent exit is desired upon unconfigured bus, remove the 375960187ffSLubomir Popov * following 'if' section: 376960187ffSLubomir Popov */ 377960187ffSLubomir Popov if (status == I2C_STAT_XRDY) 378be243e41SMugunthan V N printf("i2c_probe: pads on bus probably not configured (status=0x%x)\n", 379be243e41SMugunthan V N status); 380960187ffSLubomir Popov 381960187ffSLubomir Popov goto pr_exit; 382960187ffSLubomir Popov } 383960187ffSLubomir Popov 384960187ffSLubomir Popov /* Check for ACK (!NAK) */ 385960187ffSLubomir Popov if (!(status & I2C_STAT_NACK)) { 386960187ffSLubomir Popov res = 0; /* Device found */ 387be243e41SMugunthan V N udelay(waitdelay);/* Required by AM335X in SPL */ 388960187ffSLubomir Popov /* Abort transfer (force idle state) */ 389960187ffSLubomir Popov writew(I2C_CON_MST | I2C_CON_TRX, &i2c_base->con); /* Reset */ 390960187ffSLubomir Popov udelay(1000); 391960187ffSLubomir Popov writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_TRX | 392960187ffSLubomir Popov I2C_CON_STP, &i2c_base->con); /* STP */ 393960187ffSLubomir Popov } 394960187ffSLubomir Popov pr_exit: 395be243e41SMugunthan V N flush_fifo(i2c_base); 3961d2e96deSDirk Behme writew(0xFFFF, &i2c_base->stat); 397080c646dSJean-Christophe PLAGNIOL-VILLARD return res; 398080c646dSJean-Christophe PLAGNIOL-VILLARD } 399080c646dSJean-Christophe PLAGNIOL-VILLARD 400960187ffSLubomir Popov /* 401960187ffSLubomir Popov * i2c_read: Function now uses a single I2C read transaction with bulk transfer 402960187ffSLubomir Popov * of the requested number of bytes (note that the 'i2c md' command 403960187ffSLubomir Popov * limits this to 16 bytes anyway). If CONFIG_I2C_REPEATED_START is 404960187ffSLubomir Popov * defined in the board config header, this transaction shall be with 405960187ffSLubomir Popov * Repeated Start (Sr) between the address and data phases; otherwise 406960187ffSLubomir Popov * Stop-Start (P-S) shall be used (some I2C chips do require a P-S). 407960187ffSLubomir Popov * The address (reg offset) may be 0, 1 or 2 bytes long. 408960187ffSLubomir Popov * Function now reads correctly from chips that return more than one 409960187ffSLubomir Popov * byte of data per addressed register (like TI temperature sensors), 410960187ffSLubomir Popov * or that do not need a register address at all (such as some clock 411960187ffSLubomir Popov * distributors). 412960187ffSLubomir Popov */ 413be243e41SMugunthan V N static int __omap24_i2c_read(struct i2c *i2c_base, int waitdelay, uchar chip, 414be243e41SMugunthan V N uint addr, int alen, uchar *buffer, int len) 415080c646dSJean-Christophe PLAGNIOL-VILLARD { 416960187ffSLubomir Popov int i2c_error = 0; 417960187ffSLubomir Popov u16 status; 418960187ffSLubomir Popov 419960187ffSLubomir Popov if (alen < 0) { 420960187ffSLubomir Popov puts("I2C read: addr len < 0\n"); 421960187ffSLubomir Popov return 1; 422960187ffSLubomir Popov } 423960187ffSLubomir Popov if (len < 0) { 424960187ffSLubomir Popov puts("I2C read: data len < 0\n"); 425960187ffSLubomir Popov return 1; 426960187ffSLubomir Popov } 427960187ffSLubomir Popov if (buffer == NULL) { 428960187ffSLubomir Popov puts("I2C read: NULL pointer passed\n"); 429960187ffSLubomir Popov return 1; 430960187ffSLubomir Popov } 431080c646dSJean-Christophe PLAGNIOL-VILLARD 43255faa589SIlya Yanok if (alen > 2) { 433cec487a4STom Rini printf("I2C read: addr len %d not supported\n", alen); 434080c646dSJean-Christophe PLAGNIOL-VILLARD return 1; 435080c646dSJean-Christophe PLAGNIOL-VILLARD } 436080c646dSJean-Christophe PLAGNIOL-VILLARD 43755faa589SIlya Yanok if (addr + len > (1 << 16)) { 438cec487a4STom Rini puts("I2C read: address out of range\n"); 439080c646dSJean-Christophe PLAGNIOL-VILLARD return 1; 440080c646dSJean-Christophe PLAGNIOL-VILLARD } 441080c646dSJean-Christophe PLAGNIOL-VILLARD 44232b9b556SGuy Thouret #ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW 44332b9b556SGuy Thouret /* 44432b9b556SGuy Thouret * EEPROM chips that implement "address overflow" are ones 44532b9b556SGuy Thouret * like Catalyst 24WC04/08/16 which has 9/10/11 bits of 44632b9b556SGuy Thouret * address and the extra bits end up in the "chip address" 44732b9b556SGuy Thouret * bit slots. This makes a 24WC08 (1Kbyte) chip look like 44832b9b556SGuy Thouret * four 256 byte chips. 44932b9b556SGuy Thouret * 45032b9b556SGuy Thouret * Note that we consider the length of the address field to 45132b9b556SGuy Thouret * still be one byte because the extra address bits are 45232b9b556SGuy Thouret * hidden in the chip address. 45332b9b556SGuy Thouret */ 45432b9b556SGuy Thouret if (alen > 0) 45532b9b556SGuy Thouret chip |= ((addr >> (alen * 8)) & 45632b9b556SGuy Thouret CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); 45732b9b556SGuy Thouret #endif 45832b9b556SGuy Thouret 459960187ffSLubomir Popov /* Wait until bus not busy */ 460be243e41SMugunthan V N if (wait_for_bb(i2c_base, waitdelay)) 461080c646dSJean-Christophe PLAGNIOL-VILLARD return 1; 462960187ffSLubomir Popov 463960187ffSLubomir Popov /* Zero, one or two bytes reg address (offset) */ 464960187ffSLubomir Popov writew(alen, &i2c_base->cnt); 465960187ffSLubomir Popov /* Set slave address */ 466960187ffSLubomir Popov writew(chip, &i2c_base->sa); 467960187ffSLubomir Popov 468960187ffSLubomir Popov if (alen) { 469960187ffSLubomir Popov /* Must write reg offset first */ 470960187ffSLubomir Popov #ifdef CONFIG_I2C_REPEATED_START 471960187ffSLubomir Popov /* No stop bit, use Repeated Start (Sr) */ 472960187ffSLubomir Popov writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | 473960187ffSLubomir Popov I2C_CON_TRX, &i2c_base->con); 474960187ffSLubomir Popov #else 475960187ffSLubomir Popov /* Stop - Start (P-S) */ 476960187ffSLubomir Popov writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP | 477960187ffSLubomir Popov I2C_CON_TRX, &i2c_base->con); 478960187ffSLubomir Popov #endif 479960187ffSLubomir Popov /* Send register offset */ 480960187ffSLubomir Popov while (1) { 481be243e41SMugunthan V N status = wait_for_event(i2c_base, waitdelay); 482960187ffSLubomir Popov /* Try to identify bus that is not padconf'd for I2C */ 483960187ffSLubomir Popov if (status == I2C_STAT_XRDY) { 484960187ffSLubomir Popov i2c_error = 2; 485be243e41SMugunthan V N printf("i2c_read (addr phase): pads on bus probably not configured (status=0x%x)\n", 486be243e41SMugunthan V N status); 487960187ffSLubomir Popov goto rd_exit; 488960187ffSLubomir Popov } 489d5243359SHannes Petermaier if (status == 0 || (status & I2C_STAT_NACK)) { 490960187ffSLubomir Popov i2c_error = 1; 491960187ffSLubomir Popov printf("i2c_read: error waiting for addr ACK (status=0x%x)\n", 492960187ffSLubomir Popov status); 493960187ffSLubomir Popov goto rd_exit; 494960187ffSLubomir Popov } 495960187ffSLubomir Popov if (alen) { 496960187ffSLubomir Popov if (status & I2C_STAT_XRDY) { 497960187ffSLubomir Popov alen--; 498960187ffSLubomir Popov /* Do we have to use byte access? */ 499960187ffSLubomir Popov writeb((addr >> (8 * alen)) & 0xff, 500960187ffSLubomir Popov &i2c_base->data); 501960187ffSLubomir Popov writew(I2C_STAT_XRDY, &i2c_base->stat); 502960187ffSLubomir Popov } 503960187ffSLubomir Popov } 504960187ffSLubomir Popov if (status & I2C_STAT_ARDY) { 505960187ffSLubomir Popov writew(I2C_STAT_ARDY, &i2c_base->stat); 506960187ffSLubomir Popov break; 507960187ffSLubomir Popov } 508960187ffSLubomir Popov } 509960187ffSLubomir Popov } 510960187ffSLubomir Popov /* Set slave address */ 511960187ffSLubomir Popov writew(chip, &i2c_base->sa); 512960187ffSLubomir Popov /* Read len bytes from slave */ 513960187ffSLubomir Popov writew(len, &i2c_base->cnt); 514960187ffSLubomir Popov /* Need stop bit here */ 515960187ffSLubomir Popov writew(I2C_CON_EN | I2C_CON_MST | 516960187ffSLubomir Popov I2C_CON_STT | I2C_CON_STP, 517960187ffSLubomir Popov &i2c_base->con); 518960187ffSLubomir Popov 519960187ffSLubomir Popov /* Receive data */ 520960187ffSLubomir Popov while (1) { 521be243e41SMugunthan V N status = wait_for_event(i2c_base, waitdelay); 522960187ffSLubomir Popov /* 523960187ffSLubomir Popov * Try to identify bus that is not padconf'd for I2C. This 524960187ffSLubomir Popov * state could be left over from previous transactions if 525960187ffSLubomir Popov * the address phase is skipped due to alen=0. 526960187ffSLubomir Popov */ 527960187ffSLubomir Popov if (status == I2C_STAT_XRDY) { 528960187ffSLubomir Popov i2c_error = 2; 529be243e41SMugunthan V N printf("i2c_read (data phase): pads on bus probably not configured (status=0x%x)\n", 530be243e41SMugunthan V N status); 531960187ffSLubomir Popov goto rd_exit; 532960187ffSLubomir Popov } 533d5243359SHannes Petermaier if (status == 0 || (status & I2C_STAT_NACK)) { 534960187ffSLubomir Popov i2c_error = 1; 535960187ffSLubomir Popov goto rd_exit; 536960187ffSLubomir Popov } 537960187ffSLubomir Popov if (status & I2C_STAT_RRDY) { 538960187ffSLubomir Popov *buffer++ = readb(&i2c_base->data); 539960187ffSLubomir Popov writew(I2C_STAT_RRDY, &i2c_base->stat); 540960187ffSLubomir Popov } 541960187ffSLubomir Popov if (status & I2C_STAT_ARDY) { 542960187ffSLubomir Popov writew(I2C_STAT_ARDY, &i2c_base->stat); 543960187ffSLubomir Popov break; 544080c646dSJean-Christophe PLAGNIOL-VILLARD } 545080c646dSJean-Christophe PLAGNIOL-VILLARD } 546080c646dSJean-Christophe PLAGNIOL-VILLARD 547960187ffSLubomir Popov rd_exit: 548be243e41SMugunthan V N flush_fifo(i2c_base); 549960187ffSLubomir Popov writew(0xFFFF, &i2c_base->stat); 550960187ffSLubomir Popov return i2c_error; 551080c646dSJean-Christophe PLAGNIOL-VILLARD } 552080c646dSJean-Christophe PLAGNIOL-VILLARD 553960187ffSLubomir Popov /* i2c_write: Address (reg offset) may be 0, 1 or 2 bytes long. */ 554be243e41SMugunthan V N static int __omap24_i2c_write(struct i2c *i2c_base, int waitdelay, uchar chip, 555be243e41SMugunthan V N uint addr, int alen, uchar *buffer, int len) 556080c646dSJean-Christophe PLAGNIOL-VILLARD { 557cec487a4STom Rini int i; 558cec487a4STom Rini u16 status; 559cec487a4STom Rini int i2c_error = 0; 560d5243359SHannes Petermaier int timeout = I2C_TIMEOUT; 561960187ffSLubomir Popov 562960187ffSLubomir Popov if (alen < 0) { 563960187ffSLubomir Popov puts("I2C write: addr len < 0\n"); 564960187ffSLubomir Popov return 1; 565960187ffSLubomir Popov } 566960187ffSLubomir Popov 567960187ffSLubomir Popov if (len < 0) { 568960187ffSLubomir Popov puts("I2C write: data len < 0\n"); 569960187ffSLubomir Popov return 1; 570960187ffSLubomir Popov } 571960187ffSLubomir Popov 572960187ffSLubomir Popov if (buffer == NULL) { 573960187ffSLubomir Popov puts("I2C write: NULL pointer passed\n"); 574960187ffSLubomir Popov return 1; 575960187ffSLubomir Popov } 576080c646dSJean-Christophe PLAGNIOL-VILLARD 57755faa589SIlya Yanok if (alen > 2) { 578cec487a4STom Rini printf("I2C write: addr len %d not supported\n", alen); 579080c646dSJean-Christophe PLAGNIOL-VILLARD return 1; 580cec487a4STom Rini } 581080c646dSJean-Christophe PLAGNIOL-VILLARD 58255faa589SIlya Yanok if (addr + len > (1 << 16)) { 583cec487a4STom Rini printf("I2C write: address 0x%x + 0x%x out of range\n", 584cec487a4STom Rini addr, len); 585080c646dSJean-Christophe PLAGNIOL-VILLARD return 1; 586080c646dSJean-Christophe PLAGNIOL-VILLARD } 587080c646dSJean-Christophe PLAGNIOL-VILLARD 58832b9b556SGuy Thouret #ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW 58932b9b556SGuy Thouret /* 59032b9b556SGuy Thouret * EEPROM chips that implement "address overflow" are ones 59132b9b556SGuy Thouret * like Catalyst 24WC04/08/16 which has 9/10/11 bits of 59232b9b556SGuy Thouret * address and the extra bits end up in the "chip address" 59332b9b556SGuy Thouret * bit slots. This makes a 24WC08 (1Kbyte) chip look like 59432b9b556SGuy Thouret * four 256 byte chips. 59532b9b556SGuy Thouret * 59632b9b556SGuy Thouret * Note that we consider the length of the address field to 59732b9b556SGuy Thouret * still be one byte because the extra address bits are 59832b9b556SGuy Thouret * hidden in the chip address. 59932b9b556SGuy Thouret */ 60032b9b556SGuy Thouret if (alen > 0) 60132b9b556SGuy Thouret chip |= ((addr >> (alen * 8)) & 60232b9b556SGuy Thouret CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); 60332b9b556SGuy Thouret #endif 60432b9b556SGuy Thouret 605960187ffSLubomir Popov /* Wait until bus not busy */ 606be243e41SMugunthan V N if (wait_for_bb(i2c_base, waitdelay)) 607febc4cd4SVincent Stehlé return 1; 6080607e2b9SMichael Jones 609960187ffSLubomir Popov /* Start address phase - will write regoffset + len bytes data */ 610cec487a4STom Rini writew(alen + len, &i2c_base->cnt); 611960187ffSLubomir Popov /* Set slave address */ 6120607e2b9SMichael Jones writew(chip, &i2c_base->sa); 613960187ffSLubomir Popov /* Stop bit needed here */ 6140607e2b9SMichael Jones writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | 6150607e2b9SMichael Jones I2C_CON_STP, &i2c_base->con); 6160607e2b9SMichael Jones 617960187ffSLubomir Popov while (alen) { 618960187ffSLubomir Popov /* Must write reg offset (one or two bytes) */ 619be243e41SMugunthan V N status = wait_for_event(i2c_base, waitdelay); 620960187ffSLubomir Popov /* Try to identify bus that is not padconf'd for I2C */ 621960187ffSLubomir Popov if (status == I2C_STAT_XRDY) { 622960187ffSLubomir Popov i2c_error = 2; 623be243e41SMugunthan V N printf("i2c_write: pads on bus probably not configured (status=0x%x)\n", 624be243e41SMugunthan V N status); 625960187ffSLubomir Popov goto wr_exit; 626960187ffSLubomir Popov } 627d5243359SHannes Petermaier if (status == 0 || (status & I2C_STAT_NACK)) { 6282faa7619SPatil, Rachna i2c_error = 1; 629960187ffSLubomir Popov printf("i2c_write: error waiting for addr ACK (status=0x%x)\n", 630cec487a4STom Rini status); 631960187ffSLubomir Popov goto wr_exit; 632cec487a4STom Rini } 6330607e2b9SMichael Jones if (status & I2C_STAT_XRDY) { 634960187ffSLubomir Popov alen--; 635960187ffSLubomir Popov writeb((addr >> (8 * alen)) & 0xff, &i2c_base->data); 636cec487a4STom Rini writew(I2C_STAT_XRDY, &i2c_base->stat); 637cec487a4STom Rini } else { 6380607e2b9SMichael Jones i2c_error = 1; 639960187ffSLubomir Popov printf("i2c_write: bus not ready for addr Tx (status=0x%x)\n", 640960187ffSLubomir Popov status); 641960187ffSLubomir Popov goto wr_exit; 642960187ffSLubomir Popov } 643960187ffSLubomir Popov } 644960187ffSLubomir Popov /* Address phase is over, now write data */ 645960187ffSLubomir Popov for (i = 0; i < len; i++) { 646be243e41SMugunthan V N status = wait_for_event(i2c_base, waitdelay); 647d5243359SHannes Petermaier if (status == 0 || (status & I2C_STAT_NACK)) { 648960187ffSLubomir Popov i2c_error = 1; 649960187ffSLubomir Popov printf("i2c_write: error waiting for data ACK (status=0x%x)\n", 650960187ffSLubomir Popov status); 651960187ffSLubomir Popov goto wr_exit; 652960187ffSLubomir Popov } 653960187ffSLubomir Popov if (status & I2C_STAT_XRDY) { 654960187ffSLubomir Popov writeb(buffer[i], &i2c_base->data); 655960187ffSLubomir Popov writew(I2C_STAT_XRDY, &i2c_base->stat); 656960187ffSLubomir Popov } else { 657960187ffSLubomir Popov i2c_error = 1; 658960187ffSLubomir Popov printf("i2c_write: bus not ready for data Tx (i=%d)\n", 659960187ffSLubomir Popov i); 660960187ffSLubomir Popov goto wr_exit; 6612faa7619SPatil, Rachna } 6622faa7619SPatil, Rachna } 663d5243359SHannes Petermaier /* 664d5243359SHannes Petermaier * poll ARDY bit for making sure that last byte really has been 665d5243359SHannes Petermaier * transferred on the bus. 666d5243359SHannes Petermaier */ 667d5243359SHannes Petermaier do { 668be243e41SMugunthan V N status = wait_for_event(i2c_base, waitdelay); 669d5243359SHannes Petermaier } while (!(status & I2C_STAT_ARDY) && timeout--); 670d5243359SHannes Petermaier if (timeout <= 0) 671d5243359SHannes Petermaier printf("i2c_write: timed out writig last byte!\n"); 6722faa7619SPatil, Rachna 673960187ffSLubomir Popov wr_exit: 674be243e41SMugunthan V N flush_fifo(i2c_base); 6750607e2b9SMichael Jones writew(0xFFFF, &i2c_base->stat); 676cec487a4STom Rini return i2c_error; 677080c646dSJean-Christophe PLAGNIOL-VILLARD } 678080c646dSJean-Christophe PLAGNIOL-VILLARD 679*daa69ffeSMugunthan V N #ifndef CONFIG_DM_I2C 680960187ffSLubomir Popov /* 681be243e41SMugunthan V N * The legacy I2C functions. These need to get removed once 682be243e41SMugunthan V N * all users of this driver are converted to DM. 683960187ffSLubomir Popov */ 6846789e84eSHeiko Schocher static struct i2c *omap24_get_base(struct i2c_adapter *adap) 6851d2e96deSDirk Behme { 6866789e84eSHeiko Schocher switch (adap->hwadapnr) { 687960187ffSLubomir Popov case 0: 6886789e84eSHeiko Schocher return (struct i2c *)I2C_BASE1; 689960187ffSLubomir Popov break; 690960187ffSLubomir Popov case 1: 6916789e84eSHeiko Schocher return (struct i2c *)I2C_BASE2; 692960187ffSLubomir Popov break; 693960187ffSLubomir Popov #if (I2C_BUS_MAX > 2) 694960187ffSLubomir Popov case 2: 6956789e84eSHeiko Schocher return (struct i2c *)I2C_BASE3; 696960187ffSLubomir Popov break; 697960187ffSLubomir Popov #if (I2C_BUS_MAX > 3) 698960187ffSLubomir Popov case 3: 6996789e84eSHeiko Schocher return (struct i2c *)I2C_BASE4; 700960187ffSLubomir Popov break; 701960187ffSLubomir Popov #if (I2C_BUS_MAX > 4) 702960187ffSLubomir Popov case 4: 7036789e84eSHeiko Schocher return (struct i2c *)I2C_BASE5; 704960187ffSLubomir Popov break; 705960187ffSLubomir Popov #endif 706960187ffSLubomir Popov #endif 707960187ffSLubomir Popov #endif 7086789e84eSHeiko Schocher default: 7096789e84eSHeiko Schocher printf("wrong hwadapnr: %d\n", adap->hwadapnr); 7106789e84eSHeiko Schocher break; 7116789e84eSHeiko Schocher } 7126789e84eSHeiko Schocher return NULL; 713960187ffSLubomir Popov } 7141d2e96deSDirk Behme 715be243e41SMugunthan V N 716be243e41SMugunthan V N static int omap24_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, 717be243e41SMugunthan V N int alen, uchar *buffer, int len) 718be243e41SMugunthan V N { 719be243e41SMugunthan V N struct i2c *i2c_base = omap24_get_base(adap); 720be243e41SMugunthan V N 721be243e41SMugunthan V N return __omap24_i2c_read(i2c_base, adap->waitdelay, chip, addr, 722be243e41SMugunthan V N alen, buffer, len); 723be243e41SMugunthan V N } 724be243e41SMugunthan V N 725be243e41SMugunthan V N 726be243e41SMugunthan V N static int omap24_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, 727be243e41SMugunthan V N int alen, uchar *buffer, int len) 728be243e41SMugunthan V N { 729be243e41SMugunthan V N struct i2c *i2c_base = omap24_get_base(adap); 730be243e41SMugunthan V N 731be243e41SMugunthan V N return __omap24_i2c_write(i2c_base, adap->waitdelay, chip, addr, 732be243e41SMugunthan V N alen, buffer, len); 733be243e41SMugunthan V N } 734be243e41SMugunthan V N 735be243e41SMugunthan V N static uint omap24_i2c_setspeed(struct i2c_adapter *adap, uint speed) 736be243e41SMugunthan V N { 737be243e41SMugunthan V N struct i2c *i2c_base = omap24_get_base(adap); 738be243e41SMugunthan V N int ret; 739be243e41SMugunthan V N 740be243e41SMugunthan V N ret = __omap24_i2c_setspeed(i2c_base, speed, &adap->waitdelay); 741be243e41SMugunthan V N if (ret) { 742be243e41SMugunthan V N error("%s: set i2c speed failed\n", __func__); 743be243e41SMugunthan V N return ret; 744be243e41SMugunthan V N } 745be243e41SMugunthan V N 746be243e41SMugunthan V N adap->speed = speed; 747be243e41SMugunthan V N 748be243e41SMugunthan V N return 0; 749be243e41SMugunthan V N } 750be243e41SMugunthan V N 751be243e41SMugunthan V N static void omap24_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) 752be243e41SMugunthan V N { 753be243e41SMugunthan V N struct i2c *i2c_base = omap24_get_base(adap); 754be243e41SMugunthan V N 755be243e41SMugunthan V N return __omap24_i2c_init(i2c_base, speed, slaveadd, &adap->waitdelay); 756be243e41SMugunthan V N } 757be243e41SMugunthan V N 758be243e41SMugunthan V N static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip) 759be243e41SMugunthan V N { 760be243e41SMugunthan V N struct i2c *i2c_base = omap24_get_base(adap); 761be243e41SMugunthan V N 762be243e41SMugunthan V N return __omap24_i2c_probe(i2c_base, adap->waitdelay, chip); 763be243e41SMugunthan V N } 764be243e41SMugunthan V N 7656789e84eSHeiko Schocher #if !defined(CONFIG_SYS_OMAP24_I2C_SPEED1) 7666789e84eSHeiko Schocher #define CONFIG_SYS_OMAP24_I2C_SPEED1 CONFIG_SYS_OMAP24_I2C_SPEED 7676789e84eSHeiko Schocher #endif 7686789e84eSHeiko Schocher #if !defined(CONFIG_SYS_OMAP24_I2C_SLAVE1) 7696789e84eSHeiko Schocher #define CONFIG_SYS_OMAP24_I2C_SLAVE1 CONFIG_SYS_OMAP24_I2C_SLAVE 7706789e84eSHeiko Schocher #endif 7711d2e96deSDirk Behme 7726789e84eSHeiko Schocher U_BOOT_I2C_ADAP_COMPLETE(omap24_0, omap24_i2c_init, omap24_i2c_probe, 773d5243359SHannes Petermaier omap24_i2c_read, omap24_i2c_write, omap24_i2c_setspeed, 7746789e84eSHeiko Schocher CONFIG_SYS_OMAP24_I2C_SPEED, 7756789e84eSHeiko Schocher CONFIG_SYS_OMAP24_I2C_SLAVE, 7766789e84eSHeiko Schocher 0) 7776789e84eSHeiko Schocher U_BOOT_I2C_ADAP_COMPLETE(omap24_1, omap24_i2c_init, omap24_i2c_probe, 778d5243359SHannes Petermaier omap24_i2c_read, omap24_i2c_write, omap24_i2c_setspeed, 7796789e84eSHeiko Schocher CONFIG_SYS_OMAP24_I2C_SPEED1, 7806789e84eSHeiko Schocher CONFIG_SYS_OMAP24_I2C_SLAVE1, 7816789e84eSHeiko Schocher 1) 7826789e84eSHeiko Schocher #if (I2C_BUS_MAX > 2) 7836789e84eSHeiko Schocher #if !defined(CONFIG_SYS_OMAP24_I2C_SPEED2) 7846789e84eSHeiko Schocher #define CONFIG_SYS_OMAP24_I2C_SPEED2 CONFIG_SYS_OMAP24_I2C_SPEED 7856789e84eSHeiko Schocher #endif 7866789e84eSHeiko Schocher #if !defined(CONFIG_SYS_OMAP24_I2C_SLAVE2) 7876789e84eSHeiko Schocher #define CONFIG_SYS_OMAP24_I2C_SLAVE2 CONFIG_SYS_OMAP24_I2C_SLAVE 7886789e84eSHeiko Schocher #endif 7891d2e96deSDirk Behme 7906789e84eSHeiko Schocher U_BOOT_I2C_ADAP_COMPLETE(omap24_2, omap24_i2c_init, omap24_i2c_probe, 7916789e84eSHeiko Schocher omap24_i2c_read, omap24_i2c_write, NULL, 7926789e84eSHeiko Schocher CONFIG_SYS_OMAP24_I2C_SPEED2, 7936789e84eSHeiko Schocher CONFIG_SYS_OMAP24_I2C_SLAVE2, 7946789e84eSHeiko Schocher 2) 7956789e84eSHeiko Schocher #if (I2C_BUS_MAX > 3) 7966789e84eSHeiko Schocher #if !defined(CONFIG_SYS_OMAP24_I2C_SPEED3) 7976789e84eSHeiko Schocher #define CONFIG_SYS_OMAP24_I2C_SPEED3 CONFIG_SYS_OMAP24_I2C_SPEED 7986789e84eSHeiko Schocher #endif 7996789e84eSHeiko Schocher #if !defined(CONFIG_SYS_OMAP24_I2C_SLAVE3) 8006789e84eSHeiko Schocher #define CONFIG_SYS_OMAP24_I2C_SLAVE3 CONFIG_SYS_OMAP24_I2C_SLAVE 8016789e84eSHeiko Schocher #endif 802938717ceSSteve Sakoman 8036789e84eSHeiko Schocher U_BOOT_I2C_ADAP_COMPLETE(omap24_3, omap24_i2c_init, omap24_i2c_probe, 8046789e84eSHeiko Schocher omap24_i2c_read, omap24_i2c_write, NULL, 8056789e84eSHeiko Schocher CONFIG_SYS_OMAP24_I2C_SPEED3, 8066789e84eSHeiko Schocher CONFIG_SYS_OMAP24_I2C_SLAVE3, 8076789e84eSHeiko Schocher 3) 8086789e84eSHeiko Schocher #if (I2C_BUS_MAX > 4) 8096789e84eSHeiko Schocher #if !defined(CONFIG_SYS_OMAP24_I2C_SPEED4) 8106789e84eSHeiko Schocher #define CONFIG_SYS_OMAP24_I2C_SPEED4 CONFIG_SYS_OMAP24_I2C_SPEED 8116789e84eSHeiko Schocher #endif 8126789e84eSHeiko Schocher #if !defined(CONFIG_SYS_OMAP24_I2C_SLAVE4) 8136789e84eSHeiko Schocher #define CONFIG_SYS_OMAP24_I2C_SLAVE4 CONFIG_SYS_OMAP24_I2C_SLAVE 8146789e84eSHeiko Schocher #endif 8156789e84eSHeiko Schocher 8166789e84eSHeiko Schocher U_BOOT_I2C_ADAP_COMPLETE(omap24_4, omap24_i2c_init, omap24_i2c_probe, 8176789e84eSHeiko Schocher omap24_i2c_read, omap24_i2c_write, NULL, 8186789e84eSHeiko Schocher CONFIG_SYS_OMAP24_I2C_SPEED4, 8196789e84eSHeiko Schocher CONFIG_SYS_OMAP24_I2C_SLAVE4, 8206789e84eSHeiko Schocher 4) 8216789e84eSHeiko Schocher #endif 8226789e84eSHeiko Schocher #endif 8236789e84eSHeiko Schocher #endif 824*daa69ffeSMugunthan V N 825*daa69ffeSMugunthan V N #else /* CONFIG_DM_I2C */ 826*daa69ffeSMugunthan V N 827*daa69ffeSMugunthan V N static int omap_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs) 828*daa69ffeSMugunthan V N { 829*daa69ffeSMugunthan V N struct omap_i2c *priv = dev_get_priv(bus); 830*daa69ffeSMugunthan V N int ret; 831*daa69ffeSMugunthan V N 832*daa69ffeSMugunthan V N debug("i2c_xfer: %d messages\n", nmsgs); 833*daa69ffeSMugunthan V N for (; nmsgs > 0; nmsgs--, msg++) { 834*daa69ffeSMugunthan V N debug("i2c_xfer: chip=0x%x, len=0x%x\n", msg->addr, msg->len); 835*daa69ffeSMugunthan V N if (msg->flags & I2C_M_RD) { 836*daa69ffeSMugunthan V N ret = __omap24_i2c_read(priv->regs, priv->waitdelay, 837*daa69ffeSMugunthan V N msg->addr, 0, 0, msg->buf, 838*daa69ffeSMugunthan V N msg->len); 839*daa69ffeSMugunthan V N } else { 840*daa69ffeSMugunthan V N ret = __omap24_i2c_write(priv->regs, priv->waitdelay, 841*daa69ffeSMugunthan V N msg->addr, 0, 0, msg->buf, 842*daa69ffeSMugunthan V N msg->len); 843*daa69ffeSMugunthan V N } 844*daa69ffeSMugunthan V N if (ret) { 845*daa69ffeSMugunthan V N debug("i2c_write: error sending\n"); 846*daa69ffeSMugunthan V N return -EREMOTEIO; 847*daa69ffeSMugunthan V N } 848*daa69ffeSMugunthan V N } 849*daa69ffeSMugunthan V N 850*daa69ffeSMugunthan V N return 0; 851*daa69ffeSMugunthan V N } 852*daa69ffeSMugunthan V N 853*daa69ffeSMugunthan V N static int omap_i2c_set_bus_speed(struct udevice *bus, unsigned int speed) 854*daa69ffeSMugunthan V N { 855*daa69ffeSMugunthan V N struct omap_i2c *priv = dev_get_priv(bus); 856*daa69ffeSMugunthan V N 857*daa69ffeSMugunthan V N priv->speed = speed; 858*daa69ffeSMugunthan V N 859*daa69ffeSMugunthan V N return __omap24_i2c_setspeed(priv->regs, speed, &priv->waitdelay); 860*daa69ffeSMugunthan V N } 861*daa69ffeSMugunthan V N 862*daa69ffeSMugunthan V N static int omap_i2c_probe_chip(struct udevice *bus, uint chip_addr, 863*daa69ffeSMugunthan V N uint chip_flags) 864*daa69ffeSMugunthan V N { 865*daa69ffeSMugunthan V N struct omap_i2c *priv = dev_get_priv(bus); 866*daa69ffeSMugunthan V N 867*daa69ffeSMugunthan V N return __omap24_i2c_probe(priv->regs, priv->waitdelay, chip_addr); 868*daa69ffeSMugunthan V N } 869*daa69ffeSMugunthan V N 870*daa69ffeSMugunthan V N static int omap_i2c_probe(struct udevice *bus) 871*daa69ffeSMugunthan V N { 872*daa69ffeSMugunthan V N struct omap_i2c *priv = dev_get_priv(bus); 873*daa69ffeSMugunthan V N 874*daa69ffeSMugunthan V N __omap24_i2c_init(priv->regs, priv->speed, 0, &priv->waitdelay); 875*daa69ffeSMugunthan V N 876*daa69ffeSMugunthan V N return 0; 877*daa69ffeSMugunthan V N } 878*daa69ffeSMugunthan V N 879*daa69ffeSMugunthan V N static int omap_i2c_ofdata_to_platdata(struct udevice *bus) 880*daa69ffeSMugunthan V N { 881*daa69ffeSMugunthan V N struct omap_i2c *priv = dev_get_priv(bus); 882*daa69ffeSMugunthan V N 883*daa69ffeSMugunthan V N priv->regs = map_physmem(dev_get_addr(bus), sizeof(void *), 884*daa69ffeSMugunthan V N MAP_NOCACHE); 885*daa69ffeSMugunthan V N priv->speed = CONFIG_SYS_OMAP24_I2C_SPEED; 886*daa69ffeSMugunthan V N 887*daa69ffeSMugunthan V N return 0; 888*daa69ffeSMugunthan V N } 889*daa69ffeSMugunthan V N 890*daa69ffeSMugunthan V N static const struct dm_i2c_ops omap_i2c_ops = { 891*daa69ffeSMugunthan V N .xfer = omap_i2c_xfer, 892*daa69ffeSMugunthan V N .probe_chip = omap_i2c_probe_chip, 893*daa69ffeSMugunthan V N .set_bus_speed = omap_i2c_set_bus_speed, 894*daa69ffeSMugunthan V N }; 895*daa69ffeSMugunthan V N 896*daa69ffeSMugunthan V N static const struct udevice_id omap_i2c_ids[] = { 897*daa69ffeSMugunthan V N { .compatible = "ti,omap4-i2c" }, 898*daa69ffeSMugunthan V N { } 899*daa69ffeSMugunthan V N }; 900*daa69ffeSMugunthan V N 901*daa69ffeSMugunthan V N U_BOOT_DRIVER(i2c_omap) = { 902*daa69ffeSMugunthan V N .name = "i2c_omap", 903*daa69ffeSMugunthan V N .id = UCLASS_I2C, 904*daa69ffeSMugunthan V N .of_match = omap_i2c_ids, 905*daa69ffeSMugunthan V N .ofdata_to_platdata = omap_i2c_ofdata_to_platdata, 906*daa69ffeSMugunthan V N .probe = omap_i2c_probe, 907*daa69ffeSMugunthan V N .priv_auto_alloc_size = sizeof(struct omap_i2c), 908*daa69ffeSMugunthan V N .ops = &omap_i2c_ops, 909*daa69ffeSMugunthan V N .flags = DM_FLAG_PRE_RELOC, 910*daa69ffeSMugunthan V N }; 911*daa69ffeSMugunthan V N 912*daa69ffeSMugunthan V N #endif /* CONFIG_DM_I2C */ 913