Skip to content

Commit ecc2ed5

Browse files
committed
dm: i2c: Add tests for I2C
Add some basic tests to check that the system works as expected. Signed-off-by: Simon Glass <[email protected]> Acked-by: Heiko Schocher <[email protected]>
1 parent 2014201 commit ecc2ed5

File tree

4 files changed

+246
-0
lines changed

4 files changed

+246
-0
lines changed

include/dm/ut.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,18 @@ void ut_failf(struct dm_test_state *dms, const char *fname, int line,
8989
} \
9090
}
9191

92+
/* Assert that a pointer is not NULL */
93+
#define ut_assertnonnull(expr) { \
94+
const void *val = (expr); \
95+
\
96+
if (val == NULL) { \
97+
ut_failf(dms, __FILE__, __LINE__, __func__, \
98+
#expr " = NULL", \
99+
"Expected non-null, got NULL"); \
100+
return -1; \
101+
} \
102+
}
103+
92104
/* Assert that an operation succeeds (returns 0) */
93105
#define ut_assertok(cond) ut_asserteq(0, cond)
94106

test/dm/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@ ifneq ($(CONFIG_SANDBOX),)
2020
obj-$(CONFIG_DM_GPIO) += gpio.o
2121
obj-$(CONFIG_DM_SPI) += spi.o
2222
obj-$(CONFIG_DM_SPI_FLASH) += sf.o
23+
obj-$(CONFIG_DM_I2C) += i2c.o
2324
endif

test/dm/i2c.c

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
/*
2+
* Copyright (C) 2013 Google, Inc
3+
*
4+
* SPDX-License-Identifier: GPL-2.0+
5+
*
6+
* Note: Test coverage does not include 10-bit addressing
7+
*/
8+
9+
#include <common.h>
10+
#include <dm.h>
11+
#include <fdtdec.h>
12+
#include <i2c.h>
13+
#include <dm/device-internal.h>
14+
#include <dm/test.h>
15+
#include <dm/uclass-internal.h>
16+
#include <dm/ut.h>
17+
#include <dm/util.h>
18+
#include <asm/state.h>
19+
#include <asm/test.h>
20+
21+
static const int busnum;
22+
static const int chip = 0x2c;
23+
24+
/* Test that we can find buses and chips */
25+
static int dm_test_i2c_find(struct dm_test_state *dms)
26+
{
27+
struct udevice *bus, *dev;
28+
const int no_chip = 0x10;
29+
30+
ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_I2C, busnum,
31+
false, &bus));
32+
33+
/*
34+
* i2c_post_bind() will bind devices to chip selects. Check this then
35+
* remove the emulation and the slave device.
36+
*/
37+
ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
38+
ut_assertok(i2c_probe(bus, chip, 0, &dev));
39+
ut_asserteq(-ENODEV, i2c_probe(bus, no_chip, 0, &dev));
40+
ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_I2C, 1, &bus));
41+
42+
return 0;
43+
}
44+
DM_TEST(dm_test_i2c_find, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
45+
46+
static int dm_test_i2c_read_write(struct dm_test_state *dms)
47+
{
48+
struct udevice *bus, *dev;
49+
uint8_t buf[5];
50+
51+
ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
52+
ut_assertok(i2c_get_chip(bus, chip, &dev));
53+
ut_assertok(i2c_read(dev, 0, buf, 5));
54+
ut_assertok(memcmp(buf, "\0\0\0\0\0", sizeof(buf)));
55+
ut_assertok(i2c_write(dev, 2, (uint8_t *)"AB", 2));
56+
ut_assertok(i2c_read(dev, 0, buf, 5));
57+
ut_assertok(memcmp(buf, "\0\0AB\0", sizeof(buf)));
58+
59+
return 0;
60+
}
61+
DM_TEST(dm_test_i2c_read_write, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
62+
63+
static int dm_test_i2c_speed(struct dm_test_state *dms)
64+
{
65+
struct udevice *bus, *dev;
66+
uint8_t buf[5];
67+
68+
ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
69+
ut_assertok(i2c_get_chip(bus, chip, &dev));
70+
ut_assertok(i2c_set_bus_speed(bus, 100000));
71+
ut_assertok(i2c_read(dev, 0, buf, 5));
72+
ut_assertok(i2c_set_bus_speed(bus, 400000));
73+
ut_asserteq(400000, i2c_get_bus_speed(bus));
74+
ut_assertok(i2c_read(dev, 0, buf, 5));
75+
ut_asserteq(-EINVAL, i2c_write(dev, 0, buf, 5));
76+
77+
return 0;
78+
}
79+
DM_TEST(dm_test_i2c_speed, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
80+
81+
static int dm_test_i2c_offset_len(struct dm_test_state *dms)
82+
{
83+
struct udevice *bus, *dev;
84+
uint8_t buf[5];
85+
86+
ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
87+
ut_assertok(i2c_get_chip(bus, chip, &dev));
88+
ut_assertok(i2c_set_chip_offset_len(dev, 1));
89+
ut_assertok(i2c_read(dev, 0, buf, 5));
90+
91+
/* This is not supported by the uclass */
92+
ut_asserteq(-EINVAL, i2c_set_chip_offset_len(dev, 5));
93+
94+
return 0;
95+
}
96+
DM_TEST(dm_test_i2c_offset_len, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
97+
98+
static int dm_test_i2c_probe_empty(struct dm_test_state *dms)
99+
{
100+
struct udevice *bus, *dev;
101+
102+
ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
103+
ut_assertok(i2c_probe(bus, SANDBOX_I2C_TEST_ADDR, 0, &dev));
104+
105+
return 0;
106+
}
107+
DM_TEST(dm_test_i2c_probe_empty, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
108+
109+
static int dm_test_i2c_bytewise(struct dm_test_state *dms)
110+
{
111+
struct udevice *bus, *dev;
112+
struct udevice *eeprom;
113+
uint8_t buf[5];
114+
115+
ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
116+
ut_assertok(i2c_get_chip(bus, chip, &dev));
117+
ut_assertok(i2c_read(dev, 0, buf, 5));
118+
ut_assertok(memcmp(buf, "\0\0\0\0\0", sizeof(buf)));
119+
120+
/* Tell the EEPROM to only read/write one register at a time */
121+
ut_assertok(uclass_first_device(UCLASS_I2C_EMUL, &eeprom));
122+
ut_assertnonnull(eeprom);
123+
sandbox_i2c_eeprom_set_test_mode(eeprom, SIE_TEST_MODE_SINGLE_BYTE);
124+
125+
/* Now we only get the first byte - the rest will be 0xff */
126+
ut_assertok(i2c_read(dev, 0, buf, 5));
127+
ut_assertok(memcmp(buf, "\0\xff\xff\xff\xff", sizeof(buf)));
128+
129+
/* If we do a separate transaction for each byte, it works */
130+
ut_assertok(i2c_set_chip_flags(dev, DM_I2C_CHIP_RD_ADDRESS));
131+
ut_assertok(i2c_read(dev, 0, buf, 5));
132+
ut_assertok(memcmp(buf, "\0\0\0\0\0", sizeof(buf)));
133+
134+
/* This will only write A */
135+
ut_assertok(i2c_set_chip_flags(dev, 0));
136+
ut_assertok(i2c_write(dev, 2, (uint8_t *)"AB", 2));
137+
ut_assertok(i2c_read(dev, 0, buf, 5));
138+
ut_assertok(memcmp(buf, "\0\xff\xff\xff\xff", sizeof(buf)));
139+
140+
/* Check that the B was ignored */
141+
ut_assertok(i2c_set_chip_flags(dev, DM_I2C_CHIP_RD_ADDRESS));
142+
ut_assertok(i2c_read(dev, 0, buf, 5));
143+
ut_assertok(memcmp(buf, "\0\0A\0\0\0", sizeof(buf)));
144+
145+
/* Now write it again with the new flags, it should work */
146+
ut_assertok(i2c_set_chip_flags(dev, DM_I2C_CHIP_WR_ADDRESS));
147+
ut_assertok(i2c_write(dev, 2, (uint8_t *)"AB", 2));
148+
ut_assertok(i2c_read(dev, 0, buf, 5));
149+
ut_assertok(memcmp(buf, "\0\xff\xff\xff\xff", sizeof(buf)));
150+
151+
ut_assertok(i2c_set_chip_flags(dev, DM_I2C_CHIP_WR_ADDRESS |
152+
DM_I2C_CHIP_RD_ADDRESS));
153+
ut_assertok(i2c_read(dev, 0, buf, 5));
154+
ut_assertok(memcmp(buf, "\0\0AB\0\0", sizeof(buf)));
155+
156+
/* Restore defaults */
157+
sandbox_i2c_eeprom_set_test_mode(eeprom, SIE_TEST_MODE_NONE);
158+
ut_assertok(i2c_set_chip_flags(dev, 0));
159+
160+
return 0;
161+
}
162+
DM_TEST(dm_test_i2c_bytewise, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
163+
164+
static int dm_test_i2c_offset(struct dm_test_state *dms)
165+
{
166+
struct udevice *eeprom;
167+
struct udevice *dev;
168+
uint8_t buf[5];
169+
170+
ut_assertok(i2c_get_chip_for_busnum(busnum, chip, &dev));
171+
172+
/* Do a transfer so we can find the emulator */
173+
ut_assertok(i2c_read(dev, 0, buf, 5));
174+
ut_assertok(uclass_first_device(UCLASS_I2C_EMUL, &eeprom));
175+
176+
/* Offset length 0 */
177+
sandbox_i2c_eeprom_set_offset_len(eeprom, 0);
178+
ut_assertok(i2c_set_chip_offset_len(dev, 0));
179+
ut_assertok(i2c_write(dev, 10 /* ignored */, (uint8_t *)"AB", 2));
180+
ut_assertok(i2c_read(dev, 0, buf, 5));
181+
ut_assertok(memcmp(buf, "AB\0\0\0\0", sizeof(buf)));
182+
183+
/* Offset length 1 */
184+
sandbox_i2c_eeprom_set_offset_len(eeprom, 1);
185+
ut_assertok(i2c_set_chip_offset_len(dev, 1));
186+
ut_assertok(i2c_write(dev, 2, (uint8_t *)"AB", 2));
187+
ut_assertok(i2c_read(dev, 0, buf, 5));
188+
ut_assertok(memcmp(buf, "ABAB\0", sizeof(buf)));
189+
190+
/* Offset length 2 */
191+
sandbox_i2c_eeprom_set_offset_len(eeprom, 2);
192+
ut_assertok(i2c_set_chip_offset_len(dev, 2));
193+
ut_assertok(i2c_write(dev, 0x210, (uint8_t *)"AB", 2));
194+
ut_assertok(i2c_read(dev, 0x210, buf, 5));
195+
ut_assertok(memcmp(buf, "AB\0\0\0", sizeof(buf)));
196+
197+
/* Offset length 3 */
198+
sandbox_i2c_eeprom_set_offset_len(eeprom, 2);
199+
ut_assertok(i2c_set_chip_offset_len(dev, 2));
200+
ut_assertok(i2c_write(dev, 0x410, (uint8_t *)"AB", 2));
201+
ut_assertok(i2c_read(dev, 0x410, buf, 5));
202+
ut_assertok(memcmp(buf, "AB\0\0\0", sizeof(buf)));
203+
204+
/* Offset length 4 */
205+
sandbox_i2c_eeprom_set_offset_len(eeprom, 2);
206+
ut_assertok(i2c_set_chip_offset_len(dev, 2));
207+
ut_assertok(i2c_write(dev, 0x420, (uint8_t *)"AB", 2));
208+
ut_assertok(i2c_read(dev, 0x420, buf, 5));
209+
ut_assertok(memcmp(buf, "AB\0\0\0", sizeof(buf)));
210+
211+
/* Restore defaults */
212+
sandbox_i2c_eeprom_set_offset_len(eeprom, 1);
213+
214+
return 0;
215+
}
216+
DM_TEST(dm_test_i2c_offset, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);

test/dm/test.dts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,23 @@
9393
num-gpios = <10>;
9494
};
9595

96+
i2c@0 {
97+
#address-cells = <1>;
98+
#size-cells = <0>;
99+
reg = <0>;
100+
compatible = "sandbox,i2c";
101+
clock-frequency = <100000>;
102+
eeprom@2c {
103+
reg = <0x2c>;
104+
compatible = "i2c-eeprom";
105+
emul {
106+
compatible = "sandbox,i2c-eeprom";
107+
sandbox,filename = "i2c.bin";
108+
sandbox,size = <256>;
109+
};
110+
};
111+
};
112+
96113
spi@0 {
97114
#address-cells = <1>;
98115
#size-cells = <0>;

0 commit comments

Comments
 (0)