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.

AM3359: problem with TPS6598x Linux driver with TPS65988

Part Number: AM3359
Other Parts Discussed in Thread: TPS65988, , TPS65987, TPS65982, TPS65981

I have a custom board with an AM3359 that runs Linux. The board includes two USB-C ports with a TPS65988DH. I'm building mainline kernel 5.4.106 with the Linaro toolchain and using a custom device tree and config. I have the TPS6598x driver built into the kernel. There is no configuration storage device for the TPS65988. The board was made before my involvement with the project, but I was hoping to be able to use the TPS firmware and configurations already in ROM.

Monitoring the AM3359's i2c interface to the TPS65988 with a logic analyzer revealed that the bus was always busy with traffic between the two devices. The TPS i2c IRQ line to the AM3359 is always pulled down, and I see a repeated pattern of register reads and writes that seems to be consistent with the tps6598x.c source for the tps6598x_handle_interrupt_status(struct tps6598x *tps) function. The driver reads the interrupt event registers and attempts to clear any active interrupt events, but it uses an 8 byte type to store the 11 bytes sent by the TPS. I see that some other members of the TPS6598x family only have an 8 byte interrupt event register. Due to a bug, the driver clocks out more data than it wants to read, so I was able to read 0x02 for byte 11, which corresponds to byte 11 bit 1, which the TPS65987/TPS65988 host interface document indicates is the patch bundle bit. The handler then writes the active interrupts to the interrupt clear registers, but it only writes 8 bytes of zeros, so I would not expect the event bit to be cleared, explaining the constant IRQ line assertion.

I believe the device is pin configured to boot without requiring a firmware update. SPI-MISO is pulled up to LDO_3V3 through 10kOhm, and ADCIN1 is pulled to ground with a 0 ohm link.

I checked a few versions of the mainline and TI kernel source, and while I see that some issues have been fixed (in 5.4.106, 64 bytes are always clocked out regardless of register length, but I think this gets fixed in a later version), things are reorganized (most of the tps6598x.c stuff gets put in tipd/core.c), the driver still only seemed to be able to clear the first 8 bytes of the interrupt event register.

Also, from my logic analyzer captures, it seems like the probe function is being run before the driver gets bogged down servicing the IRQ, which includes a read of 0x28, the port configuration register. The port mode is determined from the 3 LSB and handled according to the TPS_PORTINFO enum:
enum {
    TPS_PORTINFO_SINK,
    TPS_PORTINFO_SINK_ACCESSORY,
    TPS_PORTINFO_DRP_UFP,
    TPS_PORTINFO_DRP_UFP_DRD,
    TPS_PORTINFO_DRP_DFP,
    TPS_PORTINFO_DRP_DFP_DRD,
    TPS_PORTINFO_SOURCE,
};

 which matches the host interface spec for the TPS65981, TPS65982, and TPS65986, but not the 87 or 88. This still seems to be the case in later kernel versions.

Before trying to address this by editing the source, I thought I'd check to see if I'm missing something and there is already a patch for these issues, or another driver I should be using for the 88 or whether these are even the problems that I think they are. If I do need to edit the source, are there any other important changes in the interface to the 88 that would need to be accommodated? We'll need another board rev - it might also be an option to use another TPS6598x chip. Please let me know if you need a kernel defconfig or dts.

Thanks!

  • Hi Jordan,

    I see the TPS6598x driver in kernel source - drivers/usb/typec/tps6598x.c - is mainly maintained by Intel engineer Heikki Krogerus, so I would recommend you post your question to the kernel open source community for comments.

  • Hi Bin Liu,

        I decided to make a few changes to the driver source which had the intended effect of clearing the flag and releasing the IRQ line, but the interrupt handler was still running continually. It turned out that there was also a problem in the device tree. The interrupt-parent had been assigned to the interrupt-controller for the wrong GPIO bank. The driver's interrupt handler only runs twice now on boot.