Reading I2C bus frequency from /proc/device-tree/i2c@XXXXX/clock-frequency

8.5k views Asked by At

I am working on some userspace validation tool. In which I need to validate i2c freq.

In my DT file, I set clock-frequency = <400000>;, And I read it back from /proc/device-tree/i2c@XXXXX/clock-frequency from userspace. But I am getting some garbage data.

Output:

root@mymachine:~# od -bc /proc/device-tree/i2c\@XXXXXX/clock-frequency                                                                        
0000000 000 006 032 200
         \0 006 032 200
0000004

Is it in compressed form? If yes, How can I decompress it?

Output of file command:

root@nvidia:/proc/device-tree# file i2c\@7000*/clock-frequency
i2c@7000XXXX/clock-frequency: TTComp archive data
i2c@7000XXXX/clock-frequency: raw G3 data, byte-padded
i2c@7000XXXX/clock-frequency: TTComp archive data
i2c@7000XXXX/clock-frequency: raw G3 data, byte-padded
i2c@7000XXXX/clock-frequency: TTComp archive data
i2c@7000XXXX/clock-frequency: TTComp archive data
3

There are 3 answers

1
Itzik Chaimov On

Try to display the output using the follow (note the parameters):

od -txz -Ax /proc/device-tree/i2c\@XXXXXX/clock-frequency

If your clock-frequency was set to 100kHz you should get something like this:

000000 a0860100
000004

And after swapping the endians, you should get 0x186a0 which is 100kHz in decimal.

0
fingolfin00 On

I personally find useful the following parameters for od that automatically swap the endianness and print in decimal format.

For example if bus speed is set to 100 KHz (tested on ARM 64 arch):

# od -td --endian=big /proc/device-tree/soc\@0/bus\@########/i2c\@########/clock-frequency
0000000      100000
0000004

The --endian option is available from coreutils 8.23: https://github.com/coreutils/coreutils/commit/b370924c03adaef222859061c61be06fc30c9a3e.

1
a1k0n On

It's not compressed, it's just a raw binary unsigned 32-bit int stored big-endian. The four bytes you have there are shown in octal: 0, 6, 32, 200, in decimal are 0, 6, 26, and 128, and as a 32-bit int is 6*65536 + 26*256 + 128 = 400000.

There are many ways to unpack that; from python, on my RPi 2, which currently has an i2c freq of 100000:

>>> import struct; struct.unpack(">I", open('/proc/device-tree/soc/i2c@7e205000/clock-frequency').read())
(100000,)