2 * Freescale i.MX28 I2C Driver
4 * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
5 * on behalf of DENX Software Engineering GmbH
7 * Partly based on Linux kernel i2c-mxs.c driver:
8 * Copyright (C) 2011 Wolfram Sang, Pengutronix e.K.
10 * Which was based on a (non-working) driver which was:
11 * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #include <asm/errno.h>
33 #include <asm/arch/clock.h>
34 #include <asm/arch/imx-regs.h>
35 #include <asm/arch/sys_proto.h>
37 #define MXS_I2C_MAX_TIMEOUT 1000000
39 void mxs_i2c_reset(void)
41 struct mxs_i2c_regs
*i2c_regs
= (struct mxs_i2c_regs
*)MXS_I2C0_BASE
;
43 int speed
= i2c_get_bus_speed();
45 ret
= mxs_reset_block(&i2c_regs
->hw_i2c_ctrl0_reg
);
47 debug("MXS I2C: Block reset timeout\n");
51 writel(I2C_CTRL1_DATA_ENGINE_CMPLT_IRQ
| I2C_CTRL1_NO_SLAVE_ACK_IRQ
|
52 I2C_CTRL1_EARLY_TERM_IRQ
| I2C_CTRL1_MASTER_LOSS_IRQ
|
53 I2C_CTRL1_SLAVE_STOP_IRQ
| I2C_CTRL1_SLAVE_IRQ
,
54 &i2c_regs
->hw_i2c_ctrl1_clr
);
56 writel(I2C_QUEUECTRL_PIO_QUEUE_MODE
, &i2c_regs
->hw_i2c_queuectrl_set
);
58 i2c_set_bus_speed(speed
);
61 void mxs_i2c_setup_read(uint8_t chip
, int len
)
63 struct mxs_i2c_regs
*i2c_regs
= (struct mxs_i2c_regs
*)MXS_I2C0_BASE
;
65 writel(I2C_QUEUECMD_RETAIN_CLOCK
| I2C_QUEUECMD_PRE_SEND_START
|
66 I2C_QUEUECMD_MASTER_MODE
| I2C_QUEUECMD_DIRECTION
|
67 (1 << I2C_QUEUECMD_XFER_COUNT_OFFSET
),
68 &i2c_regs
->hw_i2c_queuecmd
);
70 writel((chip
<< 1) | 1, &i2c_regs
->hw_i2c_data
);
72 writel(I2C_QUEUECMD_SEND_NAK_ON_LAST
| I2C_QUEUECMD_MASTER_MODE
|
73 (len
<< I2C_QUEUECMD_XFER_COUNT_OFFSET
) |
74 I2C_QUEUECMD_POST_SEND_STOP
, &i2c_regs
->hw_i2c_queuecmd
);
76 writel(I2C_QUEUECTRL_QUEUE_RUN
, &i2c_regs
->hw_i2c_queuectrl_set
);
79 void mxs_i2c_write(uchar chip
, uint addr
, int alen
,
80 uchar
*buf
, int blen
, int stop
)
82 struct mxs_i2c_regs
*i2c_regs
= (struct mxs_i2c_regs
*)MXS_I2C0_BASE
;
86 if ((alen
> 4) || (alen
== 0)) {
87 debug("MXS I2C: Invalid address length\n");
92 stop
= I2C_QUEUECMD_POST_SEND_STOP
;
94 writel(I2C_QUEUECMD_PRE_SEND_START
|
95 I2C_QUEUECMD_MASTER_MODE
| I2C_QUEUECMD_DIRECTION
|
96 ((blen
+ alen
+ 1) << I2C_QUEUECMD_XFER_COUNT_OFFSET
) | stop
,
97 &i2c_regs
->hw_i2c_queuecmd
);
99 data
= (chip
<< 1) << 24;
101 for (i
= 0; i
< alen
; i
++) {
103 data
|= ((char *)&addr
)[alen
- i
- 1] << 24;
105 writel(data
, &i2c_regs
->hw_i2c_data
);
109 for (; i
< off
+ blen
; i
++) {
111 data
|= buf
[i
- off
] << 24;
113 writel(data
, &i2c_regs
->hw_i2c_data
);
116 remain
= 24 - ((i
& 3) * 8);
118 writel(data
>> remain
, &i2c_regs
->hw_i2c_data
);
120 writel(I2C_QUEUECTRL_QUEUE_RUN
, &i2c_regs
->hw_i2c_queuectrl_set
);
123 int mxs_i2c_wait_for_ack(void)
125 struct mxs_i2c_regs
*i2c_regs
= (struct mxs_i2c_regs
*)MXS_I2C0_BASE
;
127 int timeout
= MXS_I2C_MAX_TIMEOUT
;
130 tmp
= readl(&i2c_regs
->hw_i2c_ctrl1
);
131 if (tmp
& I2C_CTRL1_NO_SLAVE_ACK_IRQ
) {
132 debug("MXS I2C: No slave ACK\n");
137 I2C_CTRL1_EARLY_TERM_IRQ
| I2C_CTRL1_MASTER_LOSS_IRQ
|
138 I2C_CTRL1_SLAVE_STOP_IRQ
| I2C_CTRL1_SLAVE_IRQ
)) {
139 debug("MXS I2C: Error (CTRL1 = %08x)\n", tmp
);
143 if (tmp
& I2C_CTRL1_DATA_ENGINE_CMPLT_IRQ
)
147 debug("MXS I2C: Operation timed out\n");
161 int i2c_read(uchar chip
, uint addr
, int alen
, uchar
*buffer
, int len
)
163 struct mxs_i2c_regs
*i2c_regs
= (struct mxs_i2c_regs
*)MXS_I2C0_BASE
;
168 mxs_i2c_write(chip
, addr
, alen
, NULL
, 0, 0);
169 ret
= mxs_i2c_wait_for_ack();
171 debug("MXS I2C: Failed writing address\n");
175 mxs_i2c_setup_read(chip
, len
);
176 ret
= mxs_i2c_wait_for_ack();
178 debug("MXS I2C: Failed reading address\n");
182 for (i
= 0; i
< len
; i
++) {
184 while (readl(&i2c_regs
->hw_i2c_queuestat
) &
185 I2C_QUEUESTAT_RD_QUEUE_EMPTY
)
187 tmp
= readl(&i2c_regs
->hw_i2c_queuedata
);
189 buffer
[i
] = tmp
& 0xff;
196 int i2c_write(uchar chip
, uint addr
, int alen
, uchar
*buffer
, int len
)
199 mxs_i2c_write(chip
, addr
, alen
, buffer
, len
, 1);
200 ret
= mxs_i2c_wait_for_ack();
202 debug("MXS I2C: Failed writing address\n");
207 int i2c_probe(uchar chip
)
210 mxs_i2c_write(chip
, 0, 1, NULL
, 0, 1);
211 ret
= mxs_i2c_wait_for_ack();
216 static struct mxs_i2c_speed_table
{
223 (0x0078 << I2C_TIMING0_HIGH_COUNT_OFFSET
) |
224 (0x0030 << I2C_TIMING0_RCV_COUNT_OFFSET
),
225 (0x0080 << I2C_TIMING1_LOW_COUNT_OFFSET
) |
226 (0x0030 << I2C_TIMING1_XMIT_COUNT_OFFSET
)
230 (0x000f << I2C_TIMING0_HIGH_COUNT_OFFSET
) |
231 (0x0007 << I2C_TIMING0_RCV_COUNT_OFFSET
),
232 (0x001f << I2C_TIMING1_LOW_COUNT_OFFSET
) |
233 (0x000f << I2C_TIMING1_XMIT_COUNT_OFFSET
),
237 static struct mxs_i2c_speed_table
*mxs_i2c_speed_to_cfg(uint32_t speed
)
240 for (i
= 0; i
< ARRAY_SIZE(mxs_i2c_tbl
); i
++)
241 if (mxs_i2c_tbl
[i
].speed
== speed
)
242 return &mxs_i2c_tbl
[i
];
246 static uint32_t mxs_i2c_cfg_to_speed(uint32_t timing0
, uint32_t timing1
)
249 for (i
= 0; i
< ARRAY_SIZE(mxs_i2c_tbl
); i
++) {
250 if (mxs_i2c_tbl
[i
].timing0
!= timing0
)
252 if (mxs_i2c_tbl
[i
].timing1
!= timing1
)
254 return mxs_i2c_tbl
[i
].speed
;
260 int i2c_set_bus_speed(unsigned int speed
)
262 struct mxs_i2c_regs
*i2c_regs
= (struct mxs_i2c_regs
*)MXS_I2C0_BASE
;
263 struct mxs_i2c_speed_table
*spd
= mxs_i2c_speed_to_cfg(speed
);
266 printf("MXS I2C: Invalid speed selected (%d Hz)\n", speed
);
270 writel(spd
->timing0
, &i2c_regs
->hw_i2c_timing0
);
271 writel(spd
->timing1
, &i2c_regs
->hw_i2c_timing1
);
273 writel((0x0030 << I2C_TIMING2_BUS_FREE_OFFSET
) |
274 (0x0030 << I2C_TIMING2_LEADIN_COUNT_OFFSET
),
275 &i2c_regs
->hw_i2c_timing2
);
280 unsigned int i2c_get_bus_speed(void)
282 struct mxs_i2c_regs
*i2c_regs
= (struct mxs_i2c_regs
*)MXS_I2C0_BASE
;
283 uint32_t timing0
, timing1
;
285 timing0
= readl(&i2c_regs
->hw_i2c_timing0
);
286 timing1
= readl(&i2c_regs
->hw_i2c_timing1
);
288 return mxs_i2c_cfg_to_speed(timing0
, timing1
);
291 void i2c_init(int speed
, int slaveadd
)
294 i2c_set_bus_speed(speed
);