LXR | KVM | PM | Time | Interrupt | Systems Performance | Bootup Optimization

Linux extcon概要记录

关键词:extcon、uevent等。

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);

posted on 2024-05-04 23:59  ArnoldLu  阅读(44)  评论(0编辑  收藏  举报

导航