How to use I2C in U-Boot SPL
Thomas Thielemann
th.thielemann at web.de
Wed Nov 22 21:57:18 CET 2023
Hello U-Boot,
I was able to use the I2C commands from within U-Boot to control my I2C device:
Configured the Processor GPIOs for the I2C bus in device tree
Enabled the I2C bus in device tree
Added my device to the I2C bus in device tree
Wrote my script into a U-Boot variable
Run my script
Now I want to do the same from within the U-Boot SPL. I extended int board_early_init_f(void) in board.c for my hardware. The debug output is printed at run time. But the I2C device is not found.
How do I review whether the I2C bus is using the right GPIOs and whether my device is configured right?
static int i2c_get_dev(uint bus_num, uint dev_num, struct udevice **i2c_dev)
{
int ret;
if (!i2c_led_bus) {
ret = uclass_get_device_by_seq(UCLASS_I2C, bus_num, &i2c_led_bus);
if (ret) {
printf("I2C bus %i not found (%d)\n", dev_num, ret);
return -ENODEV;
}
}
return i2c_get_chip(i2c_led_bus, dev_num, bus_num, i2c_dev);
}
#endif
static int i2c_enable_leds(void)
{
log_info("i2c_enable_leds\n");
const uint bus_num = 1; // i2c bus
const uint dev_num = 0x28; // i2c chip address
const uint dev_addr = 0x00; // write all bytes in one junk from start
const uint dev_addr_len = 1;
int ret;
const uint cmd_len = 29; // cmd_len is the number of bytes.
uchar cmd[29] = {
0x40, 0x3c, // init
0x00, 0x00, 0x00, 0x00, 0x00, // unused
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // set intensitiy to max
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // unused
0xff, 0x00, 0x00, // RGB LED
0xff, 0x00, 0x00 // RGB LED
};
#if CONFIG_IS_ENABLED(DM_I2C)
struct udevice *i2c_dev;
struct dm_i2c_chip *i2c_chip;
#endif
#if CONFIG_IS_ENABLED(DM_I2C)
ret = i2c_get_dev(bus_num, dev_num, &i2c_dev);
if (!ret)
ret = i2c_set_chip_offset_len(i2c_dev, dev_addr_len);
if (ret) {
log_err("Failed to write to 0x28 (%d)\n", ret);
return ret;
}
i2c_chip = dev_get_parent_plat(i2c_dev);
if (!i2c_chip) {
log_err("Failed to write to 0x28 (%d)\n", ret);
return ret;
}
#endif
#if CONFIG_IS_ENABLED(DM_I2C)
i2c_chip->flags &= ~DM_I2C_CHIP_WR_ADDRESS;
ret = dm_i2c_write(i2c_dev, dev_addr, cmd, cmd_len);
#else
ret = i2c_write(dev_num, dev_addr, dev_addr_len, cmd, cmd_len);
#endif
if (ret)
log_err("Failed to write to 0x28 (%d)\n", ret);
return 0;
}
int board_early_init_f(void)
{
i2c_enable_leds();
return 0;
}
Regards,
Thomas
More information about the U-Boot
mailing list