This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TDA2SX: How to enable i2c 2~5 in uboot?

Part Number: TDA2SX

Hi,

For implementing "early boot late attach" to our custom board for VSDK304, we need to enable i2c2 ~ i2c5 in uboot to control our devices. They are disabled by default. We do these:

add pinmux define

modify .dtsi

add a sensor device

but still get err in uboot

=> i2c dev 1

Setting bus to 1

Failure changing bus number (-19)

How to solve it? Thanks.

  • Hi,

    Please try the command below from the U-Boot command prompt:

    i2c bus

    The above will give all the busses/i2c instances that are registered.

    Based on that we can get the bus number that i2c2 is registered as & then use that number x.

    i2c dev x instead of using 1.

    Best Regards,
    Keerthy

  • Hi,

    Running "i2c bus", we only get one bus

    => i2c bus

    Bus -1: i2c@48070000  (active 0)

       58: tps659038@58, offset len 1, flags 0

    BR,

    Jeff

  • Hi Jeff,

    The other instances are not getting probed. Can you add prints to the i2c driver and check?

    Only the i2c instance hosting the PMIC seems to be getting probed. In the case of U-Boot the nodes get probed on a bed basis. You will have to invoke probes by using uclass APIs.

    Regards,

    Keerthy

  • Hi Keerthy,

    1. Where should we add prints to the i2c driver to check?

    2. How to use uclass APIs? We can't find some code useful for this issue. Can you give us some sample?

    3. Can we enable i2c in ipu2 instead? Please help us for this: https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1172977/tda2sx-how-to-enable-i2c-2-5-in-ipu2

    BR,

    Jeff

  • Can we enable i2c in ipu2 instead? Please help us for this:

    Hi Jeff,

    Our IPU expert will feedback on the thread. If your final intent is that then let's wait for that feedback on that thread.

    Best Regards,

    Keerthy

  • Hi Keerthy,

    Our goal is to enable i2c before linux, so we hope to study both methods in case one of them can't work eventually. Please continue helping us for "enable i2c in uboot'. Thans a lot!

    BR,

    Jeff

  • Hi Jeff,

    At the end of the function spl_board_init under: arch/arm/mach-omap2/boot-common.c
    Can you try something like:

    ret = uclass_get_device_by_name(UCLASS_I2C,  "i2c@48072000", &dev);

    This will ensure that i2c2 device gets probed.

    Best Regards,
    Keerthy

  • Hi Keerthy,

    We only find same file name here:./os_tools/linux/u-boot/u-boot/arch/arm/cpu/armv7/omap-common/boot-common.c

    And it looks weird to add your code to spl_board_init():

    void spl_board_init(void)
    {
    /*
    * Save the boot parameters passed from romcode.
    * We cannot delay the saving further than this,
    * to prevent overwrites.
    */
    save_omap_boot_params();

    /* Prepare console output */
    preloader_console_init();

    #if defined(CONFIG_SPL_NAND_SUPPORT) || defined(CONFIG_SPL_ONENAND_SUPPORT)
    gpmc_init();
    #endif
    #ifdef CONFIG_SPL_I2C_SUPPORT
    i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE);
    #endif
    #if defined(CONFIG_AM33XX) && defined(CONFIG_SPL_MUSB_NEW_SUPPORT)

    arch_misc_init();
    #endif
    #if defined(CONFIG_HW_WATCHDOG)
    hw_watchdog_init();
    #endif
    #ifdef CONFIG_AM33XX
    am33xx_spl_board_init();
    #endif

    #if defined(CONFIG_SPL_ANDROID_BOOT_SUPPORT)
    board_init();
    #endif

    }

    On the other hand, we modify .dts file:

    &i2c2 {

              status = "okay";

              clock-frequency = <400000>;

              max96708: max96708@48 {

                       compatible = "maxim,max96708";

                       reg = <0x48>;

                                 interrupt-controller;

                       };

    };

     

    &i2c3 {

              status = "okay";

              clock-frequency = <400000>;

              max96708_1: max96708@48 {

                       compatible = "maxim,max96708";

                       reg = <0x48>;

                                 interrupt-controller;

                       };      

    };

    &i2c4 {

              status = "okay";

              clock-frequency = <400000>;

              max96708_2: max96708@48 {

                       compatible = "maxim,max96708";

                       reg = <0x48>;

                                 interrupt-controller;

                       };               

    };

    &i2c5 {

              status = "okay";

              clock-frequency = <400000>;

              max96708_3: max96708@48 {

                       compatible = "maxim,max96708";

                       reg = <0x48>;

                                 interrupt-controller;

                       };               

    };

    And add a driver for our sensor: Max96708.c

    static int max96708_write(struct udevice *dev, uint reg, const uint8_t *buff,

                                   int len)

    {

              printf("%s,%d \r\n",__func__,__LINE__);

              if (dm_i2c_write(dev, reg, buff, len)) {

                       error("write error to device: %p register: %#x!", dev, reg);

                       return -EIO;

              }

              return 0;

    }

    static int max96708_read(struct udevice *dev, uint reg, uint8_t *buff, int len)

    {

              printf("%s,%d \r\n",__func__,__LINE__);

              if (dm_i2c_read(dev, reg, buff, len)) {

                       error("read error from device: %p register: %#x!", dev, reg);

                       return -EIO;

              }

              return 0;

    }

    static int max96708_bind(struct udevice *dev)

    {

              int pmic_node = -1, regulators_node;

              const void *blob = gd->fdt_blob;

              int children;

              int node = dev->of_offset;

              int subnode, len;

              printf("%s,%d \r\n",__func__,__LINE__);

              fdt_for_each_subnode(blob, subnode, node) {

                       const char *name;

                       char *temp;

     

                       name = fdt_get_name(blob, subnode, &len);

                       temp = strstr(name, "pmic");

                       if (temp) {

                                 pmic_node = subnode;

                                 break;

                       }

              }

              #if 0

              if (pmic_node <= 0) {

                       debug("%s: %s pmic subnode not found!", __func__, dev->name);

                       return -ENXIO;

              }

     

              regulators_node = fdt_subnode_offset(blob, pmic_node, "regulators");

     

              if (regulators_node <= 0) {

                       debug("%s: %s reg subnode not found!", __func__, dev->name);

                       return -ENXIO;

              }

     

              children = pmic_bind_children(dev, regulators_node, pmic_children_info);

              if (!children)

                       debug("%s: %s - no child found\n", __func__, dev->name);

              #endif

              printf("%s,%d \r\n",__func__,__LINE__);

              /* Always return success for this device */

              return 0;

    }

    static struct dm_pmic_ops max96708_ops = {

    //      .reg_count = max96708_reg_count,

              .read = max96708_read,

              .write = max96708_write,

    };

     

    static const struct udevice_id max96708_ids[] = {

              { .compatible = "maxim,max96708" },

              { }

    };

     

    U_BOOT_DRIVER(pmic_max96708) = {

              .name = "max96708_pmic",

              .id = UCLASS_PMIC,

              .of_match = max96708_ids,

              .bind = max96708_bind,

              .ops = &max96708_ops,

             

    };

     

    Power on, and we get:

    => i2c bus

    Bus -1: i2c@48070000  (active 0)

       58: tps659038@58, offset len 1, flags 0

    Bus -1: i2c@48072000

       48: max96708@48, offset len 1, flags 0

    Bus -1: i2c@48060000

       48: max96708@48, offset len 1, flags 0

    Bus -1: i2c@4807a000

       48: max96708@48, offset len 1, flags 0

    Bus -1: i2c@4807c000

       48: max96708@48, offset len 1, flags 0

    => i2c dev 0

    Setting bus to 0

    => i2c dev 1

    Setting bus to 1

    Failure changing bus number (-19)

    =>

    Did we modify the dts file correctly? How should we write the max96708 driver file? Thanks.

    BR,

    Jeff

  • Hi Jeff,

    I am not aware of the max part please consult the maxim experts.

    Best Regards,

    Keerthy

  • Hi Keerthy,

    Ok. If you are not family with maxim chip, let's focus on i2c. Please help us setup i2c part correctly.

    BR,

    Jeff

  • Bus -1: i2c@48070000 (active 0)
    58: tps659038@58, offset len 1, flags 0
    Bus -1: i2c@48072000
    Bus -1: i2c@48060000
    Bus -1: i2c@4807a000
    => i2c dev 1
    Setting bus to 1
    Failure changing bus number (-19)
    => i2c dev 0
    Setting bus to 0

    remove maxim chip device , have detect i2c2 ~ i2c4 , still not switch i2c2,
    Can you tell me where can get  example  code  ? 

  • Hi Casper,

    Apologies for the delayed response, Could you please elaborate on the above questions?
    Have you checked why the below error comes up?

    Failure changing bus number (-19)

    - Keerthy

  • Hi Keerthy,

    We found example code from newer uboot and solved our problems. Thanks.

    BR,

    Jeff