xref: /rk3399_rockchip-uboot/drivers/i2c/omap24xx_i2c.c (revision 90aa625c9a9e1fb7a2f001fd8e50099bacaf92b8)
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>
42daa69ffeSMugunthan 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 
57daa69ffeSMugunthan V N struct omap_i2c {
58daa69ffeSMugunthan V N 	struct udevice *clk;
59daa69ffeSMugunthan V N 	struct i2c *regs;
60daa69ffeSMugunthan V N 	unsigned int speed;
61daa69ffeSMugunthan V N 	int waitdelay;
62daa69ffeSMugunthan V N 	int clk_id;
63daa69ffeSMugunthan V N };
64daa69ffeSMugunthan V N 
omap24_i2c_findpsc(u32 * pscl,u32 * psch,uint speed)65d5243359SHannes Petermaier static int omap24_i2c_findpsc(u32 *pscl, u32 *psch, uint speed)
66d5243359SHannes Petermaier {
67b52a3fa0SLukasz Majewski 	unsigned long internal_clk = 0, fclk;
68b52a3fa0SLukasz Majewski 	unsigned int prescaler;
69080c646dSJean-Christophe PLAGNIOL-VILLARD 
70d5243359SHannes Petermaier 	/*
71b52a3fa0SLukasz Majewski 	 * This method is only called for Standard and Fast Mode speeds
72b52a3fa0SLukasz Majewski 	 *
73b52a3fa0SLukasz Majewski 	 * For some TI SoCs it is explicitly written in TRM (e,g, SPRUHZ6G,
74b52a3fa0SLukasz Majewski 	 * page 5685, Table 24-7)
75b52a3fa0SLukasz Majewski 	 * that the internal I2C clock (after prescaler) should be between
76b52a3fa0SLukasz Majewski 	 * 7-12 MHz (at least for Fast Mode (FS)).
77b52a3fa0SLukasz Majewski 	 *
78b52a3fa0SLukasz Majewski 	 * Such approach is used in v4.9 Linux kernel in:
79b52a3fa0SLukasz Majewski 	 * ./drivers/i2c/busses/i2c-omap.c (omap_i2c_init function).
80d5243359SHannes Petermaier 	 */
81d5243359SHannes Petermaier 
82b52a3fa0SLukasz Majewski 	speed /= 1000; /* convert speed to kHz */
83d5243359SHannes Petermaier 
84b52a3fa0SLukasz Majewski 	if (speed > 100)
85b52a3fa0SLukasz Majewski 		internal_clk = 9600;
86b52a3fa0SLukasz Majewski 	else
87b52a3fa0SLukasz Majewski 		internal_clk = 4000;
88b52a3fa0SLukasz Majewski 
89b52a3fa0SLukasz Majewski 	fclk = I2C_IP_CLK / 1000;
90b52a3fa0SLukasz Majewski 	prescaler = fclk / internal_clk;
91b52a3fa0SLukasz Majewski 	prescaler = prescaler - 1;
92b52a3fa0SLukasz Majewski 
93b52a3fa0SLukasz Majewski 	if (speed > 100) {
94b52a3fa0SLukasz Majewski 		unsigned long scl;
95b52a3fa0SLukasz Majewski 
96b52a3fa0SLukasz Majewski 		/* Fast mode */
97b52a3fa0SLukasz Majewski 		scl = internal_clk / speed;
98b52a3fa0SLukasz Majewski 		*pscl = scl - (scl / 3) - I2C_FASTSPEED_SCLL_TRIM;
99b52a3fa0SLukasz Majewski 		*psch = (scl / 3) - I2C_FASTSPEED_SCLH_TRIM;
100b52a3fa0SLukasz Majewski 	} else {
101b52a3fa0SLukasz Majewski 		/* Standard mode */
102b52a3fa0SLukasz Majewski 		*pscl = internal_clk / (speed * 2) - I2C_FASTSPEED_SCLL_TRIM;
103b52a3fa0SLukasz Majewski 		*psch = internal_clk / (speed * 2) - I2C_FASTSPEED_SCLH_TRIM;
104b52a3fa0SLukasz Majewski 	}
105b52a3fa0SLukasz Majewski 
106b52a3fa0SLukasz Majewski 	debug("%s: speed [kHz]: %d psc: 0x%x sscl: 0x%x ssch: 0x%x\n",
107b52a3fa0SLukasz Majewski 	      __func__, speed, prescaler, *pscl, *psch);
108b52a3fa0SLukasz Majewski 
109b52a3fa0SLukasz Majewski 	if (*pscl <= 0 || *psch <= 0 || prescaler <= 0)
110b52a3fa0SLukasz Majewski 		return -EINVAL;
111d5243359SHannes Petermaier 
112d5243359SHannes Petermaier 	return prescaler;
113d5243359SHannes Petermaier }
114be243e41SMugunthan V N 
115be243e41SMugunthan V N /*
116be243e41SMugunthan V N  * Wait for the bus to be free by checking the Bus Busy (BB)
117be243e41SMugunthan V N  * bit to become clear
118be243e41SMugunthan V N  */
wait_for_bb(struct i2c * i2c_base,int waitdelay)119be243e41SMugunthan V N static int wait_for_bb(struct i2c *i2c_base, int waitdelay)
120080c646dSJean-Christophe PLAGNIOL-VILLARD {
121be243e41SMugunthan V N 	int timeout = I2C_TIMEOUT;
122be243e41SMugunthan V N 	u16 stat;
123be243e41SMugunthan V N 
124be243e41SMugunthan V N 	writew(0xFFFF, &i2c_base->stat);	/* clear current interrupts...*/
1258f339d23STom Rini #if defined(CONFIG_OMAP34XX)
126be243e41SMugunthan V N 	while ((stat = readw(&i2c_base->stat) & I2C_STAT_BB) && timeout--) {
127be243e41SMugunthan V N #else
128be243e41SMugunthan V N 	/* Read RAW status */
129be243e41SMugunthan V N 	while ((stat = readw(&i2c_base->irqstatus_raw) &
130be243e41SMugunthan V N 		I2C_STAT_BB) && timeout--) {
131be243e41SMugunthan V N #endif
132be243e41SMugunthan V N 		writew(stat, &i2c_base->stat);
133be243e41SMugunthan V N 		udelay(waitdelay);
134be243e41SMugunthan V N 	}
135be243e41SMugunthan V N 
136be243e41SMugunthan V N 	if (timeout <= 0) {
137be243e41SMugunthan V N 		printf("Timed out in wait_for_bb: status=%04x\n",
138be243e41SMugunthan V N 		       stat);
139be243e41SMugunthan V N 		return 1;
140be243e41SMugunthan V N 	}
141be243e41SMugunthan V N 	writew(0xFFFF, &i2c_base->stat);	 /* clear delayed stuff*/
142be243e41SMugunthan V N 	return 0;
143be243e41SMugunthan V N }
144be243e41SMugunthan V N 
145be243e41SMugunthan V N /*
146be243e41SMugunthan V N  * Wait for the I2C controller to complete current action
147be243e41SMugunthan V N  * and update status
148be243e41SMugunthan V N  */
149be243e41SMugunthan V N static u16 wait_for_event(struct i2c *i2c_base, int waitdelay)
150be243e41SMugunthan V N {
151be243e41SMugunthan V N 	u16 status;
152be243e41SMugunthan V N 	int timeout = I2C_TIMEOUT;
153be243e41SMugunthan V N 
154be243e41SMugunthan V N 	do {
155be243e41SMugunthan V N 		udelay(waitdelay);
1568f339d23STom Rini #if defined(CONFIG_OMAP34XX)
157be243e41SMugunthan V N 		status = readw(&i2c_base->stat);
158be243e41SMugunthan V N #else
159be243e41SMugunthan V N 		/* Read RAW status */
160be243e41SMugunthan V N 		status = readw(&i2c_base->irqstatus_raw);
161be243e41SMugunthan V N #endif
162be243e41SMugunthan V N 	} while (!(status &
163be243e41SMugunthan V N 		   (I2C_STAT_ROVR | I2C_STAT_XUDF | I2C_STAT_XRDY |
164be243e41SMugunthan V N 		    I2C_STAT_RRDY | I2C_STAT_ARDY | I2C_STAT_NACK |
165be243e41SMugunthan V N 		    I2C_STAT_AL)) && timeout--);
166be243e41SMugunthan V N 
167be243e41SMugunthan V N 	if (timeout <= 0) {
168be243e41SMugunthan V N 		printf("Timed out in wait_for_event: status=%04x\n",
169be243e41SMugunthan V N 		       status);
170be243e41SMugunthan V N 		/*
171be243e41SMugunthan V N 		 * If status is still 0 here, probably the bus pads have
172be243e41SMugunthan V N 		 * not been configured for I2C, and/or pull-ups are missing.
173be243e41SMugunthan V N 		 */
174be243e41SMugunthan V N 		printf("Check if pads/pull-ups of bus are properly configured\n");
175be243e41SMugunthan V N 		writew(0xFFFF, &i2c_base->stat);
176be243e41SMugunthan V N 		status = 0;
177be243e41SMugunthan V N 	}
178be243e41SMugunthan V N 
179be243e41SMugunthan V N 	return status;
180be243e41SMugunthan V N }
181be243e41SMugunthan V N 
182be243e41SMugunthan V N static void flush_fifo(struct i2c *i2c_base)
183be243e41SMugunthan V N {
184be243e41SMugunthan V N 	u16 stat;
185be243e41SMugunthan V N 
186be243e41SMugunthan V N 	/*
187be243e41SMugunthan V N 	 * note: if you try and read data when its not there or ready
188be243e41SMugunthan V N 	 * you get a bus error
189be243e41SMugunthan V N 	 */
190be243e41SMugunthan V N 	while (1) {
191be243e41SMugunthan V N 		stat = readw(&i2c_base->stat);
192be243e41SMugunthan V N 		if (stat == I2C_STAT_RRDY) {
193be243e41SMugunthan V N 			readb(&i2c_base->data);
194be243e41SMugunthan V N 			writew(I2C_STAT_RRDY, &i2c_base->stat);
195be243e41SMugunthan V N 			udelay(1000);
196be243e41SMugunthan V N 		} else
197be243e41SMugunthan V N 			break;
198be243e41SMugunthan V N 	}
199be243e41SMugunthan V N }
200be243e41SMugunthan V N 
201be243e41SMugunthan V N static int __omap24_i2c_setspeed(struct i2c *i2c_base, uint speed,
202be243e41SMugunthan V N 				 int *waitdelay)
203be243e41SMugunthan V N {
204d5243359SHannes Petermaier 	int psc, fsscll = 0, fssclh = 0;
2057f79dfb4STom Rix 	int hsscll = 0, hssclh = 0;
206d5243359SHannes Petermaier 	u32 scll = 0, sclh = 0;
2077f79dfb4STom Rix 
208d5243359SHannes Petermaier 	if (speed >= OMAP_I2C_HIGH_SPEED) {
209d5243359SHannes Petermaier 		/* High speed */
2107f79dfb4STom Rix 		psc = I2C_IP_CLK / I2C_INTERNAL_SAMPLING_CLK;
2117f79dfb4STom Rix 		psc -= 1;
2127f79dfb4STom Rix 		if (psc < I2C_PSC_MIN) {
213d5243359SHannes Petermaier 			printf("Error : I2C unsupported prescaler %d\n", psc);
214d5243359SHannes Petermaier 			return -1;
2157f79dfb4STom Rix 		}
2167f79dfb4STom Rix 
2177f79dfb4STom Rix 		/* For first phase of HS mode */
218d5243359SHannes Petermaier 		fsscll = I2C_INTERNAL_SAMPLING_CLK / (2 * speed);
219d5243359SHannes Petermaier 
220d5243359SHannes Petermaier 		fssclh = fsscll;
2217f79dfb4STom Rix 
2227f79dfb4STom Rix 		fsscll -= I2C_HIGHSPEED_PHASE_ONE_SCLL_TRIM;
2237f79dfb4STom Rix 		fssclh -= I2C_HIGHSPEED_PHASE_ONE_SCLH_TRIM;
2247f79dfb4STom Rix 		if (((fsscll < 0) || (fssclh < 0)) ||
2257f79dfb4STom Rix 		    ((fsscll > 255) || (fssclh > 255))) {
22649e9b4bdSAndreas Müller 			puts("Error : I2C initializing first phase clock\n");
227d5243359SHannes Petermaier 			return -1;
2287f79dfb4STom Rix 		}
2297f79dfb4STom Rix 
2307f79dfb4STom Rix 		/* For second phase of HS mode */
2317f79dfb4STom Rix 		hsscll = hssclh = I2C_INTERNAL_SAMPLING_CLK / (2 * speed);
2327f79dfb4STom Rix 
2337f79dfb4STom Rix 		hsscll -= I2C_HIGHSPEED_PHASE_TWO_SCLL_TRIM;
2347f79dfb4STom Rix 		hssclh -= I2C_HIGHSPEED_PHASE_TWO_SCLH_TRIM;
2357f79dfb4STom Rix 		if (((fsscll < 0) || (fssclh < 0)) ||
2367f79dfb4STom Rix 		    ((fsscll > 255) || (fssclh > 255))) {
23749e9b4bdSAndreas Müller 			puts("Error : I2C initializing second phase clock\n");
238d5243359SHannes Petermaier 			return -1;
2397f79dfb4STom Rix 		}
2407f79dfb4STom Rix 
2417f79dfb4STom Rix 		scll = (unsigned int)hsscll << 8 | (unsigned int)fsscll;
2427f79dfb4STom Rix 		sclh = (unsigned int)hssclh << 8 | (unsigned int)fssclh;
2437f79dfb4STom Rix 
2447f79dfb4STom Rix 	} else {
2457f79dfb4STom Rix 		/* Standard and fast speed */
246d5243359SHannes Petermaier 		psc = omap24_i2c_findpsc(&scll, &sclh, speed);
247d5243359SHannes Petermaier 		if (0 > psc) {
24849e9b4bdSAndreas Müller 			puts("Error : I2C initializing clock\n");
249d5243359SHannes Petermaier 			return -1;
250d5243359SHannes Petermaier 		}
2517f79dfb4STom Rix 	}
2527f79dfb4STom Rix 
253be243e41SMugunthan V N 	*waitdelay = (10000000 / speed) * 2; /* wait for 20 clkperiods */
254d5243359SHannes Petermaier 	writew(0, &i2c_base->con);
255d5243359SHannes Petermaier 	writew(psc, &i2c_base->psc);
256d5243359SHannes Petermaier 	writew(scll, &i2c_base->scll);
257d5243359SHannes Petermaier 	writew(sclh, &i2c_base->sclh);
258d5243359SHannes Petermaier 	writew(I2C_CON_EN, &i2c_base->con);
259d5243359SHannes Petermaier 	writew(0xFFFF, &i2c_base->stat);	/* clear all pending status */
260d5243359SHannes Petermaier 
261d5243359SHannes Petermaier 	return 0;
2627f79dfb4STom Rix }
263f7c10535SHeiko Schocher 
264be243e41SMugunthan V N static void omap24_i2c_deblock(struct i2c *i2c_base)
265f7c10535SHeiko Schocher {
266f7c10535SHeiko Schocher 	int i;
267f7c10535SHeiko Schocher 	u16 systest;
268f7c10535SHeiko Schocher 	u16 orgsystest;
269f7c10535SHeiko Schocher 
270f7c10535SHeiko Schocher 	/* set test mode ST_EN = 1 */
271f7c10535SHeiko Schocher 	orgsystest = readw(&i2c_base->systest);
272f7c10535SHeiko Schocher 	systest = orgsystest;
273f7c10535SHeiko Schocher 	/* enable testmode */
274f7c10535SHeiko Schocher 	systest |= I2C_SYSTEST_ST_EN;
275f7c10535SHeiko Schocher 	writew(systest, &i2c_base->systest);
276f7c10535SHeiko Schocher 	systest &= ~I2C_SYSTEST_TMODE_MASK;
277f7c10535SHeiko Schocher 	systest |= 3 << I2C_SYSTEST_TMODE_SHIFT;
278f7c10535SHeiko Schocher 	writew(systest, &i2c_base->systest);
279f7c10535SHeiko Schocher 
280f7c10535SHeiko Schocher 	/* set SCL, SDA  = 1 */
281f7c10535SHeiko Schocher 	systest |= I2C_SYSTEST_SCL_O | I2C_SYSTEST_SDA_O;
282f7c10535SHeiko Schocher 	writew(systest, &i2c_base->systest);
283f7c10535SHeiko Schocher 	udelay(10);
284f7c10535SHeiko Schocher 
285f7c10535SHeiko Schocher 	/* toggle scl 9 clocks */
286f7c10535SHeiko Schocher 	for (i = 0; i < 9; i++) {
287f7c10535SHeiko Schocher 		/* SCL = 0 */
288f7c10535SHeiko Schocher 		systest &= ~I2C_SYSTEST_SCL_O;
289f7c10535SHeiko Schocher 		writew(systest, &i2c_base->systest);
290f7c10535SHeiko Schocher 		udelay(10);
291f7c10535SHeiko Schocher 		/* SCL = 1 */
292f7c10535SHeiko Schocher 		systest |= I2C_SYSTEST_SCL_O;
293f7c10535SHeiko Schocher 		writew(systest, &i2c_base->systest);
294f7c10535SHeiko Schocher 		udelay(10);
295f7c10535SHeiko Schocher 	}
296f7c10535SHeiko Schocher 
297f7c10535SHeiko Schocher 	/* send stop */
298f7c10535SHeiko Schocher 	systest &= ~I2C_SYSTEST_SDA_O;
299f7c10535SHeiko Schocher 	writew(systest, &i2c_base->systest);
300f7c10535SHeiko Schocher 	udelay(10);
301f7c10535SHeiko Schocher 	systest |= I2C_SYSTEST_SCL_O | I2C_SYSTEST_SDA_O;
302f7c10535SHeiko Schocher 	writew(systest, &i2c_base->systest);
303f7c10535SHeiko Schocher 	udelay(10);
304f7c10535SHeiko Schocher 
305f7c10535SHeiko Schocher 	/* restore original mode */
306f7c10535SHeiko Schocher 	writew(orgsystest, &i2c_base->systest);
307f7c10535SHeiko Schocher }
308f7c10535SHeiko Schocher 
309be243e41SMugunthan V N static void __omap24_i2c_init(struct i2c *i2c_base, int speed, int slaveadd,
310be243e41SMugunthan V N 			      int *waitdelay)
311d5243359SHannes Petermaier {
312d5243359SHannes Petermaier 	int timeout = I2C_TIMEOUT;
313f7c10535SHeiko Schocher 	int deblock = 1;
314080c646dSJean-Christophe PLAGNIOL-VILLARD 
315f7c10535SHeiko Schocher retry:
3161d2e96deSDirk Behme 	if (readw(&i2c_base->con) & I2C_CON_EN) {
3171d2e96deSDirk Behme 		writew(0, &i2c_base->con);
318080c646dSJean-Christophe PLAGNIOL-VILLARD 		udelay(50000);
319080c646dSJean-Christophe PLAGNIOL-VILLARD 	}
320080c646dSJean-Christophe PLAGNIOL-VILLARD 
321cec487a4STom Rini 	writew(0x2, &i2c_base->sysc); /* for ES2 after soft reset */
322cec487a4STom Rini 	udelay(1000);
323cec487a4STom Rini 
324cec487a4STom Rini 	writew(I2C_CON_EN, &i2c_base->con);
325cec487a4STom Rini 	while (!(readw(&i2c_base->syss) & I2C_SYSS_RDONE) && timeout--) {
326cec487a4STom Rini 		if (timeout <= 0) {
327cec487a4STom Rini 			puts("ERROR: Timeout in soft-reset\n");
328cec487a4STom Rini 			return;
329cec487a4STom Rini 		}
330cec487a4STom Rini 		udelay(1000);
331cec487a4STom Rini 	}
332cec487a4STom Rini 
333be243e41SMugunthan V N 	if (0 != __omap24_i2c_setspeed(i2c_base, speed, waitdelay)) {
334d5243359SHannes Petermaier 		printf("ERROR: failed to setup I2C bus-speed!\n");
335d5243359SHannes Petermaier 		return;
336d5243359SHannes Petermaier 	}
3377f79dfb4STom Rix 
338080c646dSJean-Christophe PLAGNIOL-VILLARD 	/* own address */
3391d2e96deSDirk Behme 	writew(slaveadd, &i2c_base->oa);
340d5243359SHannes Petermaier 
3418f339d23STom Rini #if defined(CONFIG_OMAP34XX)
342960187ffSLubomir Popov 	/*
343960187ffSLubomir Popov 	 * Have to enable interrupts for OMAP2/3, these IPs don't have
344960187ffSLubomir Popov 	 * an 'irqstatus_raw' register and we shall have to poll 'stat'
345960187ffSLubomir Popov 	 */
346e23c7c95SDirk Behme 	writew(I2C_IE_XRDY_IE | I2C_IE_RRDY_IE | I2C_IE_ARDY_IE |
3471d2e96deSDirk Behme 	       I2C_IE_NACK_IE | I2C_IE_AL_IE, &i2c_base->ie);
348960187ffSLubomir Popov #endif
349080c646dSJean-Christophe PLAGNIOL-VILLARD 	udelay(1000);
350be243e41SMugunthan V N 	flush_fifo(i2c_base);
3511d2e96deSDirk Behme 	writew(0xFFFF, &i2c_base->stat);
352f7c10535SHeiko Schocher 
353f7c10535SHeiko Schocher 	/* Handle possible failed I2C state */
354be243e41SMugunthan V N 	if (wait_for_bb(i2c_base, *waitdelay))
355f7c10535SHeiko Schocher 		if (deblock == 1) {
356be243e41SMugunthan V N 			omap24_i2c_deblock(i2c_base);
357f7c10535SHeiko Schocher 			deblock = 0;
358f7c10535SHeiko Schocher 			goto retry;
359f7c10535SHeiko Schocher 		}
360cec487a4STom Rini }
361cec487a4STom Rini 
362960187ffSLubomir Popov /*
363960187ffSLubomir Popov  * i2c_probe: Use write access. Allows to identify addresses that are
364960187ffSLubomir Popov  *            write-only (like the config register of dual-port EEPROMs)
365960187ffSLubomir Popov  */
366be243e41SMugunthan V N static int __omap24_i2c_probe(struct i2c *i2c_base, int waitdelay, uchar chip)
367080c646dSJean-Christophe PLAGNIOL-VILLARD {
368cec487a4STom Rini 	u16 status;
369080c646dSJean-Christophe PLAGNIOL-VILLARD 	int res = 1; /* default = fail */
370080c646dSJean-Christophe PLAGNIOL-VILLARD 
37189677b27SMichael Jones 	if (chip == readw(&i2c_base->oa))
372080c646dSJean-Christophe PLAGNIOL-VILLARD 		return res;
373080c646dSJean-Christophe PLAGNIOL-VILLARD 
374960187ffSLubomir Popov 	/* Wait until bus is free */
375be243e41SMugunthan V N 	if (wait_for_bb(i2c_base, waitdelay))
376febc4cd4SVincent Stehlé 		return res;
377080c646dSJean-Christophe PLAGNIOL-VILLARD 
378960187ffSLubomir Popov 	/* No data transfer, slave addr only */
379960187ffSLubomir Popov 	writew(chip, &i2c_base->sa);
380960187ffSLubomir Popov 	/* Stop bit needed here */
381960187ffSLubomir Popov 	writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
382960187ffSLubomir Popov 	       I2C_CON_STP, &i2c_base->con);
383960187ffSLubomir Popov 
384be243e41SMugunthan V N 	status = wait_for_event(i2c_base, waitdelay);
385960187ffSLubomir Popov 
386960187ffSLubomir Popov 	if ((status & ~I2C_STAT_XRDY) == 0 || (status & I2C_STAT_AL)) {
387960187ffSLubomir Popov 		/*
388960187ffSLubomir Popov 		 * With current high-level command implementation, notifying
389960187ffSLubomir Popov 		 * the user shall flood the console with 127 messages. If
390960187ffSLubomir Popov 		 * silent exit is desired upon unconfigured bus, remove the
391960187ffSLubomir Popov 		 * following 'if' section:
392960187ffSLubomir Popov 		 */
393960187ffSLubomir Popov 		if (status == I2C_STAT_XRDY)
394be243e41SMugunthan V N 			printf("i2c_probe: pads on bus probably not configured (status=0x%x)\n",
395be243e41SMugunthan V N 			       status);
396960187ffSLubomir Popov 
397960187ffSLubomir Popov 		goto pr_exit;
398960187ffSLubomir Popov 	}
399960187ffSLubomir Popov 
400960187ffSLubomir Popov 	/* Check for ACK (!NAK) */
401960187ffSLubomir Popov 	if (!(status & I2C_STAT_NACK)) {
402960187ffSLubomir Popov 		res = 0;				/* Device found */
403be243e41SMugunthan V N 		udelay(waitdelay);/* Required by AM335X in SPL */
404960187ffSLubomir Popov 		/* Abort transfer (force idle state) */
405960187ffSLubomir Popov 		writew(I2C_CON_MST | I2C_CON_TRX, &i2c_base->con); /* Reset */
406960187ffSLubomir Popov 		udelay(1000);
407960187ffSLubomir Popov 		writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_TRX |
408960187ffSLubomir Popov 		       I2C_CON_STP, &i2c_base->con);		/* STP */
409960187ffSLubomir Popov 	}
410960187ffSLubomir Popov pr_exit:
411be243e41SMugunthan V N 	flush_fifo(i2c_base);
4121d2e96deSDirk Behme 	writew(0xFFFF, &i2c_base->stat);
413080c646dSJean-Christophe PLAGNIOL-VILLARD 	return res;
414080c646dSJean-Christophe PLAGNIOL-VILLARD }
415080c646dSJean-Christophe PLAGNIOL-VILLARD 
416960187ffSLubomir Popov /*
417960187ffSLubomir Popov  * i2c_read: Function now uses a single I2C read transaction with bulk transfer
418960187ffSLubomir Popov  *           of the requested number of bytes (note that the 'i2c md' command
419960187ffSLubomir Popov  *           limits this to 16 bytes anyway). If CONFIG_I2C_REPEATED_START is
420960187ffSLubomir Popov  *           defined in the board config header, this transaction shall be with
421960187ffSLubomir Popov  *           Repeated Start (Sr) between the address and data phases; otherwise
422960187ffSLubomir Popov  *           Stop-Start (P-S) shall be used (some I2C chips do require a P-S).
423960187ffSLubomir Popov  *           The address (reg offset) may be 0, 1 or 2 bytes long.
424960187ffSLubomir Popov  *           Function now reads correctly from chips that return more than one
425960187ffSLubomir Popov  *           byte of data per addressed register (like TI temperature sensors),
426960187ffSLubomir Popov  *           or that do not need a register address at all (such as some clock
427960187ffSLubomir Popov  *           distributors).
428960187ffSLubomir Popov  */
429be243e41SMugunthan V N static int __omap24_i2c_read(struct i2c *i2c_base, int waitdelay, uchar chip,
430be243e41SMugunthan V N 			     uint addr, int alen, uchar *buffer, int len)
431080c646dSJean-Christophe PLAGNIOL-VILLARD {
432960187ffSLubomir Popov 	int i2c_error = 0;
433960187ffSLubomir Popov 	u16 status;
434960187ffSLubomir Popov 
435960187ffSLubomir Popov 	if (alen < 0) {
436960187ffSLubomir Popov 		puts("I2C read: addr len < 0\n");
437960187ffSLubomir Popov 		return 1;
438960187ffSLubomir Popov 	}
439960187ffSLubomir Popov 	if (len < 0) {
440960187ffSLubomir Popov 		puts("I2C read: data len < 0\n");
441960187ffSLubomir Popov 		return 1;
442960187ffSLubomir Popov 	}
443960187ffSLubomir Popov 	if (buffer == NULL) {
444960187ffSLubomir Popov 		puts("I2C read: NULL pointer passed\n");
445960187ffSLubomir Popov 		return 1;
446960187ffSLubomir Popov 	}
447080c646dSJean-Christophe PLAGNIOL-VILLARD 
44855faa589SIlya Yanok 	if (alen > 2) {
449cec487a4STom Rini 		printf("I2C read: addr len %d not supported\n", alen);
450080c646dSJean-Christophe PLAGNIOL-VILLARD 		return 1;
451080c646dSJean-Christophe PLAGNIOL-VILLARD 	}
452080c646dSJean-Christophe PLAGNIOL-VILLARD 
45355faa589SIlya Yanok 	if (addr + len > (1 << 16)) {
454cec487a4STom Rini 		puts("I2C read: address out of range\n");
455080c646dSJean-Christophe PLAGNIOL-VILLARD 		return 1;
456080c646dSJean-Christophe PLAGNIOL-VILLARD 	}
457080c646dSJean-Christophe PLAGNIOL-VILLARD 
45832b9b556SGuy Thouret #ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW
45932b9b556SGuy Thouret 	/*
46032b9b556SGuy Thouret 	 * EEPROM chips that implement "address overflow" are ones
46132b9b556SGuy Thouret 	 * like Catalyst 24WC04/08/16 which has 9/10/11 bits of
46232b9b556SGuy Thouret 	 * address and the extra bits end up in the "chip address"
46332b9b556SGuy Thouret 	 * bit slots. This makes a 24WC08 (1Kbyte) chip look like
46432b9b556SGuy Thouret 	 * four 256 byte chips.
46532b9b556SGuy Thouret 	 *
46632b9b556SGuy Thouret 	 * Note that we consider the length of the address field to
46732b9b556SGuy Thouret 	 * still be one byte because the extra address bits are
46832b9b556SGuy Thouret 	 * hidden in the chip address.
46932b9b556SGuy Thouret 	 */
47032b9b556SGuy Thouret 	if (alen > 0)
47132b9b556SGuy Thouret 		chip |= ((addr >> (alen * 8)) &
47232b9b556SGuy Thouret 			 CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);
47332b9b556SGuy Thouret #endif
47432b9b556SGuy Thouret 
475960187ffSLubomir Popov 	/* Wait until bus not busy */
476be243e41SMugunthan V N 	if (wait_for_bb(i2c_base, waitdelay))
477080c646dSJean-Christophe PLAGNIOL-VILLARD 		return 1;
478960187ffSLubomir Popov 
479960187ffSLubomir Popov 	/* Zero, one or two bytes reg address (offset) */
480960187ffSLubomir Popov 	writew(alen, &i2c_base->cnt);
481960187ffSLubomir Popov 	/* Set slave address */
482960187ffSLubomir Popov 	writew(chip, &i2c_base->sa);
483960187ffSLubomir Popov 
484960187ffSLubomir Popov 	if (alen) {
485960187ffSLubomir Popov 		/* Must write reg offset first */
486960187ffSLubomir Popov #ifdef CONFIG_I2C_REPEATED_START
487960187ffSLubomir Popov 		/* No stop bit, use Repeated Start (Sr) */
488960187ffSLubomir Popov 		writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT |
489960187ffSLubomir Popov 		       I2C_CON_TRX, &i2c_base->con);
490960187ffSLubomir Popov #else
491960187ffSLubomir Popov 		/* Stop - Start (P-S) */
492960187ffSLubomir Popov 		writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP |
493960187ffSLubomir Popov 		       I2C_CON_TRX, &i2c_base->con);
494960187ffSLubomir Popov #endif
495960187ffSLubomir Popov 		/* Send register offset */
496960187ffSLubomir Popov 		while (1) {
497be243e41SMugunthan V N 			status = wait_for_event(i2c_base, waitdelay);
498960187ffSLubomir Popov 			/* Try to identify bus that is not padconf'd for I2C */
499960187ffSLubomir Popov 			if (status == I2C_STAT_XRDY) {
500960187ffSLubomir Popov 				i2c_error = 2;
501be243e41SMugunthan V N 				printf("i2c_read (addr phase): pads on bus probably not configured (status=0x%x)\n",
502be243e41SMugunthan V N 				       status);
503960187ffSLubomir Popov 				goto rd_exit;
504960187ffSLubomir Popov 			}
505d5243359SHannes Petermaier 			if (status == 0 || (status & I2C_STAT_NACK)) {
506960187ffSLubomir Popov 				i2c_error = 1;
507960187ffSLubomir Popov 				printf("i2c_read: error waiting for addr ACK (status=0x%x)\n",
508960187ffSLubomir Popov 				       status);
509960187ffSLubomir Popov 				goto rd_exit;
510960187ffSLubomir Popov 			}
511960187ffSLubomir Popov 			if (alen) {
512960187ffSLubomir Popov 				if (status & I2C_STAT_XRDY) {
513960187ffSLubomir Popov 					alen--;
514960187ffSLubomir Popov 					/* Do we have to use byte access? */
515960187ffSLubomir Popov 					writeb((addr >> (8 * alen)) & 0xff,
516960187ffSLubomir Popov 					       &i2c_base->data);
517960187ffSLubomir Popov 					writew(I2C_STAT_XRDY, &i2c_base->stat);
518960187ffSLubomir Popov 				}
519960187ffSLubomir Popov 			}
520960187ffSLubomir Popov 			if (status & I2C_STAT_ARDY) {
521960187ffSLubomir Popov 				writew(I2C_STAT_ARDY, &i2c_base->stat);
522960187ffSLubomir Popov 				break;
523960187ffSLubomir Popov 			}
524960187ffSLubomir Popov 		}
525960187ffSLubomir Popov 	}
526960187ffSLubomir Popov 	/* Set slave address */
527960187ffSLubomir Popov 	writew(chip, &i2c_base->sa);
528960187ffSLubomir Popov 	/* Read len bytes from slave */
529960187ffSLubomir Popov 	writew(len, &i2c_base->cnt);
530960187ffSLubomir Popov 	/* Need stop bit here */
531960187ffSLubomir Popov 	writew(I2C_CON_EN | I2C_CON_MST |
532960187ffSLubomir Popov 	       I2C_CON_STT | I2C_CON_STP,
533960187ffSLubomir Popov 	       &i2c_base->con);
534960187ffSLubomir Popov 
535960187ffSLubomir Popov 	/* Receive data */
536960187ffSLubomir Popov 	while (1) {
537be243e41SMugunthan V N 		status = wait_for_event(i2c_base, waitdelay);
538960187ffSLubomir Popov 		/*
539960187ffSLubomir Popov 		 * Try to identify bus that is not padconf'd for I2C. This
540960187ffSLubomir Popov 		 * state could be left over from previous transactions if
541960187ffSLubomir Popov 		 * the address phase is skipped due to alen=0.
542960187ffSLubomir Popov 		 */
543960187ffSLubomir Popov 		if (status == I2C_STAT_XRDY) {
544960187ffSLubomir Popov 			i2c_error = 2;
545be243e41SMugunthan V N 			printf("i2c_read (data phase): pads on bus probably not configured (status=0x%x)\n",
546be243e41SMugunthan V N 			       status);
547960187ffSLubomir Popov 			goto rd_exit;
548960187ffSLubomir Popov 		}
549d5243359SHannes Petermaier 		if (status == 0 || (status & I2C_STAT_NACK)) {
550960187ffSLubomir Popov 			i2c_error = 1;
551960187ffSLubomir Popov 			goto rd_exit;
552960187ffSLubomir Popov 		}
553960187ffSLubomir Popov 		if (status & I2C_STAT_RRDY) {
554960187ffSLubomir Popov 			*buffer++ = readb(&i2c_base->data);
555960187ffSLubomir Popov 			writew(I2C_STAT_RRDY, &i2c_base->stat);
556960187ffSLubomir Popov 		}
557960187ffSLubomir Popov 		if (status & I2C_STAT_ARDY) {
558960187ffSLubomir Popov 			writew(I2C_STAT_ARDY, &i2c_base->stat);
559960187ffSLubomir Popov 			break;
560080c646dSJean-Christophe PLAGNIOL-VILLARD 		}
561080c646dSJean-Christophe PLAGNIOL-VILLARD 	}
562080c646dSJean-Christophe PLAGNIOL-VILLARD 
563960187ffSLubomir Popov rd_exit:
564be243e41SMugunthan V N 	flush_fifo(i2c_base);
565960187ffSLubomir Popov 	writew(0xFFFF, &i2c_base->stat);
566960187ffSLubomir Popov 	return i2c_error;
567080c646dSJean-Christophe PLAGNIOL-VILLARD }
568080c646dSJean-Christophe PLAGNIOL-VILLARD 
569960187ffSLubomir Popov /* i2c_write: Address (reg offset) may be 0, 1 or 2 bytes long. */
570be243e41SMugunthan V N static int __omap24_i2c_write(struct i2c *i2c_base, int waitdelay, uchar chip,
571be243e41SMugunthan V N 			      uint addr, int alen, uchar *buffer, int len)
572080c646dSJean-Christophe PLAGNIOL-VILLARD {
573cec487a4STom Rini 	int i;
574cec487a4STom Rini 	u16 status;
575cec487a4STom Rini 	int i2c_error = 0;
576d5243359SHannes Petermaier 	int timeout = I2C_TIMEOUT;
577960187ffSLubomir Popov 
578960187ffSLubomir Popov 	if (alen < 0) {
579960187ffSLubomir Popov 		puts("I2C write: addr len < 0\n");
580960187ffSLubomir Popov 		return 1;
581960187ffSLubomir Popov 	}
582960187ffSLubomir Popov 
583960187ffSLubomir Popov 	if (len < 0) {
584960187ffSLubomir Popov 		puts("I2C write: data len < 0\n");
585960187ffSLubomir Popov 		return 1;
586960187ffSLubomir Popov 	}
587960187ffSLubomir Popov 
588960187ffSLubomir Popov 	if (buffer == NULL) {
589960187ffSLubomir Popov 		puts("I2C write: NULL pointer passed\n");
590960187ffSLubomir Popov 		return 1;
591960187ffSLubomir Popov 	}
592080c646dSJean-Christophe PLAGNIOL-VILLARD 
59355faa589SIlya Yanok 	if (alen > 2) {
594cec487a4STom Rini 		printf("I2C write: addr len %d not supported\n", alen);
595080c646dSJean-Christophe PLAGNIOL-VILLARD 		return 1;
596cec487a4STom Rini 	}
597080c646dSJean-Christophe PLAGNIOL-VILLARD 
59855faa589SIlya Yanok 	if (addr + len > (1 << 16)) {
599cec487a4STom Rini 		printf("I2C write: address 0x%x + 0x%x out of range\n",
600cec487a4STom Rini 		       addr, len);
601080c646dSJean-Christophe PLAGNIOL-VILLARD 		return 1;
602080c646dSJean-Christophe PLAGNIOL-VILLARD 	}
603080c646dSJean-Christophe PLAGNIOL-VILLARD 
60432b9b556SGuy Thouret #ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW
60532b9b556SGuy Thouret 	/*
60632b9b556SGuy Thouret 	 * EEPROM chips that implement "address overflow" are ones
60732b9b556SGuy Thouret 	 * like Catalyst 24WC04/08/16 which has 9/10/11 bits of
60832b9b556SGuy Thouret 	 * address and the extra bits end up in the "chip address"
60932b9b556SGuy Thouret 	 * bit slots. This makes a 24WC08 (1Kbyte) chip look like
61032b9b556SGuy Thouret 	 * four 256 byte chips.
61132b9b556SGuy Thouret 	 *
61232b9b556SGuy Thouret 	 * Note that we consider the length of the address field to
61332b9b556SGuy Thouret 	 * still be one byte because the extra address bits are
61432b9b556SGuy Thouret 	 * hidden in the chip address.
61532b9b556SGuy Thouret 	 */
61632b9b556SGuy Thouret 	if (alen > 0)
61732b9b556SGuy Thouret 		chip |= ((addr >> (alen * 8)) &
61832b9b556SGuy Thouret 			 CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);
61932b9b556SGuy Thouret #endif
62032b9b556SGuy Thouret 
621960187ffSLubomir Popov 	/* Wait until bus not busy */
622be243e41SMugunthan V N 	if (wait_for_bb(i2c_base, waitdelay))
623febc4cd4SVincent Stehlé 		return 1;
6240607e2b9SMichael Jones 
625960187ffSLubomir Popov 	/* Start address phase - will write regoffset + len bytes data */
626cec487a4STom Rini 	writew(alen + len, &i2c_base->cnt);
627960187ffSLubomir Popov 	/* Set slave address */
6280607e2b9SMichael Jones 	writew(chip, &i2c_base->sa);
629960187ffSLubomir Popov 	/* Stop bit needed here */
6300607e2b9SMichael Jones 	writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
6310607e2b9SMichael Jones 	       I2C_CON_STP, &i2c_base->con);
6320607e2b9SMichael Jones 
633960187ffSLubomir Popov 	while (alen) {
634960187ffSLubomir Popov 		/* Must write reg offset (one or two bytes) */
635be243e41SMugunthan V N 		status = wait_for_event(i2c_base, waitdelay);
636960187ffSLubomir Popov 		/* Try to identify bus that is not padconf'd for I2C */
637960187ffSLubomir Popov 		if (status == I2C_STAT_XRDY) {
638960187ffSLubomir Popov 			i2c_error = 2;
639be243e41SMugunthan V N 			printf("i2c_write: pads on bus probably not configured (status=0x%x)\n",
640be243e41SMugunthan V N 			       status);
641960187ffSLubomir Popov 			goto wr_exit;
642960187ffSLubomir Popov 		}
643d5243359SHannes Petermaier 		if (status == 0 || (status & I2C_STAT_NACK)) {
6442faa7619SPatil, Rachna 			i2c_error = 1;
645960187ffSLubomir Popov 			printf("i2c_write: error waiting for addr ACK (status=0x%x)\n",
646cec487a4STom Rini 			       status);
647960187ffSLubomir Popov 			goto wr_exit;
648cec487a4STom Rini 		}
6490607e2b9SMichael Jones 		if (status & I2C_STAT_XRDY) {
650960187ffSLubomir Popov 			alen--;
651960187ffSLubomir Popov 			writeb((addr >> (8 * alen)) & 0xff, &i2c_base->data);
652cec487a4STom Rini 			writew(I2C_STAT_XRDY, &i2c_base->stat);
653cec487a4STom Rini 		} else {
6540607e2b9SMichael Jones 			i2c_error = 1;
655960187ffSLubomir Popov 			printf("i2c_write: bus not ready for addr Tx (status=0x%x)\n",
656960187ffSLubomir Popov 			       status);
657960187ffSLubomir Popov 			goto wr_exit;
658960187ffSLubomir Popov 		}
659960187ffSLubomir Popov 	}
660960187ffSLubomir Popov 	/* Address phase is over, now write data */
661960187ffSLubomir Popov 	for (i = 0; i < len; i++) {
662be243e41SMugunthan V N 		status = wait_for_event(i2c_base, waitdelay);
663d5243359SHannes Petermaier 		if (status == 0 || (status & I2C_STAT_NACK)) {
664960187ffSLubomir Popov 			i2c_error = 1;
665960187ffSLubomir Popov 			printf("i2c_write: error waiting for data ACK (status=0x%x)\n",
666960187ffSLubomir Popov 			       status);
667960187ffSLubomir Popov 			goto wr_exit;
668960187ffSLubomir Popov 		}
669960187ffSLubomir Popov 		if (status & I2C_STAT_XRDY) {
670960187ffSLubomir Popov 			writeb(buffer[i], &i2c_base->data);
671960187ffSLubomir Popov 			writew(I2C_STAT_XRDY, &i2c_base->stat);
672960187ffSLubomir Popov 		} else {
673960187ffSLubomir Popov 			i2c_error = 1;
674960187ffSLubomir Popov 			printf("i2c_write: bus not ready for data Tx (i=%d)\n",
675960187ffSLubomir Popov 			       i);
676960187ffSLubomir Popov 			goto wr_exit;
6772faa7619SPatil, Rachna 		}
6782faa7619SPatil, Rachna 	}
679d5243359SHannes Petermaier 	/*
680d5243359SHannes Petermaier 	 * poll ARDY bit for making sure that last byte really has been
681d5243359SHannes Petermaier 	 * transferred on the bus.
682d5243359SHannes Petermaier 	 */
683d5243359SHannes Petermaier 	do {
684be243e41SMugunthan V N 		status = wait_for_event(i2c_base, waitdelay);
685d5243359SHannes Petermaier 	} while (!(status & I2C_STAT_ARDY) && timeout--);
686d5243359SHannes Petermaier 	if (timeout <= 0)
687d5243359SHannes Petermaier 		printf("i2c_write: timed out writig last byte!\n");
6882faa7619SPatil, Rachna 
689960187ffSLubomir Popov wr_exit:
690be243e41SMugunthan V N 	flush_fifo(i2c_base);
6910607e2b9SMichael Jones 	writew(0xFFFF, &i2c_base->stat);
692cec487a4STom Rini 	return i2c_error;
693080c646dSJean-Christophe PLAGNIOL-VILLARD }
694080c646dSJean-Christophe PLAGNIOL-VILLARD 
695daa69ffeSMugunthan V N #ifndef CONFIG_DM_I2C
696960187ffSLubomir Popov /*
697be243e41SMugunthan V N  * The legacy I2C functions. These need to get removed once
698be243e41SMugunthan V N  * all users of this driver are converted to DM.
699960187ffSLubomir Popov  */
7006789e84eSHeiko Schocher static struct i2c *omap24_get_base(struct i2c_adapter *adap)
7011d2e96deSDirk Behme {
7026789e84eSHeiko Schocher 	switch (adap->hwadapnr) {
703960187ffSLubomir Popov 	case 0:
7046789e84eSHeiko Schocher 		return (struct i2c *)I2C_BASE1;
705960187ffSLubomir Popov 		break;
706960187ffSLubomir Popov 	case 1:
7076789e84eSHeiko Schocher 		return (struct i2c *)I2C_BASE2;
708960187ffSLubomir Popov 		break;
709ac1d8ac8SAdam Ford #if (CONFIG_SYS_I2C_BUS_MAX > 2)
710960187ffSLubomir Popov 	case 2:
7116789e84eSHeiko Schocher 		return (struct i2c *)I2C_BASE3;
712960187ffSLubomir Popov 		break;
713ac1d8ac8SAdam Ford #if (CONFIG_SYS_I2C_BUS_MAX > 3)
714960187ffSLubomir Popov 	case 3:
7156789e84eSHeiko Schocher 		return (struct i2c *)I2C_BASE4;
716960187ffSLubomir Popov 		break;
717ac1d8ac8SAdam Ford #if (CONFIG_SYS_I2C_BUS_MAX > 4)
718960187ffSLubomir Popov 	case 4:
7196789e84eSHeiko Schocher 		return (struct i2c *)I2C_BASE5;
720960187ffSLubomir Popov 		break;
721960187ffSLubomir Popov #endif
722960187ffSLubomir Popov #endif
723960187ffSLubomir Popov #endif
7246789e84eSHeiko Schocher 	default:
7256789e84eSHeiko Schocher 		printf("wrong hwadapnr: %d\n", adap->hwadapnr);
7266789e84eSHeiko Schocher 		break;
7276789e84eSHeiko Schocher 	}
7286789e84eSHeiko Schocher 	return NULL;
729960187ffSLubomir Popov }
7301d2e96deSDirk Behme 
731be243e41SMugunthan V N 
732be243e41SMugunthan V N static int omap24_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
733be243e41SMugunthan V N 			   int alen, uchar *buffer, int len)
734be243e41SMugunthan V N {
735be243e41SMugunthan V N 	struct i2c *i2c_base = omap24_get_base(adap);
736be243e41SMugunthan V N 
737be243e41SMugunthan V N 	return __omap24_i2c_read(i2c_base, adap->waitdelay, chip, addr,
738be243e41SMugunthan V N 				 alen, buffer, len);
739be243e41SMugunthan V N }
740be243e41SMugunthan V N 
741be243e41SMugunthan V N 
742be243e41SMugunthan V N static int omap24_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
743be243e41SMugunthan V N 			    int alen, uchar *buffer, int len)
744be243e41SMugunthan V N {
745be243e41SMugunthan V N 	struct i2c *i2c_base = omap24_get_base(adap);
746be243e41SMugunthan V N 
747be243e41SMugunthan V N 	return __omap24_i2c_write(i2c_base, adap->waitdelay, chip, addr,
748be243e41SMugunthan V N 				  alen, buffer, len);
749be243e41SMugunthan V N }
750be243e41SMugunthan V N 
751be243e41SMugunthan V N static uint omap24_i2c_setspeed(struct i2c_adapter *adap, uint speed)
752be243e41SMugunthan V N {
753be243e41SMugunthan V N 	struct i2c *i2c_base = omap24_get_base(adap);
754be243e41SMugunthan V N 	int ret;
755be243e41SMugunthan V N 
756be243e41SMugunthan V N 	ret = __omap24_i2c_setspeed(i2c_base, speed, &adap->waitdelay);
757be243e41SMugunthan V N 	if (ret) {
758*90aa625cSMasahiro Yamada 		pr_err("%s: set i2c speed failed\n", __func__);
759be243e41SMugunthan V N 		return ret;
760be243e41SMugunthan V N 	}
761be243e41SMugunthan V N 
762be243e41SMugunthan V N 	adap->speed = speed;
763be243e41SMugunthan V N 
764be243e41SMugunthan V N 	return 0;
765be243e41SMugunthan V N }
766be243e41SMugunthan V N 
767be243e41SMugunthan V N static void omap24_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
768be243e41SMugunthan V N {
769be243e41SMugunthan V N 	struct i2c *i2c_base = omap24_get_base(adap);
770be243e41SMugunthan V N 
771be243e41SMugunthan V N 	return __omap24_i2c_init(i2c_base, speed, slaveadd, &adap->waitdelay);
772be243e41SMugunthan V N }
773be243e41SMugunthan V N 
774be243e41SMugunthan V N static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip)
775be243e41SMugunthan V N {
776be243e41SMugunthan V N 	struct i2c *i2c_base = omap24_get_base(adap);
777be243e41SMugunthan V N 
778be243e41SMugunthan V N 	return __omap24_i2c_probe(i2c_base, adap->waitdelay, chip);
779be243e41SMugunthan V N }
780be243e41SMugunthan V N 
7816789e84eSHeiko Schocher #if !defined(CONFIG_SYS_OMAP24_I2C_SPEED1)
7826789e84eSHeiko Schocher #define CONFIG_SYS_OMAP24_I2C_SPEED1 CONFIG_SYS_OMAP24_I2C_SPEED
7836789e84eSHeiko Schocher #endif
7846789e84eSHeiko Schocher #if !defined(CONFIG_SYS_OMAP24_I2C_SLAVE1)
7856789e84eSHeiko Schocher #define CONFIG_SYS_OMAP24_I2C_SLAVE1 CONFIG_SYS_OMAP24_I2C_SLAVE
7866789e84eSHeiko Schocher #endif
7871d2e96deSDirk Behme 
7886789e84eSHeiko Schocher U_BOOT_I2C_ADAP_COMPLETE(omap24_0, omap24_i2c_init, omap24_i2c_probe,
789d5243359SHannes Petermaier 			 omap24_i2c_read, omap24_i2c_write, omap24_i2c_setspeed,
7906789e84eSHeiko Schocher 			 CONFIG_SYS_OMAP24_I2C_SPEED,
7916789e84eSHeiko Schocher 			 CONFIG_SYS_OMAP24_I2C_SLAVE,
7926789e84eSHeiko Schocher 			 0)
7936789e84eSHeiko Schocher U_BOOT_I2C_ADAP_COMPLETE(omap24_1, omap24_i2c_init, omap24_i2c_probe,
794d5243359SHannes Petermaier 			 omap24_i2c_read, omap24_i2c_write, omap24_i2c_setspeed,
7956789e84eSHeiko Schocher 			 CONFIG_SYS_OMAP24_I2C_SPEED1,
7966789e84eSHeiko Schocher 			 CONFIG_SYS_OMAP24_I2C_SLAVE1,
7976789e84eSHeiko Schocher 			 1)
798ac1d8ac8SAdam Ford #if (CONFIG_SYS_I2C_BUS_MAX > 2)
7996789e84eSHeiko Schocher #if !defined(CONFIG_SYS_OMAP24_I2C_SPEED2)
8006789e84eSHeiko Schocher #define CONFIG_SYS_OMAP24_I2C_SPEED2 CONFIG_SYS_OMAP24_I2C_SPEED
8016789e84eSHeiko Schocher #endif
8026789e84eSHeiko Schocher #if !defined(CONFIG_SYS_OMAP24_I2C_SLAVE2)
8036789e84eSHeiko Schocher #define CONFIG_SYS_OMAP24_I2C_SLAVE2 CONFIG_SYS_OMAP24_I2C_SLAVE
8046789e84eSHeiko Schocher #endif
8051d2e96deSDirk Behme 
8066789e84eSHeiko Schocher U_BOOT_I2C_ADAP_COMPLETE(omap24_2, omap24_i2c_init, omap24_i2c_probe,
8076789e84eSHeiko Schocher 			 omap24_i2c_read, omap24_i2c_write, NULL,
8086789e84eSHeiko Schocher 			 CONFIG_SYS_OMAP24_I2C_SPEED2,
8096789e84eSHeiko Schocher 			 CONFIG_SYS_OMAP24_I2C_SLAVE2,
8106789e84eSHeiko Schocher 			 2)
811ac1d8ac8SAdam Ford #if (CONFIG_SYS_I2C_BUS_MAX > 3)
8126789e84eSHeiko Schocher #if !defined(CONFIG_SYS_OMAP24_I2C_SPEED3)
8136789e84eSHeiko Schocher #define CONFIG_SYS_OMAP24_I2C_SPEED3 CONFIG_SYS_OMAP24_I2C_SPEED
8146789e84eSHeiko Schocher #endif
8156789e84eSHeiko Schocher #if !defined(CONFIG_SYS_OMAP24_I2C_SLAVE3)
8166789e84eSHeiko Schocher #define CONFIG_SYS_OMAP24_I2C_SLAVE3 CONFIG_SYS_OMAP24_I2C_SLAVE
8176789e84eSHeiko Schocher #endif
818938717ceSSteve Sakoman 
8196789e84eSHeiko Schocher U_BOOT_I2C_ADAP_COMPLETE(omap24_3, omap24_i2c_init, omap24_i2c_probe,
8206789e84eSHeiko Schocher 			 omap24_i2c_read, omap24_i2c_write, NULL,
8216789e84eSHeiko Schocher 			 CONFIG_SYS_OMAP24_I2C_SPEED3,
8226789e84eSHeiko Schocher 			 CONFIG_SYS_OMAP24_I2C_SLAVE3,
8236789e84eSHeiko Schocher 			 3)
824ac1d8ac8SAdam Ford #if (CONFIG_SYS_I2C_BUS_MAX > 4)
8256789e84eSHeiko Schocher #if !defined(CONFIG_SYS_OMAP24_I2C_SPEED4)
8266789e84eSHeiko Schocher #define CONFIG_SYS_OMAP24_I2C_SPEED4 CONFIG_SYS_OMAP24_I2C_SPEED
8276789e84eSHeiko Schocher #endif
8286789e84eSHeiko Schocher #if !defined(CONFIG_SYS_OMAP24_I2C_SLAVE4)
8296789e84eSHeiko Schocher #define CONFIG_SYS_OMAP24_I2C_SLAVE4 CONFIG_SYS_OMAP24_I2C_SLAVE
8306789e84eSHeiko Schocher #endif
8316789e84eSHeiko Schocher 
8326789e84eSHeiko Schocher U_BOOT_I2C_ADAP_COMPLETE(omap24_4, omap24_i2c_init, omap24_i2c_probe,
8336789e84eSHeiko Schocher 			 omap24_i2c_read, omap24_i2c_write, NULL,
8346789e84eSHeiko Schocher 			 CONFIG_SYS_OMAP24_I2C_SPEED4,
8356789e84eSHeiko Schocher 			 CONFIG_SYS_OMAP24_I2C_SLAVE4,
8366789e84eSHeiko Schocher 			 4)
8376789e84eSHeiko Schocher #endif
8386789e84eSHeiko Schocher #endif
8396789e84eSHeiko Schocher #endif
840daa69ffeSMugunthan V N 
841daa69ffeSMugunthan V N #else /* CONFIG_DM_I2C */
842daa69ffeSMugunthan V N 
843daa69ffeSMugunthan V N static int omap_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
844daa69ffeSMugunthan V N {
845daa69ffeSMugunthan V N 	struct omap_i2c *priv = dev_get_priv(bus);
846daa69ffeSMugunthan V N 	int ret;
847daa69ffeSMugunthan V N 
848daa69ffeSMugunthan V N 	debug("i2c_xfer: %d messages\n", nmsgs);
849daa69ffeSMugunthan V N 	for (; nmsgs > 0; nmsgs--, msg++) {
850daa69ffeSMugunthan V N 		debug("i2c_xfer: chip=0x%x, len=0x%x\n", msg->addr, msg->len);
851daa69ffeSMugunthan V N 		if (msg->flags & I2C_M_RD) {
852daa69ffeSMugunthan V N 			ret = __omap24_i2c_read(priv->regs, priv->waitdelay,
853daa69ffeSMugunthan V N 						msg->addr, 0, 0, msg->buf,
854daa69ffeSMugunthan V N 						msg->len);
855daa69ffeSMugunthan V N 		} else {
856daa69ffeSMugunthan V N 			ret = __omap24_i2c_write(priv->regs, priv->waitdelay,
857daa69ffeSMugunthan V N 						 msg->addr, 0, 0, msg->buf,
858daa69ffeSMugunthan V N 						 msg->len);
859daa69ffeSMugunthan V N 		}
860daa69ffeSMugunthan V N 		if (ret) {
861daa69ffeSMugunthan V N 			debug("i2c_write: error sending\n");
862daa69ffeSMugunthan V N 			return -EREMOTEIO;
863daa69ffeSMugunthan V N 		}
864daa69ffeSMugunthan V N 	}
865daa69ffeSMugunthan V N 
866daa69ffeSMugunthan V N 	return 0;
867daa69ffeSMugunthan V N }
868daa69ffeSMugunthan V N 
869daa69ffeSMugunthan V N static int omap_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
870daa69ffeSMugunthan V N {
871daa69ffeSMugunthan V N 	struct omap_i2c *priv = dev_get_priv(bus);
872daa69ffeSMugunthan V N 
873daa69ffeSMugunthan V N 	priv->speed = speed;
874daa69ffeSMugunthan V N 
875daa69ffeSMugunthan V N 	return __omap24_i2c_setspeed(priv->regs, speed, &priv->waitdelay);
876daa69ffeSMugunthan V N }
877daa69ffeSMugunthan V N 
878daa69ffeSMugunthan V N static int omap_i2c_probe_chip(struct udevice *bus, uint chip_addr,
879daa69ffeSMugunthan V N 				     uint chip_flags)
880daa69ffeSMugunthan V N {
881daa69ffeSMugunthan V N 	struct omap_i2c *priv = dev_get_priv(bus);
882daa69ffeSMugunthan V N 
883daa69ffeSMugunthan V N 	return __omap24_i2c_probe(priv->regs, priv->waitdelay, chip_addr);
884daa69ffeSMugunthan V N }
885daa69ffeSMugunthan V N 
886daa69ffeSMugunthan V N static int omap_i2c_probe(struct udevice *bus)
887daa69ffeSMugunthan V N {
888daa69ffeSMugunthan V N 	struct omap_i2c *priv = dev_get_priv(bus);
889daa69ffeSMugunthan V N 
890daa69ffeSMugunthan V N 	__omap24_i2c_init(priv->regs, priv->speed, 0, &priv->waitdelay);
891daa69ffeSMugunthan V N 
892daa69ffeSMugunthan V N 	return 0;
893daa69ffeSMugunthan V N }
894daa69ffeSMugunthan V N 
895daa69ffeSMugunthan V N static int omap_i2c_ofdata_to_platdata(struct udevice *bus)
896daa69ffeSMugunthan V N {
897daa69ffeSMugunthan V N 	struct omap_i2c *priv = dev_get_priv(bus);
898daa69ffeSMugunthan V N 
899a821c4afSSimon Glass 	priv->regs = map_physmem(devfdt_get_addr(bus), sizeof(void *),
900daa69ffeSMugunthan V N 				 MAP_NOCACHE);
901daa69ffeSMugunthan V N 	priv->speed = CONFIG_SYS_OMAP24_I2C_SPEED;
902daa69ffeSMugunthan V N 
903daa69ffeSMugunthan V N 	return 0;
904daa69ffeSMugunthan V N }
905daa69ffeSMugunthan V N 
906daa69ffeSMugunthan V N static const struct dm_i2c_ops omap_i2c_ops = {
907daa69ffeSMugunthan V N 	.xfer		= omap_i2c_xfer,
908daa69ffeSMugunthan V N 	.probe_chip	= omap_i2c_probe_chip,
909daa69ffeSMugunthan V N 	.set_bus_speed	= omap_i2c_set_bus_speed,
910daa69ffeSMugunthan V N };
911daa69ffeSMugunthan V N 
912daa69ffeSMugunthan V N static const struct udevice_id omap_i2c_ids[] = {
9130fc8a3afSAdam Ford 	{ .compatible = "ti,omap3-i2c" },
914daa69ffeSMugunthan V N 	{ .compatible = "ti,omap4-i2c" },
915daa69ffeSMugunthan V N 	{ }
916daa69ffeSMugunthan V N };
917daa69ffeSMugunthan V N 
918daa69ffeSMugunthan V N U_BOOT_DRIVER(i2c_omap) = {
919daa69ffeSMugunthan V N 	.name	= "i2c_omap",
920daa69ffeSMugunthan V N 	.id	= UCLASS_I2C,
921daa69ffeSMugunthan V N 	.of_match = omap_i2c_ids,
922daa69ffeSMugunthan V N 	.ofdata_to_platdata = omap_i2c_ofdata_to_platdata,
923daa69ffeSMugunthan V N 	.probe	= omap_i2c_probe,
924daa69ffeSMugunthan V N 	.priv_auto_alloc_size = sizeof(struct omap_i2c),
925daa69ffeSMugunthan V N 	.ops	= &omap_i2c_ops,
926daa69ffeSMugunthan V N 	.flags  = DM_FLAG_PRE_RELOC,
927daa69ffeSMugunthan V N };
928daa69ffeSMugunthan V N 
929daa69ffeSMugunthan V N #endif /* CONFIG_DM_I2C */
930