kHi Thomas, On Wed, 22 Nov 2023 at 13:57, Thomas Thielemann <th.thielem...@web.de> wrote: > > 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; > }
You should use driver mode for this, i.e. add your i2c device to the devicetree with a suitable driver in place, then probe it, e.g. with uclass_first_device(UCLASS_LED) Accessing the chip directly like this is a bit hacky :-) If you include a bit more info about what piece breaks, it would help people to offer ideas. Regards, SImon