]>
Commit | Line | Data |
---|---|---|
8ed96046 WD |
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 | * | |
960187ff LP |
21 | * Copyright (c) 2013 Lubomir Popov <lpopov@mm-sol.com>, MM Solutions |
22 | * New i2c_read, i2c_write and i2c_probe functions, tested on OMAP4 | |
23 | * (4430/60/70), OMAP5 (5430) and AM335X (3359); should work on older | |
24 | * OMAPs and derivatives as well. The only anticipated exception would | |
25 | * be the OMAP2420, which shall require driver modification. | |
26 | * - Rewritten i2c_read to operate correctly with all types of chips | |
27 | * (old function could not read consistent data from some I2C slaves). | |
28 | * - Optimized i2c_write. | |
29 | * - New i2c_probe, performs write access vs read. The old probe could | |
30 | * hang the system under certain conditions (e.g. unconfigured pads). | |
31 | * - The read/write/probe functions try to identify unconfigured bus. | |
32 | * - Status functions now read irqstatus_raw as per TRM guidelines | |
33 | * (except for OMAP243X and OMAP34XX). | |
34 | * - Driver now supports up to I2C5 (OMAP5). | |
d5243359 | 35 | * |
4c302b9a | 36 | * Copyright (c) 2014 Hannes Schmelzer <oe5hpm@oevsv.at>, B&R |
d5243359 HP |
37 | * - Added support for set_speed |
38 | * | |
8ed96046 WD |
39 | */ |
40 | ||
41 | #include <common.h> | |
6789e84e | 42 | #include <i2c.h> |
289f932c | 43 | |
8ed96046 WD |
44 | #include <asm/arch/i2c.h> |
45 | #include <asm/io.h> | |
46 | ||
938717ce SS |
47 | #include "omap24xx_i2c.h" |
48 | ||
29565326 JR |
49 | DECLARE_GLOBAL_DATA_PTR; |
50 | ||
cec487a4 | 51 | #define I2C_TIMEOUT 1000 |
d708395d | 52 | |
960187ff LP |
53 | /* Absolutely safe for status update at 100 kHz I2C: */ |
54 | #define I2C_WAIT 200 | |
55 | ||
6789e84e HS |
56 | static int wait_for_bb(struct i2c_adapter *adap); |
57 | static struct i2c *omap24_get_base(struct i2c_adapter *adap); | |
58 | static u16 wait_for_event(struct i2c_adapter *adap); | |
59 | static void flush_fifo(struct i2c_adapter *adap); | |
d5243359 | 60 | static int omap24_i2c_findpsc(u32 *pscl, u32 *psch, uint speed) |
8ed96046 | 61 | { |
d5243359 HP |
62 | unsigned int sampleclk, prescaler; |
63 | int fsscll, fssclh; | |
7f79dfb4 | 64 | |
d5243359 HP |
65 | speed <<= 1; |
66 | prescaler = 0; | |
67 | /* | |
68 | * some divisors may cause a precission loss, but shouldn't | |
69 | * be a big thing, because i2c_clk is then allready very slow. | |
70 | */ | |
71 | while (prescaler <= 0xFF) { | |
72 | sampleclk = I2C_IP_CLK / (prescaler+1); | |
7f79dfb4 | 73 | |
d5243359 HP |
74 | fsscll = sampleclk / speed; |
75 | fssclh = fsscll; | |
76 | fsscll -= I2C_FASTSPEED_SCLL_TRIM; | |
77 | fssclh -= I2C_FASTSPEED_SCLH_TRIM; | |
78 | ||
79 | if (((fsscll > 0) && (fssclh > 0)) && | |
80 | ((fsscll <= (255-I2C_FASTSPEED_SCLL_TRIM)) && | |
81 | (fssclh <= (255-I2C_FASTSPEED_SCLH_TRIM)))) { | |
82 | if (pscl) | |
83 | *pscl = fsscll; | |
84 | if (psch) | |
85 | *psch = fssclh; | |
86 | ||
87 | return prescaler; | |
88 | } | |
89 | prescaler++; | |
7f79dfb4 | 90 | } |
d5243359 HP |
91 | return -1; |
92 | } | |
93 | static uint omap24_i2c_setspeed(struct i2c_adapter *adap, uint speed) | |
94 | { | |
95 | struct i2c *i2c_base = omap24_get_base(adap); | |
96 | int psc, fsscll = 0, fssclh = 0; | |
97 | int hsscll = 0, hssclh = 0; | |
98 | u32 scll = 0, sclh = 0; | |
7f79dfb4 | 99 | |
d5243359 | 100 | if (speed >= OMAP_I2C_HIGH_SPEED) { |
7f79dfb4 | 101 | /* High speed */ |
d5243359 HP |
102 | psc = I2C_IP_CLK / I2C_INTERNAL_SAMPLING_CLK; |
103 | psc -= 1; | |
104 | if (psc < I2C_PSC_MIN) { | |
105 | printf("Error : I2C unsupported prescaler %d\n", psc); | |
106 | return -1; | |
107 | } | |
7f79dfb4 TR |
108 | |
109 | /* For first phase of HS mode */ | |
d5243359 HP |
110 | fsscll = I2C_INTERNAL_SAMPLING_CLK / (2 * speed); |
111 | ||
112 | fssclh = fsscll; | |
7f79dfb4 TR |
113 | |
114 | fsscll -= I2C_HIGHSPEED_PHASE_ONE_SCLL_TRIM; | |
115 | fssclh -= I2C_HIGHSPEED_PHASE_ONE_SCLH_TRIM; | |
116 | if (((fsscll < 0) || (fssclh < 0)) || | |
117 | ((fsscll > 255) || (fssclh > 255))) { | |
49e9b4bd | 118 | puts("Error : I2C initializing first phase clock\n"); |
d5243359 | 119 | return -1; |
7f79dfb4 TR |
120 | } |
121 | ||
122 | /* For second phase of HS mode */ | |
123 | hsscll = hssclh = I2C_INTERNAL_SAMPLING_CLK / (2 * speed); | |
124 | ||
125 | hsscll -= I2C_HIGHSPEED_PHASE_TWO_SCLL_TRIM; | |
126 | hssclh -= I2C_HIGHSPEED_PHASE_TWO_SCLH_TRIM; | |
127 | if (((fsscll < 0) || (fssclh < 0)) || | |
128 | ((fsscll > 255) || (fssclh > 255))) { | |
49e9b4bd | 129 | puts("Error : I2C initializing second phase clock\n"); |
d5243359 | 130 | return -1; |
7f79dfb4 TR |
131 | } |
132 | ||
133 | scll = (unsigned int)hsscll << 8 | (unsigned int)fsscll; | |
134 | sclh = (unsigned int)hssclh << 8 | (unsigned int)fssclh; | |
135 | ||
136 | } else { | |
137 | /* Standard and fast speed */ | |
d5243359 HP |
138 | psc = omap24_i2c_findpsc(&scll, &sclh, speed); |
139 | if (0 > psc) { | |
49e9b4bd | 140 | puts("Error : I2C initializing clock\n"); |
d5243359 | 141 | return -1; |
7f79dfb4 | 142 | } |
7f79dfb4 | 143 | } |
8ed96046 | 144 | |
d5243359 HP |
145 | adap->speed = speed; |
146 | adap->waitdelay = (10000000 / speed) * 2; /* wait for 20 clkperiods */ | |
147 | writew(0, &i2c_base->con); | |
148 | writew(psc, &i2c_base->psc); | |
149 | writew(scll, &i2c_base->scll); | |
150 | writew(sclh, &i2c_base->sclh); | |
151 | writew(I2C_CON_EN, &i2c_base->con); | |
152 | writew(0xFFFF, &i2c_base->stat); /* clear all pending status */ | |
153 | ||
154 | return 0; | |
155 | } | |
f7c10535 HS |
156 | |
157 | static void omap24_i2c_deblock(struct i2c_adapter *adap) | |
158 | { | |
159 | struct i2c *i2c_base = omap24_get_base(adap); | |
160 | int i; | |
161 | u16 systest; | |
162 | u16 orgsystest; | |
163 | ||
164 | /* set test mode ST_EN = 1 */ | |
165 | orgsystest = readw(&i2c_base->systest); | |
166 | systest = orgsystest; | |
167 | /* enable testmode */ | |
168 | systest |= I2C_SYSTEST_ST_EN; | |
169 | writew(systest, &i2c_base->systest); | |
170 | systest &= ~I2C_SYSTEST_TMODE_MASK; | |
171 | systest |= 3 << I2C_SYSTEST_TMODE_SHIFT; | |
172 | writew(systest, &i2c_base->systest); | |
173 | ||
174 | /* set SCL, SDA = 1 */ | |
175 | systest |= I2C_SYSTEST_SCL_O | I2C_SYSTEST_SDA_O; | |
176 | writew(systest, &i2c_base->systest); | |
177 | udelay(10); | |
178 | ||
179 | /* toggle scl 9 clocks */ | |
180 | for (i = 0; i < 9; i++) { | |
181 | /* SCL = 0 */ | |
182 | systest &= ~I2C_SYSTEST_SCL_O; | |
183 | writew(systest, &i2c_base->systest); | |
184 | udelay(10); | |
185 | /* SCL = 1 */ | |
186 | systest |= I2C_SYSTEST_SCL_O; | |
187 | writew(systest, &i2c_base->systest); | |
188 | udelay(10); | |
189 | } | |
190 | ||
191 | /* send stop */ | |
192 | systest &= ~I2C_SYSTEST_SDA_O; | |
193 | writew(systest, &i2c_base->systest); | |
194 | udelay(10); | |
195 | systest |= I2C_SYSTEST_SCL_O | I2C_SYSTEST_SDA_O; | |
196 | writew(systest, &i2c_base->systest); | |
197 | udelay(10); | |
198 | ||
199 | /* restore original mode */ | |
200 | writew(orgsystest, &i2c_base->systest); | |
201 | } | |
202 | ||
d5243359 HP |
203 | static void omap24_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) |
204 | { | |
205 | struct i2c *i2c_base = omap24_get_base(adap); | |
206 | int timeout = I2C_TIMEOUT; | |
f7c10535 | 207 | int deblock = 1; |
d5243359 | 208 | |
f7c10535 | 209 | retry: |
89677b27 MJ |
210 | if (readw(&i2c_base->con) & I2C_CON_EN) { |
211 | writew(0, &i2c_base->con); | |
212 | udelay(50000); | |
8ed96046 WD |
213 | } |
214 | ||
cec487a4 TR |
215 | writew(0x2, &i2c_base->sysc); /* for ES2 after soft reset */ |
216 | udelay(1000); | |
217 | ||
218 | writew(I2C_CON_EN, &i2c_base->con); | |
219 | while (!(readw(&i2c_base->syss) & I2C_SYSS_RDONE) && timeout--) { | |
220 | if (timeout <= 0) { | |
221 | puts("ERROR: Timeout in soft-reset\n"); | |
222 | return; | |
223 | } | |
224 | udelay(1000); | |
225 | } | |
226 | ||
d5243359 HP |
227 | if (0 != omap24_i2c_setspeed(adap, speed)) { |
228 | printf("ERROR: failed to setup I2C bus-speed!\n"); | |
229 | return; | |
230 | } | |
7f79dfb4 | 231 | |
8ed96046 | 232 | /* own address */ |
89677b27 | 233 | writew(slaveadd, &i2c_base->oa); |
d5243359 | 234 | |
960187ff LP |
235 | #if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) |
236 | /* | |
237 | * Have to enable interrupts for OMAP2/3, these IPs don't have | |
238 | * an 'irqstatus_raw' register and we shall have to poll 'stat' | |
239 | */ | |
89677b27 | 240 | writew(I2C_IE_XRDY_IE | I2C_IE_RRDY_IE | I2C_IE_ARDY_IE | |
960187ff LP |
241 | I2C_IE_NACK_IE | I2C_IE_AL_IE, &i2c_base->ie); |
242 | #endif | |
89677b27 | 243 | udelay(1000); |
6789e84e | 244 | flush_fifo(adap); |
89677b27 | 245 | writew(0xFFFF, &i2c_base->stat); |
f7c10535 HS |
246 | |
247 | /* Handle possible failed I2C state */ | |
248 | if (wait_for_bb(adap)) | |
249 | if (deblock == 1) { | |
250 | omap24_i2c_deblock(adap); | |
251 | deblock = 0; | |
252 | goto retry; | |
253 | } | |
cec487a4 TR |
254 | } |
255 | ||
6789e84e HS |
256 | static void flush_fifo(struct i2c_adapter *adap) |
257 | { | |
258 | struct i2c *i2c_base = omap24_get_base(adap); | |
259 | u16 stat; | |
082acfd4 | 260 | |
d5243359 HP |
261 | /* |
262 | * note: if you try and read data when its not there or ready | |
082acfd4 WD |
263 | * you get a bus error |
264 | */ | |
89677b27 | 265 | while (1) { |
1d2e96de | 266 | stat = readw(&i2c_base->stat); |
89677b27 | 267 | if (stat == I2C_STAT_RRDY) { |
1d2e96de | 268 | readb(&i2c_base->data); |
89677b27 | 269 | writew(I2C_STAT_RRDY, &i2c_base->stat); |
8ed96046 | 270 | udelay(1000); |
89677b27 | 271 | } else |
8ed96046 WD |
272 | break; |
273 | } | |
274 | } | |
275 | ||
960187ff LP |
276 | /* |
277 | * i2c_probe: Use write access. Allows to identify addresses that are | |
278 | * write-only (like the config register of dual-port EEPROMs) | |
279 | */ | |
6789e84e | 280 | static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip) |
8ed96046 | 281 | { |
6789e84e | 282 | struct i2c *i2c_base = omap24_get_base(adap); |
cec487a4 | 283 | u16 status; |
8ed96046 WD |
284 | int res = 1; /* default = fail */ |
285 | ||
89677b27 | 286 | if (chip == readw(&i2c_base->oa)) |
8ed96046 | 287 | return res; |
8ed96046 | 288 | |
960187ff | 289 | /* Wait until bus is free */ |
6789e84e | 290 | if (wait_for_bb(adap)) |
febc4cd4 | 291 | return res; |
8ed96046 | 292 | |
960187ff | 293 | /* No data transfer, slave addr only */ |
89677b27 | 294 | writew(chip, &i2c_base->sa); |
960187ff LP |
295 | /* Stop bit needed here */ |
296 | writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | | |
297 | I2C_CON_STP, &i2c_base->con); | |
298 | ||
6789e84e | 299 | status = wait_for_event(adap); |
960187ff LP |
300 | |
301 | if ((status & ~I2C_STAT_XRDY) == 0 || (status & I2C_STAT_AL)) { | |
302 | /* | |
303 | * With current high-level command implementation, notifying | |
304 | * the user shall flood the console with 127 messages. If | |
305 | * silent exit is desired upon unconfigured bus, remove the | |
306 | * following 'if' section: | |
307 | */ | |
308 | if (status == I2C_STAT_XRDY) | |
309 | printf("i2c_probe: pads on bus %d probably not configured (status=0x%x)\n", | |
6789e84e | 310 | adap->hwadapnr, status); |
960187ff LP |
311 | |
312 | goto pr_exit; | |
168a5acb | 313 | } |
cec487a4 | 314 | |
960187ff LP |
315 | /* Check for ACK (!NAK) */ |
316 | if (!(status & I2C_STAT_NACK)) { | |
d5243359 HP |
317 | res = 0; /* Device found */ |
318 | udelay(adap->waitdelay);/* Required by AM335X in SPL */ | |
960187ff LP |
319 | /* Abort transfer (force idle state) */ |
320 | writew(I2C_CON_MST | I2C_CON_TRX, &i2c_base->con); /* Reset */ | |
321 | udelay(1000); | |
322 | writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_TRX | | |
323 | I2C_CON_STP, &i2c_base->con); /* STP */ | |
324 | } | |
325 | pr_exit: | |
6789e84e | 326 | flush_fifo(adap); |
1d2e96de | 327 | writew(0xFFFF, &i2c_base->stat); |
8ed96046 WD |
328 | return res; |
329 | } | |
330 | ||
960187ff LP |
331 | /* |
332 | * i2c_read: Function now uses a single I2C read transaction with bulk transfer | |
333 | * of the requested number of bytes (note that the 'i2c md' command | |
334 | * limits this to 16 bytes anyway). If CONFIG_I2C_REPEATED_START is | |
335 | * defined in the board config header, this transaction shall be with | |
336 | * Repeated Start (Sr) between the address and data phases; otherwise | |
337 | * Stop-Start (P-S) shall be used (some I2C chips do require a P-S). | |
338 | * The address (reg offset) may be 0, 1 or 2 bytes long. | |
339 | * Function now reads correctly from chips that return more than one | |
340 | * byte of data per addressed register (like TI temperature sensors), | |
341 | * or that do not need a register address at all (such as some clock | |
342 | * distributors). | |
343 | */ | |
6789e84e HS |
344 | static int omap24_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, |
345 | int alen, uchar *buffer, int len) | |
8ed96046 | 346 | { |
6789e84e | 347 | struct i2c *i2c_base = omap24_get_base(adap); |
960187ff LP |
348 | int i2c_error = 0; |
349 | u16 status; | |
350 | ||
351 | if (alen < 0) { | |
352 | puts("I2C read: addr len < 0\n"); | |
353 | return 1; | |
354 | } | |
355 | if (len < 0) { | |
356 | puts("I2C read: data len < 0\n"); | |
357 | return 1; | |
358 | } | |
359 | if (buffer == NULL) { | |
360 | puts("I2C read: NULL pointer passed\n"); | |
361 | return 1; | |
362 | } | |
8ed96046 | 363 | |
55faa589 | 364 | if (alen > 2) { |
cec487a4 | 365 | printf("I2C read: addr len %d not supported\n", alen); |
8ed96046 WD |
366 | return 1; |
367 | } | |
368 | ||
55faa589 | 369 | if (addr + len > (1 << 16)) { |
cec487a4 | 370 | puts("I2C read: address out of range\n"); |
8ed96046 WD |
371 | return 1; |
372 | } | |
373 | ||
960187ff | 374 | /* Wait until bus not busy */ |
6789e84e | 375 | if (wait_for_bb(adap)) |
960187ff LP |
376 | return 1; |
377 | ||
378 | /* Zero, one or two bytes reg address (offset) */ | |
379 | writew(alen, &i2c_base->cnt); | |
380 | /* Set slave address */ | |
381 | writew(chip, &i2c_base->sa); | |
382 | ||
383 | if (alen) { | |
384 | /* Must write reg offset first */ | |
385 | #ifdef CONFIG_I2C_REPEATED_START | |
386 | /* No stop bit, use Repeated Start (Sr) */ | |
387 | writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | | |
388 | I2C_CON_TRX, &i2c_base->con); | |
389 | #else | |
390 | /* Stop - Start (P-S) */ | |
391 | writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP | | |
392 | I2C_CON_TRX, &i2c_base->con); | |
393 | #endif | |
394 | /* Send register offset */ | |
395 | while (1) { | |
6789e84e | 396 | status = wait_for_event(adap); |
960187ff LP |
397 | /* Try to identify bus that is not padconf'd for I2C */ |
398 | if (status == I2C_STAT_XRDY) { | |
399 | i2c_error = 2; | |
400 | printf("i2c_read (addr phase): pads on bus %d probably not configured (status=0x%x)\n", | |
6789e84e | 401 | adap->hwadapnr, status); |
960187ff LP |
402 | goto rd_exit; |
403 | } | |
d5243359 | 404 | if (status == 0 || (status & I2C_STAT_NACK)) { |
960187ff LP |
405 | i2c_error = 1; |
406 | printf("i2c_read: error waiting for addr ACK (status=0x%x)\n", | |
407 | status); | |
408 | goto rd_exit; | |
409 | } | |
410 | if (alen) { | |
411 | if (status & I2C_STAT_XRDY) { | |
412 | alen--; | |
413 | /* Do we have to use byte access? */ | |
414 | writeb((addr >> (8 * alen)) & 0xff, | |
415 | &i2c_base->data); | |
416 | writew(I2C_STAT_XRDY, &i2c_base->stat); | |
417 | } | |
418 | } | |
419 | if (status & I2C_STAT_ARDY) { | |
420 | writew(I2C_STAT_ARDY, &i2c_base->stat); | |
421 | break; | |
422 | } | |
8ed96046 WD |
423 | } |
424 | } | |
960187ff LP |
425 | /* Set slave address */ |
426 | writew(chip, &i2c_base->sa); | |
427 | /* Read len bytes from slave */ | |
428 | writew(len, &i2c_base->cnt); | |
429 | /* Need stop bit here */ | |
430 | writew(I2C_CON_EN | I2C_CON_MST | | |
431 | I2C_CON_STT | I2C_CON_STP, | |
432 | &i2c_base->con); | |
8ed96046 | 433 | |
960187ff LP |
434 | /* Receive data */ |
435 | while (1) { | |
6789e84e | 436 | status = wait_for_event(adap); |
960187ff LP |
437 | /* |
438 | * Try to identify bus that is not padconf'd for I2C. This | |
439 | * state could be left over from previous transactions if | |
440 | * the address phase is skipped due to alen=0. | |
441 | */ | |
442 | if (status == I2C_STAT_XRDY) { | |
443 | i2c_error = 2; | |
444 | printf("i2c_read (data phase): pads on bus %d probably not configured (status=0x%x)\n", | |
6789e84e | 445 | adap->hwadapnr, status); |
960187ff LP |
446 | goto rd_exit; |
447 | } | |
d5243359 | 448 | if (status == 0 || (status & I2C_STAT_NACK)) { |
960187ff LP |
449 | i2c_error = 1; |
450 | goto rd_exit; | |
451 | } | |
452 | if (status & I2C_STAT_RRDY) { | |
453 | *buffer++ = readb(&i2c_base->data); | |
454 | writew(I2C_STAT_RRDY, &i2c_base->stat); | |
455 | } | |
456 | if (status & I2C_STAT_ARDY) { | |
457 | writew(I2C_STAT_ARDY, &i2c_base->stat); | |
458 | break; | |
459 | } | |
460 | } | |
461 | ||
462 | rd_exit: | |
6789e84e | 463 | flush_fifo(adap); |
960187ff | 464 | writew(0xFFFF, &i2c_base->stat); |
960187ff | 465 | return i2c_error; |
8ed96046 WD |
466 | } |
467 | ||
960187ff | 468 | /* i2c_write: Address (reg offset) may be 0, 1 or 2 bytes long. */ |
6789e84e HS |
469 | static int omap24_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, |
470 | int alen, uchar *buffer, int len) | |
8ed96046 | 471 | { |
6789e84e | 472 | struct i2c *i2c_base = omap24_get_base(adap); |
cec487a4 TR |
473 | int i; |
474 | u16 status; | |
475 | int i2c_error = 0; | |
d5243359 | 476 | int timeout = I2C_TIMEOUT; |
960187ff LP |
477 | |
478 | if (alen < 0) { | |
479 | puts("I2C write: addr len < 0\n"); | |
480 | return 1; | |
481 | } | |
482 | ||
483 | if (len < 0) { | |
484 | puts("I2C write: data len < 0\n"); | |
485 | return 1; | |
486 | } | |
487 | ||
488 | if (buffer == NULL) { | |
489 | puts("I2C write: NULL pointer passed\n"); | |
490 | return 1; | |
491 | } | |
8ed96046 | 492 | |
55faa589 | 493 | if (alen > 2) { |
cec487a4 | 494 | printf("I2C write: addr len %d not supported\n", alen); |
8ed96046 | 495 | return 1; |
cec487a4 | 496 | } |
8ed96046 | 497 | |
55faa589 | 498 | if (addr + len > (1 << 16)) { |
cec487a4 | 499 | printf("I2C write: address 0x%x + 0x%x out of range\n", |
960187ff | 500 | addr, len); |
8ed96046 WD |
501 | return 1; |
502 | } | |
503 | ||
960187ff | 504 | /* Wait until bus not busy */ |
6789e84e | 505 | if (wait_for_bb(adap)) |
febc4cd4 | 506 | return 1; |
0607e2b9 | 507 | |
960187ff | 508 | /* Start address phase - will write regoffset + len bytes data */ |
cec487a4 | 509 | writew(alen + len, &i2c_base->cnt); |
960187ff | 510 | /* Set slave address */ |
0607e2b9 | 511 | writew(chip, &i2c_base->sa); |
960187ff | 512 | /* Stop bit needed here */ |
0607e2b9 | 513 | writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | |
960187ff LP |
514 | I2C_CON_STP, &i2c_base->con); |
515 | ||
516 | while (alen) { | |
517 | /* Must write reg offset (one or two bytes) */ | |
6789e84e | 518 | status = wait_for_event(adap); |
960187ff LP |
519 | /* Try to identify bus that is not padconf'd for I2C */ |
520 | if (status == I2C_STAT_XRDY) { | |
521 | i2c_error = 2; | |
522 | printf("i2c_write: pads on bus %d probably not configured (status=0x%x)\n", | |
6789e84e | 523 | adap->hwadapnr, status); |
960187ff LP |
524 | goto wr_exit; |
525 | } | |
d5243359 | 526 | if (status == 0 || (status & I2C_STAT_NACK)) { |
cec487a4 | 527 | i2c_error = 1; |
960187ff LP |
528 | printf("i2c_write: error waiting for addr ACK (status=0x%x)\n", |
529 | status); | |
530 | goto wr_exit; | |
cec487a4 | 531 | } |
cec487a4 | 532 | if (status & I2C_STAT_XRDY) { |
960187ff LP |
533 | alen--; |
534 | writeb((addr >> (8 * alen)) & 0xff, &i2c_base->data); | |
535 | writew(I2C_STAT_XRDY, &i2c_base->stat); | |
536 | } else { | |
537 | i2c_error = 1; | |
538 | printf("i2c_write: bus not ready for addr Tx (status=0x%x)\n", | |
539 | status); | |
540 | goto wr_exit; | |
541 | } | |
542 | } | |
543 | /* Address phase is over, now write data */ | |
544 | for (i = 0; i < len; i++) { | |
6789e84e | 545 | status = wait_for_event(adap); |
d5243359 | 546 | if (status == 0 || (status & I2C_STAT_NACK)) { |
960187ff LP |
547 | i2c_error = 1; |
548 | printf("i2c_write: error waiting for data ACK (status=0x%x)\n", | |
549 | status); | |
550 | goto wr_exit; | |
551 | } | |
552 | if (status & I2C_STAT_XRDY) { | |
553 | writeb(buffer[i], &i2c_base->data); | |
cec487a4 TR |
554 | writew(I2C_STAT_XRDY, &i2c_base->stat); |
555 | } else { | |
556 | i2c_error = 1; | |
960187ff LP |
557 | printf("i2c_write: bus not ready for data Tx (i=%d)\n", |
558 | i); | |
559 | goto wr_exit; | |
8ed96046 WD |
560 | } |
561 | } | |
d5243359 HP |
562 | /* |
563 | * poll ARDY bit for making sure that last byte really has been | |
564 | * transferred on the bus. | |
565 | */ | |
566 | do { | |
567 | status = wait_for_event(adap); | |
568 | } while (!(status & I2C_STAT_ARDY) && timeout--); | |
569 | if (timeout <= 0) | |
570 | printf("i2c_write: timed out writig last byte!\n"); | |
8ed96046 | 571 | |
960187ff | 572 | wr_exit: |
6789e84e | 573 | flush_fifo(adap); |
0607e2b9 | 574 | writew(0xFFFF, &i2c_base->stat); |
cec487a4 | 575 | return i2c_error; |
8ed96046 WD |
576 | } |
577 | ||
960187ff LP |
578 | /* |
579 | * Wait for the bus to be free by checking the Bus Busy (BB) | |
580 | * bit to become clear | |
581 | */ | |
6789e84e | 582 | static int wait_for_bb(struct i2c_adapter *adap) |
8ed96046 | 583 | { |
6789e84e | 584 | struct i2c *i2c_base = omap24_get_base(adap); |
73e8747f | 585 | int timeout = I2C_TIMEOUT; |
cec487a4 | 586 | u16 stat; |
8ed96046 | 587 | |
cec487a4 | 588 | writew(0xFFFF, &i2c_base->stat); /* clear current interrupts...*/ |
960187ff | 589 | #if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) |
89677b27 | 590 | while ((stat = readw(&i2c_base->stat) & I2C_STAT_BB) && timeout--) { |
960187ff LP |
591 | #else |
592 | /* Read RAW status */ | |
593 | while ((stat = readw(&i2c_base->irqstatus_raw) & | |
594 | I2C_STAT_BB) && timeout--) { | |
595 | #endif | |
89677b27 | 596 | writew(stat, &i2c_base->stat); |
d5243359 | 597 | udelay(adap->waitdelay); |
8ed96046 WD |
598 | } |
599 | ||
600 | if (timeout <= 0) { | |
960187ff LP |
601 | printf("Timed out in wait_for_bb: status=%04x\n", |
602 | stat); | |
febc4cd4 | 603 | return 1; |
8ed96046 | 604 | } |
1d2e96de | 605 | writew(0xFFFF, &i2c_base->stat); /* clear delayed stuff*/ |
febc4cd4 | 606 | return 0; |
8ed96046 WD |
607 | } |
608 | ||
960187ff LP |
609 | /* |
610 | * Wait for the I2C controller to complete current action | |
611 | * and update status | |
612 | */ | |
6789e84e | 613 | static u16 wait_for_event(struct i2c_adapter *adap) |
8ed96046 | 614 | { |
6789e84e | 615 | struct i2c *i2c_base = omap24_get_base(adap); |
cec487a4 | 616 | u16 status; |
73e8747f | 617 | int timeout = I2C_TIMEOUT; |
8ed96046 WD |
618 | |
619 | do { | |
d5243359 | 620 | udelay(adap->waitdelay); |
960187ff | 621 | #if defined(CONFIG_OMAP243X) || defined(CONFIG_OMAP34XX) |
89677b27 | 622 | status = readw(&i2c_base->stat); |
960187ff LP |
623 | #else |
624 | /* Read RAW status */ | |
625 | status = readw(&i2c_base->irqstatus_raw); | |
626 | #endif | |
cec487a4 TR |
627 | } while (!(status & |
628 | (I2C_STAT_ROVR | I2C_STAT_XUDF | I2C_STAT_XRDY | | |
629 | I2C_STAT_RRDY | I2C_STAT_ARDY | I2C_STAT_NACK | | |
630 | I2C_STAT_AL)) && timeout--); | |
8ed96046 WD |
631 | |
632 | if (timeout <= 0) { | |
960187ff LP |
633 | printf("Timed out in wait_for_event: status=%04x\n", |
634 | status); | |
635 | /* | |
636 | * If status is still 0 here, probably the bus pads have | |
637 | * not been configured for I2C, and/or pull-ups are missing. | |
638 | */ | |
639 | printf("Check if pads/pull-ups of bus %d are properly configured\n", | |
6789e84e | 640 | adap->hwadapnr); |
73e8747f | 641 | writew(0xFFFF, &i2c_base->stat); |
cec487a4 | 642 | status = 0; |
73e8747f | 643 | } |
cec487a4 | 644 | |
8ed96046 WD |
645 | return status; |
646 | } | |
1d2e96de | 647 | |
6789e84e | 648 | static struct i2c *omap24_get_base(struct i2c_adapter *adap) |
1d2e96de | 649 | { |
6789e84e | 650 | switch (adap->hwadapnr) { |
960187ff | 651 | case 0: |
6789e84e | 652 | return (struct i2c *)I2C_BASE1; |
960187ff LP |
653 | break; |
654 | case 1: | |
6789e84e | 655 | return (struct i2c *)I2C_BASE2; |
960187ff LP |
656 | break; |
657 | #if (I2C_BUS_MAX > 2) | |
658 | case 2: | |
6789e84e | 659 | return (struct i2c *)I2C_BASE3; |
960187ff LP |
660 | break; |
661 | #if (I2C_BUS_MAX > 3) | |
662 | case 3: | |
6789e84e | 663 | return (struct i2c *)I2C_BASE4; |
960187ff LP |
664 | break; |
665 | #if (I2C_BUS_MAX > 4) | |
666 | case 4: | |
6789e84e | 667 | return (struct i2c *)I2C_BASE5; |
960187ff | 668 | break; |
a5322780 | 669 | #endif |
1d2e96de | 670 | #endif |
960187ff | 671 | #endif |
6789e84e HS |
672 | default: |
673 | printf("wrong hwadapnr: %d\n", adap->hwadapnr); | |
674 | break; | |
960187ff | 675 | } |
6789e84e HS |
676 | return NULL; |
677 | } | |
1d2e96de | 678 | |
6789e84e HS |
679 | #if !defined(CONFIG_SYS_OMAP24_I2C_SPEED1) |
680 | #define CONFIG_SYS_OMAP24_I2C_SPEED1 CONFIG_SYS_OMAP24_I2C_SPEED | |
681 | #endif | |
682 | #if !defined(CONFIG_SYS_OMAP24_I2C_SLAVE1) | |
683 | #define CONFIG_SYS_OMAP24_I2C_SLAVE1 CONFIG_SYS_OMAP24_I2C_SLAVE | |
684 | #endif | |
1d2e96de | 685 | |
6789e84e | 686 | U_BOOT_I2C_ADAP_COMPLETE(omap24_0, omap24_i2c_init, omap24_i2c_probe, |
d5243359 | 687 | omap24_i2c_read, omap24_i2c_write, omap24_i2c_setspeed, |
6789e84e HS |
688 | CONFIG_SYS_OMAP24_I2C_SPEED, |
689 | CONFIG_SYS_OMAP24_I2C_SLAVE, | |
690 | 0) | |
691 | U_BOOT_I2C_ADAP_COMPLETE(omap24_1, omap24_i2c_init, omap24_i2c_probe, | |
d5243359 | 692 | omap24_i2c_read, omap24_i2c_write, omap24_i2c_setspeed, |
6789e84e HS |
693 | CONFIG_SYS_OMAP24_I2C_SPEED1, |
694 | CONFIG_SYS_OMAP24_I2C_SLAVE1, | |
695 | 1) | |
696 | #if (I2C_BUS_MAX > 2) | |
697 | #if !defined(CONFIG_SYS_OMAP24_I2C_SPEED2) | |
698 | #define CONFIG_SYS_OMAP24_I2C_SPEED2 CONFIG_SYS_OMAP24_I2C_SPEED | |
699 | #endif | |
700 | #if !defined(CONFIG_SYS_OMAP24_I2C_SLAVE2) | |
701 | #define CONFIG_SYS_OMAP24_I2C_SLAVE2 CONFIG_SYS_OMAP24_I2C_SLAVE | |
702 | #endif | |
1d2e96de | 703 | |
6789e84e HS |
704 | U_BOOT_I2C_ADAP_COMPLETE(omap24_2, omap24_i2c_init, omap24_i2c_probe, |
705 | omap24_i2c_read, omap24_i2c_write, NULL, | |
706 | CONFIG_SYS_OMAP24_I2C_SPEED2, | |
707 | CONFIG_SYS_OMAP24_I2C_SLAVE2, | |
708 | 2) | |
709 | #if (I2C_BUS_MAX > 3) | |
710 | #if !defined(CONFIG_SYS_OMAP24_I2C_SPEED3) | |
711 | #define CONFIG_SYS_OMAP24_I2C_SPEED3 CONFIG_SYS_OMAP24_I2C_SPEED | |
712 | #endif | |
713 | #if !defined(CONFIG_SYS_OMAP24_I2C_SLAVE3) | |
714 | #define CONFIG_SYS_OMAP24_I2C_SLAVE3 CONFIG_SYS_OMAP24_I2C_SLAVE | |
715 | #endif | |
938717ce | 716 | |
6789e84e HS |
717 | U_BOOT_I2C_ADAP_COMPLETE(omap24_3, omap24_i2c_init, omap24_i2c_probe, |
718 | omap24_i2c_read, omap24_i2c_write, NULL, | |
719 | CONFIG_SYS_OMAP24_I2C_SPEED3, | |
720 | CONFIG_SYS_OMAP24_I2C_SLAVE3, | |
721 | 3) | |
722 | #if (I2C_BUS_MAX > 4) | |
723 | #if !defined(CONFIG_SYS_OMAP24_I2C_SPEED4) | |
724 | #define CONFIG_SYS_OMAP24_I2C_SPEED4 CONFIG_SYS_OMAP24_I2C_SPEED | |
725 | #endif | |
726 | #if !defined(CONFIG_SYS_OMAP24_I2C_SLAVE4) | |
727 | #define CONFIG_SYS_OMAP24_I2C_SLAVE4 CONFIG_SYS_OMAP24_I2C_SLAVE | |
728 | #endif | |
729 | ||
730 | U_BOOT_I2C_ADAP_COMPLETE(omap24_4, omap24_i2c_init, omap24_i2c_probe, | |
731 | omap24_i2c_read, omap24_i2c_write, NULL, | |
732 | CONFIG_SYS_OMAP24_I2C_SPEED4, | |
733 | CONFIG_SYS_OMAP24_I2C_SLAVE4, | |
734 | 4) | |
735 | #endif | |
736 | #endif | |
737 | #endif |