123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387 |
- .. SPDX-License-Identifier: GPL-2.0
- ===============
- Linux I2C Sysfs
- ===============
- Overview
- ========
- I2C topology can be complex because of the existence of I2C MUX
- (I2C Multiplexer). The Linux
- kernel abstracts the MUX channels into logical I2C bus numbers. However, there
- is a gap of knowledge to map from the I2C bus physical number and MUX topology
- to logical I2C bus number. This doc is aimed to fill in this gap, so the
- audience (hardware engineers and new software developers for example) can learn
- the concept of logical I2C buses in the kernel, by knowing the physical I2C
- topology and navigating through the I2C sysfs in Linux shell. This knowledge is
- useful and essential to use ``i2c-tools`` for the purpose of development and
- debugging.
- Target audience
- ---------------
- People who need to use Linux shell to interact with I2C subsystem on a system
- which the Linux is running on.
- Prerequisites
- -------------
- 1. Knowledge of general Linux shell file system commands and operations.
- 2. General knowledge of I2C, I2C MUX and I2C topology.
- Location of I2C Sysfs
- =====================
- Typically, the Linux Sysfs filesystem is mounted at the ``/sys`` directory,
- so you can find the I2C Sysfs under ``/sys/bus/i2c/devices``
- where you can directly ``cd`` to it.
- There is a list of symbolic links under that directory. The links that
- start with ``i2c-`` are I2C buses, which may be either physical or logical. The
- other links that begin with numbers and end with numbers are I2C devices, where
- the first number is I2C bus number, and the second number is I2C address.
- Google Pixel 3 phone for example::
- blueline:/sys/bus/i2c/devices $ ls
- 0-0008 0-0061 1-0028 3-0043 4-0036 4-0041 i2c-1 i2c-3
- 0-000c 0-0066 2-0049 4-000b 4-0040 i2c-0 i2c-2 i2c-4
- ``i2c-2`` is an I2C bus whose number is 2, and ``2-0049`` is an I2C device
- on bus 2 address 0x49 bound with a kernel driver.
- Terminology
- ===========
- First, let us define some terms to avoid confusion in later sections.
- (Physical) I2C Bus Controller
- -----------------------------
- The hardware system that the Linux kernel is running on may have multiple
- physical I2C bus controllers. The controllers are hardware and physical, and the
- system may define multiple registers in the memory space to manipulate the
- controllers. Linux kernel has I2C bus drivers under source directory
- ``drivers/i2c/busses`` to translate kernel I2C API into register
- operations for different systems. This terminology is not limited to Linux
- kernel only.
- I2C Bus Physical Number
- -----------------------
- For each physical I2C bus controller, the system vendor may assign a physical
- number to each controller. For example, the first I2C bus controller which has
- the lowest register addresses may be called ``I2C-0``.
- Logical I2C Bus
- ---------------
- Every I2C bus number you see in Linux I2C Sysfs is a logical I2C bus with a
- number assigned. This is similar to the fact that software code is usually
- written upon virtual memory space, instead of physical memory space.
- Each logical I2C bus may be an abstraction of a physical I2C bus controller, or
- an abstraction of a channel behind an I2C MUX. In case it is an abstraction of a
- MUX channel, whenever we access an I2C device via a such logical bus, the kernel
- will switch the I2C MUX for you to the proper channel as part of the
- abstraction.
- Physical I2C Bus
- ----------------
- If the logical I2C bus is a direct abstraction of a physical I2C bus controller,
- let us call it a physical I2C bus.
- Caveat
- ------
- This may be a confusing part for people who only know about the physical I2C
- design of a board. It is actually possible to rename the I2C bus physical number
- to a different number in logical I2C bus level in Device Tree Source (DTS) under
- section ``aliases``. See ``arch/arm/boot/dts/nuvoton-npcm730-gsj.dts``
- for an example of DTS file.
- Best Practice: **(To kernel software developers)** It is better to keep the I2C
- bus physical number the same as their corresponding logical I2C bus number,
- instead of renaming or mapping them, so that it may be less confusing to other
- users. These physical I2C buses can be served as good starting points for I2C
- MUX fanouts. For the following examples, we will assume that the physical I2C
- bus has a number same as their I2C bus physical number.
- Walk through Logical I2C Bus
- ============================
- For the following content, we will use a more complex I2C topology as an
- example. Here is a brief graph for the I2C topology. If you do not understand
- this graph at first glance, do not be afraid to continue reading this doc
- and review it when you finish reading.
- ::
- i2c-7 (physical I2C bus controller 7)
- `-- 7-0071 (4-channel I2C MUX at 0x71)
- |-- i2c-60 (channel-0)
- |-- i2c-73 (channel-1)
- | |-- 73-0040 (I2C sensor device with hwmon directory)
- | |-- 73-0070 (I2C MUX at 0x70, exists in DTS, but failed to probe)
- | `-- 73-0072 (8-channel I2C MUX at 0x72)
- | |-- i2c-78 (channel-0)
- | |-- ... (channel-1...6, i2c-79...i2c-84)
- | `-- i2c-85 (channel-7)
- |-- i2c-86 (channel-2)
- `-- i2c-203 (channel-3)
- Distinguish Physical and Logical I2C Bus
- ----------------------------------------
- One simple way to distinguish between a physical I2C bus and a logical I2C bus,
- is to read the symbolic link ``device`` under the I2C bus directory by using
- command ``ls -l`` or ``readlink``.
- An alternative symbolic link to check is ``mux_device``. This link only exists
- in logical I2C bus directory which is fanned out from another I2C bus.
- Reading this link will also tell you which I2C MUX device created
- this logical I2C bus.
- If the symbolic link points to a directory ending with ``.i2c``, it should be a
- physical I2C bus, directly abstracting a physical I2C bus controller. For
- example::
- $ readlink /sys/bus/i2c/devices/i2c-7/device
- ../../f0087000.i2c
- $ ls /sys/bus/i2c/devices/i2c-7/mux_device
- ls: /sys/bus/i2c/devices/i2c-7/mux_device: No such file or directory
- In this case, ``i2c-7`` is a physical I2C bus, so it does not have the symbolic
- link ``mux_device`` under its directory. And if the kernel software developer
- follows the common practice by not renaming physical I2C buses, this should also
- mean the physical I2C bus controller 7 of the system.
- On the other hand, if the symbolic link points to another I2C bus, the I2C bus
- presented by the current directory has to be a logical bus. The I2C bus pointed
- by the link is the parent bus which may be either a physical I2C bus or a
- logical one. In this case, the I2C bus presented by the current directory
- abstracts an I2C MUX channel under the parent bus.
- For example::
- $ readlink /sys/bus/i2c/devices/i2c-73/device
- ../../i2c-7
- $ readlink /sys/bus/i2c/devices/i2c-73/mux_device
- ../7-0071
- ``i2c-73`` is a logical bus fanout by an I2C MUX under ``i2c-7``
- whose I2C address is 0x71.
- Whenever we access an I2C device with bus 73, the kernel will always
- switch the I2C MUX addressed 0x71 to the proper channel for you as part of the
- abstraction.
- Finding out Logical I2C Bus Number
- ----------------------------------
- In this section, we will describe how to find out the logical I2C bus number
- representing certain I2C MUX channels based on the knowledge of physical
- hardware I2C topology.
- In this example, we have a system which has a physical I2C bus 7 and not renamed
- in DTS. There is a 4-channel MUX at address 0x71 on that bus. There is another
- 8-channel MUX at address 0x72 behind the channel 1 of the 0x71 MUX. Let us
- navigate through Sysfs and find out the logical I2C bus number of the channel 3
- of the 0x72 MUX.
- First of all, let us go to the directory of ``i2c-7``::
- ~$ cd /sys/bus/i2c/devices/i2c-7
- /sys/bus/i2c/devices/i2c-7$ ls
- 7-0071 i2c-60 name subsystem
- delete_device i2c-73 new_device uevent
- device i2c-86 of_node
- i2c-203 i2c-dev power
- There, we see the 0x71 MUX as ``7-0071``. Go inside it::
- /sys/bus/i2c/devices/i2c-7$ cd 7-0071/
- /sys/bus/i2c/devices/i2c-7/7-0071$ ls -l
- channel-0 channel-3 modalias power
- channel-1 driver name subsystem
- channel-2 idle_state of_node uevent
- Read the link ``channel-1`` using ``readlink`` or ``ls -l``::
- /sys/bus/i2c/devices/i2c-7/7-0071$ readlink channel-1
- ../i2c-73
- We find out that the channel 1 of 0x71 MUX on ``i2c-7`` is assigned
- with a logical I2C bus number of 73.
- Let us continue the journey to directory ``i2c-73`` in either ways::
- # cd to i2c-73 under I2C Sysfs root
- /sys/bus/i2c/devices/i2c-7/7-0071$ cd /sys/bus/i2c/devices/i2c-73
- /sys/bus/i2c/devices/i2c-73$
- # cd the channel symbolic link
- /sys/bus/i2c/devices/i2c-7/7-0071$ cd channel-1
- /sys/bus/i2c/devices/i2c-7/7-0071/channel-1$
- # cd the link content
- /sys/bus/i2c/devices/i2c-7/7-0071$ cd ../i2c-73
- /sys/bus/i2c/devices/i2c-7/i2c-73$
- Either ways, you will end up in the directory of ``i2c-73``. Similar to above,
- we can now find the 0x72 MUX and what logical I2C bus numbers
- that its channels are assigned::
- /sys/bus/i2c/devices/i2c-73$ ls
- 73-0040 device i2c-83 new_device
- 73-004e i2c-78 i2c-84 of_node
- 73-0050 i2c-79 i2c-85 power
- 73-0070 i2c-80 i2c-dev subsystem
- 73-0072 i2c-81 mux_device uevent
- delete_device i2c-82 name
- /sys/bus/i2c/devices/i2c-73$ cd 73-0072
- /sys/bus/i2c/devices/i2c-73/73-0072$ ls
- channel-0 channel-4 driver of_node
- channel-1 channel-5 idle_state power
- channel-2 channel-6 modalias subsystem
- channel-3 channel-7 name uevent
- /sys/bus/i2c/devices/i2c-73/73-0072$ readlink channel-3
- ../i2c-81
- There, we find out the logical I2C bus number of the channel 3 of the 0x72 MUX
- is 81. We can later use this number to switch to its own I2C Sysfs directory or
- issue ``i2c-tools`` commands.
- Tip: Once you understand the I2C topology with MUX, command
- `i2cdetect -l
- <https://manpages.debian.org/unstable/i2c-tools/i2cdetect.8.en.html>`_
- in
- `I2C Tools
- <https://i2c.wiki.kernel.org/index.php/I2C_Tools>`_
- can give you
- an overview of the I2C topology easily, if it is available on your system. For
- example::
- $ i2cdetect -l | grep -e '\-73' -e _7 | sort -V
- i2c-7 i2c npcm_i2c_7 I2C adapter
- i2c-73 i2c i2c-7-mux (chan_id 1) I2C adapter
- i2c-78 i2c i2c-73-mux (chan_id 0) I2C adapter
- i2c-79 i2c i2c-73-mux (chan_id 1) I2C adapter
- i2c-80 i2c i2c-73-mux (chan_id 2) I2C adapter
- i2c-81 i2c i2c-73-mux (chan_id 3) I2C adapter
- i2c-82 i2c i2c-73-mux (chan_id 4) I2C adapter
- i2c-83 i2c i2c-73-mux (chan_id 5) I2C adapter
- i2c-84 i2c i2c-73-mux (chan_id 6) I2C adapter
- i2c-85 i2c i2c-73-mux (chan_id 7) I2C adapter
- Pinned Logical I2C Bus Number
- -----------------------------
- If not specified in DTS, when an I2C MUX driver is applied and the MUX device is
- successfully probed, the kernel will assign the MUX channels with a logical bus
- number based on the current biggest logical bus number incrementally. For
- example, if the system has ``i2c-15`` as the highest logical bus number, and a
- 4-channel MUX is applied successfully, we will have ``i2c-16`` for the
- MUX channel 0, and all the way to ``i2c-19`` for the MUX channel 3.
- The kernel software developer is able to pin the fanout MUX channels to a static
- logical I2C bus number in the DTS. This doc will not go through the details on
- how to implement this in DTS, but we can see an example in:
- ``arch/arm/boot/dts/aspeed-bmc-facebook-wedge400.dts``
- In the above example, there is an 8-channel I2C MUX at address 0x70 on physical
- I2C bus 2. The channel 2 of the MUX is defined as ``imux18`` in DTS,
- and pinned to logical I2C bus number 18 with the line of ``i2c18 = &imux18;``
- in section ``aliases``.
- Take it further, it is possible to design a logical I2C bus number schema that
- can be easily remembered by humans or calculated arithmetically. For example, we
- can pin the fanout channels of a MUX on bus 3 to start at 30. So 30 will be the
- logical bus number of the channel 0 of the MUX on bus 3, and 37 will be the
- logical bus number of the channel 7 of the MUX on bus 3.
- I2C Devices
- ===========
- In previous sections, we mostly covered the I2C bus. In this section, let us see
- what we can learn from the I2C device directory whose link name is in the format
- of ``${bus}-${addr}``. The ``${bus}`` part in the name is a logical I2C bus
- decimal number, while the ``${addr}`` part is a hex number of the I2C address
- of each device.
- I2C Device Directory Content
- ----------------------------
- Inside each I2C device directory, there is a file named ``name``.
- This file tells what device name it was used for the kernel driver to
- probe this device. Use command ``cat`` to read its content. For example::
- /sys/bus/i2c/devices/i2c-73$ cat 73-0040/name
- ina230
- /sys/bus/i2c/devices/i2c-73$ cat 73-0070/name
- pca9546
- /sys/bus/i2c/devices/i2c-73$ cat 73-0072/name
- pca9547
- There is a symbolic link named ``driver`` to tell what Linux kernel driver was
- used to probe this device::
- /sys/bus/i2c/devices/i2c-73$ readlink -f 73-0040/driver
- /sys/bus/i2c/drivers/ina2xx
- /sys/bus/i2c/devices/i2c-73$ readlink -f 73-0072/driver
- /sys/bus/i2c/drivers/pca954x
- But if the link ``driver`` does not exist at the first place,
- it may mean that the kernel driver failed to probe this device due to
- some errors. The error may be found in ``dmesg``::
- /sys/bus/i2c/devices/i2c-73$ ls 73-0070/driver
- ls: 73-0070/driver: No such file or directory
- /sys/bus/i2c/devices/i2c-73$ dmesg | grep 73-0070
- pca954x 73-0070: probe failed
- pca954x 73-0070: probe failed
- Depending on what the I2C device is and what kernel driver was used to probe the
- device, we may have different content in the device directory.
- I2C MUX Device
- --------------
- While you may be already aware of this in previous sections, an I2C MUX device
- will have symbolic link ``channel-*`` inside its device directory.
- These symbolic links point to their logical I2C bus directories::
- /sys/bus/i2c/devices/i2c-73$ ls -l 73-0072/channel-*
- lrwxrwxrwx ... 73-0072/channel-0 -> ../i2c-78
- lrwxrwxrwx ... 73-0072/channel-1 -> ../i2c-79
- lrwxrwxrwx ... 73-0072/channel-2 -> ../i2c-80
- lrwxrwxrwx ... 73-0072/channel-3 -> ../i2c-81
- lrwxrwxrwx ... 73-0072/channel-4 -> ../i2c-82
- lrwxrwxrwx ... 73-0072/channel-5 -> ../i2c-83
- lrwxrwxrwx ... 73-0072/channel-6 -> ../i2c-84
- lrwxrwxrwx ... 73-0072/channel-7 -> ../i2c-85
- I2C Sensor Device / Hwmon
- -------------------------
- I2C sensor device is also common to see. If they are bound by a kernel hwmon
- (Hardware Monitoring) driver successfully, you will see a ``hwmon`` directory
- inside the I2C device directory. Keep digging into it, you will find the Hwmon
- Sysfs for the I2C sensor device::
- /sys/bus/i2c/devices/i2c-73/73-0040/hwmon/hwmon17$ ls
- curr1_input in0_lcrit_alarm name subsystem
- device in1_crit power uevent
- in0_crit in1_crit_alarm power1_crit update_interval
- in0_crit_alarm in1_input power1_crit_alarm
- in0_input in1_lcrit power1_input
- in0_lcrit in1_lcrit_alarm shunt_resistor
- For more info on the Hwmon Sysfs, refer to the doc:
- ../hwmon/sysfs-interface.rst
- Instantiate I2C Devices in I2C Sysfs
- ------------------------------------
- Refer to section "Method 4: Instantiate from user-space" of instantiating-devices.rst
|