요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
=======================
I2C/SMBus Functionality
=======================
INTRODUCTION
------------
Because not every I2C or SMBus adapter implements everything in the
I2C specifications, a client can not trust that everything it needs
is implemented when it is given the option to attach to an adapter:
the client needs some way to check whether an adapter has the needed
functionality.
FUNCTIONALITY CONSTANTS
-----------------------
For the most up-to-date list of functionality constants, please check
<uapi/linux/i2c.h>!
=============================== ==============================================
I2C_FUNC_I2C Plain i2c-level commands (Pure SMBus
adapters typically can not do these)
I2C_FUNC_10BIT_ADDR Handles the 10-bit address extensions
I2C_FUNC_PROTOCOL_MANGLING Knows about the I2C_M_IGNORE_NAK,
I2C_M_REV_DIR_ADDR and I2C_M_NO_RD_ACK
flags (which modify the I2C protocol!)
I2C_FUNC_NOSTART Can skip repeated start sequence
I2C_FUNC_SMBUS_QUICK Handles the SMBus write_quick command
I2C_FUNC_SMBUS_READ_BYTE Handles the SMBus read_byte command
I2C_FUNC_SMBUS_WRITE_BYTE Handles the SMBus write_byte command
I2C_FUNC_SMBUS_READ_BYTE_DATA Handles the SMBus read_byte_data command
I2C_FUNC_SMBUS_WRITE_BYTE_DATA Handles the SMBus write_byte_data command
I2C_FUNC_SMBUS_READ_WORD_DATA Handles the SMBus read_word_data command
I2C_FUNC_SMBUS_WRITE_WORD_DATA Handles the SMBus write_byte_data command
I2C_FUNC_SMBUS_PROC_CALL Handles the SMBus process_call command
I2C_FUNC_SMBUS_READ_BLOCK_DATA Handles the SMBus read_block_data command
I2C_FUNC_SMBUS_WRITE_BLOCK_DATA Handles the SMBus write_block_data command
I2C_FUNC_SMBUS_READ_I2C_BLOCK Handles the SMBus read_i2c_block_data command
I2C_FUNC_SMBUS_WRITE_I2C_BLOCK Handles the SMBus write_i2c_block_data command
=============================== ==============================================
A few combinations of the above flags are also defined for your convenience:
========================= ======================================
I2C_FUNC_SMBUS_BYTE Handles the SMBus read_byte
and write_byte commands
I2C_FUNC_SMBUS_BYTE_DATA Handles the SMBus read_byte_data
and write_byte_data commands
I2C_FUNC_SMBUS_WORD_DATA Handles the SMBus read_word_data
and write_word_data commands
I2C_FUNC_SMBUS_BLOCK_DATA Handles the SMBus read_block_data
and write_block_data commands
I2C_FUNC_SMBUS_I2C_BLOCK Handles the SMBus read_i2c_block_data
and write_i2c_block_data commands
I2C_FUNC_SMBUS_EMUL Handles all SMBus commands that can be
emulated by a real I2C adapter (using
the transparent emulation layer)
========================= ======================================
In kernel versions prior to 3.5 I2C_FUNC_NOSTART was implemented as
part of I2C_FUNC_PROTOCOL_MANGLING.
ADAPTER IMPLEMENTATION
----------------------
When you write a new adapter driver, you will have to implement a
function callback ``functionality``. Typical implementations are given
below.
A typical SMBus-only adapter would list all the SMBus transactions it
supports. This example comes from the i2c-piix4 driver::
static u32 piix4_func(struct i2c_adapter *adapter)
{
return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
I2C_FUNC_SMBUS_BLOCK_DATA;
}
A typical full-I2C adapter would use the following (from the i2c-pxa
driver)::
static u32 i2c_pxa_functionality(struct i2c_adapter *adap)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}
I2C_FUNC_SMBUS_EMUL includes all the SMBus transactions (with the
addition of I2C block transactions) which i2c-core can emulate using
I2C_FUNC_I2C without any help from the adapter driver. The idea is
to let the client drivers check for the support of SMBus functions
without having to care whether the said functions are implemented in
hardware by the adapter, or emulated in software by i2c-core on top
of an I2C adapter.
CLIENT CHECKING
---------------
Before a client tries to attach to an adapter, or even do tests to check
whether one of the devices it supports is present on an adapter, it should
check whether the needed functionality is present. The typical way to do
this is (from the lm75 driver)::
static int lm75_detect(...)
{
(...)
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_WORD_DATA))
goto exit;
(...)
}
Here, the lm75 driver checks if the adapter can do both SMBus byte data
and SMBus word data transactions. If not, then the driver won't work on
this adapter and there's no point in going on. If the check above is
successful, then the driver knows that it can call the following
functions: i2c_smbus_read_byte_data(), i2c_smbus_write_byte_data(),
i2c_smbus_read_word_data() and i2c_smbus_write_word_data(). As a rule of
thumb, the functionality constants you test for with
i2c_check_functionality() should match exactly the i2c_smbus_* functions
which you driver is calling.
Note that the check above doesn't tell whether the functionalities are
implemented in hardware by the underlying adapter or emulated in
software by i2c-core. Client drivers don't have to care about this, as
i2c-core will transparently implement SMBus transactions on top of I2C
adapters.
CHECKING THROUGH /DEV
---------------------
If you try to access an adapter from a userspace program, you will have
to use the /dev interface. You will still have to check whether the
functionality you need is supported, of course. This is done using
the I2C_FUNCS ioctl. An example, adapted from the i2cdetect program, is
below::
int file;
if (file = open("/dev/i2c-0", O_RDWR) < 0) {
/* Some kind of error handling */
exit(1);
}
if (ioctl(file, I2C_FUNCS, &funcs) < 0) {
/* Some kind of error handling */
exit(1);
}
if (!(funcs & I2C_FUNC_SMBUS_QUICK)) {
/* Oops, the needed functionality (SMBus write_quick function) is
not available! */
exit(1);
}
/* Now it is safe to use the SMBus write_quick command */
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
I2C/SMBus 기능 확인의 필요성
1-19모든 I2C 또는 SMBus 어댑터가 I2C 명세의 모든 기능을 구현하는 것은 아닙니다. 따라서 클라이언트는 어떤 어댑터에 연결할 기회가 주어졌다는 사실만으로 자신에게 필요한 기능이 모두 구현되어 있다고 믿어서는 안 됩니다.
클라이언트에는 해당 어댑터가 필요한 기능을 갖추었는지 확인할 방법이 필요합니다. 가장 최신 기능 상수 목록은 `<uapi/linux/i2c.h>`에서 확인해야 합니다.
어댑터와 클라이언트가 맡는 역할을 구분합니다.
장치 접근 전 필요한 기능을 확정하는 흐름입니다.
=======================
I2C/SMBus Functionality
=======================
INTRODUCTION
------------
Because not every I2C or SMBus adapter implements everything in the
I2C specifications, a client can not trust that everything it needs
is implemented when it is given the option to attach to an adapter:
the client needs some way to check whether an adapter has the needed
functionality.
FUNCTIONALITY CONSTANTS
-----------------------
For the most up-to-date list of functionality constants, please check
<uapi/linux/i2c.h>!
기능 상수와 편의 조합
20-62개별 기능 상수는 어댑터가 수행할 수 있는 주소 형식, 프로토콜 변형, SMBus 명령을 비트 단위로 표현합니다. 클라이언트는 자신이 호출할 API에 정확히 대응하는 비트를 검사해야 합니다.
원문의 기능 상수 16개를 빠짐없이 정리합니다.
자주 함께 쓰는 읽기와 쓰기 비트에는 편의 조합 상수가 정의되어 있습니다. 이 조합은 지원 범위를 간결하게 보고하거나 검사할 때 사용합니다.
쌍으로 묶인 명령과 투명 에뮬레이션 범위입니다.
커널 3.5 이전에는 `I2C_FUNC_NOSTART`가 별도 기능 비트가 아니라 `I2C_FUNC_PROTOCOL_MANGLING`의 일부로 구현되었습니다.
=============================== ==============================================
I2C_FUNC_I2C Plain i2c-level commands (Pure SMBus
adapters typically can not do these)
I2C_FUNC_10BIT_ADDR Handles the 10-bit address extensions
I2C_FUNC_PROTOCOL_MANGLING Knows about the I2C_M_IGNORE_NAK,
I2C_M_REV_DIR_ADDR and I2C_M_NO_RD_ACK
flags (which modify the I2C protocol!)
I2C_FUNC_NOSTART Can skip repeated start sequence
I2C_FUNC_SMBUS_QUICK Handles the SMBus write_quick command
I2C_FUNC_SMBUS_READ_BYTE Handles the SMBus read_byte command
I2C_FUNC_SMBUS_WRITE_BYTE Handles the SMBus write_byte command
I2C_FUNC_SMBUS_READ_BYTE_DATA Handles the SMBus read_byte_data command
I2C_FUNC_SMBUS_WRITE_BYTE_DATA Handles the SMBus write_byte_data command
I2C_FUNC_SMBUS_READ_WORD_DATA Handles the SMBus read_word_data command
I2C_FUNC_SMBUS_WRITE_WORD_DATA Handles the SMBus write_byte_data command
I2C_FUNC_SMBUS_PROC_CALL Handles the SMBus process_call command
I2C_FUNC_SMBUS_READ_BLOCK_DATA Handles the SMBus read_block_data command
I2C_FUNC_SMBUS_WRITE_BLOCK_DATA Handles the SMBus write_block_data command
I2C_FUNC_SMBUS_READ_I2C_BLOCK Handles the SMBus read_i2c_block_data command
I2C_FUNC_SMBUS_WRITE_I2C_BLOCK Handles the SMBus write_i2c_block_data command
=============================== ==============================================
A few combinations of the above flags are also defined for your convenience:
========================= ======================================
I2C_FUNC_SMBUS_BYTE Handles the SMBus read_byte
and write_byte commands
I2C_FUNC_SMBUS_BYTE_DATA Handles the SMBus read_byte_data
and write_byte_data commands
I2C_FUNC_SMBUS_WORD_DATA Handles the SMBus read_word_data
and write_word_data commands
I2C_FUNC_SMBUS_BLOCK_DATA Handles the SMBus read_block_data
and write_block_data commands
I2C_FUNC_SMBUS_I2C_BLOCK Handles the SMBus read_i2c_block_data
and write_i2c_block_data commands
I2C_FUNC_SMBUS_EMUL Handles all SMBus commands that can be
emulated by a real I2C adapter (using
the transparent emulation layer)
========================= ======================================
In kernel versions prior to 3.5 I2C_FUNC_NOSTART was implemented as
part of I2C_FUNC_PROTOCOL_MANGLING.
어댑터 드라이버의 functionality 콜백
63-97새 어댑터 드라이버를 작성할 때는 `functionality` 함수 콜백을 구현해야 합니다. SMBus 전용 어댑터는 자신이 지원하는 SMBus 트랜잭션을 모두 나열합니다.
`i2c-piix4` 예제의 `piix4_func()`는 Quick, Byte, Byte Data, Word Data, Block Data 기능 비트를 OR하여 반환합니다. 반면 완전한 I2C 어댑터의 전형인 `i2c-pxa` 예제는 `I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL`을 반환합니다.
`I2C_FUNC_SMBUS_EMUL`에는 어댑터 드라이버의 별도 도움 없이 `I2C_FUNC_I2C`를 이용해 i2c-core가 에뮬레이션할 수 있는 모든 SMBus 트랜잭션과 I2C 블록 트랜잭션이 포함됩니다.
이 설계 덕분에 클라이언트 드라이버는 필요한 SMBus 기능이 어댑터 하드웨어에 직접 구현되었는지, 아니면 I2C 어댑터 위에서 i2c-core가 소프트웨어로 에뮬레이션하는지 구분할 필요가 없습니다.
예제 드라이버가 반환하는 기능 마스크를 비교합니다.
어댑터의 실제 능력이 클라이언트 검사 결과가 되는 과정입니다.
ADAPTER IMPLEMENTATION
----------------------
When you write a new adapter driver, you will have to implement a
function callback ``functionality``. Typical implementations are given
below.
A typical SMBus-only adapter would list all the SMBus transactions it
supports. This example comes from the i2c-piix4 driver::
static u32 piix4_func(struct i2c_adapter *adapter)
{
return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
I2C_FUNC_SMBUS_BLOCK_DATA;
}
A typical full-I2C adapter would use the following (from the i2c-pxa
driver)::
static u32 i2c_pxa_functionality(struct i2c_adapter *adap)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}
I2C_FUNC_SMBUS_EMUL includes all the SMBus transactions (with the
addition of I2C block transactions) which i2c-core can emulate using
I2C_FUNC_I2C without any help from the adapter driver. The idea is
to let the client drivers check for the support of SMBus functions
without having to care whether the said functions are implemented in
hardware by the adapter, or emulated in software by i2c-core on top
of an I2C adapter.
클라이언트 드라이버의 기능 검사
98-131클라이언트는 어댑터에 연결하거나 지원 장치가 존재하는지 시험하기 전에 필요한 기능이 있는지 확인해야 합니다. `lm75` 예제는 `i2c_check_functionality()`로 SMBus Byte Data와 Word Data 기능을 동시에 검사합니다.
두 기능 중 하나라도 없으면 이 드라이버는 해당 어댑터에서 동작할 수 없으므로 탐색을 계속할 이유가 없습니다. 검사가 성공하면 `i2c_smbus_read_byte_data()`, `i2c_smbus_write_byte_data()`, `i2c_smbus_read_word_data()`, `i2c_smbus_write_word_data()`를 안전하게 호출할 수 있습니다.
경험 법칙은 명확합니다. `i2c_check_functionality()`로 검사하는 기능 상수는 드라이버가 실제로 호출하는 `i2c_smbus_*` 함수와 정확히 일치해야 합니다.
검사 결과만으로 기능이 하드웨어에 구현되었는지 i2c-core가 소프트웨어로 에뮬레이션하는지는 알 수 없습니다. 그러나 I2C core가 이 차이를 투명하게 처리하므로 클라이언트 드라이버는 이를 신경 쓸 필요가 없습니다.
검사한 비트와 이후 호출 가능한 함수의 대응입니다.
기능 검사는 장치 탐색보다 앞서 수행합니다.
CLIENT CHECKING
---------------
Before a client tries to attach to an adapter, or even do tests to check
whether one of the devices it supports is present on an adapter, it should
check whether the needed functionality is present. The typical way to do
this is (from the lm75 driver)::
static int lm75_detect(...)
{
(...)
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_WORD_DATA))
goto exit;
(...)
}
Here, the lm75 driver checks if the adapter can do both SMBus byte data
and SMBus word data transactions. If not, then the driver won't work on
this adapter and there's no point in going on. If the check above is
successful, then the driver knows that it can call the following
functions: i2c_smbus_read_byte_data(), i2c_smbus_write_byte_data(),
i2c_smbus_read_word_data() and i2c_smbus_write_word_data(). As a rule of
thumb, the functionality constants you test for with
i2c_check_functionality() should match exactly the i2c_smbus_* functions
which you driver is calling.
Note that the check above doesn't tell whether the functionalities are
implemented in hardware by the underlying adapter or emulated in
software by i2c-core. Client drivers don't have to care about this, as
i2c-core will transparently implement SMBus transactions on top of I2C
adapters.
/dev 인터페이스에서 기능 확인
132-156사용자 공간 프로그램에서 어댑터에 접근하려면 `/dev` 인터페이스를 사용합니다. 이 경우에도 필요한 기능의 지원 여부를 반드시 확인해야 하며, `I2C_FUNCS` ioctl로 기능 마스크를 읽습니다.
`i2cdetect`에서 가져온 예제는 `/dev/i2c-0`을 읽기·쓰기 모드로 열고 `ioctl(file, I2C_FUNCS, &funcs)`로 기능 비트를 가져옵니다. 장치 열기나 ioctl이 실패하면 오류를 처리하고 종료합니다.
가져온 `funcs`에 `I2C_FUNC_SMBUS_QUICK` 비트가 없으면 필요한 SMBus `write_quick` 기능을 사용할 수 없으므로 종료합니다. 비트가 있을 때만 해당 명령을 안전하게 사용합니다.
`/dev/i2c-N`을 통한 검사 순서입니다.
CHECKING THROUGH /DEV
---------------------
If you try to access an adapter from a userspace program, you will have
to use the /dev interface. You will still have to check whether the
functionality you need is supported, of course. This is done using
the I2C_FUNCS ioctl. An example, adapted from the i2cdetect program, is
below::
int file;
if (file = open("/dev/i2c-0", O_RDWR) < 0) {
/* Some kind of error handling */
exit(1);
}
if (ioctl(file, I2C_FUNCS, &funcs) < 0) {
/* Some kind of error handling */
exit(1);
}
if (!(funcs & I2C_FUNC_SMBUS_QUICK)) {
/* Oops, the needed functionality (SMBus write_quick function) is
not available! */
exit(1);
}
/* Now it is safe to use the SMBus write_quick command */
요약·해설
functionality.rst:1-156I2C 클라이언트는 연결이나 장치 탐색 전에 자신이 호출할 API와 정확히 대응하는 기능 비트를 검사해야 하며, 하드웨어 구현과 i2c-core 에뮬레이션의 차이는 core가 투명하게 처리합니다.
원문 분량과 핵심 검토 대상을 요약합니다.
문서의 주요 판단이나 전송 순서를 압축해 보여 줍니다.