One thing you may want to try is replace the cadence I2C driver with the generic bit-bang GPIO driver (on the same pins).

Example devicetree that does this in the kernel (you'll need to activate the bitbang gpio i2c driver in the kernel config though):
https://github.com/topic-embedded-products/linux/blob/topic-miami/arch/arm/boot/dts/topic-miami.dtsi#L52

We have had lots of troubles with the I2C controller in the Zynq, it appears to be broken, and replacing the driver with a bitbang GPIO one solved all issues. In our case, the problem was with longer transfers like sending EDID tables to video encoder chips, but we've seen occasional failures on simple transfers (eeprom, hw monitors, etc) as well.



On 30-11-18 19:47, Martin Townsend wrote:
Hi,

We are in the process of upgrading to Sumo which has the 4.14
linux-xlnx kernel and everything is working fine except for our
LTC-3375 regulator device driver which was working fine with the 4.9
kernel but with the newer kernel we are getting the following in the
log.

SW1: failed to get the current voltage(-6)
ltc3375 6-0034: failed to register regulator SW1: -6

We get this message twice as there are 2 LTC-3375 on different
channels of the PCA9548, here's a cut down version of the device tree:

&i2c0 {
     status = "okay";
     /* clock-frequency = <400000>; */
     clock-frequency = <100000>;
     pinctrl-names = "default";
     pinctrl-0 = <&pinctrl_i2c0_default>;


     /* I2C Switch */
     i2cswitch@70 {
         compatible = "nxp,pca9548";
         #address-cells = <1>;
         #size-cells = <0>;
         reg = <0x70>;

         /* PS Power Switcher */
         i2c@4 {
             #address-cells = <1>;
             #size-cells = <0>;
             reg = <4>;

             powerswitcher1@34 {
                 compatible = "ltc,ltc3375";
                 reg = <0x34>;
                 interrupt-parent = <&gpiom2>;
                 interrupts = <12 1>;

                 regulators {
                   sw1 {
                         regulator-min-microvolt = <693987>;
                         regulator-max-microvolt = <1306329>;
                         lltc,fb-voltage-divider = <100000 158000>;
                         regulator-ramp-delay = <7000>;
                         regulator-boot-on;
                         regulator-always-on;
                     };
                     sw2 {
                         ...
                     };
                     sw3 {
                         ...
                     };
                     sw4 {
                         ...
                     };
                     sw5 {
                         ...
                     };
                     sw6 {
                         ...
                     };
                     sw7 {
                         ...
                     };
                     sw8 {
                         ...
                     };
                 };
             };
         };

         /* PL Power Switcher */
         i2c@5 {
             #address-cells = <1>;
             #size-cells = <0>;
             reg = <5>;

             powerswitcher1@34 {
                 compatible = "ltc,ltc3375";
                 reg = <0x34>;
                 interrupt-parent = <&gpiom2>;
                 interrupts = <13 1>;

                 regulators {
                     sw1 {
                         regulator-min-microvolt = <693987>;
                         regulator-max-microvolt = <1306329>;
                         lltc,fb-voltage-divider = <100000 158000>;
                         regulator-ramp-delay = <7000>;
                         regulator-boot-on;
                         regulator-always-on;
                     };
                     sw2 {
                         ...
                     };
                     sw3 {
                         ...
                     };
                     sw4 {
                         ...
                     };
                     sw5 {
                         ...
                     };
                     sw6 {
                         ...
                     };
                     sw7 {
                         ...
                     };
                     sw8 {
                         ...
                     };
                 };
             };
         };
     };
};

I traced the -6 error code (-ENXIO) to the cadence driver where it
basically receives a NAK.

static int cdns_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
                 int num)
{
      ...
     /* Process the msg one by one */
     for (count = 0; count < num; count++, msgs++) {
         if (count == (num - 1))
             id->bus_hold_flag = 0;

         ret = cdns_i2c_process_msg(id, msgs, adap);
         if (ret)
             goto out;

         /* Report the other error interrupts to application */
         if (id->err_status) {
             cdns_i2c_master_reset(adap);

             if (id->err_status & CDNS_I2C_IXR_NACK) {
                 ret = -ENXIO;
                 goto out;
             }
             ret = -EIO;
             goto out;
         }
     }
}

After debugging further I can see that it's trying to select the right
channel of the PCA9548 but the i2c controller on the Xilinx is failing
with a NAK.  So it's not even getting as far as the LTC driver.  Here
is some of my debug that shows it's the PCA9548 that is failing as
this is address 0x70 whereas the LTC is at 0x34

pca954x_select_chan: chan:4 regval:10
pca954x_reg_write: addr:70 val:10
cdns-i2c e0004000.i2c: cdns_i2c_master_xfer: id->err_status=4
cdns-i2c e0004000.i2c: cdns_i2c_master_xfer: id->p_msg->addr=70

I've done a diff between the 4.9 and 4.14 kernel but can't see any
obvious in either of these drivers.  I've checked the device tree in
this area but again can see no changes.  The second I2C interface is
working fine, I2C1.

I did a dump_stack on the i2c read that was failing
[<c010e854>] (unwind_backtrace) from [<c010aa68>] (show_stack+0x10/0x14)
[<c010aa68>] (show_stack) from [<c064a3e8>] (dump_stack+0x80/0xa0)
[<c064a3e8>] (dump_stack) from [<c04a2e50>] (cdns_i2c_master_xfer+0x2fc/0x3e4)
[<c04a2e50>] (cdns_i2c_master_xfer) from [<c049e908>]
(_i2c_transfer+0x1cc/0x20c)
[<c049e908>] (_i2c_transfer) from [<c04a38dc>] (pca954x_reg_write+0x4c/0x8c)
[<c04a38dc>] (pca954x_reg_write) from [<c04a3990>]
(pca954x_select_chan+0x44/0x5c)
[<c04a3990>] (pca954x_select_chan) from [<c04a1548>]
(_i2c_mux_master_xfer+0x28/0x64)
[<c04a1548>] (_i2c_mux_master_xfer) from [<c049e908>]
(_i2c_transfer+0x1cc/0x20c)
[<c049e908>] (_i2c_transfer) from [<c049e9d4>] (i2c_transfer+0x8c/0xac)
[<c049e9d4>] (i2c_transfer) from [<c03d553c>] (regmap_i2c_read+0x48/0x64)
[<c03d553c>] (regmap_i2c_read) from [<c03d29fc>] (regmap_raw_read+0x84/0xd0)
[<c03d29fc>] (_regmap_raw_read) from [<c03d2a70>] (_regmap_bus_read+0x28/0x48)
[<c03d2a70>] (_regmap_bus_read) from [<c03d2504>] (_regmap_read+0x84/0xac)
[<c03d2504>] (_regmap_read) from [<c03d256c>] (regmap_read+0x40/0x58)
[<c03d256c>] (regmap_read) from [<c0364bec>]
(regulator_get_voltage_sel_regmap+0x1c/0x50)
[<c0364bec>] (regulator_get_voltage_sel_regmap) from [<bf0472a8>]
(ltc3375_get_voltage_sel_regmap+0xc/0x4c [oina_regulator_ltc3375])
[<bf0472a8>] (ltc3375_get_voltage_sel_regmap [oina_regulator_ltc3375])
from [<c0361a10>] (_regulator_get_voltage+0x8c/0x128)
[<c0361a10>] (_regulator_get_voltage) from [<c03637f4>]
(regulator_register+0x3ec/0xb60)
[<c03637f4>] (regulator_register) from [<bf0475a4>]
(ltc3375_probe+0x2bc/0x394 [oina_regulator_ltc3375])
[<bf0475a4>] (ltc3375_probe [regulator_ltc3375]) from [<c049e3d0>]
(i2c_device_probe+0x22c/0x244)

I'll look into the regulator_register code next but was just wondering
if anyone else has seen this or if anyone knows if there's a fix
available for this?

Any help appreciated,

Cheers,
Martin



--
Mike Looijmans
--
_______________________________________________
meta-xilinx mailing list
meta-xilinx@yoctoproject.org
https://lists.yoctoproject.org/listinfo/meta-xilinx

Reply via email to