요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
=======================
Extcon Device Subsystem
=======================
Overview
========
The Extcon (External Connector) subsystem provides a unified framework for
managing external connectors in Linux systems. It allows drivers to report
the state of external connectors and provides a standardized interface for
userspace to query and monitor these states.
Extcon is particularly useful in modern devices with multiple connectivity
options, such as smartphones, tablets, and laptops. It helps manage various
types of connectors, including:
1. USB connectors (e.g., USB-C, micro-USB)
2. Charging ports (e.g., fast charging, wireless charging)
3. Audio jacks (e.g., 3.5mm headphone jack)
4. Video outputs (e.g., HDMI, DisplayPort)
5. Docking stations
Real-world examples:
1. Smartphone USB-C port:
A single USB-C port on a smartphone can serve multiple functions. Extcon
can manage the different states of this port, such as:
- USB data connection
- Charging (various types like fast charging, USB Power Delivery)
- Audio output (USB-C headphones)
- Video output (USB-C to HDMI adapter)
2. Laptop docking station:
When a laptop is connected to a docking station, multiple connections are
made simultaneously. Extcon can handle the state changes for:
- Power delivery
- External displays
- USB hub connections
- Ethernet connectivity
3. Wireless charging pad:
Extcon can manage the state of a wireless charging connection, allowing
the system to respond appropriately when a device is placed on or removed
from the charging pad.
4. Smart TV HDMI ports:
In a smart TV, Extcon can manage multiple HDMI ports, detecting when
devices are connected or disconnected, and potentially identifying the
type of device (e.g., gaming console, set-top box, Blu-ray player).
The Extcon framework simplifies the development of drivers for these complex
scenarios by providing a standardized way to report and query connector
states, handle mutually exclusive connections, and manage connector
properties. This allows for more robust and flexible handling of external
connections in modern devices.
Key Components
==============
extcon_dev
----------
The core structure representing an Extcon device::
struct extcon_dev {
const char *name;
const unsigned int *supported_cable;
const u32 *mutually_exclusive;
/* Internal data */
struct device dev;
unsigned int id;
struct raw_notifier_head nh_all;
struct raw_notifier_head *nh;
struct list_head entry;
int max_supported;
spinlock_t lock;
u32 state;
/* Sysfs related */
struct device_type extcon_dev_type;
struct extcon_cable *cables;
struct attribute_group attr_g_muex;
struct attribute **attrs_muex;
struct device_attribute *d_attrs_muex;
};
Key fields:
- ``name``: Name of the Extcon device
- ``supported_cable``: Array of supported cable types
- ``mutually_exclusive``: Array defining mutually exclusive cable types
This field is crucial for enforcing hardware constraints. It's an array of
32-bit unsigned integers, where each element represents a set of mutually
exclusive cable types. The array should be terminated with a 0.
For example:
::
static const u32 mutually_exclusive[] = {
BIT(0) | BIT(1), /* Cable 0 and 1 are mutually exclusive */
BIT(2) | BIT(3) | BIT(4), /* Cables 2, 3, and 4 are mutually exclusive */
0 /* Terminator */
};
In this example, cables 0 and 1 cannot be connected simultaneously, and
cables 2, 3, and 4 are also mutually exclusive. This is useful for
scenarios like a single port that can either be USB or HDMI, but not both
at the same time.
The Extcon core uses this information to prevent invalid combinations of
cable states, ensuring that the reported states are always consistent
with the hardware capabilities.
- ``state``: Current state of the device (bitmap of connected cables)
extcon_cable
------------
Represents an individual cable managed by an Extcon device::
struct extcon_cable {
struct extcon_dev *edev;
int cable_index;
struct attribute_group attr_g;
struct device_attribute attr_name;
struct device_attribute attr_state;
struct attribute *attrs[3];
union extcon_property_value usb_propval[EXTCON_PROP_USB_CNT];
union extcon_property_value chg_propval[EXTCON_PROP_CHG_CNT];
union extcon_property_value jack_propval[EXTCON_PROP_JACK_CNT];
union extcon_property_value disp_propval[EXTCON_PROP_DISP_CNT];
DECLARE_BITMAP(usb_bits, EXTCON_PROP_USB_CNT);
DECLARE_BITMAP(chg_bits, EXTCON_PROP_CHG_CNT);
DECLARE_BITMAP(jack_bits, EXTCON_PROP_JACK_CNT);
DECLARE_BITMAP(disp_bits, EXTCON_PROP_DISP_CNT);
};
Core Functions
==============
.. kernel-doc:: drivers/extcon/extcon.c
:identifiers: extcon_get_state
.. kernel-doc:: drivers/extcon/extcon.c
:identifiers: extcon_set_state
.. kernel-doc:: drivers/extcon/extcon.c
:identifiers: extcon_set_state_sync
.. kernel-doc:: drivers/extcon/extcon.c
:identifiers: extcon_get_property
Sysfs Interface
===============
Extcon devices expose the following sysfs attributes:
- ``name``: Name of the Extcon device
- ``state``: Current state of all supported cables
- ``cable.N/name``: Name of the Nth supported cable
- ``cable.N/state``: State of the Nth supported cable
Usage Example
-------------
.. code-block:: c
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/extcon.h>
struct my_extcon_data {
struct extcon_dev *edev;
struct device *dev;
};
static const unsigned int my_extcon_cable[] = {
EXTCON_USB,
EXTCON_USB_HOST,
EXTCON_NONE,
};
static int my_extcon_probe(struct platform_device *pdev)
{
struct my_extcon_data *data;
int ret;
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
data->dev = &pdev->dev;
/* Initialize extcon device */
data->edev = devm_extcon_dev_allocate(data->dev, my_extcon_cable);
if (IS_ERR(data->edev)) {
dev_err(data->dev, "Failed to allocate extcon device\n");
return PTR_ERR(data->edev);
}
/* Register extcon device */
ret = devm_extcon_dev_register(data->dev, data->edev);
if (ret < 0) {
dev_err(data->dev, "Failed to register extcon device\n");
return ret;
}
platform_set_drvdata(pdev, data);
/* Example: Set initial state */
extcon_set_state_sync(data->edev, EXTCON_USB, true);
dev_info(data->dev, "My extcon driver probed successfully\n");
return 0;
}
static int my_extcon_remove(struct platform_device *pdev)
{
struct my_extcon_data *data = platform_get_drvdata(pdev);
/* Example: Clear state before removal */
extcon_set_state_sync(data->edev, EXTCON_USB, false);
dev_info(data->dev, "My extcon driver removed\n");
return 0;
}
static const struct of_device_id my_extcon_of_match[] = {
{ .compatible = "my,extcon-device", },
{ },
};
MODULE_DEVICE_TABLE(of, my_extcon_of_match);
static struct platform_driver my_extcon_driver = {
.driver = {
.name = "my-extcon-driver",
.of_match_table = my_extcon_of_match,
},
.probe = my_extcon_probe,
.remove = my_extcon_remove,
};
module_platform_driver(my_extcon_driver);
This example demonstrates:
---------------------------
- Defining supported cable types (USB and USB Host in this case).
- Allocating and registering an extcon device.
- Setting an initial state for a cable (USB connected in this example).
- Clearing the state when the driver is removed.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
Extcon subsystem 개요와 사용 사례
1-56문서 제목은 `Extcon Device Subsystem`입니다. Extcon(External Connector) subsystem은 Linux system의 external connector를 관리하는 통합 framework입니다. driver가 connector state를 보고할 수 있게 하고 userspace가 그 state를 query하고 monitor하는 표준 interface를 제공합니다.
Extcon은 smartphone, tablet, laptop처럼 connectivity option이 많은 현대 device에서 특히 유용합니다. USB-C·micro-USB connector, fast/wireless charging port, 3.5mm audio jack, HDMI·DisplayPort video output, docking station 등을 관리할 수 있습니다.
smartphone의 USB-C port 하나는 USB data, fast charging·USB Power Delivery, USB-C headphone audio, USB-C-to-HDMI video output 같은 여러 기능을 가질 수 있으며 Extcon이 각 state를 관리합니다.
laptop을 docking station에 연결하면 power delivery, external display, USB hub, Ethernet connection이 동시에 생길 수 있고 Extcon이 이 state change를 처리합니다.
wireless charging pad에서는 device를 pad에 올리거나 제거할 때 charging connection state를 관리해 system이 적절히 반응하게 합니다.
smart TV에서는 여러 HDMI port의 connect/disconnect를 감지하고 gaming console, set-top box, Blu-ray player 같은 device type까지 식별하는 데 사용할 수 있습니다.
Extcon framework는 connector state report/query, mutually exclusive connection, connector property 관리를 표준화해 복잡한 driver 개발을 단순화하고 external connection을 더 견고하고 유연하게 처리합니다.
하나 또는 여러 connector에서 관리하는 state를 정리했습니다.
extcon_dev와 mutually exclusive cable
57-118`struct extcon_dev`는 Extcon device를 나타내는 core structure입니다.
struct extcon_dev {
const char *name;
const unsigned int *supported_cable;
const u32 *mutually_exclusive;
/* Internal data */
struct device dev;
unsigned int id;
struct raw_notifier_head nh_all;
struct raw_notifier_head *nh;
struct list_head entry;
int max_supported;
spinlock_t lock;
u32 state;
/* Sysfs related */
struct device_type extcon_dev_type;
struct extcon_cable *cables;
struct attribute_group attr_g_muex;
struct attribute **attrs_muex;
struct device_attribute *d_attrs_muex;
};
`name`은 Extcon device 이름이고 `supported_cable`은 지원 cable type array입니다. `mutually_exclusive`는 동시에 연결될 수 없는 cable type 집합을 정의하는 array입니다. `state`는 현재 연결된 cable을 나타내는 bitmap입니다.
internal field에는 generic `struct device`, instance `id`, 전체/cable별 raw notifier head, global entry list, 최대 cable 수, state를 보호하는 spinlock이 있습니다. sysfs 관련 field는 device type, cable object array, mutually exclusive attribute group과 attribute pointer를 보관합니다.
`mutually_exclusive`는 hardware constraint를 강제하는 핵심 field입니다. 각 32-bit unsigned integer가 서로 배타적인 cable type 집합을 bitmask로 표현하며 array는 0으로 끝나야 합니다.
static const u32 mutually_exclusive[] = {
BIT(0) | BIT(1), /* Cable 0 and 1 are mutually exclusive */
BIT(2) | BIT(3) | BIT(4), /* Cables 2, 3, and 4 are mutually exclusive */
0 /* Terminator */
};
예제에서는 cable 0과 1을 동시에 연결할 수 없고 cable 2, 3, 4도 서로 배타적입니다. 하나의 port가 USB 또는 HDMI 중 하나만 제공할 수 있는 경우에 유용합니다. Extcon core는 이 정보로 잘못된 state 조합을 막아 report state가 hardware capability와 항상 일치하게 합니다.
public configuration, runtime state와 sysfs 내부 data를 구분했습니다.
새 cable state를 적용하기 전 core가 hardware constraint를 확인하는 개념 흐름입니다.
extcon_cable과 property 저장소
119-140`struct extcon_cable`은 Extcon device가 관리하는 개별 cable을 나타냅니다.
struct extcon_cable {
struct extcon_dev *edev;
int cable_index;
struct attribute_group attr_g;
struct device_attribute attr_name;
struct device_attribute attr_state;
struct attribute *attrs[3];
union extcon_property_value usb_propval[EXTCON_PROP_USB_CNT];
union extcon_property_value chg_propval[EXTCON_PROP_CHG_CNT];
union extcon_property_value jack_propval[EXTCON_PROP_JACK_CNT];
union extcon_property_value disp_propval[EXTCON_PROP_DISP_CNT];
DECLARE_BITMAP(usb_bits, EXTCON_PROP_USB_CNT);
DECLARE_BITMAP(chg_bits, EXTCON_PROP_CHG_CNT);
DECLARE_BITMAP(jack_bits, EXTCON_PROP_JACK_CNT);
DECLARE_BITMAP(disp_bits, EXTCON_PROP_DISP_CNT);
};
`edev`는 owner `extcon_dev`, `cable_index`는 지원 cable array의 index입니다. `attr_g`, `attr_name`, `attr_state`, `attrs`는 cable별 sysfs name/state attribute를 구성합니다.
USB, charger, jack, display category마다 `union extcon_property_value` array를 가지고, 각 category의 지원 property를 표시하는 bitmap도 별도로 선언합니다.
connector category별 value array와 capability bitmap의 쌍입니다.
Core function
141-156Extcon core function은 `drivers/extcon/extcon.c`의 kernel-doc에서 가져옵니다.
`extcon_get_state`는 cable의 현재 connected state를 조회합니다.
.. kernel-doc:: drivers/extcon/extcon.c
:identifiers: extcon_get_state
`extcon_set_state`는 cable state를 변경합니다.
.. kernel-doc:: drivers/extcon/extcon.c
:identifiers: extcon_set_state
`extcon_set_state_sync`는 state를 변경하고 관련 notification을 동기적으로 전달하는 API입니다.
.. kernel-doc:: drivers/extcon/extcon.c
:identifiers: extcon_set_state_sync
`extcon_get_property`는 connector의 지정 property value를 읽습니다.
.. kernel-doc:: drivers/extcon/extcon.c
:identifiers: extcon_get_property
state와 property를 조회·변경하는 핵심 operation입니다.
Sysfs interface
157-166Extcon device는 sysfs에 다음 attribute를 노출합니다.
- `name`: Extcon device 이름
- `state`: 지원하는 모든 cable의 현재 state
- `cable.N/name`: N번째 지원 cable의 이름
- `cable.N/state`: N번째 지원 cable의 state
device-wide attribute와 cable별 attribute를 구분했습니다.
Managed Extcon platform driver 예제
167-248다음 전체 예제는 USB와 USB Host cable을 지원하는 Extcon platform driver를 정의합니다.
.. code-block:: c
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/extcon.h>
struct my_extcon_data {
struct extcon_dev *edev;
struct device *dev;
};
static const unsigned int my_extcon_cable[] = {
EXTCON_USB,
EXTCON_USB_HOST,
EXTCON_NONE,
};
static int my_extcon_probe(struct platform_device *pdev)
{
struct my_extcon_data *data;
int ret;
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
data->dev = &pdev->dev;
/* Initialize extcon device */
data->edev = devm_extcon_dev_allocate(data->dev, my_extcon_cable);
if (IS_ERR(data->edev)) {
dev_err(data->dev, "Failed to allocate extcon device\n");
return PTR_ERR(data->edev);
}
/* Register extcon device */
ret = devm_extcon_dev_register(data->dev, data->edev);
if (ret < 0) {
dev_err(data->dev, "Failed to register extcon device\n");
return ret;
}
platform_set_drvdata(pdev, data);
/* Example: Set initial state */
extcon_set_state_sync(data->edev, EXTCON_USB, true);
dev_info(data->dev, "My extcon driver probed successfully\n");
return 0;
}
static int my_extcon_remove(struct platform_device *pdev)
{
struct my_extcon_data *data = platform_get_drvdata(pdev);
/* Example: Clear state before removal */
extcon_set_state_sync(data->edev, EXTCON_USB, false);
dev_info(data->dev, "My extcon driver removed\n");
return 0;
}
static const struct of_device_id my_extcon_of_match[] = {
{ .compatible = "my,extcon-device", },
{ },
};
MODULE_DEVICE_TABLE(of, my_extcon_of_match);
static struct platform_driver my_extcon_driver = {
.driver = {
.name = "my-extcon-driver",
.of_match_table = my_extcon_of_match,
},
.probe = my_extcon_probe,
.remove = my_extcon_remove,
};
module_platform_driver(my_extcon_driver);
`my_extcon_cable`은 `EXTCON_USB`, `EXTCON_USB_HOST`를 나열하고 `EXTCON_NONE`으로 끝납니다. probe는 `devm_kzalloc()`으로 private data를 할당하고 `devm_extcon_dev_allocate()`로 Extcon device를 만든 뒤 `devm_extcon_dev_register()`로 등록합니다.
등록 성공 후 `platform_set_drvdata()`로 data를 저장하고 `extcon_set_state_sync(..., EXTCON_USB, true)`로 USB connected 초기 state를 설정합니다. remove에서는 `platform_get_drvdata()`로 data를 얻어 같은 API에 false를 넘겨 state를 clear합니다.
OF match table은 compatible string `my,extcon-device`를 사용하고 `module_platform_driver()`로 platform driver를 등록합니다. managed allocation과 registration을 사용하므로 resource cleanup은 device lifecycle에 결합됩니다.
예제의 probe, state report와 remove 순서입니다.
예제가 보여주는 핵심
249-255예제는 다음 네 가지를 보여줍니다.
- USB와 USB Host라는 지원 cable type 정의
- Extcon device allocation과 registration
- USB connected라는 cable 초기 state 설정
- driver remove 때 state clear
요약과 해설
extcon.rst:1-255Extcon은 USB, charging, audio, display 같은 external connector의 state와 property를 공통 model로 보고합니다. `supported_cable`과 state bitmap, cable별 notifier를 사용하고 `mutually_exclusive` bitmask로 hardware가 허용하지 않는 동시 연결을 차단합니다.
provider driver는 managed allocation/registration API로 `extcon_dev`를 등록하고 `extcon_set_state_sync()`로 state와 notification을 갱신합니다. userspace는 device-wide state와 `cable.N` sysfs attribute로 이를 관찰합니다.