요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. 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
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
I2C sysfs의 목적과 위치
1-53이 문서는 GPL-2.0 라이선스로 제공됩니다. I2C Multiplexer(MUX)가 있으면 I2C 토폴로지가 복잡해질 수 있습니다. Linux 커널은 MUX 채널을 논리 I2C 버스 번호로 추상화하지만, 물리 버스 번호와 MUX 토폴로지를 논리 버스 번호에 대응시키는 지식에는 빈틈이 생기기 쉽습니다.
이 문서는 하드웨어 엔지니어와 신규 소프트웨어 개발자 등이 물리 I2C 토폴로지를 알고 Linux 셸에서 I2C sysfs를 탐색함으로써 커널의 논리 I2C 버스 개념을 이해하도록 돕습니다. 이 지식은 개발과 디버깅에 `i2c-tools`를 사용할 때 필수적입니다.
대상 독자는 Linux가 실행 중인 시스템에서 셸로 I2C 하위 시스템과 상호작용해야 하는 사람입니다. 일반적인 Linux 셸 파일 시스템 명령과 I2C, I2C MUX, I2C 토폴로지에 대한 기본 지식이 필요합니다.
sysfs는 보통 `/sys`에 마운트되며 I2C sysfs는 `/sys/bus/i2c/devices`에 있습니다. 이 디렉터리의 심볼릭 링크 중 `i2c-`로 시작하는 항목은 물리 또는 논리 I2C 버스이고, 숫자로 시작해 숫자로 끝나는 항목은 I2C 장치입니다. 장치 이름의 첫 숫자는 버스 번호, 둘째 숫자는 I2C 주소입니다.
Google Pixel 3 예제에서 `i2c-2`는 번호 2인 I2C 버스이며, `2-0049`는 논리 버스 2의 주소 `0x49`에 있고 커널 드라이버에 바인딩된 I2C 장치입니다.
버스 링크와 장치 링크를 구분합니다.
I2C 버스와 장치 이름을 먼저 분류합니다.
.. 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.
물리 컨트롤러와 논리 버스 용어
54-110물리 I2C 버스 컨트롤러는 Linux 커널이 실행되는 하드웨어 시스템의 실제 장치입니다. 시스템에는 여러 컨트롤러와 이를 조작하는 여러 메모리 맵 레지스터가 있을 수 있습니다. `drivers/i2c/busses` 아래의 커널 버스 드라이버가 커널 I2C API를 각 시스템의 레지스터 연산으로 변환합니다.
시스템 공급업체는 각 물리 I2C 버스 컨트롤러에 물리 번호를 지정할 수 있습니다. 예를 들어 레지스터 주소가 가장 낮은 첫 컨트롤러를 `I2C-0`이라고 부를 수 있습니다.
Linux I2C sysfs에 표시되는 모든 I2C 버스 번호는 번호를 할당받은 논리 I2C 버스입니다. 소프트웨어가 보통 물리 메모리가 아니라 가상 메모리 공간을 기준으로 작성되는 것과 비슷한 추상화입니다.
각 논리 버스는 물리 I2C 버스 컨트롤러를 직접 추상화하거나, I2C MUX 뒤의 채널을 추상화합니다. MUX 채널을 나타내는 논리 버스로 장치에 접근하면 커널이 추상화의 일부로 MUX를 올바른 채널로 자동 전환합니다.
논리 I2C 버스가 물리 I2C 버스 컨트롤러를 직접 추상화한다면 이 문서에서는 이를 물리 I2C 버스라고 부릅니다.
DTS의 `aliases` 절에서는 물리 I2C 버스 번호를 다른 논리 버스 번호로 바꿀 수 있습니다. 예는 `arch/arm/boot/dts/nuvoton-npcm730-gsj.dts`에서 볼 수 있습니다.
커널 개발자에게 권장되는 방식은 물리 버스 번호를 대응하는 논리 버스 번호와 같게 유지하는 것입니다. 번호를 바꾸거나 다시 매핑하지 않으면 다른 사용자의 혼란이 줄고, 이 물리 버스를 MUX 확장의 분명한 시작점으로 사용할 수 있습니다. 이후 예제는 물리 번호와 논리 번호가 같다고 가정합니다.
하드웨어 번호와 Linux가 노출하는 번호의 관계입니다.
MUX 채널 선택은 커널 추상화 안에서 자동으로 수행됩니다.
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.
물리 버스와 MUX 논리 버스 구별
111-178예제 토폴로지는 물리 I2C 컨트롤러 7을 나타내는 `i2c-7`에서 시작합니다. 주소 `0x71`의 4채널 MUX `7-0071`이 논리 버스 60, 73, 86, 203을 만듭니다.
그중 channel-1인 `i2c-73`에는 주소 `0x40`의 hwmon 센서, DTS에는 있으나 probe에 실패한 주소 `0x70`의 MUX, 주소 `0x72`의 8채널 MUX가 있습니다. 마지막 MUX는 channel-0부터 channel-7까지 논리 버스 78부터 85를 만듭니다.
원문의 ASCII 트리를 동일한 부모·채널 관계로 재구성합니다.
물리 버스와 MUX에서 확장된 논리 버스를 구분하는 간단한 방법은 버스 디렉터리 아래 `device` 심볼릭 링크를 `ls -l`이나 `readlink`로 읽는 것입니다. 대안으로 `mux_device`를 볼 수 있는데, 이 링크는 다른 버스에서 확장된 논리 버스에만 존재하며 해당 버스를 만든 I2C MUX 장치를 가리킵니다.
`device` 링크가 `.i2c`로 끝나는 디렉터리를 가리키면 물리 버스 컨트롤러를 직접 추상화한 물리 I2C 버스입니다. `i2c-7/device`는 `../../f0087000.i2c`를 가리키고 `mux_device`가 없으므로 물리 버스입니다. 번호를 바꾸지 않는 관례를 따랐다면 시스템의 물리 컨트롤러 7이기도 합니다.
반면 `device` 링크가 다른 I2C 버스를 가리키면 현재 버스는 그 부모 아래 MUX 채널을 추상화한 논리 버스입니다. `i2c-73/device`는 `../../i2c-7`, `i2c-73/mux_device`는 `../7-0071`을 가리킵니다. 즉 `i2c-73`은 `i2c-7`의 주소 `0x71` MUX가 만든 논리 버스입니다.
버스 73의 장치에 접근할 때마다 커널은 주소 `0x71`의 MUX를 올바른 채널로 자동 전환합니다.
두 심볼릭 링크의 대상에 따른 판별법입니다.
심볼릭 링크 두 개로 부모 관계를 복원합니다.
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.
MUX 채널의 논리 버스 번호 찾기
179-276이 절은 물리 하드웨어 토폴로지를 바탕으로 특정 MUX 채널을 나타내는 논리 I2C 버스 번호를 찾는 방법을 설명합니다. 예제에는 DTS에서 이름을 바꾸지 않은 물리 버스 7, 그 버스 주소 `0x71`의 4채널 MUX, 그리고 첫 MUX의 channel-1 뒤 주소 `0x72`의 8채널 MUX가 있습니다. 목표는 두 번째 MUX의 channel-3 논리 버스 번호를 찾는 것입니다.
먼저 `/sys/bus/i2c/devices/i2c-7`로 이동합니다. 목록에서 주소 `0x71` MUX인 `7-0071`과 그 채널들이 만든 `i2c-60`, `i2c-73`, `i2c-86`, `i2c-203`을 볼 수 있습니다.
`7-0071` 디렉터리로 들어가 `readlink channel-1`을 실행하면 `../i2c-73`이 나옵니다. 따라서 `i2c-7`의 `0x71` MUX channel-1에는 논리 버스 번호 73이 할당되었습니다.
`i2c-73`으로 이동하는 방법은 sysfs 루트의 절대 경로로 이동하거나, `channel-1` 심볼릭 링크로 들어가거나, 링크 내용인 `../i2c-73`으로 이동하는 세 가지가 있습니다. 모두 같은 논리 버스 디렉터리에 도착합니다.
`i2c-73` 목록에서 두 번째 MUX `73-0072`를 찾고 그 디렉터리에서 `readlink channel-3`을 실행하면 `../i2c-81`이 나옵니다. 따라서 주소 `0x72` MUX의 channel-3 논리 버스 번호는 81입니다. 이후 이 번호로 해당 sysfs 디렉터리에 이동하거나 `i2c-tools` 명령을 실행할 수 있습니다.
두 단계 MUX의 channel 링크를 순서대로 따라갑니다.
각 물리 장치와 채널이 만드는 논리 버스입니다.
토폴로지를 이해한 뒤 시스템에 `i2cdetect`가 있다면 `i2cdetect -l`로 전체 구조를 쉽게 훑을 수 있습니다. 예제 출력은 `i2c-7` 물리 어댑터, 그 channel-1의 `i2c-73`, 그리고 두 번째 MUX의 channel-0부터 channel-7에 대응하는 `i2c-78`부터 `i2c-85`를 보여 줍니다.
`i2cdetect -l` 예제의 논리 버스 번호를 정리합니다.
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
고정된 논리 I2C 버스 번호
277-302DTS에 번호가 지정되지 않았다면 I2C MUX 드라이버가 적용되고 장치 probe가 성공할 때 커널은 현재 가장 큰 논리 버스 번호 다음부터 MUX 채널에 순차적으로 번호를 할당합니다. 최고 번호가 `i2c-15`인 시스템에서 4채널 MUX가 성공하면 channel-0은 `i2c-16`, channel-3은 `i2c-19`가 됩니다.
커널 개발자는 DTS에서 MUX 확장 채널을 정적인 논리 I2C 버스 번호에 고정할 수 있습니다. 구체적인 구현 예는 `arch/arm/boot/dts/aspeed-bmc-facebook-wedge400.dts`에서 볼 수 있습니다.
그 예제에는 물리 버스 2의 주소 `0x70`에 8채널 MUX가 있습니다. MUX channel-2는 DTS에서 `imux18`로 정의되고 `aliases` 절의 `i2c18 = &imux18;`로 논리 버스 18에 고정됩니다.
사람이 기억하거나 산술적으로 계산하기 쉬운 번호 체계도 설계할 수 있습니다. 예를 들어 버스 3의 MUX 확장 채널을 30부터 시작하도록 고정하면 channel-0은 30, channel-7은 37이 됩니다.
동적 순차 할당과 DTS 고정을 비교합니다.
부팅 순서와 무관한 안정적인 논리 번호를 만듭니다.
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 장치 디렉터리와 probe 상태
303-346I2C 장치 디렉터리 링크 이름은 `${bus}-${addr}` 형식입니다. `${bus}`는 논리 I2C 버스의 10진수 번호이고 `${addr}`는 각 장치 I2C 주소의 16진수입니다.
각 장치 디렉터리 안의 `name` 파일은 커널 드라이버가 이 장치를 probe할 때 사용한 장치 이름을 알려 줍니다. `cat`으로 읽을 수 있으며 예제에서 `73-0040`은 `ina230`, `73-0070`은 `pca9546`, `73-0072`는 `pca9547`입니다.
`driver` 심볼릭 링크는 이 장치를 probe한 Linux 커널 드라이버를 가리킵니다. 예제에서 `73-0040/driver`는 `/sys/bus/i2c/drivers/ina2xx`, `73-0072/driver`는 `/sys/bus/i2c/drivers/pca954x`를 가리킵니다.
처음부터 `driver` 링크가 없다면 오류 때문에 커널 드라이버가 장치 probe에 실패했을 수 있습니다. 이 경우 `dmesg`에서 오류를 찾을 수 있습니다. 예제의 `73-0070`에는 driver 링크가 없고 로그에 `pca954x 73-0070: probe failed`가 기록되어 있습니다.
I2C 장치의 종류와 probe에 사용한 커널 드라이버에 따라 장치 디렉터리의 추가 내용은 달라집니다.
장치 정체와 드라이버 바인딩 상태를 확인합니다.
driver 링크의 존재 여부에서 로그 조사로 이어집니다.
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.
MUX 장치와 hwmon 센서
347-383I2C MUX 장치 디렉터리 안에는 `channel-*` 심볼릭 링크가 있습니다. 각 링크는 해당 채널을 추상화한 논리 I2C 버스 디렉터리를 가리킵니다.
예제의 `73-0072` MUX는 channel-0부터 channel-7까지 각각 `i2c-78`부터 `i2c-85`를 가리킵니다. 이 링크가 MUX의 물리 채널과 Linux 논리 버스 번호 사이의 직접적인 대응표입니다.
장치 디렉터리에서 보이는 채널별 심볼릭 링크입니다.
I2C 센서도 흔히 볼 수 있습니다. 센서가 hwmon(Hardware Monitoring) 커널 드라이버에 성공적으로 바인딩되면 I2C 장치 디렉터리 안에 `hwmon` 디렉터리가 생깁니다. 더 들어가면 센서의 hwmon sysfs를 찾을 수 있습니다.
예제 `73-0040/hwmon/hwmon17`에는 전류, 전압, 전력 입력과 임계값, 경보, 갱신 주기, 션트 저항 등의 속성이 있습니다. hwmon sysfs의 자세한 내용은 `../hwmon/sysfs-interface.rst`를 참조합니다.
원문 목록의 속성을 기능별로 묶습니다.
드라이버 바인딩 뒤 센서별 hwmon 속성이 노출됩니다.
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
I2C sysfs에서 장치 생성
384-387I2C sysfs를 통해 사용자 공간에서 장치를 생성하는 방법은 `instantiating-devices.rst`의 "Method 4: Instantiate from user-space" 절을 참조합니다.
이 문서가 연결하는 상세 절입니다.
Instantiate I2C Devices in I2C Sysfs
------------------------------------
Refer to section "Method 4: Instantiate from user-space" of instantiating-devices.rst
요약·해설
i2c-sysfs.rst:1-387Linux는 물리 컨트롤러와 각 MUX 채널을 논리 I2C 버스로 노출합니다. sysfs의 device, mux_device, channel-* 링크를 따라가면 실제 토폴로지와 논리 번호를 복원하고 장치 probe와 hwmon 상태까지 진단할 수 있습니다.
원문 분량과 핵심 검토 대상을 요약합니다.
문서의 주요 사용 또는 탐색 순서를 압축합니다.