xref: /rk3399_rockchip-uboot/drivers/i2c/davinci_i2c.c (revision 2852709676c89e45b564ff0d64ce53e921c99c1d)
1942ba996SJean-Christophe PLAGNIOL-VILLARD /*
2942ba996SJean-Christophe PLAGNIOL-VILLARD  * TI DaVinci (TMS320DM644x) I2C driver.
3942ba996SJean-Christophe PLAGNIOL-VILLARD  *
4e8459dccSVitaly Andrianov  * (C) Copyright 2012-2014
5e8459dccSVitaly Andrianov  *     Texas Instruments Incorporated, <www.ti.com>
6e8459dccSVitaly Andrianov  * (C) Copyright 2007 Sergey Kubushyn <ksi@koi8.net>
7942ba996SJean-Christophe PLAGNIOL-VILLARD  * --------------------------------------------------------
8942ba996SJean-Christophe PLAGNIOL-VILLARD  *
91a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
10*28527096SSimon Glass  *
11*28527096SSimon Glass  * NOTE: This driver should be converted to driver model before June 2017.
12*28527096SSimon Glass  * Please see doc/driver-model/i2c-howto.txt for instructions.
13942ba996SJean-Christophe PLAGNIOL-VILLARD  */
14942ba996SJean-Christophe PLAGNIOL-VILLARD 
15942ba996SJean-Christophe PLAGNIOL-VILLARD #include <common.h>
16942ba996SJean-Christophe PLAGNIOL-VILLARD #include <i2c.h>
17942ba996SJean-Christophe PLAGNIOL-VILLARD #include <asm/arch/hardware.h>
18942ba996SJean-Christophe PLAGNIOL-VILLARD #include <asm/arch/i2c_defs.h>
19e8459dccSVitaly Andrianov #include <asm/io.h>
20356d15ebSKaricheri, Muralidharan #include "davinci_i2c.h"
21942ba996SJean-Christophe PLAGNIOL-VILLARD 
22942ba996SJean-Christophe PLAGNIOL-VILLARD #define CHECK_NACK() \
23942ba996SJean-Christophe PLAGNIOL-VILLARD 	do {\
24942ba996SJean-Christophe PLAGNIOL-VILLARD 		if (tmp & (I2C_TIMEOUT | I2C_STAT_NACK)) {\
25e8459dccSVitaly Andrianov 			REG(&(i2c_base->i2c_con)) = 0;\
26e8459dccSVitaly Andrianov 			return 1;\
27942ba996SJean-Christophe PLAGNIOL-VILLARD 		} \
28942ba996SJean-Christophe PLAGNIOL-VILLARD 	} while (0)
29942ba996SJean-Christophe PLAGNIOL-VILLARD 
30e8459dccSVitaly Andrianov static struct i2c_regs *davinci_get_base(struct i2c_adapter *adap);
31942ba996SJean-Christophe PLAGNIOL-VILLARD 
32e8459dccSVitaly Andrianov static int wait_for_bus(struct i2c_adapter *adap)
33942ba996SJean-Christophe PLAGNIOL-VILLARD {
34e8459dccSVitaly Andrianov 	struct i2c_regs *i2c_base = davinci_get_base(adap);
35942ba996SJean-Christophe PLAGNIOL-VILLARD 	int	stat, timeout;
36942ba996SJean-Christophe PLAGNIOL-VILLARD 
37e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_stat)) = 0xffff;
38942ba996SJean-Christophe PLAGNIOL-VILLARD 
39942ba996SJean-Christophe PLAGNIOL-VILLARD 	for (timeout = 0; timeout < 10; timeout++) {
40e8459dccSVitaly Andrianov 		stat = REG(&(i2c_base->i2c_stat));
41e8459dccSVitaly Andrianov 		if (!((stat) & I2C_STAT_BB)) {
42e8459dccSVitaly Andrianov 			REG(&(i2c_base->i2c_stat)) = 0xffff;
4349d6da60SHeiko Schocher 			return 0;
4449d6da60SHeiko Schocher 		}
45942ba996SJean-Christophe PLAGNIOL-VILLARD 
46e8459dccSVitaly Andrianov 		REG(&(i2c_base->i2c_stat)) = stat;
47e8459dccSVitaly Andrianov 		udelay(50000);
48e8459dccSVitaly Andrianov 	}
49e8459dccSVitaly Andrianov 
50e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_stat)) = 0xffff;
51e8459dccSVitaly Andrianov 	return 1;
52e8459dccSVitaly Andrianov }
53e8459dccSVitaly Andrianov 
54e8459dccSVitaly Andrianov 
55e8459dccSVitaly Andrianov static int poll_i2c_irq(struct i2c_adapter *adap, int mask)
56942ba996SJean-Christophe PLAGNIOL-VILLARD {
57e8459dccSVitaly Andrianov 	struct i2c_regs *i2c_base = davinci_get_base(adap);
58e8459dccSVitaly Andrianov 	int	stat, timeout;
59e8459dccSVitaly Andrianov 
60e8459dccSVitaly Andrianov 	for (timeout = 0; timeout < 10; timeout++) {
61e8459dccSVitaly Andrianov 		udelay(1000);
62e8459dccSVitaly Andrianov 		stat = REG(&(i2c_base->i2c_stat));
63e8459dccSVitaly Andrianov 		if (stat & mask)
64e8459dccSVitaly Andrianov 			return stat;
65e8459dccSVitaly Andrianov 	}
66e8459dccSVitaly Andrianov 
67e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_stat)) = 0xffff;
68e8459dccSVitaly Andrianov 	return stat | I2C_TIMEOUT;
69e8459dccSVitaly Andrianov }
70e8459dccSVitaly Andrianov 
71e8459dccSVitaly Andrianov static void flush_rx(struct i2c_adapter *adap)
72e8459dccSVitaly Andrianov {
73e8459dccSVitaly Andrianov 	struct i2c_regs *i2c_base = davinci_get_base(adap);
74e8459dccSVitaly Andrianov 
75e8459dccSVitaly Andrianov 	while (1) {
76e8459dccSVitaly Andrianov 		if (!(REG(&(i2c_base->i2c_stat)) & I2C_STAT_RRDY))
77e8459dccSVitaly Andrianov 			break;
78e8459dccSVitaly Andrianov 
79e8459dccSVitaly Andrianov 		REG(&(i2c_base->i2c_drr));
80e8459dccSVitaly Andrianov 		REG(&(i2c_base->i2c_stat)) = I2C_STAT_RRDY;
81e8459dccSVitaly Andrianov 		udelay(1000);
82e8459dccSVitaly Andrianov 	}
83e8459dccSVitaly Andrianov }
84e8459dccSVitaly Andrianov 
85e8459dccSVitaly Andrianov static uint davinci_i2c_setspeed(struct i2c_adapter *adap, uint speed)
86e8459dccSVitaly Andrianov {
87e8459dccSVitaly Andrianov 	struct i2c_regs *i2c_base = davinci_get_base(adap);
88e8459dccSVitaly Andrianov 	uint32_t	div, psc;
89e8459dccSVitaly Andrianov 
90e8459dccSVitaly Andrianov 	psc = 2;
91e8459dccSVitaly Andrianov 	/* SCLL + SCLH */
92e8459dccSVitaly Andrianov 	div = (CONFIG_SYS_HZ_CLOCK / ((psc + 1) * speed)) - 10;
93e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_psc)) = psc; /* 27MHz / (2 + 1) = 9MHz */
94e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_scll)) = (div * 50) / 100; /* 50% Duty */
95e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_sclh)) = div - REG(&(i2c_base->i2c_scll));
96e8459dccSVitaly Andrianov 
97e8459dccSVitaly Andrianov 	adap->speed	= speed;
98e8459dccSVitaly Andrianov 	return 0;
99e8459dccSVitaly Andrianov }
100e8459dccSVitaly Andrianov 
101e8459dccSVitaly Andrianov static void davinci_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
102e8459dccSVitaly Andrianov {
103e8459dccSVitaly Andrianov 	struct i2c_regs *i2c_base = davinci_get_base(adap);
104e8459dccSVitaly Andrianov 
105e8459dccSVitaly Andrianov 	if (REG(&(i2c_base->i2c_con)) & I2C_CON_EN) {
106e8459dccSVitaly Andrianov 		REG(&(i2c_base->i2c_con)) = 0;
107e8459dccSVitaly Andrianov 		udelay(50000);
108e8459dccSVitaly Andrianov 	}
109e8459dccSVitaly Andrianov 
110e8459dccSVitaly Andrianov 	davinci_i2c_setspeed(adap, speed);
111e8459dccSVitaly Andrianov 
112e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_oa)) = slaveadd;
113e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_cnt)) = 0;
114e8459dccSVitaly Andrianov 
115e8459dccSVitaly Andrianov 	/* Interrupts must be enabled or I2C module won't work */
116e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_ie)) = I2C_IE_SCD_IE | I2C_IE_XRDY_IE |
117e8459dccSVitaly Andrianov 		I2C_IE_RRDY_IE | I2C_IE_ARDY_IE | I2C_IE_NACK_IE;
118e8459dccSVitaly Andrianov 
119e8459dccSVitaly Andrianov 	/* Now enable I2C controller (get it out of reset) */
120e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_con)) = I2C_CON_EN;
121e8459dccSVitaly Andrianov 
122e8459dccSVitaly Andrianov 	udelay(1000);
123e8459dccSVitaly Andrianov }
124e8459dccSVitaly Andrianov 
125e8459dccSVitaly Andrianov static int davinci_i2c_probe(struct i2c_adapter *adap, uint8_t chip)
126e8459dccSVitaly Andrianov {
127e8459dccSVitaly Andrianov 	struct i2c_regs *i2c_base = davinci_get_base(adap);
128942ba996SJean-Christophe PLAGNIOL-VILLARD 	int	rc = 1;
129942ba996SJean-Christophe PLAGNIOL-VILLARD 
130e8459dccSVitaly Andrianov 	if (chip == REG(&(i2c_base->i2c_oa)))
131e8459dccSVitaly Andrianov 		return rc;
132942ba996SJean-Christophe PLAGNIOL-VILLARD 
133e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_con)) = 0;
134e8459dccSVitaly Andrianov 	if (wait_for_bus(adap))
135e8459dccSVitaly Andrianov 		return 1;
136942ba996SJean-Christophe PLAGNIOL-VILLARD 
137942ba996SJean-Christophe PLAGNIOL-VILLARD 	/* try to read one byte from current (or only) address */
138e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_cnt)) = 1;
139e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_sa))  = chip;
140e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_con)) = (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT |
141e8459dccSVitaly Andrianov 				     I2C_CON_STP);
142942ba996SJean-Christophe PLAGNIOL-VILLARD 	udelay(50000);
143942ba996SJean-Christophe PLAGNIOL-VILLARD 
144e8459dccSVitaly Andrianov 	if (!(REG(&(i2c_base->i2c_stat)) & I2C_STAT_NACK)) {
145942ba996SJean-Christophe PLAGNIOL-VILLARD 		rc = 0;
146e8459dccSVitaly Andrianov 		flush_rx(adap);
147e8459dccSVitaly Andrianov 		REG(&(i2c_base->i2c_stat)) = 0xffff;
148942ba996SJean-Christophe PLAGNIOL-VILLARD 	} else {
149e8459dccSVitaly Andrianov 		REG(&(i2c_base->i2c_stat)) = 0xffff;
150e8459dccSVitaly Andrianov 		REG(&(i2c_base->i2c_con)) |= I2C_CON_STP;
151942ba996SJean-Christophe PLAGNIOL-VILLARD 		udelay(20000);
152e8459dccSVitaly Andrianov 		if (wait_for_bus(adap))
153e8459dccSVitaly Andrianov 			return 1;
154942ba996SJean-Christophe PLAGNIOL-VILLARD 	}
155942ba996SJean-Christophe PLAGNIOL-VILLARD 
156e8459dccSVitaly Andrianov 	flush_rx(adap);
157e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_stat)) = 0xffff;
158e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_cnt)) = 0;
159e8459dccSVitaly Andrianov 	return rc;
160942ba996SJean-Christophe PLAGNIOL-VILLARD }
161942ba996SJean-Christophe PLAGNIOL-VILLARD 
162e8459dccSVitaly Andrianov static int davinci_i2c_read(struct i2c_adapter *adap, uint8_t chip,
163e8459dccSVitaly Andrianov 				uint32_t addr, int alen, uint8_t *buf, int len)
164942ba996SJean-Christophe PLAGNIOL-VILLARD {
165e8459dccSVitaly Andrianov 	struct i2c_regs *i2c_base = davinci_get_base(adap);
166e8459dccSVitaly Andrianov 	uint32_t	tmp;
167942ba996SJean-Christophe PLAGNIOL-VILLARD 	int		i;
168942ba996SJean-Christophe PLAGNIOL-VILLARD 
169942ba996SJean-Christophe PLAGNIOL-VILLARD 	if ((alen < 0) || (alen > 2)) {
170e8459dccSVitaly Andrianov 		printf("%s(): bogus address length %x\n", __func__, alen);
171e8459dccSVitaly Andrianov 		return 1;
172942ba996SJean-Christophe PLAGNIOL-VILLARD 	}
173942ba996SJean-Christophe PLAGNIOL-VILLARD 
174e8459dccSVitaly Andrianov 	if (wait_for_bus(adap))
175e8459dccSVitaly Andrianov 		return 1;
176942ba996SJean-Christophe PLAGNIOL-VILLARD 
177942ba996SJean-Christophe PLAGNIOL-VILLARD 	if (alen != 0) {
178942ba996SJean-Christophe PLAGNIOL-VILLARD 		/* Start address phase */
179942ba996SJean-Christophe PLAGNIOL-VILLARD 		tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX;
180e8459dccSVitaly Andrianov 		REG(&(i2c_base->i2c_cnt)) = alen;
181e8459dccSVitaly Andrianov 		REG(&(i2c_base->i2c_sa)) = chip;
182e8459dccSVitaly Andrianov 		REG(&(i2c_base->i2c_con)) = tmp;
183942ba996SJean-Christophe PLAGNIOL-VILLARD 
184e8459dccSVitaly Andrianov 		tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK);
185942ba996SJean-Christophe PLAGNIOL-VILLARD 
186942ba996SJean-Christophe PLAGNIOL-VILLARD 		CHECK_NACK();
187942ba996SJean-Christophe PLAGNIOL-VILLARD 
188942ba996SJean-Christophe PLAGNIOL-VILLARD 		switch (alen) {
189942ba996SJean-Christophe PLAGNIOL-VILLARD 		case 2:
190942ba996SJean-Christophe PLAGNIOL-VILLARD 			/* Send address MSByte */
191942ba996SJean-Christophe PLAGNIOL-VILLARD 			if (tmp & I2C_STAT_XRDY) {
192e8459dccSVitaly Andrianov 				REG(&(i2c_base->i2c_dxr)) = (addr >> 8) & 0xff;
193942ba996SJean-Christophe PLAGNIOL-VILLARD 			} else {
194e8459dccSVitaly Andrianov 				REG(&(i2c_base->i2c_con)) = 0;
195e8459dccSVitaly Andrianov 				return 1;
196942ba996SJean-Christophe PLAGNIOL-VILLARD 			}
197942ba996SJean-Christophe PLAGNIOL-VILLARD 
198e8459dccSVitaly Andrianov 			tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK);
199942ba996SJean-Christophe PLAGNIOL-VILLARD 
200942ba996SJean-Christophe PLAGNIOL-VILLARD 			CHECK_NACK();
201942ba996SJean-Christophe PLAGNIOL-VILLARD 			/* No break, fall through */
202942ba996SJean-Christophe PLAGNIOL-VILLARD 		case 1:
203942ba996SJean-Christophe PLAGNIOL-VILLARD 			/* Send address LSByte */
204942ba996SJean-Christophe PLAGNIOL-VILLARD 			if (tmp & I2C_STAT_XRDY) {
205e8459dccSVitaly Andrianov 				REG(&(i2c_base->i2c_dxr)) = addr & 0xff;
206942ba996SJean-Christophe PLAGNIOL-VILLARD 			} else {
207e8459dccSVitaly Andrianov 				REG(&(i2c_base->i2c_con)) = 0;
208e8459dccSVitaly Andrianov 				return 1;
209942ba996SJean-Christophe PLAGNIOL-VILLARD 			}
210942ba996SJean-Christophe PLAGNIOL-VILLARD 
211e8459dccSVitaly Andrianov 			tmp = poll_i2c_irq(adap, I2C_STAT_XRDY |
212e8459dccSVitaly Andrianov 					   I2C_STAT_NACK | I2C_STAT_ARDY);
213942ba996SJean-Christophe PLAGNIOL-VILLARD 
214942ba996SJean-Christophe PLAGNIOL-VILLARD 			CHECK_NACK();
215942ba996SJean-Christophe PLAGNIOL-VILLARD 
216942ba996SJean-Christophe PLAGNIOL-VILLARD 			if (!(tmp & I2C_STAT_ARDY)) {
217e8459dccSVitaly Andrianov 				REG(&(i2c_base->i2c_con)) = 0;
218e8459dccSVitaly Andrianov 				return 1;
219942ba996SJean-Christophe PLAGNIOL-VILLARD 			}
220942ba996SJean-Christophe PLAGNIOL-VILLARD 		}
221942ba996SJean-Christophe PLAGNIOL-VILLARD 	}
222942ba996SJean-Christophe PLAGNIOL-VILLARD 
223942ba996SJean-Christophe PLAGNIOL-VILLARD 	/* Address phase is over, now read 'len' bytes and stop */
224942ba996SJean-Christophe PLAGNIOL-VILLARD 	tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP;
225e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_cnt)) = len & 0xffff;
226e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_sa)) = chip;
227e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_con)) = tmp;
228942ba996SJean-Christophe PLAGNIOL-VILLARD 
229942ba996SJean-Christophe PLAGNIOL-VILLARD 	for (i = 0; i < len; i++) {
230e8459dccSVitaly Andrianov 		tmp = poll_i2c_irq(adap, I2C_STAT_RRDY | I2C_STAT_NACK |
231e8459dccSVitaly Andrianov 				   I2C_STAT_ROVR);
232942ba996SJean-Christophe PLAGNIOL-VILLARD 
233942ba996SJean-Christophe PLAGNIOL-VILLARD 		CHECK_NACK();
234942ba996SJean-Christophe PLAGNIOL-VILLARD 
235942ba996SJean-Christophe PLAGNIOL-VILLARD 		if (tmp & I2C_STAT_RRDY) {
236e8459dccSVitaly Andrianov 			buf[i] = REG(&(i2c_base->i2c_drr));
237942ba996SJean-Christophe PLAGNIOL-VILLARD 		} else {
238e8459dccSVitaly Andrianov 			REG(&(i2c_base->i2c_con)) = 0;
239e8459dccSVitaly Andrianov 			return 1;
240942ba996SJean-Christophe PLAGNIOL-VILLARD 		}
241942ba996SJean-Christophe PLAGNIOL-VILLARD 	}
242942ba996SJean-Christophe PLAGNIOL-VILLARD 
243e8459dccSVitaly Andrianov 	tmp = poll_i2c_irq(adap, I2C_STAT_SCD | I2C_STAT_NACK);
244942ba996SJean-Christophe PLAGNIOL-VILLARD 
245942ba996SJean-Christophe PLAGNIOL-VILLARD 	CHECK_NACK();
246942ba996SJean-Christophe PLAGNIOL-VILLARD 
247942ba996SJean-Christophe PLAGNIOL-VILLARD 	if (!(tmp & I2C_STAT_SCD)) {
248e8459dccSVitaly Andrianov 		REG(&(i2c_base->i2c_con)) = 0;
249e8459dccSVitaly Andrianov 		return 1;
250942ba996SJean-Christophe PLAGNIOL-VILLARD 	}
251942ba996SJean-Christophe PLAGNIOL-VILLARD 
252e8459dccSVitaly Andrianov 	flush_rx(adap);
253e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_stat)) = 0xffff;
254e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_cnt)) = 0;
255e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_con)) = 0;
256942ba996SJean-Christophe PLAGNIOL-VILLARD 
257e8459dccSVitaly Andrianov 	return 0;
258942ba996SJean-Christophe PLAGNIOL-VILLARD }
259942ba996SJean-Christophe PLAGNIOL-VILLARD 
260e8459dccSVitaly Andrianov static int davinci_i2c_write(struct i2c_adapter *adap, uint8_t chip,
261e8459dccSVitaly Andrianov 				uint32_t addr, int alen, uint8_t *buf, int len)
262942ba996SJean-Christophe PLAGNIOL-VILLARD {
263e8459dccSVitaly Andrianov 	struct i2c_regs *i2c_base = davinci_get_base(adap);
264e8459dccSVitaly Andrianov 	uint32_t	tmp;
265942ba996SJean-Christophe PLAGNIOL-VILLARD 	int		i;
266942ba996SJean-Christophe PLAGNIOL-VILLARD 
267942ba996SJean-Christophe PLAGNIOL-VILLARD 	if ((alen < 0) || (alen > 2)) {
268e8459dccSVitaly Andrianov 		printf("%s(): bogus address length %x\n", __func__, alen);
269e8459dccSVitaly Andrianov 		return 1;
270942ba996SJean-Christophe PLAGNIOL-VILLARD 	}
271942ba996SJean-Christophe PLAGNIOL-VILLARD 	if (len < 0) {
272e8459dccSVitaly Andrianov 		printf("%s(): bogus length %x\n", __func__, len);
273e8459dccSVitaly Andrianov 		return 1;
274942ba996SJean-Christophe PLAGNIOL-VILLARD 	}
275942ba996SJean-Christophe PLAGNIOL-VILLARD 
276e8459dccSVitaly Andrianov 	if (wait_for_bus(adap))
277e8459dccSVitaly Andrianov 		return 1;
278942ba996SJean-Christophe PLAGNIOL-VILLARD 
279942ba996SJean-Christophe PLAGNIOL-VILLARD 	/* Start address phase */
280e8459dccSVitaly Andrianov 	tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT |
281e8459dccSVitaly Andrianov 		I2C_CON_TRX | I2C_CON_STP;
282e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_cnt)) = (alen == 0) ?
283e8459dccSVitaly Andrianov 		len & 0xffff : (len & 0xffff) + alen;
284e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_sa)) = chip;
285e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_con)) = tmp;
286942ba996SJean-Christophe PLAGNIOL-VILLARD 
287942ba996SJean-Christophe PLAGNIOL-VILLARD 	switch (alen) {
288942ba996SJean-Christophe PLAGNIOL-VILLARD 	case 2:
289942ba996SJean-Christophe PLAGNIOL-VILLARD 		/* Send address MSByte */
290e8459dccSVitaly Andrianov 		tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK);
291942ba996SJean-Christophe PLAGNIOL-VILLARD 
292942ba996SJean-Christophe PLAGNIOL-VILLARD 		CHECK_NACK();
293942ba996SJean-Christophe PLAGNIOL-VILLARD 
294942ba996SJean-Christophe PLAGNIOL-VILLARD 		if (tmp & I2C_STAT_XRDY) {
295e8459dccSVitaly Andrianov 			REG(&(i2c_base->i2c_dxr)) = (addr >> 8) & 0xff;
296942ba996SJean-Christophe PLAGNIOL-VILLARD 		} else {
297e8459dccSVitaly Andrianov 			REG(&(i2c_base->i2c_con)) = 0;
298e8459dccSVitaly Andrianov 			return 1;
299942ba996SJean-Christophe PLAGNIOL-VILLARD 		}
300942ba996SJean-Christophe PLAGNIOL-VILLARD 		/* No break, fall through */
301942ba996SJean-Christophe PLAGNIOL-VILLARD 	case 1:
302942ba996SJean-Christophe PLAGNIOL-VILLARD 		/* Send address LSByte */
303e8459dccSVitaly Andrianov 		tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK);
304942ba996SJean-Christophe PLAGNIOL-VILLARD 
305942ba996SJean-Christophe PLAGNIOL-VILLARD 		CHECK_NACK();
306942ba996SJean-Christophe PLAGNIOL-VILLARD 
307942ba996SJean-Christophe PLAGNIOL-VILLARD 		if (tmp & I2C_STAT_XRDY) {
308e8459dccSVitaly Andrianov 			REG(&(i2c_base->i2c_dxr)) = addr & 0xff;
309942ba996SJean-Christophe PLAGNIOL-VILLARD 		} else {
310e8459dccSVitaly Andrianov 			REG(&(i2c_base->i2c_con)) = 0;
311e8459dccSVitaly Andrianov 			return 1;
312942ba996SJean-Christophe PLAGNIOL-VILLARD 		}
313942ba996SJean-Christophe PLAGNIOL-VILLARD 	}
314942ba996SJean-Christophe PLAGNIOL-VILLARD 
315942ba996SJean-Christophe PLAGNIOL-VILLARD 	for (i = 0; i < len; i++) {
316e8459dccSVitaly Andrianov 		tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK);
317942ba996SJean-Christophe PLAGNIOL-VILLARD 
318942ba996SJean-Christophe PLAGNIOL-VILLARD 		CHECK_NACK();
319942ba996SJean-Christophe PLAGNIOL-VILLARD 
320e8459dccSVitaly Andrianov 		if (tmp & I2C_STAT_XRDY)
321e8459dccSVitaly Andrianov 			REG(&(i2c_base->i2c_dxr)) = buf[i];
322e8459dccSVitaly Andrianov 		else
323e8459dccSVitaly Andrianov 			return 1;
324942ba996SJean-Christophe PLAGNIOL-VILLARD 	}
325942ba996SJean-Christophe PLAGNIOL-VILLARD 
326e8459dccSVitaly Andrianov 	tmp = poll_i2c_irq(adap, I2C_STAT_SCD | I2C_STAT_NACK);
327942ba996SJean-Christophe PLAGNIOL-VILLARD 
328942ba996SJean-Christophe PLAGNIOL-VILLARD 	CHECK_NACK();
329942ba996SJean-Christophe PLAGNIOL-VILLARD 
330942ba996SJean-Christophe PLAGNIOL-VILLARD 	if (!(tmp & I2C_STAT_SCD)) {
331e8459dccSVitaly Andrianov 		REG(&(i2c_base->i2c_con)) = 0;
332e8459dccSVitaly Andrianov 		return 1;
333942ba996SJean-Christophe PLAGNIOL-VILLARD 	}
334942ba996SJean-Christophe PLAGNIOL-VILLARD 
335e8459dccSVitaly Andrianov 	flush_rx(adap);
336e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_stat)) = 0xffff;
337e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_cnt)) = 0;
338e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_con)) = 0;
339942ba996SJean-Christophe PLAGNIOL-VILLARD 
340e8459dccSVitaly Andrianov 	return 0;
341942ba996SJean-Christophe PLAGNIOL-VILLARD }
342e8459dccSVitaly Andrianov 
343e8459dccSVitaly Andrianov static struct i2c_regs *davinci_get_base(struct i2c_adapter *adap)
344e8459dccSVitaly Andrianov {
345e8459dccSVitaly Andrianov 	switch (adap->hwadapnr) {
346e8459dccSVitaly Andrianov #if I2C_BUS_MAX >= 3
347e8459dccSVitaly Andrianov 	case 2:
348e8459dccSVitaly Andrianov 		return (struct i2c_regs *)I2C2_BASE;
349e8459dccSVitaly Andrianov #endif
350e8459dccSVitaly Andrianov #if I2C_BUS_MAX >= 2
351e8459dccSVitaly Andrianov 	case 1:
352e8459dccSVitaly Andrianov 		return (struct i2c_regs *)I2C1_BASE;
353e8459dccSVitaly Andrianov #endif
354e8459dccSVitaly Andrianov 	case 0:
355e8459dccSVitaly Andrianov 		return (struct i2c_regs *)I2C_BASE;
356e8459dccSVitaly Andrianov 
357e8459dccSVitaly Andrianov 	default:
358e8459dccSVitaly Andrianov 		printf("wrong hwadapnr: %d\n", adap->hwadapnr);
359e8459dccSVitaly Andrianov 	}
360e8459dccSVitaly Andrianov 
361e8459dccSVitaly Andrianov 	return NULL;
362e8459dccSVitaly Andrianov }
363e8459dccSVitaly Andrianov 
364e8459dccSVitaly Andrianov U_BOOT_I2C_ADAP_COMPLETE(davinci_0, davinci_i2c_init, davinci_i2c_probe,
365e8459dccSVitaly Andrianov 			 davinci_i2c_read, davinci_i2c_write,
366e8459dccSVitaly Andrianov 			 davinci_i2c_setspeed,
367e8459dccSVitaly Andrianov 			 CONFIG_SYS_DAVINCI_I2C_SPEED,
368e8459dccSVitaly Andrianov 			 CONFIG_SYS_DAVINCI_I2C_SLAVE,
369e8459dccSVitaly Andrianov 			 0)
370e8459dccSVitaly Andrianov 
371e8459dccSVitaly Andrianov #if I2C_BUS_MAX >= 2
372e8459dccSVitaly Andrianov U_BOOT_I2C_ADAP_COMPLETE(davinci_1, davinci_i2c_init, davinci_i2c_probe,
373e8459dccSVitaly Andrianov 			 davinci_i2c_read, davinci_i2c_write,
374e8459dccSVitaly Andrianov 			 davinci_i2c_setspeed,
375e8459dccSVitaly Andrianov 			 CONFIG_SYS_DAVINCI_I2C_SPEED1,
376e8459dccSVitaly Andrianov 			 CONFIG_SYS_DAVINCI_I2C_SLAVE1,
377e8459dccSVitaly Andrianov 			 1)
378e8459dccSVitaly Andrianov #endif
379e8459dccSVitaly Andrianov 
380e8459dccSVitaly Andrianov #if I2C_BUS_MAX >= 3
381e8459dccSVitaly Andrianov U_BOOT_I2C_ADAP_COMPLETE(davinci_2, davinci_i2c_init, davinci_i2c_probe,
382e8459dccSVitaly Andrianov 			 davinci_i2c_read, davinci_i2c_write,
383e8459dccSVitaly Andrianov 			 davinci_i2c_setspeed,
384e8459dccSVitaly Andrianov 			 CONFIG_SYS_DAVINCI_I2C_SPEED2,
385e8459dccSVitaly Andrianov 			 CONFIG_SYS_DAVINCI_I2C_SLAVE2,
386e8459dccSVitaly Andrianov 			 2)
387e8459dccSVitaly Andrianov #endif
388