4 * Copyright (c) 2012 Andreas Färber
6 * This work is licensed under the terms of the GNU GPL, version 2 or later.
7 * See the COPYING file in the top-level directory.
14 #include "qemu/osdep.h"
17 enum OMAPI2CRegisters
{
26 enum OMAPI2CSTATBits
{
27 OMAP_I2C_STAT_NACK
= 1 << 1,
28 OMAP_I2C_STAT_ARDY
= 1 << 2,
29 OMAP_I2C_STAT_RRDY
= 1 << 3,
30 OMAP_I2C_STAT_XRDY
= 1 << 4,
31 OMAP_I2C_STAT_ROVR
= 1 << 11,
32 OMAP_I2C_STAT_SBD
= 1 << 15,
36 OMAP_I2C_CON_STT
= 1 << 0,
37 OMAP_I2C_CON_STP
= 1 << 1,
38 OMAP_I2C_CON_TRX
= 1 << 9,
39 OMAP_I2C_CON_MST
= 1 << 10,
40 OMAP_I2C_CON_BE
= 1 << 14,
41 OMAP_I2C_CON_I2C_EN
= 1 << 15,
44 typedef struct OMAPI2C
{
51 static void omap_i2c_set_slave_addr(OMAPI2C
*s
, uint8_t addr
)
55 memwrite(s
->addr
+ OMAP_I2C_SA
, &data
, 2);
56 memread(s
->addr
+ OMAP_I2C_SA
, &data
, 2);
57 g_assert_cmphex(data
, ==, addr
);
60 static void omap_i2c_send(I2CAdapter
*i2c
, uint8_t addr
,
61 const uint8_t *buf
, uint16_t len
)
63 OMAPI2C
*s
= (OMAPI2C
*)i2c
;
66 omap_i2c_set_slave_addr(s
, addr
);
69 memwrite(s
->addr
+ OMAP_I2C_CNT
, &data
, 2);
71 data
= OMAP_I2C_CON_I2C_EN
|
76 memwrite(s
->addr
+ OMAP_I2C_CON
, &data
, 2);
77 memread(s
->addr
+ OMAP_I2C_CON
, &data
, 2);
78 g_assert((data
& OMAP_I2C_CON_STP
) != 0);
80 memread(s
->addr
+ OMAP_I2C_STAT
, &data
, 2);
81 g_assert((data
& OMAP_I2C_STAT_NACK
) == 0);
84 memread(s
->addr
+ OMAP_I2C_STAT
, &data
, 2);
85 g_assert((data
& OMAP_I2C_STAT_XRDY
) != 0);
87 memwrite(s
->addr
+ OMAP_I2C_DATA
, buf
, 2);
88 buf
= (uint8_t *)buf
+ 2;
92 memread(s
->addr
+ OMAP_I2C_STAT
, &data
, 2);
93 g_assert((data
& OMAP_I2C_STAT_XRDY
) != 0);
95 memwrite(s
->addr
+ OMAP_I2C_DATA
, buf
, 1);
98 memread(s
->addr
+ OMAP_I2C_CON
, &data
, 2);
99 g_assert((data
& OMAP_I2C_CON_STP
) == 0);
102 static void omap_i2c_recv(I2CAdapter
*i2c
, uint8_t addr
,
103 uint8_t *buf
, uint16_t len
)
105 OMAPI2C
*s
= (OMAPI2C
*)i2c
;
108 omap_i2c_set_slave_addr(s
, addr
);
111 memwrite(s
->addr
+ OMAP_I2C_CNT
, &data
, 2);
113 data
= OMAP_I2C_CON_I2C_EN
|
117 memwrite(s
->addr
+ OMAP_I2C_CON
, &data
, 2);
118 memread(s
->addr
+ OMAP_I2C_CON
, &data
, 2);
119 g_assert((data
& OMAP_I2C_CON_STP
) == 0);
121 memread(s
->addr
+ OMAP_I2C_STAT
, &data
, 2);
122 g_assert((data
& OMAP_I2C_STAT_NACK
) == 0);
124 memread(s
->addr
+ OMAP_I2C_CNT
, &data
, 2);
125 g_assert_cmpuint(data
, ==, len
);
128 memread(s
->addr
+ OMAP_I2C_STAT
, &data
, 2);
129 g_assert((data
& OMAP_I2C_STAT_RRDY
) != 0);
130 g_assert((data
& OMAP_I2C_STAT_ROVR
) == 0);
132 memread(s
->addr
+ OMAP_I2C_DATA
, &data
, 2);
134 memread(s
->addr
+ OMAP_I2C_STAT
, &stat
, 2);
135 if (unlikely(len
== 1)) {
140 memcpy(buf
, &data
, 2);
146 memread(s
->addr
+ OMAP_I2C_CON
, &data
, 2);
147 g_assert((data
& OMAP_I2C_CON_STP
) == 0);
150 I2CAdapter
*omap_i2c_create(uint64_t addr
)
152 OMAPI2C
*s
= g_malloc0(sizeof(*s
));
153 I2CAdapter
*i2c
= (I2CAdapter
*)s
;
158 i2c
->send
= omap_i2c_send
;
159 i2c
->recv
= omap_i2c_recv
;
161 /* verify the mmio address by looking for a known signature */
162 memread(addr
+ OMAP_I2C_REV
, &data
, 2);
163 g_assert_cmphex(data
, ==, 0x34);