GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing docs.kernel.org — Extcon Device Subsystem — The Linux Kernel documentation 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:
Real-world examples:
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:
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¶
Parameters
Description Returns 0 if success or error number if fail.
Parameters
Description Note that this function set the state of an external connector without
a notification. To synchronize the state of an external connector,
have to use Returns 0 if success or error number if fail.
Parameters
Description Note that this function set the state of external connector and synchronize the state by sending a notification. Returns 0 if success or error number if fail.
Parameters
Description Note that when getting the property value of external connector, the external connector should be attached. If detached state, function return 0 without property value. Also, the each property should be included in the list of supported properties according to extcon type. Returns 0 if success or error number if fail. Sysfs Interface¶Extcon devices expose the following sysfs attributes:
Usage Example¶#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:¶
|
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |