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