xref: /rk3399_rockchip-uboot/drivers/i2c/omap24xx_i2c.c (revision daa69ffe3d4d603ccb7dfca92c33f19d9e1c2313)
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