blob: 681ce45107c31f8ebeedd13b1bf2745dfaf65404 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Simon Glass7df766e2014-12-10 08:55:55 -07002/*
3 * Copyright (C) 2013 Google, Inc
4 *
Simon Glass7df766e2014-12-10 08:55:55 -07005 * Note: Test coverage does not include 10-bit addressing
6 */
7
8#include <common.h>
9#include <dm.h>
10#include <fdtdec.h>
11#include <i2c.h>
Joe Hershberger3a77be52015-05-20 14:27:27 -050012#include <asm/state.h>
13#include <asm/test.h>
Simon Glass7df766e2014-12-10 08:55:55 -070014#include <dm/device-internal.h>
15#include <dm/test.h>
16#include <dm/uclass-internal.h>
Simon Glass7df766e2014-12-10 08:55:55 -070017#include <dm/util.h>
Robert Beckett1fe8a492019-10-28 17:44:58 +000018#include <hexdump.h>
Simon Glass75c4d412020-07-19 10:15:37 -060019#include <test/test.h>
Joe Hershberger3a77be52015-05-20 14:27:27 -050020#include <test/ut.h>
Simon Glass7df766e2014-12-10 08:55:55 -070021
22static const int busnum;
23static const int chip = 0x2c;
24
25/* Test that we can find buses and chips */
Joe Hershberger3a77be52015-05-20 14:27:27 -050026static int dm_test_i2c_find(struct unit_test_state *uts)
Simon Glass7df766e2014-12-10 08:55:55 -070027{
28 struct udevice *bus, *dev;
29 const int no_chip = 0x10;
30
31 ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_I2C, busnum,
32 false, &bus));
33
34 /*
Simon Glass18230342016-07-05 17:10:10 -060035 * The post_bind() method will bind devices to chip selects. Check
36 * this then remove the emulation and the slave device.
Simon Glass7df766e2014-12-10 08:55:55 -070037 */
38 ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
Simon Glass7d722762015-01-12 18:02:07 -070039 ut_assertok(dm_i2c_probe(bus, chip, 0, &dev));
Simon Glass17b56f62018-11-18 08:14:34 -070040 ut_asserteq(-ENOENT, dm_i2c_probe(bus, no_chip, 0, &dev));
Simon Glass7df766e2014-12-10 08:55:55 -070041 ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_I2C, 1, &bus));
42
43 return 0;
44}
Simon Glass974dccd2020-07-28 19:41:12 -060045DM_TEST(dm_test_i2c_find, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glass7df766e2014-12-10 08:55:55 -070046
Joe Hershberger3a77be52015-05-20 14:27:27 -050047static int dm_test_i2c_read_write(struct unit_test_state *uts)
Simon Glass7df766e2014-12-10 08:55:55 -070048{
49 struct udevice *bus, *dev;
50 uint8_t buf[5];
51
52 ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
Simon Glassa2723ae2015-01-25 08:26:55 -070053 ut_assertok(i2c_get_chip(bus, chip, 1, &dev));
Simon Glass7d722762015-01-12 18:02:07 -070054 ut_assertok(dm_i2c_read(dev, 0, buf, 5));
Simon Glassa3186e62020-05-10 12:52:45 -060055 ut_asserteq_mem(buf, "\0\0\0\0\0", sizeof(buf));
Simon Glass7d722762015-01-12 18:02:07 -070056 ut_assertok(dm_i2c_write(dev, 2, (uint8_t *)"AB", 2));
57 ut_assertok(dm_i2c_read(dev, 0, buf, 5));
Simon Glassa3186e62020-05-10 12:52:45 -060058 ut_asserteq_mem(buf, "\0\0AB\0", sizeof(buf));
Simon Glass7df766e2014-12-10 08:55:55 -070059
60 return 0;
61}
Simon Glass974dccd2020-07-28 19:41:12 -060062DM_TEST(dm_test_i2c_read_write, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glass7df766e2014-12-10 08:55:55 -070063
Joe Hershberger3a77be52015-05-20 14:27:27 -050064static int dm_test_i2c_speed(struct unit_test_state *uts)
Simon Glass7df766e2014-12-10 08:55:55 -070065{
66 struct udevice *bus, *dev;
67 uint8_t buf[5];
68
69 ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
Simon Glass4c70ed92015-04-20 12:37:15 -060070
71 /* Use test mode so we create the required errors for invalid speeds */
72 sandbox_i2c_set_test_mode(bus, true);
Simon Glassa2723ae2015-01-25 08:26:55 -070073 ut_assertok(i2c_get_chip(bus, chip, 1, &dev));
Simon Glasse4e8ff22015-02-05 21:41:32 -070074 ut_assertok(dm_i2c_set_bus_speed(bus, 100000));
Simon Glass7d722762015-01-12 18:02:07 -070075 ut_assertok(dm_i2c_read(dev, 0, buf, 5));
Simon Glasse4e8ff22015-02-05 21:41:32 -070076 ut_assertok(dm_i2c_set_bus_speed(bus, 400000));
77 ut_asserteq(400000, dm_i2c_get_bus_speed(bus));
Simon Glass7d722762015-01-12 18:02:07 -070078 ut_assertok(dm_i2c_read(dev, 0, buf, 5));
79 ut_asserteq(-EINVAL, dm_i2c_write(dev, 0, buf, 5));
Simon Glass4c70ed92015-04-20 12:37:15 -060080 sandbox_i2c_set_test_mode(bus, false);
Simon Glass7df766e2014-12-10 08:55:55 -070081
82 return 0;
83}
Simon Glass974dccd2020-07-28 19:41:12 -060084DM_TEST(dm_test_i2c_speed, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glass7df766e2014-12-10 08:55:55 -070085
Joe Hershberger3a77be52015-05-20 14:27:27 -050086static int dm_test_i2c_offset_len(struct unit_test_state *uts)
Simon Glass7df766e2014-12-10 08:55:55 -070087{
88 struct udevice *bus, *dev;
89 uint8_t buf[5];
90
91 ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
Simon Glassa2723ae2015-01-25 08:26:55 -070092 ut_assertok(i2c_get_chip(bus, chip, 1, &dev));
Simon Glass7df766e2014-12-10 08:55:55 -070093 ut_assertok(i2c_set_chip_offset_len(dev, 1));
Simon Glass7d722762015-01-12 18:02:07 -070094 ut_assertok(dm_i2c_read(dev, 0, buf, 5));
Simon Glass7df766e2014-12-10 08:55:55 -070095
96 /* This is not supported by the uclass */
97 ut_asserteq(-EINVAL, i2c_set_chip_offset_len(dev, 5));
98
99 return 0;
100}
Simon Glass974dccd2020-07-28 19:41:12 -0600101DM_TEST(dm_test_i2c_offset_len, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glass7df766e2014-12-10 08:55:55 -0700102
Joe Hershberger3a77be52015-05-20 14:27:27 -0500103static int dm_test_i2c_probe_empty(struct unit_test_state *uts)
Simon Glass7df766e2014-12-10 08:55:55 -0700104{
105 struct udevice *bus, *dev;
106
107 ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
Simon Glass4c70ed92015-04-20 12:37:15 -0600108
109 /* Use test mode so that this chip address will always probe */
110 sandbox_i2c_set_test_mode(bus, true);
Simon Glass7d722762015-01-12 18:02:07 -0700111 ut_assertok(dm_i2c_probe(bus, SANDBOX_I2C_TEST_ADDR, 0, &dev));
Simon Glass4c70ed92015-04-20 12:37:15 -0600112 sandbox_i2c_set_test_mode(bus, false);
Simon Glass7df766e2014-12-10 08:55:55 -0700113
114 return 0;
115}
Simon Glass974dccd2020-07-28 19:41:12 -0600116DM_TEST(dm_test_i2c_probe_empty, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glass7df766e2014-12-10 08:55:55 -0700117
Joe Hershberger3a77be52015-05-20 14:27:27 -0500118static int dm_test_i2c_bytewise(struct unit_test_state *uts)
Simon Glass7df766e2014-12-10 08:55:55 -0700119{
120 struct udevice *bus, *dev;
121 struct udevice *eeprom;
122 uint8_t buf[5];
123
124 ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
Simon Glassa2723ae2015-01-25 08:26:55 -0700125 ut_assertok(i2c_get_chip(bus, chip, 1, &dev));
Simon Glass7d722762015-01-12 18:02:07 -0700126 ut_assertok(dm_i2c_read(dev, 0, buf, 5));
Simon Glassa3186e62020-05-10 12:52:45 -0600127 ut_asserteq_mem(buf, "\0\0\0\0\0", sizeof(buf));
Simon Glass7df766e2014-12-10 08:55:55 -0700128
129 /* Tell the EEPROM to only read/write one register at a time */
130 ut_assertok(uclass_first_device(UCLASS_I2C_EMUL, &eeprom));
131 ut_assertnonnull(eeprom);
132 sandbox_i2c_eeprom_set_test_mode(eeprom, SIE_TEST_MODE_SINGLE_BYTE);
133
134 /* Now we only get the first byte - the rest will be 0xff */
Simon Glass7d722762015-01-12 18:02:07 -0700135 ut_assertok(dm_i2c_read(dev, 0, buf, 5));
Simon Glassa3186e62020-05-10 12:52:45 -0600136 ut_asserteq_mem(buf, "\0\xff\xff\xff\xff", sizeof(buf));
Simon Glass7df766e2014-12-10 08:55:55 -0700137
138 /* If we do a separate transaction for each byte, it works */
139 ut_assertok(i2c_set_chip_flags(dev, DM_I2C_CHIP_RD_ADDRESS));
Simon Glass7d722762015-01-12 18:02:07 -0700140 ut_assertok(dm_i2c_read(dev, 0, buf, 5));
Simon Glassa3186e62020-05-10 12:52:45 -0600141 ut_asserteq_mem(buf, "\0\0\0\0\0", sizeof(buf));
Simon Glass7df766e2014-12-10 08:55:55 -0700142
143 /* This will only write A */
144 ut_assertok(i2c_set_chip_flags(dev, 0));
Simon Glass7d722762015-01-12 18:02:07 -0700145 ut_assertok(dm_i2c_write(dev, 2, (uint8_t *)"AB", 2));
146 ut_assertok(dm_i2c_read(dev, 0, buf, 5));
Simon Glassa3186e62020-05-10 12:52:45 -0600147 ut_asserteq_mem(buf, "\0\xff\xff\xff\xff", sizeof(buf));
Simon Glass7df766e2014-12-10 08:55:55 -0700148
149 /* Check that the B was ignored */
150 ut_assertok(i2c_set_chip_flags(dev, DM_I2C_CHIP_RD_ADDRESS));
Simon Glass7d722762015-01-12 18:02:07 -0700151 ut_assertok(dm_i2c_read(dev, 0, buf, 5));
Simon Glassa3186e62020-05-10 12:52:45 -0600152 ut_asserteq_mem(buf, "\0\0A\0\0\0", sizeof(buf));
Simon Glass7df766e2014-12-10 08:55:55 -0700153
154 /* Now write it again with the new flags, it should work */
155 ut_assertok(i2c_set_chip_flags(dev, DM_I2C_CHIP_WR_ADDRESS));
Simon Glass7d722762015-01-12 18:02:07 -0700156 ut_assertok(dm_i2c_write(dev, 2, (uint8_t *)"AB", 2));
157 ut_assertok(dm_i2c_read(dev, 0, buf, 5));
Simon Glassa3186e62020-05-10 12:52:45 -0600158 ut_asserteq_mem(buf, "\0\xff\xff\xff\xff", sizeof(buf));
Simon Glass7df766e2014-12-10 08:55:55 -0700159
160 ut_assertok(i2c_set_chip_flags(dev, DM_I2C_CHIP_WR_ADDRESS |
161 DM_I2C_CHIP_RD_ADDRESS));
Simon Glass7d722762015-01-12 18:02:07 -0700162 ut_assertok(dm_i2c_read(dev, 0, buf, 5));
Simon Glassa3186e62020-05-10 12:52:45 -0600163 ut_asserteq_mem(buf, "\0\0AB\0\0", sizeof(buf));
Simon Glass7df766e2014-12-10 08:55:55 -0700164
165 /* Restore defaults */
166 sandbox_i2c_eeprom_set_test_mode(eeprom, SIE_TEST_MODE_NONE);
167 ut_assertok(i2c_set_chip_flags(dev, 0));
168
169 return 0;
170}
Simon Glass974dccd2020-07-28 19:41:12 -0600171DM_TEST(dm_test_i2c_bytewise, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glass7df766e2014-12-10 08:55:55 -0700172
Joe Hershberger3a77be52015-05-20 14:27:27 -0500173static int dm_test_i2c_offset(struct unit_test_state *uts)
Simon Glass7df766e2014-12-10 08:55:55 -0700174{
175 struct udevice *eeprom;
176 struct udevice *dev;
177 uint8_t buf[5];
178
Simon Glassa2723ae2015-01-25 08:26:55 -0700179 ut_assertok(i2c_get_chip_for_busnum(busnum, chip, 1, &dev));
Simon Glass7df766e2014-12-10 08:55:55 -0700180
181 /* Do a transfer so we can find the emulator */
Simon Glass7d722762015-01-12 18:02:07 -0700182 ut_assertok(dm_i2c_read(dev, 0, buf, 5));
Simon Glass7df766e2014-12-10 08:55:55 -0700183 ut_assertok(uclass_first_device(UCLASS_I2C_EMUL, &eeprom));
184
185 /* Offset length 0 */
186 sandbox_i2c_eeprom_set_offset_len(eeprom, 0);
187 ut_assertok(i2c_set_chip_offset_len(dev, 0));
Simon Glass7d722762015-01-12 18:02:07 -0700188 ut_assertok(dm_i2c_write(dev, 10 /* ignored */, (uint8_t *)"AB", 2));
189 ut_assertok(dm_i2c_read(dev, 0, buf, 5));
Robert Beckett1fe8a492019-10-28 17:44:58 +0000190 ut_asserteq_mem("AB\0\0\0\0", buf, sizeof(buf));
191 ut_asserteq(0, sanbox_i2c_eeprom_get_prev_offset(eeprom));
Simon Glass7df766e2014-12-10 08:55:55 -0700192
193 /* Offset length 1 */
194 sandbox_i2c_eeprom_set_offset_len(eeprom, 1);
195 ut_assertok(i2c_set_chip_offset_len(dev, 1));
Simon Glass7d722762015-01-12 18:02:07 -0700196 ut_assertok(dm_i2c_write(dev, 2, (uint8_t *)"AB", 2));
Robert Beckett1fe8a492019-10-28 17:44:58 +0000197 ut_asserteq(2, sanbox_i2c_eeprom_get_prev_offset(eeprom));
Simon Glass7d722762015-01-12 18:02:07 -0700198 ut_assertok(dm_i2c_read(dev, 0, buf, 5));
Robert Beckett1fe8a492019-10-28 17:44:58 +0000199 ut_asserteq_mem("ABAB\0", buf, sizeof(buf));
200 ut_asserteq(0, sanbox_i2c_eeprom_get_prev_offset(eeprom));
Simon Glass7df766e2014-12-10 08:55:55 -0700201
Robert Beckett1fe8a492019-10-28 17:44:58 +0000202 /* Offset length 2 boundary - check model wrapping */
Simon Glass7df766e2014-12-10 08:55:55 -0700203 sandbox_i2c_eeprom_set_offset_len(eeprom, 2);
204 ut_assertok(i2c_set_chip_offset_len(dev, 2));
Robert Beckett1fe8a492019-10-28 17:44:58 +0000205 ut_assertok(dm_i2c_write(dev, 0xFF, (uint8_t *)"A", 1));
206 ut_asserteq(0xFF, sanbox_i2c_eeprom_get_prev_offset(eeprom));
207 ut_assertok(dm_i2c_write(dev, 0x100, (uint8_t *)"B", 1));
208 ut_asserteq(0x100, sanbox_i2c_eeprom_get_prev_offset(eeprom));
209 ut_assertok(dm_i2c_write(dev, 0x101, (uint8_t *)"C", 1));
210 ut_asserteq(0x101, sanbox_i2c_eeprom_get_prev_offset(eeprom));
211 ut_assertok(dm_i2c_read(dev, 0xFF, buf, 5));
212 ut_asserteq_mem("ABCAB", buf, sizeof(buf));
213 ut_asserteq(0xFF, sanbox_i2c_eeprom_get_prev_offset(eeprom));
Simon Glass7df766e2014-12-10 08:55:55 -0700214
Robert Beckett1fe8a492019-10-28 17:44:58 +0000215 /* Offset length 2 */
Simon Glass7df766e2014-12-10 08:55:55 -0700216 sandbox_i2c_eeprom_set_offset_len(eeprom, 2);
217 ut_assertok(i2c_set_chip_offset_len(dev, 2));
Robert Beckett1fe8a492019-10-28 17:44:58 +0000218 ut_assertok(dm_i2c_write(dev, 0x2020, (uint8_t *)"AB", 2));
219 ut_assertok(dm_i2c_read(dev, 0x2020, buf, 5));
220 ut_asserteq_mem("AB\0\0\0", buf, sizeof(buf));
221 ut_asserteq(0x2020, sanbox_i2c_eeprom_get_prev_offset(eeprom));
222
223 /* Offset length 3 */
224 sandbox_i2c_eeprom_set_offset_len(eeprom, 3);
225 ut_assertok(i2c_set_chip_offset_len(dev, 3));
226 ut_assertok(dm_i2c_write(dev, 0x303030, (uint8_t *)"AB", 2));
227 ut_assertok(dm_i2c_read(dev, 0x303030, buf, 5));
228 ut_asserteq_mem("AB\0\0\0", buf, sizeof(buf));
229 ut_asserteq(0x303030, sanbox_i2c_eeprom_get_prev_offset(eeprom));
Simon Glass7df766e2014-12-10 08:55:55 -0700230
231 /* Offset length 4 */
Robert Beckett1fe8a492019-10-28 17:44:58 +0000232 sandbox_i2c_eeprom_set_offset_len(eeprom, 4);
233 ut_assertok(i2c_set_chip_offset_len(dev, 4));
234 ut_assertok(dm_i2c_write(dev, 0x40404040, (uint8_t *)"AB", 2));
235 ut_assertok(dm_i2c_read(dev, 0x40404040, buf, 5));
236 ut_asserteq_mem("AB\0\0\0", buf, sizeof(buf));
237 ut_asserteq(0x40404040, sanbox_i2c_eeprom_get_prev_offset(eeprom));
Simon Glass7df766e2014-12-10 08:55:55 -0700238
239 /* Restore defaults */
240 sandbox_i2c_eeprom_set_offset_len(eeprom, 1);
241
242 return 0;
243}
Simon Glass974dccd2020-07-28 19:41:12 -0600244DM_TEST(dm_test_i2c_offset, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Robert Beckettf695f6e2019-10-28 17:44:59 +0000245
246static int dm_test_i2c_addr_offset(struct unit_test_state *uts)
247{
248 struct udevice *eeprom;
249 struct udevice *dev;
250 u8 buf[5];
251
252 ut_assertok(i2c_get_chip_for_busnum(busnum, chip, 1, &dev));
253
254 /* Do a transfer so we can find the emulator */
255 ut_assertok(dm_i2c_read(dev, 0, buf, 5));
256 ut_assertok(uclass_first_device(UCLASS_I2C_EMUL, &eeprom));
257
258 /* Offset length 0 */
259 sandbox_i2c_eeprom_set_offset_len(eeprom, 0);
260 sandbox_i2c_eeprom_set_chip_addr_offset_mask(eeprom, 0x3);
261 ut_assertok(i2c_set_chip_offset_len(dev, 0));
262 ut_assertok(i2c_set_chip_addr_offset_mask(dev, 0x3));
263 ut_assertok(dm_i2c_write(dev, 0x3, (uint8_t *)"AB", 2));
264 ut_assertok(dm_i2c_read(dev, 0x3, buf, 5));
265 ut_asserteq_mem("AB\0\0\0\0", buf, sizeof(buf));
266 ut_asserteq(0x3, sanbox_i2c_eeprom_get_prev_offset(eeprom));
267 ut_asserteq(chip | 0x3, sanbox_i2c_eeprom_get_prev_addr(eeprom));
268
269 /* Offset length 1 */
270 sandbox_i2c_eeprom_set_offset_len(eeprom, 1);
271 sandbox_i2c_eeprom_set_chip_addr_offset_mask(eeprom, 0x3);
272 ut_assertok(i2c_set_chip_offset_len(dev, 1));
273 ut_assertok(i2c_set_chip_addr_offset_mask(dev, 0x3));
274 ut_assertok(dm_i2c_write(dev, 0x310, (uint8_t *)"AB", 2));
275 ut_assertok(dm_i2c_read(dev, 0x310, buf, 5));
276 ut_asserteq_mem("AB\0\0\0\0", buf, sizeof(buf));
277 ut_asserteq(0x310, sanbox_i2c_eeprom_get_prev_offset(eeprom));
278 ut_asserteq(chip | 0x3, sanbox_i2c_eeprom_get_prev_addr(eeprom));
279
280 /* Offset length 2 */
281 sandbox_i2c_eeprom_set_offset_len(eeprom, 2);
282 sandbox_i2c_eeprom_set_chip_addr_offset_mask(eeprom, 0x3);
283 ut_assertok(i2c_set_chip_offset_len(dev, 2));
284 ut_assertok(i2c_set_chip_addr_offset_mask(dev, 0x3));
285 ut_assertok(dm_i2c_write(dev, 0x32020, (uint8_t *)"AB", 2));
286 ut_assertok(dm_i2c_read(dev, 0x32020, buf, 5));
287 ut_asserteq_mem("AB\0\0\0\0", buf, sizeof(buf));
288 ut_asserteq(0x32020, sanbox_i2c_eeprom_get_prev_offset(eeprom));
289 ut_asserteq(chip | 0x3, sanbox_i2c_eeprom_get_prev_addr(eeprom));
290
291 /* Offset length 3 */
292 sandbox_i2c_eeprom_set_offset_len(eeprom, 3);
293 sandbox_i2c_eeprom_set_chip_addr_offset_mask(eeprom, 0x3);
294 ut_assertok(i2c_set_chip_offset_len(dev, 3));
295 ut_assertok(i2c_set_chip_addr_offset_mask(dev, 0x3));
296 ut_assertok(dm_i2c_write(dev, 0x3303030, (uint8_t *)"AB", 2));
297 ut_assertok(dm_i2c_read(dev, 0x3303030, buf, 5));
298 ut_asserteq_mem("AB\0\0\0\0", buf, sizeof(buf));
299 ut_asserteq(0x3303030, sanbox_i2c_eeprom_get_prev_offset(eeprom));
300 ut_asserteq(chip | 0x3, sanbox_i2c_eeprom_get_prev_addr(eeprom));
301
302 /* Restore defaults */
303 sandbox_i2c_eeprom_set_offset_len(eeprom, 1);
304 sandbox_i2c_eeprom_set_chip_addr_offset_mask(eeprom, 0);
305
306 return 0;
307}
308
Simon Glass974dccd2020-07-28 19:41:12 -0600309DM_TEST(dm_test_i2c_addr_offset, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);