How to compile the FW16 EC from open source code

Well, I have tracked down and fixed another EC bug.

It was a really difficult one to track down.
The initial symptom was that in some rare cases, the power adapter plug/unplug would not be detected. Investigating that, resulted in seeing that the Make/Model names/strings being read from the smart battery were missing characters. This led to the wrong battery profile being used, that then led to AC on/off state transitions not working. So, this was the first hint that something was not right with the I2C transfers.
The EC i2c_transfer() transactions were unreliable.
This resulting in, for example, the symptom of the UCSI PPM_RESET failing and other odd behavior.
Its a guess, but it might also be causing some of the stuck in 544 Mhz problems.

The reason it was so difficult to track down is because some transactions worked and some did not. They just silently fail. No indication of failed transaction. The problematic ones were the block writes. The write was happening, but the cypd USB PD chip was not seeing the transaction. I had to then go looking for something on the cypd USB PD chip i2c that I could use as a scratchpad. I could write to it, and then read it back to see if the write worked. There is no documentation on the cypd USB PD chip api, but I eventually found a scratchpad, and then a solution, as one can see from the patch linked to above.

The problem turned out to be split i2c_transfer().
If one does half the transaction in one call to i2c_transfer() with START set, and then the second half of the transaction in another call to i2c_transfer() with STOP set. It is unreliable.
Putting both parts into i2c_msg msg[ ] and then doing a single i2c_transfer() is 100% reliable.
It also seems to mainly be a problem associated with i2c writes. It seems that doing i2c reads, and splitting them across i2c_transfer() does not cause so many problems.

I think if the EC needs to do more reliable i2c transactions writes. It should also do a i2c transaction read, to double check that the data sent, arrived OK at the destination.
The I2C ACKs are supposed to help with making i2c more reliable, but it appears the EC code has no way, currently, of detecting the errors. There might be a i2c_transfer() callback, that may exist, but is not currently being used.

Here is another i2c function that I have fixed. It had the same problem of spliting the START and STOP i2c_transfer().

static int platform_ec_i2c_write(const int port, const uint16_t addr_flags,
                                 const uint8_t *out, int out_size)

This function is used to update the EC → APU/CPU with the new PMF settings.
e.g. “PMF: SPL 45000mW, sPPT 54000mW, fPPT 65000mW, p3T 227000mW, ao_sppt 0mW”
If it fails, it will result in the settings not being successfully sent to the APU. This is separate from APU SMU hang problems, that are caused by problems on the APU side.

4 Likes