xref: /openbmc/u-boot/drivers/i2c/omap24xx_i2c.c (revision 7d9b5bae)
1 /*
2  * Basic I2C functions
3  *
4  * Copyright (c) 2004 Texas Instruments
5  *
6  * This package is free software;  you can redistribute it and/or
7  * modify it under the terms of the license found in the file
8  * named COPYING that should have accompanied this file.
9  *
10  * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
11  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
12  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13  *
14  * Author: Jian Zhang jzhang@ti.com, Texas Instruments
15  *
16  * Copyright (c) 2003 Wolfgang Denk, wd@denx.de
17  * Rewritten to fit into the current U-Boot framework
18  *
19  * Adapted for OMAP2420 I2C, r-woodruff2@ti.com
20  *
21  */
22 
23 #include <common.h>
24 
25 #include <asm/arch/i2c.h>
26 #include <asm/io.h>
27 
28 #define inw(a) __raw_readw(a)
29 #define outw(a,v) __raw_writew(a,v)
30 
31 static void wait_for_bb (void);
32 static u16 wait_for_pin (void);
33 static void flush_fifo(void);
34 
35 void i2c_init (int speed, int slaveadd)
36 {
37 	u16 scl;
38 
39 	outw(0x2, I2C_SYSC); /* for ES2 after soft reset */
40 	udelay(1000);
41 	outw(0x0, I2C_SYSC); /* will probably self clear but */
42 
43 	if (inw (I2C_CON) & I2C_CON_EN) {
44 		outw (0, I2C_CON);
45 		udelay (50000);
46 	}
47 
48 	/* 12Mhz I2C module clock */
49 	outw (0, I2C_PSC);
50 	speed = speed/1000;		    /* 100 or 400 */
51 	scl = ((12000/(speed*2)) - 7);	/* use 7 when PSC = 0 */
52 	outw (scl, I2C_SCLL);
53 	outw (scl, I2C_SCLH);
54 	/* own address */
55 	outw (slaveadd, I2C_OA);
56 	outw (I2C_CON_EN, I2C_CON);
57 
58 	/* have to enable intrrupts or OMAP i2c module doesn't work */
59 	outw (I2C_IE_XRDY_IE | I2C_IE_RRDY_IE | I2C_IE_ARDY_IE |
60 	      I2C_IE_NACK_IE | I2C_IE_AL_IE, I2C_IE);
61 	udelay (1000);
62 	flush_fifo();
63 	outw (0xFFFF, I2C_STAT);
64 	outw (0, I2C_CNT);
65 }
66 
67 static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value)
68 {
69 	int i2c_error = 0;
70 	u16 status;
71 
72 	/* wait until bus not busy */
73 	wait_for_bb ();
74 
75 	/* one byte only */
76 	outw (1, I2C_CNT);
77 	/* set slave address */
78 	outw (devaddr, I2C_SA);
79 	/* no stop bit needed here */
80 	outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX, I2C_CON);
81 
82 	status = wait_for_pin ();
83 
84 	if (status & I2C_STAT_XRDY) {
85 		/* Important: have to use byte access */
86 		*(volatile u8 *) (I2C_DATA) = regoffset;
87 		udelay (20000);
88 		if (inw (I2C_STAT) & I2C_STAT_NACK) {
89 			i2c_error = 1;
90 		}
91 	} else {
92 		i2c_error = 1;
93 	}
94 
95 	if (!i2c_error) {
96 		/* free bus, otherwise we can't use a combined transction */
97 		outw (0, I2C_CON);
98 		while (inw (I2C_STAT) || (inw (I2C_CON) & I2C_CON_MST)) {
99 			udelay (10000);
100 			/* Have to clear pending interrupt to clear I2C_STAT */
101 			outw (0xFFFF, I2C_STAT);
102 		}
103 
104 		wait_for_bb ();
105 		/* set slave address */
106 		outw (devaddr, I2C_SA);
107 		/* read one byte from slave */
108 		outw (1, I2C_CNT);
109 		/* need stop bit here */
110 		outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP,
111 		      I2C_CON);
112 
113 		status = wait_for_pin ();
114 		if (status & I2C_STAT_RRDY) {
115 			*value = inw (I2C_DATA);
116 			udelay (20000);
117 		} else {
118 			i2c_error = 1;
119 		}
120 
121 		if (!i2c_error) {
122 			outw (I2C_CON_EN, I2C_CON);
123 			while (inw (I2C_STAT)
124 			       || (inw (I2C_CON) & I2C_CON_MST)) {
125 				udelay (10000);
126 				outw (0xFFFF, I2C_STAT);
127 			}
128 		}
129 	}
130 	flush_fifo();
131 	outw (0xFFFF, I2C_STAT);
132 	outw (0, I2C_CNT);
133 	return i2c_error;
134 }
135 
136 static int i2c_write_byte (u8 devaddr, u8 regoffset, u8 value)
137 {
138 	int i2c_error = 0;
139 	u16 status, stat;
140 
141 	/* wait until bus not busy */
142 	wait_for_bb ();
143 
144 	/* two bytes */
145 	outw (2, I2C_CNT);
146 	/* set slave address */
147 	outw (devaddr, I2C_SA);
148 	/* stop bit needed here */
149 	outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
150 	      I2C_CON_STP, I2C_CON);
151 
152 	/* wait until state change */
153 	status = wait_for_pin ();
154 
155 	if (status & I2C_STAT_XRDY) {
156 		/* send out two bytes */
157 		outw ((value << 8) + regoffset, I2C_DATA);
158 		/* must have enough delay to allow BB bit to go low */
159 		udelay (50000);
160 		if (inw (I2C_STAT) & I2C_STAT_NACK) {
161 			i2c_error = 1;
162 		}
163 	} else {
164 		i2c_error = 1;
165 	}
166 
167 	if (!i2c_error) {
168 		int eout = 200;
169 
170 		outw (I2C_CON_EN, I2C_CON);
171 		while ((stat = inw (I2C_STAT)) || (inw (I2C_CON) & I2C_CON_MST)) {
172 			udelay (1000);
173 			/* have to read to clear intrrupt */
174 			outw (0xFFFF, I2C_STAT);
175 			if(--eout == 0) /* better leave with error than hang */
176 				break;
177 		}
178 	}
179 	flush_fifo();
180 	outw (0xFFFF, I2C_STAT);
181 	outw (0, I2C_CNT);
182 	return i2c_error;
183 }
184 
185 static void flush_fifo(void)
186 {	u16 stat;
187 
188 	/* note: if you try and read data when its not there or ready
189 	 * you get a bus error
190 	 */
191 	while(1){
192 		stat = inw(I2C_STAT);
193 		if(stat == I2C_STAT_RRDY){
194 			inw(I2C_DATA);
195 			outw(I2C_STAT_RRDY,I2C_STAT);
196 			udelay(1000);
197 		}else
198 			break;
199 	}
200 }
201 
202 int i2c_probe (uchar chip)
203 {
204 	int res = 1; /* default = fail */
205 
206 	if (chip == inw (I2C_OA)) {
207 		return res;
208 	}
209 
210 	/* wait until bus not busy */
211 	wait_for_bb ();
212 
213 	/* try to read one byte */
214 	outw (1, I2C_CNT);
215 	/* set slave address */
216 	outw (chip, I2C_SA);
217 	/* stop bit needed here */
218 	outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, I2C_CON);
219 	/* enough delay for the NACK bit set */
220 	udelay (50000);
221 
222 	if (!(inw (I2C_STAT) & I2C_STAT_NACK)) {
223 		res = 0;      /* success case */
224 		flush_fifo();
225 		outw(0xFFFF, I2C_STAT);
226 	} else {
227 		outw(0xFFFF, I2C_STAT);	 /* failue, clear sources*/
228 		outw (inw (I2C_CON) | I2C_CON_STP, I2C_CON); /* finish up xfer */
229 		udelay(20000);
230 		wait_for_bb ();
231 	}
232 	flush_fifo();
233 	outw (0, I2C_CNT); /* don't allow any more data in...we don't want it.*/
234 	outw(0xFFFF, I2C_STAT);
235 	return res;
236 }
237 
238 int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len)
239 {
240 	int i;
241 
242 	if (alen > 1) {
243 		printf ("I2C read: addr len %d not supported\n", alen);
244 		return 1;
245 	}
246 
247 	if (addr + len > 256) {
248 		printf ("I2C read: address out of range\n");
249 		return 1;
250 	}
251 
252 	for (i = 0; i < len; i++) {
253 		if (i2c_read_byte (chip, addr + i, &buffer[i])) {
254 			printf ("I2C read: I/O error\n");
255 			i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
256 			return 1;
257 		}
258 	}
259 
260 	return 0;
261 }
262 
263 int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len)
264 {
265 	int i;
266 
267 	if (alen > 1) {
268 		printf ("I2C read: addr len %d not supported\n", alen);
269 		return 1;
270 	}
271 
272 	if (addr + len > 256) {
273 		printf ("I2C read: address out of range\n");
274 		return 1;
275 	}
276 
277 	for (i = 0; i < len; i++) {
278 		if (i2c_write_byte (chip, addr + i, buffer[i])) {
279 			printf ("I2C read: I/O error\n");
280 			i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
281 			return 1;
282 		}
283 	}
284 
285 	return 0;
286 }
287 
288 static void wait_for_bb (void)
289 {
290 	int timeout = 10;
291 	u16 stat;
292 
293 	outw(0xFFFF, I2C_STAT);	 /* clear current interruts...*/
294 	while ((stat = inw (I2C_STAT) & I2C_STAT_BB) && timeout--) {
295 		outw (stat, I2C_STAT);
296 		udelay (50000);
297 	}
298 
299 	if (timeout <= 0) {
300 		printf ("timed out in wait_for_bb: I2C_STAT=%x\n",
301 			inw (I2C_STAT));
302 	}
303 	outw(0xFFFF, I2C_STAT);	 /* clear delayed stuff*/
304 }
305 
306 static u16 wait_for_pin (void)
307 {
308 	u16 status;
309 	int timeout = 10;
310 
311 	do {
312 		udelay (1000);
313 		status = inw (I2C_STAT);
314 	} while (  !(status &
315 		   (I2C_STAT_ROVR | I2C_STAT_XUDF | I2C_STAT_XRDY |
316 		    I2C_STAT_RRDY | I2C_STAT_ARDY | I2C_STAT_NACK |
317 		    I2C_STAT_AL)) && timeout--);
318 
319 	if (timeout <= 0) {
320 		printf ("timed out in wait_for_pin: I2C_STAT=%x\n",
321 			inw (I2C_STAT));
322 			outw(0xFFFF, I2C_STAT);
323 }
324 	return status;
325 }
326