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