Linux extcon概要记录
1 extcon介绍
extcon是External Connector的简称,用于抽象外部连接器,比如说Audio Jack、USB MicroB/TypeC接口等。
extcon驱动的主要功能是识别外部连接器状态变化,并将状态变化通知到与外部连接器相关的其他驱动。
2 extcon内核配置
extcon配置如下:
Device Drivers
External Connector Class (extcon) support
ADC Jack extcon support
GPIO extcon support
USB GPIO extcon support
extcon相关文件包括:核心devres.c和extcon.c,以及特定Connector接口的实现,比如ADC、GPIO等。
drivers/extcon/├── devres.c--带资源管理的API。
├── extcon-adc-jack.c--基于ADC读取值进行extcon状态更新。
├── extcon.c
├── extcon-gpio.c--基于读取GPIO值进行extcon状态更新。
├── extcon-usb-gpio.c--基于gpio和vbus判断USB相关的extcon状态。
3 extcon类初始化
extcon类的初始化很简单,仅创建了一个extcon_class以及相关属性节点。
extcon_class_init
create_extcon_class--创建extcon_class,此类设备属性为extcon_groups。
4 extcon相关数据结构和API
struct extcon_dev表示一个External Connector设备:
struct extcon_dev {
/* Optional user initializing data */
const char *name;
const unsigned int *supported_cable;
const u32 *mutually_exclusive;
/* Internal data. Please do not set. */
struct device dev;
struct raw_notifier_head nh_all;
struct raw_notifier_head *nh;
struct list_head entry;
int max_supported;--当前extcon支持的最多cable数。
spinlock_t lock; /* could be called by irq handler */
u32 state;
/* /sys/class/extcon/.../cable.n/... */
struct device_type extcon_dev_type;
struct extcon_cable *cables;
/* /sys/class/extcon/.../mutually_exclusive/... */
struct attribute_group attr_g_muex;
struct attribute **attrs_muex;
struct device_attribute *d_attrs_muex;
};
支持的extcon类型和ID如下:
#define EXTCON_TYPE_USB BIT(0) /* USB connector */
#define EXTCON_TYPE_CHG BIT(1) /* Charger connector */
#define EXTCON_TYPE_JACK BIT(2) /* Jack connector */
#define EXTCON_TYPE_DISP BIT(3) /* Display connector */
#define EXTCON_TYPE_MISC BIT(4) /* Miscellaneous connector */
#define EXTCON_NONE 0
/* USB external connector */
#define EXTCON_USB 1
#define EXTCON_USB_HOST 2
#define EXTCON_USB_VBUS_EN 3
...
/* Jack external connector */
#define EXTCON_JACK_MICROPHONE 20
#define EXTCON_JACK_HEADPHONE 21
#define EXTCON_JACK_LINE_IN 22
#define EXTCON_JACK_LINE_OUT 23
#define EXTCON_JACK_VIDEO_IN 24
#define EXTCON_JACK_VIDEO_OUT 25
#define EXTCON_JACK_SPDIF_IN 26 /* Sony Philips Digital InterFace */
#define EXTCON_JACK_SPDIF_OUT 27
...
#define EXTCON_NUM 63
extcon内存的分配和释放函数:
struct extcon_dev *extcon_dev_allocate(const unsigned int *cable);
void extcon_dev_free(struct extcon_dev *edev);
struct extcon_dev *devm_extcon_dev_allocate(struct device *dev,
const unsigned int *cable);
void devm_extcon_dev_free(struct device *dev, struct extcon_dev *edev);
extcon的注册和注销函数:
int extcon_dev_register(struct extcon_dev *edev);
void extcon_dev_unregister(struct extcon_dev *edev);
int devm_extcon_dev_register(struct device *dev,
struct extcon_dev *edev);
void devm_extcon_dev_unregister(struct device *dev,
struct extcon_dev *edev);
devm_extcon_dev_register()是带资源管理的extcon注册函数:
devm_extcon_dev_register--带资源管理的extcon注册函数,去注册时调用devm_extcon_dev_unreg。
extcon_dev_register
--设置extcon名。
--为每个Cable创建name和state属性。
--device_register--注册设备。
extcon状态设置函数:
int extcon_set_state(struct extcon_dev *edev, unsigned int id,
bool state);--设置状态但不sync。
int extcon_set_state_sync(struct extcon_dev *edev, unsigned int id,
bool state);--设置状态并sync。
extcon_set_state_sync()设置一个exton的状态,并通过uevent通知用户空间:
extcon_set_state_sync
->is_extcon_changed
->extcon_set_state
->extcon_sync
->kobject_uevent_env--获取name/state属性,以KOBJ_CHANGE动作发送uevent到用户空间。
extcon属性配置函数:
int extcon_set_property(struct extcon_dev *edev, unsigned int id,
unsigned int prop,
union extcon_property_value prop_val);
int extcon_set_property_sync(struct extcon_dev *edev, unsigned int id,
unsigned int prop,
union extcon_property_value prop_val);
int extcon_set_property_capability(struct extcon_dev *edev,
unsigned int id, unsigned int prop);