2 * QTest i.MX I2C driver
4 * Copyright (c) 2013 Jean-Christophe Dubois
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, see <http://www.gnu.org/licenses/>.
20 #include "qemu/osdep.h"
21 #include "libqos/i2c.h"
26 #include "hw/i2c/imx_i2c.h"
28 enum IMXI2CDirection
{
33 static void imx_i2c_set_slave_addr(IMXI2C
*s
, uint8_t addr
,
34 enum IMXI2CDirection direction
)
36 qtest_writeb(s
->parent
.qts
, s
->addr
+ I2DR_ADDR
,
37 (addr
<< 1) | (direction
== IMX_I2C_READ
? 1 : 0));
40 static void imx_i2c_send(I2CAdapter
*i2c
, uint8_t addr
,
41 const uint8_t *buf
, uint16_t len
)
43 IMXI2C
*s
= container_of(i2c
, IMXI2C
, parent
);
52 /* set the bus for write */
59 qtest_writeb(i2c
->qts
, s
->addr
+ I2CR_ADDR
, data
);
60 status
= qtest_readb(i2c
->qts
, s
->addr
+ I2SR_ADDR
);
61 g_assert((status
& I2SR_IBB
) != 0);
63 /* set the slave address */
64 imx_i2c_set_slave_addr(s
, addr
, IMX_I2C_WRITE
);
65 status
= qtest_readb(i2c
->qts
, s
->addr
+ I2SR_ADDR
);
66 g_assert((status
& I2SR_IIF
) != 0);
67 g_assert((status
& I2SR_RXAK
) == 0);
69 /* ack the interrupt */
70 qtest_writeb(i2c
->qts
, s
->addr
+ I2SR_ADDR
, 0);
71 status
= qtest_readb(i2c
->qts
, s
->addr
+ I2SR_ADDR
);
72 g_assert((status
& I2SR_IIF
) == 0);
75 /* check we are still busy */
76 status
= qtest_readb(i2c
->qts
, s
->addr
+ I2SR_ADDR
);
77 g_assert((status
& I2SR_IBB
) != 0);
80 qtest_writeb(i2c
->qts
, s
->addr
+ I2DR_ADDR
, buf
[size
]);
81 status
= qtest_readb(i2c
->qts
, s
->addr
+ I2SR_ADDR
);
82 g_assert((status
& I2SR_IIF
) != 0);
83 g_assert((status
& I2SR_RXAK
) == 0);
85 /* ack the interrupt */
86 qtest_writeb(i2c
->qts
, s
->addr
+ I2SR_ADDR
, 0);
87 status
= qtest_readb(i2c
->qts
, s
->addr
+ I2SR_ADDR
);
88 g_assert((status
& I2SR_IIF
) == 0);
94 data
&= ~(I2CR_MSTA
| I2CR_MTX
);
95 qtest_writeb(i2c
->qts
, s
->addr
+ I2CR_ADDR
, data
);
96 status
= qtest_readb(i2c
->qts
, s
->addr
+ I2SR_ADDR
);
97 g_assert((status
& I2SR_IBB
) == 0);
100 static void imx_i2c_recv(I2CAdapter
*i2c
, uint8_t addr
,
101 uint8_t *buf
, uint16_t len
)
103 IMXI2C
*s
= container_of(i2c
, IMXI2C
, parent
);
112 /* set the bus for write */
119 qtest_writeb(i2c
->qts
, s
->addr
+ I2CR_ADDR
, data
);
120 status
= qtest_readb(i2c
->qts
, s
->addr
+ I2SR_ADDR
);
121 g_assert((status
& I2SR_IBB
) != 0);
123 /* set the slave address */
124 imx_i2c_set_slave_addr(s
, addr
, IMX_I2C_READ
);
125 status
= qtest_readb(i2c
->qts
, s
->addr
+ I2SR_ADDR
);
126 g_assert((status
& I2SR_IIF
) != 0);
127 g_assert((status
& I2SR_RXAK
) == 0);
129 /* ack the interrupt */
130 qtest_writeb(i2c
->qts
, s
->addr
+ I2SR_ADDR
, 0);
131 status
= qtest_readb(i2c
->qts
, s
->addr
+ I2SR_ADDR
);
132 g_assert((status
& I2SR_IIF
) == 0);
134 /* set the bus for read */
136 /* if only one byte don't ack */
140 qtest_writeb(i2c
->qts
, s
->addr
+ I2CR_ADDR
, data
);
141 status
= qtest_readb(i2c
->qts
, s
->addr
+ I2SR_ADDR
);
142 g_assert((status
& I2SR_IBB
) != 0);
145 qtest_readb(i2c
->qts
, s
->addr
+ I2DR_ADDR
);
146 status
= qtest_readb(i2c
->qts
, s
->addr
+ I2SR_ADDR
);
147 g_assert((status
& I2SR_IIF
) != 0);
149 /* ack the interrupt */
150 qtest_writeb(i2c
->qts
, s
->addr
+ I2SR_ADDR
, 0);
151 status
= qtest_readb(i2c
->qts
, s
->addr
+ I2SR_ADDR
);
152 g_assert((status
& I2SR_IIF
) == 0);
155 /* check we are still busy */
156 status
= qtest_readb(i2c
->qts
, s
->addr
+ I2SR_ADDR
);
157 g_assert((status
& I2SR_IBB
) != 0);
159 if (size
== (len
- 1)) {
160 /* stop the read transaction */
161 data
&= ~(I2CR_MSTA
| I2CR_MTX
);
163 /* ack the data read */
166 qtest_writeb(i2c
->qts
, s
->addr
+ I2CR_ADDR
, data
);
169 buf
[size
] = qtest_readb(i2c
->qts
, s
->addr
+ I2DR_ADDR
);
171 if (size
!= (len
- 1)) {
172 status
= qtest_readb(i2c
->qts
, s
->addr
+ I2SR_ADDR
);
173 g_assert((status
& I2SR_IIF
) != 0);
175 /* ack the interrupt */
176 qtest_writeb(i2c
->qts
, s
->addr
+ I2SR_ADDR
, 0);
179 status
= qtest_readb(i2c
->qts
, s
->addr
+ I2SR_ADDR
);
180 g_assert((status
& I2SR_IIF
) == 0);
185 status
= qtest_readb(i2c
->qts
, s
->addr
+ I2SR_ADDR
);
186 g_assert((status
& I2SR_IBB
) == 0);
189 static void *imx_i2c_get_driver(void *obj
, const char *interface
)
192 if (!g_strcmp0(interface
, "i2c-bus")) {
195 fprintf(stderr
, "%s not present in imx-i2c\n", interface
);
196 g_assert_not_reached();
199 void imx_i2c_init(IMXI2C
*s
, QTestState
*qts
, uint64_t addr
)
203 s
->obj
.get_driver
= imx_i2c_get_driver
;
205 s
->parent
.send
= imx_i2c_send
;
206 s
->parent
.recv
= imx_i2c_recv
;
210 static void imx_i2c_register_nodes(void)
212 qos_node_create_driver("imx.i2c", NULL
);
213 qos_node_produces("imx.i2c", "i2c-bus");
216 libqos_init(imx_i2c_register_nodes
);