xref: /rk3399_rockchip-uboot/drivers/i2c/davinci_i2c.c (revision e8459dcc33c3f3fc5a98b7b69bb3ddd7ad77f632)
1942ba996SJean-Christophe PLAGNIOL-VILLARD /*
2942ba996SJean-Christophe PLAGNIOL-VILLARD  * TI DaVinci (TMS320DM644x) I2C driver.
3942ba996SJean-Christophe PLAGNIOL-VILLARD  *
4*e8459dccSVitaly Andrianov  * (C) Copyright 2012-2014
5*e8459dccSVitaly Andrianov  *     Texas Instruments Incorporated, <www.ti.com>
6*e8459dccSVitaly 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+
10942ba996SJean-Christophe PLAGNIOL-VILLARD  */
11942ba996SJean-Christophe PLAGNIOL-VILLARD 
12942ba996SJean-Christophe PLAGNIOL-VILLARD #include <common.h>
13942ba996SJean-Christophe PLAGNIOL-VILLARD #include <i2c.h>
14942ba996SJean-Christophe PLAGNIOL-VILLARD #include <asm/arch/hardware.h>
15942ba996SJean-Christophe PLAGNIOL-VILLARD #include <asm/arch/i2c_defs.h>
16*e8459dccSVitaly Andrianov #include <asm/io.h>
17356d15ebSKaricheri, Muralidharan #include "davinci_i2c.h"
18942ba996SJean-Christophe PLAGNIOL-VILLARD 
19942ba996SJean-Christophe PLAGNIOL-VILLARD #define CHECK_NACK() \
20942ba996SJean-Christophe PLAGNIOL-VILLARD 	do {\
21942ba996SJean-Christophe PLAGNIOL-VILLARD 		if (tmp & (I2C_TIMEOUT | I2C_STAT_NACK)) {\
22*e8459dccSVitaly Andrianov 			REG(&(i2c_base->i2c_con)) = 0;\
23*e8459dccSVitaly Andrianov 			return 1;\
24942ba996SJean-Christophe PLAGNIOL-VILLARD 		} \
25942ba996SJean-Christophe PLAGNIOL-VILLARD 	} while (0)
26942ba996SJean-Christophe PLAGNIOL-VILLARD 
27*e8459dccSVitaly Andrianov static struct i2c_regs *davinci_get_base(struct i2c_adapter *adap);
28942ba996SJean-Christophe PLAGNIOL-VILLARD 
29*e8459dccSVitaly Andrianov static int wait_for_bus(struct i2c_adapter *adap)
30942ba996SJean-Christophe PLAGNIOL-VILLARD {
31*e8459dccSVitaly Andrianov 	struct i2c_regs *i2c_base = davinci_get_base(adap);
32942ba996SJean-Christophe PLAGNIOL-VILLARD 	int	stat, timeout;
33942ba996SJean-Christophe PLAGNIOL-VILLARD 
34*e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_stat)) = 0xffff;
35942ba996SJean-Christophe PLAGNIOL-VILLARD 
36942ba996SJean-Christophe PLAGNIOL-VILLARD 	for (timeout = 0; timeout < 10; timeout++) {
37*e8459dccSVitaly Andrianov 		stat = REG(&(i2c_base->i2c_stat));
38*e8459dccSVitaly Andrianov 		if (!((stat) & I2C_STAT_BB)) {
39*e8459dccSVitaly Andrianov 			REG(&(i2c_base->i2c_stat)) = 0xffff;
4049d6da60SHeiko Schocher 			return 0;
4149d6da60SHeiko Schocher 		}
42942ba996SJean-Christophe PLAGNIOL-VILLARD 
43*e8459dccSVitaly Andrianov 		REG(&(i2c_base->i2c_stat)) = stat;
44*e8459dccSVitaly Andrianov 		udelay(50000);
45*e8459dccSVitaly Andrianov 	}
46*e8459dccSVitaly Andrianov 
47*e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_stat)) = 0xffff;
48*e8459dccSVitaly Andrianov 	return 1;
49*e8459dccSVitaly Andrianov }
50*e8459dccSVitaly Andrianov 
51*e8459dccSVitaly Andrianov 
52*e8459dccSVitaly Andrianov static int poll_i2c_irq(struct i2c_adapter *adap, int mask)
53942ba996SJean-Christophe PLAGNIOL-VILLARD {
54*e8459dccSVitaly Andrianov 	struct i2c_regs *i2c_base = davinci_get_base(adap);
55*e8459dccSVitaly Andrianov 	int	stat, timeout;
56*e8459dccSVitaly Andrianov 
57*e8459dccSVitaly Andrianov 	for (timeout = 0; timeout < 10; timeout++) {
58*e8459dccSVitaly Andrianov 		udelay(1000);
59*e8459dccSVitaly Andrianov 		stat = REG(&(i2c_base->i2c_stat));
60*e8459dccSVitaly Andrianov 		if (stat & mask)
61*e8459dccSVitaly Andrianov 			return stat;
62*e8459dccSVitaly Andrianov 	}
63*e8459dccSVitaly Andrianov 
64*e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_stat)) = 0xffff;
65*e8459dccSVitaly Andrianov 	return stat | I2C_TIMEOUT;
66*e8459dccSVitaly Andrianov }
67*e8459dccSVitaly Andrianov 
68*e8459dccSVitaly Andrianov static void flush_rx(struct i2c_adapter *adap)
69*e8459dccSVitaly Andrianov {
70*e8459dccSVitaly Andrianov 	struct i2c_regs *i2c_base = davinci_get_base(adap);
71*e8459dccSVitaly Andrianov 
72*e8459dccSVitaly Andrianov 	while (1) {
73*e8459dccSVitaly Andrianov 		if (!(REG(&(i2c_base->i2c_stat)) & I2C_STAT_RRDY))
74*e8459dccSVitaly Andrianov 			break;
75*e8459dccSVitaly Andrianov 
76*e8459dccSVitaly Andrianov 		REG(&(i2c_base->i2c_drr));
77*e8459dccSVitaly Andrianov 		REG(&(i2c_base->i2c_stat)) = I2C_STAT_RRDY;
78*e8459dccSVitaly Andrianov 		udelay(1000);
79*e8459dccSVitaly Andrianov 	}
80*e8459dccSVitaly Andrianov }
81*e8459dccSVitaly Andrianov 
82*e8459dccSVitaly Andrianov static uint davinci_i2c_setspeed(struct i2c_adapter *adap, uint speed)
83*e8459dccSVitaly Andrianov {
84*e8459dccSVitaly Andrianov 	struct i2c_regs *i2c_base = davinci_get_base(adap);
85*e8459dccSVitaly Andrianov 	uint32_t	div, psc;
86*e8459dccSVitaly Andrianov 
87*e8459dccSVitaly Andrianov 	psc = 2;
88*e8459dccSVitaly Andrianov 	/* SCLL + SCLH */
89*e8459dccSVitaly Andrianov 	div = (CONFIG_SYS_HZ_CLOCK / ((psc + 1) * speed)) - 10;
90*e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_psc)) = psc; /* 27MHz / (2 + 1) = 9MHz */
91*e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_scll)) = (div * 50) / 100; /* 50% Duty */
92*e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_sclh)) = div - REG(&(i2c_base->i2c_scll));
93*e8459dccSVitaly Andrianov 
94*e8459dccSVitaly Andrianov 	adap->speed	= speed;
95*e8459dccSVitaly Andrianov 	return 0;
96*e8459dccSVitaly Andrianov }
97*e8459dccSVitaly Andrianov 
98*e8459dccSVitaly Andrianov static void davinci_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
99*e8459dccSVitaly Andrianov {
100*e8459dccSVitaly Andrianov 	struct i2c_regs *i2c_base = davinci_get_base(adap);
101*e8459dccSVitaly Andrianov 
102*e8459dccSVitaly Andrianov 	if (REG(&(i2c_base->i2c_con)) & I2C_CON_EN) {
103*e8459dccSVitaly Andrianov 		REG(&(i2c_base->i2c_con)) = 0;
104*e8459dccSVitaly Andrianov 		udelay(50000);
105*e8459dccSVitaly Andrianov 	}
106*e8459dccSVitaly Andrianov 
107*e8459dccSVitaly Andrianov 	davinci_i2c_setspeed(adap, speed);
108*e8459dccSVitaly Andrianov 
109*e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_oa)) = slaveadd;
110*e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_cnt)) = 0;
111*e8459dccSVitaly Andrianov 
112*e8459dccSVitaly Andrianov 	/* Interrupts must be enabled or I2C module won't work */
113*e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_ie)) = I2C_IE_SCD_IE | I2C_IE_XRDY_IE |
114*e8459dccSVitaly Andrianov 		I2C_IE_RRDY_IE | I2C_IE_ARDY_IE | I2C_IE_NACK_IE;
115*e8459dccSVitaly Andrianov 
116*e8459dccSVitaly Andrianov 	/* Now enable I2C controller (get it out of reset) */
117*e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_con)) = I2C_CON_EN;
118*e8459dccSVitaly Andrianov 
119*e8459dccSVitaly Andrianov 	udelay(1000);
120*e8459dccSVitaly Andrianov }
121*e8459dccSVitaly Andrianov 
122*e8459dccSVitaly Andrianov static int davinci_i2c_probe(struct i2c_adapter *adap, uint8_t chip)
123*e8459dccSVitaly Andrianov {
124*e8459dccSVitaly Andrianov 	struct i2c_regs *i2c_base = davinci_get_base(adap);
125942ba996SJean-Christophe PLAGNIOL-VILLARD 	int	rc = 1;
126942ba996SJean-Christophe PLAGNIOL-VILLARD 
127*e8459dccSVitaly Andrianov 	if (chip == REG(&(i2c_base->i2c_oa)))
128*e8459dccSVitaly Andrianov 		return rc;
129942ba996SJean-Christophe PLAGNIOL-VILLARD 
130*e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_con)) = 0;
131*e8459dccSVitaly Andrianov 	if (wait_for_bus(adap))
132*e8459dccSVitaly Andrianov 		return 1;
133942ba996SJean-Christophe PLAGNIOL-VILLARD 
134942ba996SJean-Christophe PLAGNIOL-VILLARD 	/* try to read one byte from current (or only) address */
135*e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_cnt)) = 1;
136*e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_sa))  = chip;
137*e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_con)) = (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT |
138*e8459dccSVitaly Andrianov 				     I2C_CON_STP);
139942ba996SJean-Christophe PLAGNIOL-VILLARD 	udelay(50000);
140942ba996SJean-Christophe PLAGNIOL-VILLARD 
141*e8459dccSVitaly Andrianov 	if (!(REG(&(i2c_base->i2c_stat)) & I2C_STAT_NACK)) {
142942ba996SJean-Christophe PLAGNIOL-VILLARD 		rc = 0;
143*e8459dccSVitaly Andrianov 		flush_rx(adap);
144*e8459dccSVitaly Andrianov 		REG(&(i2c_base->i2c_stat)) = 0xffff;
145942ba996SJean-Christophe PLAGNIOL-VILLARD 	} else {
146*e8459dccSVitaly Andrianov 		REG(&(i2c_base->i2c_stat)) = 0xffff;
147*e8459dccSVitaly Andrianov 		REG(&(i2c_base->i2c_con)) |= I2C_CON_STP;
148942ba996SJean-Christophe PLAGNIOL-VILLARD 		udelay(20000);
149*e8459dccSVitaly Andrianov 		if (wait_for_bus(adap))
150*e8459dccSVitaly Andrianov 			return 1;
151942ba996SJean-Christophe PLAGNIOL-VILLARD 	}
152942ba996SJean-Christophe PLAGNIOL-VILLARD 
153*e8459dccSVitaly Andrianov 	flush_rx(adap);
154*e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_stat)) = 0xffff;
155*e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_cnt)) = 0;
156*e8459dccSVitaly Andrianov 	return rc;
157942ba996SJean-Christophe PLAGNIOL-VILLARD }
158942ba996SJean-Christophe PLAGNIOL-VILLARD 
159*e8459dccSVitaly Andrianov static int davinci_i2c_read(struct i2c_adapter *adap, uint8_t chip,
160*e8459dccSVitaly Andrianov 				uint32_t addr, int alen, uint8_t *buf, int len)
161942ba996SJean-Christophe PLAGNIOL-VILLARD {
162*e8459dccSVitaly Andrianov 	struct i2c_regs *i2c_base = davinci_get_base(adap);
163*e8459dccSVitaly Andrianov 	uint32_t	tmp;
164942ba996SJean-Christophe PLAGNIOL-VILLARD 	int		i;
165942ba996SJean-Christophe PLAGNIOL-VILLARD 
166942ba996SJean-Christophe PLAGNIOL-VILLARD 	if ((alen < 0) || (alen > 2)) {
167*e8459dccSVitaly Andrianov 		printf("%s(): bogus address length %x\n", __func__, alen);
168*e8459dccSVitaly Andrianov 		return 1;
169942ba996SJean-Christophe PLAGNIOL-VILLARD 	}
170942ba996SJean-Christophe PLAGNIOL-VILLARD 
171*e8459dccSVitaly Andrianov 	if (wait_for_bus(adap))
172*e8459dccSVitaly Andrianov 		return 1;
173942ba996SJean-Christophe PLAGNIOL-VILLARD 
174942ba996SJean-Christophe PLAGNIOL-VILLARD 	if (alen != 0) {
175942ba996SJean-Christophe PLAGNIOL-VILLARD 		/* Start address phase */
176942ba996SJean-Christophe PLAGNIOL-VILLARD 		tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX;
177*e8459dccSVitaly Andrianov 		REG(&(i2c_base->i2c_cnt)) = alen;
178*e8459dccSVitaly Andrianov 		REG(&(i2c_base->i2c_sa)) = chip;
179*e8459dccSVitaly Andrianov 		REG(&(i2c_base->i2c_con)) = tmp;
180942ba996SJean-Christophe PLAGNIOL-VILLARD 
181*e8459dccSVitaly Andrianov 		tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK);
182942ba996SJean-Christophe PLAGNIOL-VILLARD 
183942ba996SJean-Christophe PLAGNIOL-VILLARD 		CHECK_NACK();
184942ba996SJean-Christophe PLAGNIOL-VILLARD 
185942ba996SJean-Christophe PLAGNIOL-VILLARD 		switch (alen) {
186942ba996SJean-Christophe PLAGNIOL-VILLARD 		case 2:
187942ba996SJean-Christophe PLAGNIOL-VILLARD 			/* Send address MSByte */
188942ba996SJean-Christophe PLAGNIOL-VILLARD 			if (tmp & I2C_STAT_XRDY) {
189*e8459dccSVitaly Andrianov 				REG(&(i2c_base->i2c_dxr)) = (addr >> 8) & 0xff;
190942ba996SJean-Christophe PLAGNIOL-VILLARD 			} else {
191*e8459dccSVitaly Andrianov 				REG(&(i2c_base->i2c_con)) = 0;
192*e8459dccSVitaly Andrianov 				return 1;
193942ba996SJean-Christophe PLAGNIOL-VILLARD 			}
194942ba996SJean-Christophe PLAGNIOL-VILLARD 
195*e8459dccSVitaly Andrianov 			tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK);
196942ba996SJean-Christophe PLAGNIOL-VILLARD 
197942ba996SJean-Christophe PLAGNIOL-VILLARD 			CHECK_NACK();
198942ba996SJean-Christophe PLAGNIOL-VILLARD 			/* No break, fall through */
199942ba996SJean-Christophe PLAGNIOL-VILLARD 		case 1:
200942ba996SJean-Christophe PLAGNIOL-VILLARD 			/* Send address LSByte */
201942ba996SJean-Christophe PLAGNIOL-VILLARD 			if (tmp & I2C_STAT_XRDY) {
202*e8459dccSVitaly Andrianov 				REG(&(i2c_base->i2c_dxr)) = addr & 0xff;
203942ba996SJean-Christophe PLAGNIOL-VILLARD 			} else {
204*e8459dccSVitaly Andrianov 				REG(&(i2c_base->i2c_con)) = 0;
205*e8459dccSVitaly Andrianov 				return 1;
206942ba996SJean-Christophe PLAGNIOL-VILLARD 			}
207942ba996SJean-Christophe PLAGNIOL-VILLARD 
208*e8459dccSVitaly Andrianov 			tmp = poll_i2c_irq(adap, I2C_STAT_XRDY |
209*e8459dccSVitaly Andrianov 					   I2C_STAT_NACK | I2C_STAT_ARDY);
210942ba996SJean-Christophe PLAGNIOL-VILLARD 
211942ba996SJean-Christophe PLAGNIOL-VILLARD 			CHECK_NACK();
212942ba996SJean-Christophe PLAGNIOL-VILLARD 
213942ba996SJean-Christophe PLAGNIOL-VILLARD 			if (!(tmp & I2C_STAT_ARDY)) {
214*e8459dccSVitaly Andrianov 				REG(&(i2c_base->i2c_con)) = 0;
215*e8459dccSVitaly Andrianov 				return 1;
216942ba996SJean-Christophe PLAGNIOL-VILLARD 			}
217942ba996SJean-Christophe PLAGNIOL-VILLARD 		}
218942ba996SJean-Christophe PLAGNIOL-VILLARD 	}
219942ba996SJean-Christophe PLAGNIOL-VILLARD 
220942ba996SJean-Christophe PLAGNIOL-VILLARD 	/* Address phase is over, now read 'len' bytes and stop */
221942ba996SJean-Christophe PLAGNIOL-VILLARD 	tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP;
222*e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_cnt)) = len & 0xffff;
223*e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_sa)) = chip;
224*e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_con)) = tmp;
225942ba996SJean-Christophe PLAGNIOL-VILLARD 
226942ba996SJean-Christophe PLAGNIOL-VILLARD 	for (i = 0; i < len; i++) {
227*e8459dccSVitaly Andrianov 		tmp = poll_i2c_irq(adap, I2C_STAT_RRDY | I2C_STAT_NACK |
228*e8459dccSVitaly Andrianov 				   I2C_STAT_ROVR);
229942ba996SJean-Christophe PLAGNIOL-VILLARD 
230942ba996SJean-Christophe PLAGNIOL-VILLARD 		CHECK_NACK();
231942ba996SJean-Christophe PLAGNIOL-VILLARD 
232942ba996SJean-Christophe PLAGNIOL-VILLARD 		if (tmp & I2C_STAT_RRDY) {
233*e8459dccSVitaly Andrianov 			buf[i] = REG(&(i2c_base->i2c_drr));
234942ba996SJean-Christophe PLAGNIOL-VILLARD 		} else {
235*e8459dccSVitaly Andrianov 			REG(&(i2c_base->i2c_con)) = 0;
236*e8459dccSVitaly Andrianov 			return 1;
237942ba996SJean-Christophe PLAGNIOL-VILLARD 		}
238942ba996SJean-Christophe PLAGNIOL-VILLARD 	}
239942ba996SJean-Christophe PLAGNIOL-VILLARD 
240*e8459dccSVitaly Andrianov 	tmp = poll_i2c_irq(adap, I2C_STAT_SCD | I2C_STAT_NACK);
241942ba996SJean-Christophe PLAGNIOL-VILLARD 
242942ba996SJean-Christophe PLAGNIOL-VILLARD 	CHECK_NACK();
243942ba996SJean-Christophe PLAGNIOL-VILLARD 
244942ba996SJean-Christophe PLAGNIOL-VILLARD 	if (!(tmp & I2C_STAT_SCD)) {
245*e8459dccSVitaly Andrianov 		REG(&(i2c_base->i2c_con)) = 0;
246*e8459dccSVitaly Andrianov 		return 1;
247942ba996SJean-Christophe PLAGNIOL-VILLARD 	}
248942ba996SJean-Christophe PLAGNIOL-VILLARD 
249*e8459dccSVitaly Andrianov 	flush_rx(adap);
250*e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_stat)) = 0xffff;
251*e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_cnt)) = 0;
252*e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_con)) = 0;
253942ba996SJean-Christophe PLAGNIOL-VILLARD 
254*e8459dccSVitaly Andrianov 	return 0;
255942ba996SJean-Christophe PLAGNIOL-VILLARD }
256942ba996SJean-Christophe PLAGNIOL-VILLARD 
257*e8459dccSVitaly Andrianov static int davinci_i2c_write(struct i2c_adapter *adap, uint8_t chip,
258*e8459dccSVitaly Andrianov 				uint32_t addr, int alen, uint8_t *buf, int len)
259942ba996SJean-Christophe PLAGNIOL-VILLARD {
260*e8459dccSVitaly Andrianov 	struct i2c_regs *i2c_base = davinci_get_base(adap);
261*e8459dccSVitaly Andrianov 	uint32_t	tmp;
262942ba996SJean-Christophe PLAGNIOL-VILLARD 	int		i;
263942ba996SJean-Christophe PLAGNIOL-VILLARD 
264942ba996SJean-Christophe PLAGNIOL-VILLARD 	if ((alen < 0) || (alen > 2)) {
265*e8459dccSVitaly Andrianov 		printf("%s(): bogus address length %x\n", __func__, alen);
266*e8459dccSVitaly Andrianov 		return 1;
267942ba996SJean-Christophe PLAGNIOL-VILLARD 	}
268942ba996SJean-Christophe PLAGNIOL-VILLARD 	if (len < 0) {
269*e8459dccSVitaly Andrianov 		printf("%s(): bogus length %x\n", __func__, len);
270*e8459dccSVitaly Andrianov 		return 1;
271942ba996SJean-Christophe PLAGNIOL-VILLARD 	}
272942ba996SJean-Christophe PLAGNIOL-VILLARD 
273*e8459dccSVitaly Andrianov 	if (wait_for_bus(adap))
274*e8459dccSVitaly Andrianov 		return 1;
275942ba996SJean-Christophe PLAGNIOL-VILLARD 
276942ba996SJean-Christophe PLAGNIOL-VILLARD 	/* Start address phase */
277*e8459dccSVitaly Andrianov 	tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT |
278*e8459dccSVitaly Andrianov 		I2C_CON_TRX | I2C_CON_STP;
279*e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_cnt)) = (alen == 0) ?
280*e8459dccSVitaly Andrianov 		len & 0xffff : (len & 0xffff) + alen;
281*e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_sa)) = chip;
282*e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_con)) = tmp;
283942ba996SJean-Christophe PLAGNIOL-VILLARD 
284942ba996SJean-Christophe PLAGNIOL-VILLARD 	switch (alen) {
285942ba996SJean-Christophe PLAGNIOL-VILLARD 	case 2:
286942ba996SJean-Christophe PLAGNIOL-VILLARD 		/* Send address MSByte */
287*e8459dccSVitaly Andrianov 		tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK);
288942ba996SJean-Christophe PLAGNIOL-VILLARD 
289942ba996SJean-Christophe PLAGNIOL-VILLARD 		CHECK_NACK();
290942ba996SJean-Christophe PLAGNIOL-VILLARD 
291942ba996SJean-Christophe PLAGNIOL-VILLARD 		if (tmp & I2C_STAT_XRDY) {
292*e8459dccSVitaly Andrianov 			REG(&(i2c_base->i2c_dxr)) = (addr >> 8) & 0xff;
293942ba996SJean-Christophe PLAGNIOL-VILLARD 		} else {
294*e8459dccSVitaly Andrianov 			REG(&(i2c_base->i2c_con)) = 0;
295*e8459dccSVitaly Andrianov 			return 1;
296942ba996SJean-Christophe PLAGNIOL-VILLARD 		}
297942ba996SJean-Christophe PLAGNIOL-VILLARD 		/* No break, fall through */
298942ba996SJean-Christophe PLAGNIOL-VILLARD 	case 1:
299942ba996SJean-Christophe PLAGNIOL-VILLARD 		/* Send address LSByte */
300*e8459dccSVitaly Andrianov 		tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK);
301942ba996SJean-Christophe PLAGNIOL-VILLARD 
302942ba996SJean-Christophe PLAGNIOL-VILLARD 		CHECK_NACK();
303942ba996SJean-Christophe PLAGNIOL-VILLARD 
304942ba996SJean-Christophe PLAGNIOL-VILLARD 		if (tmp & I2C_STAT_XRDY) {
305*e8459dccSVitaly Andrianov 			REG(&(i2c_base->i2c_dxr)) = addr & 0xff;
306942ba996SJean-Christophe PLAGNIOL-VILLARD 		} else {
307*e8459dccSVitaly Andrianov 			REG(&(i2c_base->i2c_con)) = 0;
308*e8459dccSVitaly Andrianov 			return 1;
309942ba996SJean-Christophe PLAGNIOL-VILLARD 		}
310942ba996SJean-Christophe PLAGNIOL-VILLARD 	}
311942ba996SJean-Christophe PLAGNIOL-VILLARD 
312942ba996SJean-Christophe PLAGNIOL-VILLARD 	for (i = 0; i < len; i++) {
313*e8459dccSVitaly Andrianov 		tmp = poll_i2c_irq(adap, I2C_STAT_XRDY | I2C_STAT_NACK);
314942ba996SJean-Christophe PLAGNIOL-VILLARD 
315942ba996SJean-Christophe PLAGNIOL-VILLARD 		CHECK_NACK();
316942ba996SJean-Christophe PLAGNIOL-VILLARD 
317*e8459dccSVitaly Andrianov 		if (tmp & I2C_STAT_XRDY)
318*e8459dccSVitaly Andrianov 			REG(&(i2c_base->i2c_dxr)) = buf[i];
319*e8459dccSVitaly Andrianov 		else
320*e8459dccSVitaly Andrianov 			return 1;
321942ba996SJean-Christophe PLAGNIOL-VILLARD 	}
322942ba996SJean-Christophe PLAGNIOL-VILLARD 
323*e8459dccSVitaly Andrianov 	tmp = poll_i2c_irq(adap, I2C_STAT_SCD | I2C_STAT_NACK);
324942ba996SJean-Christophe PLAGNIOL-VILLARD 
325942ba996SJean-Christophe PLAGNIOL-VILLARD 	CHECK_NACK();
326942ba996SJean-Christophe PLAGNIOL-VILLARD 
327942ba996SJean-Christophe PLAGNIOL-VILLARD 	if (!(tmp & I2C_STAT_SCD)) {
328*e8459dccSVitaly Andrianov 		REG(&(i2c_base->i2c_con)) = 0;
329*e8459dccSVitaly Andrianov 		return 1;
330942ba996SJean-Christophe PLAGNIOL-VILLARD 	}
331942ba996SJean-Christophe PLAGNIOL-VILLARD 
332*e8459dccSVitaly Andrianov 	flush_rx(adap);
333*e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_stat)) = 0xffff;
334*e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_cnt)) = 0;
335*e8459dccSVitaly Andrianov 	REG(&(i2c_base->i2c_con)) = 0;
336942ba996SJean-Christophe PLAGNIOL-VILLARD 
337*e8459dccSVitaly Andrianov 	return 0;
338942ba996SJean-Christophe PLAGNIOL-VILLARD }
339*e8459dccSVitaly Andrianov 
340*e8459dccSVitaly Andrianov static struct i2c_regs *davinci_get_base(struct i2c_adapter *adap)
341*e8459dccSVitaly Andrianov {
342*e8459dccSVitaly Andrianov 	switch (adap->hwadapnr) {
343*e8459dccSVitaly Andrianov #if I2C_BUS_MAX >= 3
344*e8459dccSVitaly Andrianov 	case 2:
345*e8459dccSVitaly Andrianov 		return (struct i2c_regs *)I2C2_BASE;
346*e8459dccSVitaly Andrianov #endif
347*e8459dccSVitaly Andrianov #if I2C_BUS_MAX >= 2
348*e8459dccSVitaly Andrianov 	case 1:
349*e8459dccSVitaly Andrianov 		return (struct i2c_regs *)I2C1_BASE;
350*e8459dccSVitaly Andrianov #endif
351*e8459dccSVitaly Andrianov 	case 0:
352*e8459dccSVitaly Andrianov 		return (struct i2c_regs *)I2C_BASE;
353*e8459dccSVitaly Andrianov 
354*e8459dccSVitaly Andrianov 	default:
355*e8459dccSVitaly Andrianov 		printf("wrong hwadapnr: %d\n", adap->hwadapnr);
356*e8459dccSVitaly Andrianov 	}
357*e8459dccSVitaly Andrianov 
358*e8459dccSVitaly Andrianov 	return NULL;
359*e8459dccSVitaly Andrianov }
360*e8459dccSVitaly Andrianov 
361*e8459dccSVitaly Andrianov U_BOOT_I2C_ADAP_COMPLETE(davinci_0, davinci_i2c_init, davinci_i2c_probe,
362*e8459dccSVitaly Andrianov 			 davinci_i2c_read, davinci_i2c_write,
363*e8459dccSVitaly Andrianov 			 davinci_i2c_setspeed,
364*e8459dccSVitaly Andrianov 			 CONFIG_SYS_DAVINCI_I2C_SPEED,
365*e8459dccSVitaly Andrianov 			 CONFIG_SYS_DAVINCI_I2C_SLAVE,
366*e8459dccSVitaly Andrianov 			 0)
367*e8459dccSVitaly Andrianov 
368*e8459dccSVitaly Andrianov #if I2C_BUS_MAX >= 2
369*e8459dccSVitaly Andrianov U_BOOT_I2C_ADAP_COMPLETE(davinci_1, davinci_i2c_init, davinci_i2c_probe,
370*e8459dccSVitaly Andrianov 			 davinci_i2c_read, davinci_i2c_write,
371*e8459dccSVitaly Andrianov 			 davinci_i2c_setspeed,
372*e8459dccSVitaly Andrianov 			 CONFIG_SYS_DAVINCI_I2C_SPEED1,
373*e8459dccSVitaly Andrianov 			 CONFIG_SYS_DAVINCI_I2C_SLAVE1,
374*e8459dccSVitaly Andrianov 			 1)
375*e8459dccSVitaly Andrianov #endif
376*e8459dccSVitaly Andrianov 
377*e8459dccSVitaly Andrianov #if I2C_BUS_MAX >= 3
378*e8459dccSVitaly Andrianov U_BOOT_I2C_ADAP_COMPLETE(davinci_2, davinci_i2c_init, davinci_i2c_probe,
379*e8459dccSVitaly Andrianov 			 davinci_i2c_read, davinci_i2c_write,
380*e8459dccSVitaly Andrianov 			 davinci_i2c_setspeed,
381*e8459dccSVitaly Andrianov 			 CONFIG_SYS_DAVINCI_I2C_SPEED2,
382*e8459dccSVitaly Andrianov 			 CONFIG_SYS_DAVINCI_I2C_SLAVE2,
383*e8459dccSVitaly Andrianov 			 2)
384*e8459dccSVitaly Andrianov #endif
385