Commit 931115e7 authored by Bob Beckett's avatar Bob Beckett
Browse files

dm: i2c: EEPROM simulator add tests for addr offset mask



Add support for setting the chip address offset mask to EEPROM sumulator
and add tests to test it.
Signed-off-by: Bob Beckett's avatarRobert Beckett <bob.beckett@collabora.com>
Series-to: u-boot@lists.denx.de
Series-cc: Robert Beckett <bob.beckett@collabora.com>
Cover-letter:
i2c: add support for offset overflow in to chip address
Add support for devices that can overflow the offset in to the chip
address. This makes the devices effectively steal consecutive chip
addresses.

Also improve i2c testing and add new test for this new addressing mode.
END
parent 9ddf31c4
......@@ -72,6 +72,9 @@ void sandbox_i2c_eeprom_set_test_mode(struct udevice *dev,
void sandbox_i2c_eeprom_set_offset_len(struct udevice *dev, int offset_len);
void sandbox_i2c_eeprom_set_chip_addr_offset_mask(struct udevice *dev,
uint mask);
uint sanbox_i2c_eeprom_get_prev_addr(struct udevice *dev);
uint sanbox_i2c_eeprom_get_prev_offset(struct udevice *dev);
......
......@@ -23,6 +23,7 @@ struct sandbox_i2c_flash_plat_data {
const char *filename;
int offset_len; /* Length of an offset in bytes */
int size; /* Size of data buffer */
uint chip_addr_offset_mask; /* mask of addr bits used for offset */
};
struct sandbox_i2c_flash {
......@@ -46,6 +47,14 @@ void sandbox_i2c_eeprom_set_offset_len(struct udevice *dev, int offset_len)
plat->offset_len = offset_len;
}
void sandbox_i2c_eeprom_set_chip_addr_offset_mask(struct udevice *dev,
uint mask)
{
struct sandbox_i2c_flash_plat_data *plat = dev_get_platdata(dev);
plat->chip_addr_offset_mask = mask;
}
uint sanbox_i2c_eeprom_get_prev_addr(struct udevice *dev)
{
struct sandbox_i2c_flash *priv = dev_get_priv(dev);
......@@ -64,7 +73,8 @@ static int sandbox_i2c_eeprom_xfer(struct udevice *emul, struct i2c_msg *msg,
int nmsgs)
{
struct sandbox_i2c_flash *priv = dev_get_priv(emul);
uint offset = 0;
struct sandbox_i2c_flash_plat_data *plat = dev_get_platdata(emul);
uint offset = msg->addr & plat->chip_addr_offset_mask;
debug("\n%s\n", __func__);
debug_buffer(0, priv->data, 1, 16, 0);
......@@ -73,17 +83,15 @@ static int sandbox_i2c_eeprom_xfer(struct udevice *emul, struct i2c_msg *msg,
priv->prev_addr = msg->addr;
for (; nmsgs > 0; nmsgs--, msg++) {
struct sandbox_i2c_flash_plat_data *plat =
dev_get_platdata(emul);
int len;
u8 *ptr;
if (!plat->size)
return -ENODEV;
len = msg->len;
debug(" %s: msg->len=%d",
debug(" %s: msg->addr=%x msg->len=%d",
msg->flags & I2C_M_RD ? "read" : "write",
msg->len);
msg->addr, msg->len);
if (msg->flags & I2C_M_RD) {
if (plat->test_mode == SIE_TEST_MODE_SINGLE_BYTE)
len = 1;
......@@ -153,6 +161,7 @@ static int sandbox_i2c_eeprom_ofdata_to_platdata(struct udevice *dev)
}
plat->test_mode = SIE_TEST_MODE_NONE;
plat->offset_len = 1;
plat->chip_addr_offset_mask = 0;
return 0;
}
......
......@@ -241,3 +241,67 @@ static int dm_test_i2c_offset(struct unit_test_state *uts)
return 0;
}
DM_TEST(dm_test_i2c_offset, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
static int dm_test_i2c_addr_offset(struct unit_test_state *uts)
{
struct udevice *eeprom;
struct udevice *dev;
u8 buf[5];
ut_assertok(i2c_get_chip_for_busnum(busnum, chip, 1, &dev));
/* Do a transfer so we can find the emulator */
ut_assertok(dm_i2c_read(dev, 0, buf, 5));
ut_assertok(uclass_first_device(UCLASS_I2C_EMUL, &eeprom));
/* Offset length 0 */
sandbox_i2c_eeprom_set_offset_len(eeprom, 0);
sandbox_i2c_eeprom_set_chip_addr_offset_mask(eeprom, 0x3);
ut_assertok(i2c_set_chip_offset_len(dev, 0));
ut_assertok(i2c_set_chip_addr_offset_mask(dev, 0x3));
ut_assertok(dm_i2c_write(dev, 0x3, (uint8_t *)"AB", 2));
ut_assertok(dm_i2c_read(dev, 0x3, buf, 5));
ut_asserteq_mem("AB\0\0\0\0", buf, sizeof(buf));
ut_asserteq(0x3, sanbox_i2c_eeprom_get_prev_offset(eeprom));
ut_asserteq(chip | 0x3, sanbox_i2c_eeprom_get_prev_addr(eeprom));
/* Offset length 1 */
sandbox_i2c_eeprom_set_offset_len(eeprom, 1);
sandbox_i2c_eeprom_set_chip_addr_offset_mask(eeprom, 0x3);
ut_assertok(i2c_set_chip_offset_len(dev, 1));
ut_assertok(i2c_set_chip_addr_offset_mask(dev, 0x3));
ut_assertok(dm_i2c_write(dev, 0x310, (uint8_t *)"AB", 2));
ut_assertok(dm_i2c_read(dev, 0x310, buf, 5));
ut_asserteq_mem("AB\0\0\0\0", buf, sizeof(buf));
ut_asserteq(0x310, sanbox_i2c_eeprom_get_prev_offset(eeprom));
ut_asserteq(chip | 0x3, sanbox_i2c_eeprom_get_prev_addr(eeprom));
/* Offset length 2 */
sandbox_i2c_eeprom_set_offset_len(eeprom, 2);
sandbox_i2c_eeprom_set_chip_addr_offset_mask(eeprom, 0x3);
ut_assertok(i2c_set_chip_offset_len(dev, 2));
ut_assertok(i2c_set_chip_addr_offset_mask(dev, 0x3));
ut_assertok(dm_i2c_write(dev, 0x32020, (uint8_t *)"AB", 2));
ut_assertok(dm_i2c_read(dev, 0x32020, buf, 5));
ut_asserteq_mem("AB\0\0\0\0", buf, sizeof(buf));
ut_asserteq(0x32020, sanbox_i2c_eeprom_get_prev_offset(eeprom));
ut_asserteq(chip | 0x3, sanbox_i2c_eeprom_get_prev_addr(eeprom));
/* Offset length 3 */
sandbox_i2c_eeprom_set_offset_len(eeprom, 3);
sandbox_i2c_eeprom_set_chip_addr_offset_mask(eeprom, 0x3);
ut_assertok(i2c_set_chip_offset_len(dev, 3));
ut_assertok(i2c_set_chip_addr_offset_mask(dev, 0x3));
ut_assertok(dm_i2c_write(dev, 0x3303030, (uint8_t *)"AB", 2));
ut_assertok(dm_i2c_read(dev, 0x3303030, buf, 5));
ut_asserteq_mem("AB\0\0\0\0", buf, sizeof(buf));
ut_asserteq(0x3303030, sanbox_i2c_eeprom_get_prev_offset(eeprom));
ut_asserteq(chip | 0x3, sanbox_i2c_eeprom_get_prev_addr(eeprom));
/* Restore defaults */
sandbox_i2c_eeprom_set_offset_len(eeprom, 1);
sandbox_i2c_eeprom_set_chip_addr_offset_mask(eeprom, 0);
return 0;
}
DM_TEST(dm_test_i2c_addr_offset, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment