Message ID | 20210505011236.3264393-1-xqiu@google.com |
---|---|
State | Superseded |
Headers | show |
Series | Documentation: i2c: Add doc for I2C sysfs | expand |
On 5/4/21 6:12 PM, Alex Qiu wrote: > This doc helps Linux users navigate through I2C sysfs and learn > the system I2C topology. > > Signed-off-by: Alex Qiu <xqiu@google.com> > Cc: Guenter Roeck <linux@roeck-us.net> lgtm. I was struggling with the idea of renaming instances of MUX to "multiplexer" or "multiplexers", but ultimately that doesn't seem to be worth the effort, and at the end I wasn't sure if it would be an improvement at all. The only improvement I can think of would be to introduce the term "MUX" as shortcut for multiplexer(s) in the "Overview" section. Reviewed-by: Guenter Roeck <linux@roeck-us.net> > --- > Documentation/i2c/i2c-sysfs.rst | 394 ++++++++++++++++++++++++++++++++ > 1 file changed, 394 insertions(+) > create mode 100644 Documentation/i2c/i2c-sysfs.rst > > diff --git a/Documentation/i2c/i2c-sysfs.rst b/Documentation/i2c/i2c-sysfs.rst > new file mode 100644 > index 000000000000..58a90af8d966 > --- /dev/null > +++ b/Documentation/i2c/i2c-sysfs.rst > @@ -0,0 +1,394 @@ > +.. SPDX-License-Identifier: GPL-2.0 > + > +=============== > +Linux I2C Sysfs > +=============== > + > +Overview > +======== > + > +I2C topology can be complex because of the existence of I2C MUX. 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. > + > +Terminologies > +============= > + > +First, let us define a couple of terminologies to avoid confusions in the 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 > +<../../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 the 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 > +<../../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: > + > +`Naming and data format standards for sysfs files > +<../hwmon/sysfs-interface.rst>`_ > + > +Instantiate I2C Devices in I2C Sysfs > +------------------------------------ > + > +Refer to the doc: > + > +`How to instantiate I2C devices, Method 4: Instantiate from user-space > +<instantiating-devices.rst#method-4-instantiate-from-user-space>`_ >
On Sun, May 16, 2021 at 7:24 AM Guenter Roeck <linux@roeck-us.net> wrote: > > On 5/4/21 6:12 PM, Alex Qiu wrote: > > This doc helps Linux users navigate through I2C sysfs and learn > > the system I2C topology. > > > > Signed-off-by: Alex Qiu <xqiu@google.com> > > Cc: Guenter Roeck <linux@roeck-us.net> > > lgtm. I was struggling with the idea of renaming instances of MUX > to "multiplexer" or "multiplexers", but ultimately that doesn't seem > to be worth the effort, and at the end I wasn't sure if it would be > an improvement at all. The only improvement I can think of would be > to introduce the term "MUX" as shortcut for multiplexer(s) in the > "Overview" section. Thanks for the review! I'll add a note on the I2C MUX as I2C Multiplexer. Let me see if I can get the updated patch email correct this time... > > Reviewed-by: Guenter Roeck <linux@roeck-us.net> > > > --- > > Documentation/i2c/i2c-sysfs.rst | 394 ++++++++++++++++++++++++++++++++ > > 1 file changed, 394 insertions(+) > > create mode 100644 Documentation/i2c/i2c-sysfs.rst > > > > diff --git a/Documentation/i2c/i2c-sysfs.rst b/Documentation/i2c/i2c-sysfs.rst > > new file mode 100644 > > index 000000000000..58a90af8d966 > > --- /dev/null > > +++ b/Documentation/i2c/i2c-sysfs.rst > > @@ -0,0 +1,394 @@ > > +.. SPDX-License-Identifier: GPL-2.0 > > + > > +=============== > > +Linux I2C Sysfs > > +=============== > > + > > +Overview > > +======== > > + > > +I2C topology can be complex because of the existence of I2C MUX. 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. > > + > > +Terminologies > > +============= > > + > > +First, let us define a couple of terminologies to avoid confusions in the 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 > > +<../../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 the 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 > > +<../../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: > > + > > +`Naming and data format standards for sysfs files > > +<../hwmon/sysfs-interface.rst>`_ > > + > > +Instantiate I2C Devices in I2C Sysfs > > +------------------------------------ > > + > > +Refer to the doc: > > + > > +`How to instantiate I2C devices, Method 4: Instantiate from user-space > > +<instantiating-devices.rst#method-4-instantiate-from-user-space>`_ > > >
diff --git a/Documentation/i2c/i2c-sysfs.rst b/Documentation/i2c/i2c-sysfs.rst new file mode 100644 index 000000000000..58a90af8d966 --- /dev/null +++ b/Documentation/i2c/i2c-sysfs.rst @@ -0,0 +1,394 @@ +.. SPDX-License-Identifier: GPL-2.0 + +=============== +Linux I2C Sysfs +=============== + +Overview +======== + +I2C topology can be complex because of the existence of I2C MUX. 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. + +Terminologies +============= + +First, let us define a couple of terminologies to avoid confusions in the 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 +<../../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 the 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 +<../../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: + +`Naming and data format standards for sysfs files +<../hwmon/sysfs-interface.rst>`_ + +Instantiate I2C Devices in I2C Sysfs +------------------------------------ + +Refer to the doc: + +`How to instantiate I2C devices, Method 4: Instantiate from user-space +<instantiating-devices.rst#method-4-instantiate-from-user-space>`_
This doc helps Linux users navigate through I2C sysfs and learn the system I2C topology. Signed-off-by: Alex Qiu <xqiu@google.com> Cc: Guenter Roeck <linux@roeck-us.net> --- Documentation/i2c/i2c-sysfs.rst | 394 ++++++++++++++++++++++++++++++++ 1 file changed, 394 insertions(+) create mode 100644 Documentation/i2c/i2c-sysfs.rst