1. 原始充电、快充调用逻辑分析

1.1 系统架构

SDP
CDP
DCP
Unknown
成功
失败
成功
失败
成功
失败
VBUS中断
BC2.1检测
充电器类型
标准充电 500mA
充电数据端口 1A
专用充电端口 1.5A
未知类型 500mA
快充检测流程
SFCP检测
触发SFCP快充
PD检测
触发PD快充
Customized FCHG检测
触发Customized FCHG
回退到DCP模式

以上的电流都可以通过dts设置,如dts未设置才使用默认电流

1.2 核心文件分析

1.2.1 sprd_fchg_extcon.c - 快充扩展控制

主要功能

  • 管理多种快充协议(SFCP、PD、Customized FCHG)
  • 提供统一的快充接口和状态标志位
  • 处理快充协议间的优先级和切换

关键函数

// 快充类型检测和切换
static void sprd_fchg_work(struct work_struct *data)
{
    // 检测当前快充类型并设置相应的使能状
    if (info->pd_extcon && (val.intval == POWER_SUPPLY_USB_TYPE_PD)) {
        info->pd_enable = true;
        info->fchg_type = POWER_SUPPLY_CHARGE_TYPE_FAST;
    } else if (info->sfcp_extcon && val.intval == POWER_SUPPLY_CHARGE_TYPE_FAST) {
        info->sfcp_enable = true;
        info->fchg_type = POWER_SUPPLY_CHARGE_TYPE_FAST;
    } else if (info->customized_fchg_extcon && val.intval == POWER_SUPPLY_CHARGE_TYPE_FAST) {
        info->customized_fchg_enable = true;
        info->fchg_type = POWER_SUPPLY_CHARGE_TYPE_FAST;
    }
}

快充检测流程图

TCPM PD
SFCP
Customized
Power Supply事件
事件类型
PD检测
SFCP检测
Customized检测
设置PD使能
设置SFCP使能
设置Customized使能
通知CM_EVENT_FAST_CHARGE
1.2.2 sd76930-charger.c - 充电器驱

主要功能

  • 硬件充电器控制(SD76930芯片)
  • 充电电流/电压调节
  • 充电状态监
  • 支持CUSTOM快充模式(硬件表现为可以设置DP/DM的pin脚电压)

关键函数

// CUSTOM快充模式设置
static int sd76930_charger_set_custom_chg(struct sd76930_charger_info *info, u32 vol)
{
    if (vol < 7000) {
        // 退出CUSTOM模式,恢复DCP
        reg_val = 0x0;
        ret = sd76930_update_bits(info, SD76930_REG_4, 
                     SD76930_REG_DPVOL_MASK | SD76930_REG_DMVOL_MASK, 
                     reg_val);
    } else {
        // 进入CUSTOM模式:DP=0V, DM=0V -> DP=3.3V, DM=0V
        reg_val = SD76930_REG_DPVOL_0V | SD76930_REG_DMVOL_0V;
        ret = sd76930_update_bits(info, SD76930_REG_4, 
                     SD76930_REG_DPVOL_MASK | SD76930_REG_DMVOL_MASK, 
                     reg_val);
        msleep(10);
        reg_val = SD76930_REG_DPVOL_3V3 | SD76930_REG_DMVOL_0V;
        ret = sd76930_update_bits(info, SD76930_REG_4, 
                     SD76930_REG_DPVOL_MASK | SD76930_REG_DMVOL_MASK, 
                     reg_val);
    }
}
1.2.3 charger-manager.c - 充电管理

主要功能

  • 统一管理所有充电相关功
  • 处理快充事件和状态切
  • 提供 custom_fchg_dpdm_set 接口供外部调

关键函数

// 快充事件处理
static void fast_charge_handler(struct charger_manager *cm)
{
    // 检查是否满足快充条
    if (cm_is_reach_fchg_threshold(cm)) {
        // 启用固定快充
        cm_fixed_fchg_enable(cm);
    }
}

// CUSTOM快充DP/DM设置接口
int custom_fchg_dpdm_set(bool enable)
{
    // 设置充电限制电流00mA
    if (enable) {
        val.intval = 500000; // 500mA
        power_supply_set_property(psy, POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, &val);
    }
    
    // 设置CUSTOM_CHG属
    val.intval = enable ? 7500 : 0; // 7.5V或退
    power_supply_set_property(psy, POWER_SUPPLY_PROP_CHARGE_TYPE, &val);
    
    // 检查电压是否达V以上
    if (enable) {
        for (j = 0; j < 3; j++) {
            msleep(600);
            ret = get_charger_voltage(cm_public, &vbus);
            if (ret == 0 && vbus > 7000000) {
                voltage_ok = true;
                break;
            }
        }
    }
}

2. 协议内容

2.1 CUSTOM 18W快充协议规范

CUSTOM 18W快充协议是一种基于DP/DM电平检测的简单快充协议,具体规范如下

协议触发条件

  • 当DP引脚.3V,DM引脚V
  • 充电器检测到此电平组合后,自动切换到快充模式
  • 输出7.5V电压,最大电.4A
  • 总功率:7.5V × 2.4A = 18W

电平时序要求

  1. 初始状态:DP=0V, DM=0V(DCP模式
  2. 握手阶段:DP=0V, DM=0V 延时10ms DP=3.3V, DM=0V
  3. 检测阶段:维持DP=3.3V, DM=0V状态至00ms
  4. 电压检测:充电器输出电压应达到7V以上
  5. 确认阶段:连次检测电压均超过7V阈

协议优势

  • 实现简单,无需复杂的通信协议
  • 硬件成本低,兼容性好
  • 检测速度快,响应时间

3. 快充识别流程

6.1 整体识别流程

SDP
CDP
DCP
Unknown
成功
失败
成功
失败
成功
失败
成功
失败
VBUS插入
BC2.1检测
充电器类型
标准充电 500mA
充电数据端口 1A
专用充电端口 1.5A
未知类型 500mA
快充检测流程
SFCP检测
触发SFCP快充
PD检测
触发PD快充
Customized FCHG检测
触发Customized FCHG
回退到DCP模式
CUSTOM协议检测
DP=3.3V, DM=0V
电压检>7V
启用18W快充
回退到DCP

6.2 详细识别步骤

步骤1:充电器类型检
// 在charger-manager.c中的检测逻辑
static int cm_get_bc1p2_type(struct charger_manager *cm, int *type)
{
    // 1. 检测VBUS是否插入
    if (!cm_is_ext_pwr_online(cm)) {
        *type = CM_CHARGER_TYPE_NONE;
        return 0;
    }
    
    // 2. 读取充电器类型寄存器
    ret = regmap_read(cm->desc->charger_detect, &reg_val);
    
    // 3. 根据寄存器值判断类
    switch (reg_val & CHARGER_TYPE_MASK) {
    case SDP_TYPE:
        *type = CM_CHARGER_TYPE_SDP;
        break;
    case DCP_TYPE:
        *type = CM_CHARGER_TYPE_DCP;
        break;
    case CDP_TYPE:
        *type = CM_CHARGER_TYPE_CDP;
        break;
    default:
        *type = CM_CHARGER_TYPE_UNKNOWN;
        break;
    }
}
步骤2:快充协议优先级检
// 在sprd_fchg_extcon.c中的检测逻辑
static void sprd_fchg_work(struct work_struct *data)
{
    // 1. 首先检测PD协议
    if (info->pd_extcon && (val.intval == POWER_SUPPLY_USB_TYPE_PD)) {
        info->pd_enable = true;
        info->fchg_type = POWER_SUPPLY_CHARGE_TYPE_FAST;
        goto notify;
    }
    
    // 2. 检测SFCP协议
    if (info->sfcp_extcon && val.intval == POWER_SUPPLY_CHARGE_TYPE_FAST) {
        info->sfcp_enable = true;
        info->fchg_type = POWER_SUPPLY_CHARGE_TYPE_FAST;
        goto notify;
    }
    
    // 3. 检测Customized FCHG协议
    if (info->customized_fchg_extcon && val.intval == POWER_SUPPLY_CHARGE_TYPE_FAST) {
        info->customized_fchg_enable = true;
        info->fchg_type = POWER_SUPPLY_CHARGE_TYPE_FAST;
        goto notify;
    }
    
notify:
    // 4. 通知充电管理
    cm_notify_event(info->psy, CM_EVENT_FAST_CHARGE, NULL);
}

7. 快充检

7.1 CUSTOM协议检测详细流

7.1.1 检测工作函数部分
static void custom_18w_detect_only_work(struct work_struct *work)
{
    struct delayed_work *dwork = to_delayed_work(work);
    struct custom_18w_info *info = container_of(dwork, struct custom_18w_info, detect_work);
    int ret;

    dev_info(info->dev, "[debug] custom_fchg Starting 18W fast charge detection only");

    // 步骤1:关闭DCP模式,释放DP/DM准备进入检测模
    // 这里通过设置寄存器位来禁用BC1.2检测功
    ret = custom_dcp_switch_en(info, false);
    if (ret) {
        dev_err(info->dev, "Failed to disable DCP mode: %d\n", ret);
        return;
    }

    // 步骤2:设置DP/DM电平进行协议握手
    // 调用charger-manager.c中的custom_fchg_dpdm_set函数
    ret = custom_fchg_dpdm_set(true);
    if (ret) {
        // 检测失败的处理逻辑
        dev_info(info->dev, "[debug] custom_fchg 18W fast charge not supported, fallback to DCP mode");
        
        // 恢复DCP模式
        custom_dcp_switch_en(info, true);
        custom_fchg_dpdm_set(false);
        info->is_fast_charge_susport = false;
    } else {
        // 检测成功的处理逻辑
        dev_info(info->dev, "[debug] custom_fchg 18W fast charge detection successful, but closing fast charge");
        info->is_fast_charge_susport = true;
        
        // 检测完成后立即关闭快充,只做检测不做启
        custom_fchg_dpdm_set(false);
        custom_dcp_switch_en(info, true);
        
        // 通知Power Supply属性变
        power_supply_changed(info->psy);
    }

    info->is_detecting = false;
}

函数逻辑分析

  1. DCP模式关闭:通过custom_dcp_switch_en(info, false)禁用BC1.2检测,避免与快充检测冲
  2. 协议握手:调用custom_fchg_dpdm_set(true)设置DP=3.3V, DM=0V进行协议握手
  3. 结果判断:根据返回值判断是否支18W快充
  4. 状态恢:无论成功与否,都恢复到DCP模式,只做检测不做启
  5. 属性通知:通过power_supply_changed通知上层属性变
7.1.2 DCP模式切换函数分析
static int custom_dcp_switch_en(struct custom_18w_info *info, bool enable)
{
    int ret;

    dev_info(info->dev, "[debug] custom_fchg %s: enable = %d\n", __func__, enable);
    
    // 通过regmap操作PMIC寄存
    // BIT_DP_DM_BC_ENB_MASK控制BC1.2检测功能的使能
    ret = regmap_update_bits(info->pmic, info->det_offset,
                  BIT_DP_DM_BC_ENB_MASK,
                  enable << BIT_DP_DM_BC_ENB_SHIFT);
    if (ret)
        dev_err(info->dev, "[debug] custom_fchg failed to switch dcp detect\n");
    return ret;
}

函数逻辑分析

  1. 寄存器操:通过regmap_update_bits操作PMIC寄存
  2. 位控BIT_DP_DM_BC_ENB_MASK控制BC1.2检测功能的使能/禁用
  3. 参数传enable参数决定是启用还是禁用DCP检
  4. 错误处理:如果寄存器操作失败,记录错误日志并返回错误
7.1.3 DP/DM设置函数分析
// 在charger-manager.c中的实现
int custom_fchg_dpdm_set(bool enable)
{
    struct power_supply *psy;
    union power_supply_propval val;
    int ret = 0;
    int i, vbus, j;
    unsigned int back_limit_cur = 0;
    bool voltage_ok = false;

    dev_info(cm_public->dev, "[debug] custom_fchg: enable=%d\n", enable);

    // 遍历所有充电器Power Supply
    for (i = 0; cm_public->desc->psy_charger_stat[i]; i++) {
        psy = power_supply_get_by_name(cm_public->desc->psy_charger_stat[i]);
        if (!psy) {
            dev_err(cm_public->dev, "Cannot find power supply \"%s\"\n", 
                   cm_public->desc->psy_charger_stat[i]);
            continue;
        }

        // 步骤1:保存并设置充电限制电流500mA
        if (enable) {
            // 获取当前电流限制
            ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, &val);
            if (ret) {
                dev_err(cm_public->dev, "failed to get current limit: %d\n", ret);
                power_supply_put(psy);
                continue;
            }
            back_limit_cur = val.intval;
            
            // 如果当前限制电流大于500mA,则设置500mA
            if (back_limit_cur > 500000) {
                val.intval = 500000; // 500mA
                ret = power_supply_set_property(psy, POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, &val);
                if (ret) {
                    dev_err(cm_public->dev, "failed to set current limit: %d\n", ret);
                }
            }
        }
        
        // 步骤2:设置CUSTOM_CHG属性
        // 7500mV = 7.5V表示启用CUSTOM快充表示退出为0
        val.intval = enable ? 7500 : 0;
        power_supply_set_property(psy, POWER_SUPPLY_PROP_CHARGE_TYPE, &val);

        // 步骤3:如果启用,检查电压是否达V以上
        if (enable) {
            voltage_ok = false;
            for (j = 0; j < 3; j++) {
                msleep(600); // 等待600ms让充电器响应
                ret = get_charger_voltage(cm_public, &vbus);
                dev_info(cm_public->dev, "[debug] custom_fchg: vbus=%d ret=%d\n", vbus, ret);
                
                if (ret == 0 && vbus > 7000000) { // 7V阈值
                    voltage_ok = true;
                    break;
                }
            }
            
            if (!voltage_ok) {
                dev_err(cm_public->dev, "[debug] custom_fchg: voltage check failed\n");
                ret = -EINVAL;
            }
        }

        power_supply_put(psy);
    }
    
    dev_info(cm_public->dev, "[debug]custom_fchg: result=%d, voltage_ok=%d\n", ret, voltage_ok);
    return ret;
}

函数逻辑分析

  1. 电流限制:在启用快充前,将充电电流限制为500mA,避免电流过大,导致压降太大检测失败
  2. 协议触发:通过设置POWER_SUPPLY_PROP_CHARGE_TYPE(GKI限制不能添加属性,故使用该属性)500mV来触发CUSTOM协议
  3. 电压检:连次检测充电器输出电压,必须超7V阈值
  4. 时序控制:每次检测间00ms,给充电器足够的响应时间
  5. 错误处理:如果电压检测失败,返回错误
7.1.4 硬件层DP/DM控制分析
// 在sd76930-charger.c中的实现
static int sd76930_charger_set_custom_chg(struct sd76930_charger_info *info, u32 vol)
{
    u8 reg_val;
    int ret;

    dev_info(info->dev, "sd76930_charger_set_custom_chg: vol=%d\n", vol);

    if (vol < 7000) {
        // 退出CUSTOM模式,恢复DCP
        reg_val = 0x0;
        ret = sd76930_update_bits(info, SD76930_REG_4, 
                     SD76930_REG_DPVOL_MASK | SD76930_REG_DMVOL_MASK, 
                     reg_val);
        if (ret) {
            dev_err(info->dev, "failed to exit custom charge mode: %d\n", ret);
            return ret;
        }
        dev_info(info->dev, "exited custom charge mode\n");
    } else {
        // 进入CUSTOM模式:DP=0V, DM=0V
        reg_val = SD76930_REG_DPVOL_0V | SD76930_REG_DMVOL_0V;
        ret = sd76930_update_bits(info, SD76930_REG_4, 
                     SD76930_REG_DPVOL_MASK | SD76930_REG_DMVOL_MASK, 
                     reg_val);
        if (ret) {
            dev_err(info->dev, "failed to set DP=0V, DM=0V: %d\n", ret);
            return ret;
        }
        msleep(10); // 等待10ms
        
        // 然后设置DP=3.3V, DM=0V
        reg_val = SD76930_REG_DPVOL_3V3 | SD76930_REG_DMVOL_0V;
        ret = sd76930_update_bits(info, SD76930_REG_4, 
                     SD76930_REG_DPVOL_MASK | SD76930_REG_DMVOL_MASK, 
                     reg_val);
        if (ret) {
            dev_err(info->dev, "failed to set DP=3.3V, DM=0V: %d\n", ret);
            return ret;
        }
        
        // 等待确保DP电平稳定.3V
        msleep(10);
        
        dev_info(info->dev, "entered custom charge mode\n");
    }

    // 验证寄存器设置是否成
    ret = sd76930_read(info, SD76930_REG_4, &reg_val);
    if (ret) {
        dev_err(info->dev, "failed to read register after setting: %d\n", ret);
        return ret;
    }
    
    dev_info(info->dev, "sd76930_charger_set_custom_chg: vol=%d, reg_val=0x%x, ret=%d\n", 
             vol, reg_val, ret);
    return ret;
}

函数逻辑分析

  1. 两阶段设:先设置DP=0V, DM=0V,延10ms后再设置DP=3.3V, DM=0V
  2. 时序控制:通过msleep(10)确保电平切换的时序
  3. 寄存器操作:使用sd76930_update_bits更新SD76930芯片的寄存器
  4. 状态较验:通过sd76930_read读取寄存器值验证设置是否成
  5. 错误处理:每个步骤都有详细的错误检查和日志记录

7.2 使能工作函数分析

static void custom_18w_enable_work(struct work_struct *work)
{
    struct delayed_work *dwork = to_delayed_work(work);
    struct custom_18w_info *info = container_of(dwork, struct custom_18w_info, enable_work);
    int ret;

    dev_info(info->dev, "[debug] custom_fchg Starting 18W fast charge enable");

    // 步骤1:关闭DCP模式,释放DP/DM
    ret = custom_dcp_switch_en(info, false);
    if (ret) {
        dev_err(info->dev, "Failed to disable DCP mode: %d\n", ret);
        return;
    }

    // 步骤2:启用快充
    ret = custom_fchg_dpdm_set(true);
    if (ret) {
        // 启用失败,回退到DCP模式
        dev_info(info->dev, "[debug] custom_fchg 18W fast charge not supported, fallback to DCP mode");
        custom_dcp_switch_en(info, true);
        custom_fchg_dpdm_set(false);
        info->is_fast_charge = false;
    } else {
        // 启用成功
        dev_info(info->dev, "[debug] custom_fchg 18W fast charge enable successful");
        info->is_fast_charge = true;
        
        // 通知Power Supply属性变
        power_supply_changed(info->psy);
        
        // 通知sprd_fchg_extcon快充状态变
        if (info->fchg_info && info->fchg_info->psy) {
            dev_info(info->dev, "[debug] custom_fchg Notifying CM_EVENT_FAST_CHARGE\n");
            cm_notify_event(info->fchg_info->psy, CM_EVENT_FAST_CHARGE, NULL);
        } else {
            dev_err(info->dev, "[debug] custom_fchg fchg_info or psy is null, cannot notify fast charge\n");
        }
    }

    info->is_detecting = false;
}

*函数逻辑分析

  1. 与检测函数的区别:使能函数会真正启用快充,而检测函数只做检
  2. 状态管理:设置is_fast_charge = true表示快充已启
  3. 事件通知:通过cm_notify_event通知充电管理器快充状态变化
  4. 错误处理:如果启用失败,立即回退到DCP模式
  5. 属性通知:通过power_supply_changed同步Power Supply属

5. 新加文件调用逻辑分析

5.1 custom_18w_max_fchg.c 架构

ONLINE=1
VOLTAGE_MAX=7.5V
ONLINE=0
Platform Device
custom_18w_probe
注册Power Supply
注册到sprd_fchg_extcon
初始化工作队列
Power Supply事件
custom_set_prop
属性类型
启动检测工作
启动使能工作
停止快充
custom_18w_detect_only_work
custom_18w_enable_work
检测快充支持
启用快充
通知Power Supply变化
通知CM_EVENT_FAST_CHARGE

5.2 Power Supply属性处理详细分

5.2.1 属性设置函数分析
static int custom_set_prop(struct power_supply *psy,
              enum power_supply_property psp,
              const union power_supply_propval *val)
{
    struct custom_18w_info *info = power_supply_get_drvdata(psy);

    switch (psp) {
    case POWER_SUPPLY_PROP_ONLINE:
        if (val->intval == 1) {
            dev_info(info->dev, "[debug] custom_fchg ONLINE=1: Starting fast charge detection only, delay 2 seconds");
            
            // 取消之前的检测工作,避免重复执行
            cancel_delayed_work_sync(&info->detect_work);
            
            // 设置检测状态并延时2秒后开始检
            info->is_detecting = true;
            schedule_delayed_work(&info->detect_work, msecs_to_jiffies(2000));
        } else {
            dev_info(info->dev, "[debug] custom_fchg ONLINE=0: Immediately stop detection");
            
            // 立即停止检测,回到DCP模式
            cancel_delayed_work_sync(&info->detect_work);
            info->is_detecting = false;
            info->is_fast_charge = false;
            
            // 通知Power Supply属性变
            power_supply_changed(info->psy);
            
            // 恢复硬件状
            custom_fchg_dpdm_set(false);
            custom_dcp_switch_en(info, true);
        }
        break;
        
    case POWER_SUPPLY_PROP_VOLTAGE_MAX:
        dev_info(info->dev, "[debug] custom_fchg set voltage_max: %d uV\n", val->intval);
        
        // 判断传入的电压是否与输出的POWER_SUPPLY_PROP_VOLTAGE_MAX相同
        if (val->intval == 7500000) { // 7.5V
            dev_info(info->dev, "[debug] custom_fchg voltage_max matches, starting fast charge enable");
            
            // 取消之前的使能工
            cancel_delayed_work_sync(&info->enable_work);
            
            // 延时2秒后开始快充使
            info->is_detecting = true;
            schedule_delayed_work(&info->enable_work, msecs_to_jiffies(2000));
        } else {
            dev_info(info->dev, "[debug] custom_fchg voltage_max not match, disabling fast charge");
            
            // 电压不匹配,停止快充
            cancel_delayed_work_sync(&info->enable_work);
            info->is_detecting = false;
            info->is_fast_charge = false;
            
            // 通知Power Supply属性变
            power_supply_changed(info->psy);
            
            // 恢复硬件状
            custom_fchg_dpdm_set(false);
            custom_dcp_switch_en(info, true);
        }
        break;
    }
    
    return 0;
}

函数逻辑分析

  1. ONLINE属性处

    • ONLINE=1:启动检测工作,延时2秒执行,避免与BC1.2检测冲
    • ONLINE=0:立即停止所有工作,恢复到DCP模式
    • 使用cancel_delayed_work_sync确保工作队列不会重复执行
  2. VOLTAGE_MAX属性处

    • 只有电压.5V时才启用快充,其他电压值都会禁用快
    • 延时2秒执行使能工作,给检测工作足够的时间完成
    • 通过电压值作为启用快充的触发条件
  3. 状态管理

    • is_detecting标志防止重复执行检使能工作
    • is_fast_charge标志表示快充是否已启
    • 通过power_supply_changed通知属性变
5.2.2 属性获取函数分析
static int custom_get_prop(struct power_supply *psy,
              enum power_supply_property psp,
              union power_supply_propval *val)
{
    struct custom_18w_info *info = power_supply_get_drvdata(psy);

    switch (psp) {
    case POWER_SUPPLY_PROP_ONLINE:
        val->intval = info->is_fast_charge ? 1 : 0;
        dev_info(info->dev, "[debug] custom_fchg is_fast_charge: %d\n", val->intval);
        break;
        
    case POWER_SUPPLY_PROP_VOLTAGE_MAX:
        val->intval = 7500000; // 7.5V
        break;
        
    case POWER_SUPPLY_PROP_CURRENT_MAX:
        val->intval = 2400000; // 2.4A
        break;
        
    case POWER_SUPPLY_PROP_CHARGE_TYPE:
        val->intval = info->is_fast_charge_susport ? POWER_SUPPLY_CHARGE_TYPE_FAST : POWER_SUPPLY_CHARGE_TYPE_NONE;
        dev_info(info->dev, "[debug] custom_fchg is_fast_charge_susport: %d\n", val->intval);
        break;
    }
    
    return 0;
}

*函数逻辑分析

  1. ONLINE属性:返回当前快充是否启用的状
  2. VOLTAGE_MAX属性:固定返7500000,表示支持的最大电压为7.5V
  3. CURRENT_MAX属性:固定返2400000,表示支持的最大电2.4A
  4. CHARGE_TYPE属性:根据是否支持快充返回相应的充电类型
5.2.3 属性可写性检查函数分析
static int custom_prop_writeable(struct power_supply *psy,
                    enum power_supply_property psp)
{
    return (psp == POWER_SUPPLY_PROP_ONLINE || psp == POWER_SUPPLY_PROP_VOLTAGE_MAX);
}

函数逻辑分析

  • 只有ONLINEVOLTAGE_MAX属性是可写
  • 其他属性(CURRENT_MAXCHARGE_TYPE)是只读
  • 这确保了外部只能通过特定属性来控制快充行为

5.3 驱动初始化流程分

5.3.1 Probe函数详细分析
static int custom_18w_probe(struct platform_device *pdev)
{
    struct custom_18w_info *info;
    struct device_node *sys_np;
    struct power_supply_config cfg = {};
    struct platform_device *regmap_pdev;
    int ret;

    // 步骤1:分配内存并初始化基本信
    info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
    if (!info)
        return -ENOMEM;

    info->dev = &pdev->dev;
    info->det_offset = CUSTOM_CHARGER_DET_OFFSET;
    info->is_detecting = false;
    info->is_fast_charge = false;

    // 步骤2:初始化工作队列
    INIT_DELAYED_WORK(&info->detect_work, custom_18w_detect_only_work);
    INIT_DELAYED_WORK(&info->enable_work, custom_18w_enable_work);

    // 步骤3:查找syscon节点
    sys_np = of_find_compatible_node(NULL, NULL, "sprd,sc27xx-syscon");
    if (!sys_np)
        return -ENODEV;

    // 步骤4:判断芯片类型并设置offset
    if (of_device_is_compatible(sys_np->parent, "sprd,sc2730"))
        info->det_offset = CUSTOM_CHARGER_DETECT_MASK_SC2730;
    else if (of_device_is_compatible(sys_np->parent, "sprd,sc2721"))
        info->det_offset = CUSTOM_CHARGER_DETECT_MASK_SC2721;
    else {
        of_node_put(sys_np);
        return -ENODEV;
    }

    // 步骤5:获取regmap
    regmap_pdev = of_find_device_by_node(sys_np);
    of_node_put(sys_np);
    info->pmic = dev_get_regmap(regmap_pdev->dev.parent, NULL);
    if (IS_ERR(info->pmic)) {
        dev_err(info->dev, "failed to get regmap (%ld)\n", PTR_ERR(info->pmic));
        return PTR_ERR(info->pmic);
    }

    // 步骤6:注册Power Supply
    cfg.drv_data = info;
    info->psy = devm_power_supply_register(&pdev->dev, &custom_desc, &cfg);
    if (IS_ERR(info->psy)) {
        dev_err(info->dev, "failed to register power supply (%ld)\n", PTR_ERR(info->psy));
        return PTR_ERR(info->psy);
    }

    // 步骤7:注册到sprd_fchg_extcon系统
    info->fchg_info = sprd_fchg_info_register(&pdev->dev);
    if (IS_ERR(info->fchg_info)) {
        dev_err(info->dev, "failed to register with sprd_fchg_extcon\n");
        return PTR_ERR(info->fchg_info);
    }

    // 步骤8:初始化sprd_fchg_extcon
    ret = info->fchg_info->ops->extcon_init(info->fchg_info, info->psy);
    if (ret) {
        dev_err(info->dev, "failed to init sprd_fchg_extcon\n");
        if (info->fchg_info) {
            info->fchg_info->ops->remove(info->fchg_info);
        }
        return ret;
    }

    platform_set_drvdata(pdev, info);
    dev_info(info->dev, "%s: probe OK, integrated customized_fchg_psy\n", __func__);
    return 0;
}

函数逻辑分析

  1. 内存分配:使用devm_kzalloc分配内存,自动管理生命周
  2. 工作队列初始化:初始化检测和使能两个工作队列
  3. 设备树解:查找syscon节点并判断芯片类
  4. 寄存器映射:获取PMIC的regmap用于寄存器操作DP/DM切换
  5. Power Supply注册:注册到Linux Power Supply子系统
  6. 系统集成:注册到sprd_fchg_extcon系统,实现与现有快充框架的集成
  7. 错误处理:每个步骤都有完善的错误处理和资源清理
5.3.2 设备树匹配分析
static const struct of_device_id custom_18w_of_match[] = {
    { .compatible = "sprd,customized-fchg-psy" },
    { }
};

设备树配置示例:

custom_18w_max_fchg: custom_18w_max_fchg {
    compatible = "sprd,customized-fchg-psy";
    phys = <&hsphy>;
    extcon = <&pmic_typec>, <&pmic_pd>;
};

5.4 驱动清理流程分析

static int custom_18w_remove(struct platform_device *pdev)
{
    struct custom_18w_info *info = platform_get_drvdata(pdev);

    // 取消工作队列
    cancel_delayed_work_sync(&info->detect_work);
    cancel_delayed_work_sync(&info->enable_work);

    // 停止检
    custom_fchg_dpdm_set(false);
    custom_dcp_switch_en(info, true);

    // 清理sprd_fchg_extcon
    if (info->fchg_info) {
        info->fchg_info->ops->remove(info->fchg_info);
    }

    dev_info(info->dev, "%s: removed\n", __func__);
    return 0;
}

函数逻辑分析

  1. 工作队列清理:取消所有待执行的工作队
  2. 硬件状态恢:恢复到DCP模式,停止快充
  3. 系统集成清理:从sprd_fchg_extcon系统中注销
  4. 资源释放:由于使用了devm_*函数,资源会自动释放

6. 自定义psy_customized_fchg快充方案推荐(AI给的建议)

6.1 方案架构设计

自定义快充驱动
Power Supply接口
硬件控制接口
协议检测模块
ONLINE属性
VOLTAGE_MAX属性
CURRENT_MAX属性
CHARGE_TYPE属性
DP/DM控制
电压调节
电流调节
协议握手
状态检测
错误处理
sprd_fchg_extcon
注册到系统
事件通知
CM_EVENT_FAST_CHARGE

6.2 实现步骤

步骤1:创建驱动框
// 1. 定义设备树兼容
static const struct of_device_id custom_fchg_of_match[] = {
    { .compatible = "vendor,custom-fchg-psy" },
    { }
};

// 2. 定义Power Supply属
static enum power_supply_property custom_fchg_props[] = {
    POWER_SUPPLY_PROP_ONLINE,
    POWER_SUPPLY_PROP_VOLTAGE_MAX,
    POWER_SUPPLY_PROP_CURRENT_MAX,
    POWER_SUPPLY_PROP_CHARGE_TYPE,
};

// 3. 定义Power Supply描述
static const struct power_supply_desc custom_fchg_desc = {
    .name                   = "custom_fchg",
    .type                   = POWER_SUPPLY_TYPE_UNKNOWN,
    .properties             = custom_fchg_props,
    .num_properties         = ARRAY_SIZE(custom_fchg_props),
    .get_property           = custom_fchg_get_prop,
    .set_property           = custom_fchg_set_prop,
    .property_is_writeable  = custom_fchg_prop_writeable,
};
步骤2:实现硬件控制接口
// 硬件控制函数
static int custom_fchg_hw_init(struct custom_fchg_info *info)
{
    // 初始化硬件寄存器
    // 设置默认参数
    // 配置中断
}

static int custom_fchg_set_dpdm(struct custom_fchg_info *info, bool enable)
{
    if (enable) {
        // 设置DP=3.3V, DM=0V进行快充握手
        regmap_update_bits(info->pmic, info->dpdm_reg, 
                          DP_MASK | DM_MASK, 
                          DP_3V3 | DM_0V);
    } else {
        // 恢复DCP模式
        regmap_update_bits(info->pmic, info->dpdm_reg, 
                          DP_MASK | DM_MASK, 
                          DP_HIZ | DM_HIZ);
    }
}

static int custom_fchg_detect_protocol(struct custom_fchg_info *info)
{
    // 实现协议检测逻辑
    // 检查电压、电流变化
    // 判断是否支持快充
}
步骤3:实现Power Supply接口
static int custom_fchg_set_prop(struct power_supply *psy,
                               enum power_supply_property psp,
                               const union power_supply_propval *val)
{
    struct custom_fchg_info *info = power_supply_get_drvdata(psy);
    
    switch (psp) {
    case POWER_SUPPLY_PROP_ONLINE:
        if (val->intval == 1) {
            // 启动快充检
            schedule_delayed_work(&info->detect_work, 
                                msecs_to_jiffies(2000));
        } else {
            // 停止快充
            cancel_delayed_work_sync(&info->detect_work);
            custom_fchg_set_dpdm(info, false);
            info->is_fast_charge = false;
        }
        break;
        
    case POWER_SUPPLY_PROP_VOLTAGE_MAX:
        if (val->intval == 9000000) { // 9V
            // 启用快充
            schedule_delayed_work(&info->enable_work, 
                                msecs_to_jiffies(2000));
        } else {
            // 禁用快充
            cancel_delayed_work_sync(&info->enable_work);
            custom_fchg_set_dpdm(info, false);
            info->is_fast_charge = false;
        }
        break;
    }
    
    return 0;
}
步骤4:集成到sprd_fchg_extcon系统
static int custom_fchg_probe(struct platform_device *pdev)
{
    // 1. 注册Power Supply
    info->psy = devm_power_supply_register(&pdev->dev, 
                                          &custom_fchg_desc, &cfg);
    
    // 2. 注册到sprd_fchg_extcon系统
    info->fchg_info = sprd_fchg_info_register(&pdev->dev);
    
    // 3. 初始化sprd_fchg_extcon
    ret = info->fchg_info->ops->extcon_init(info->fchg_info, info->psy);
    
    // 4. 初始化工作队
    INIT_DELAYED_WORK(&info->detect_work, custom_fchg_detect_work);
    INIT_DELAYED_WORK(&info->enable_work, custom_fchg_enable_work);
}

6.3 设备树配置示

custom_fchg: custom-fchg {
    compatible = "vendor,custom-fchg-psy";
    reg = <0x1b9c 0x4>;
    interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
    interrupt-names = "fchg";
    
    // 硬件相关配置
    dpdm-reg = <0x1b9c>;
    voltage-reg = <0x1ba0>;
    current-reg = <0x1ba4>;
    
    // 快充参数
    fchg-voltage-max = <9000000>;  // 9V
    fchg-current-max = <2000000>;  // 2A
    fchg-power-max = <18000000>;   // 18W
    
    // 检测参
    detect-delay-ms = <2000>;
    enable-delay-ms = <2000>;
    voltage-threshold = <7000000>;  // 7V
};

6.4 测试和验

测试用例
  1. 基本功能测试

    • Power Supply属性读
    • 硬件控制接口
    • 协议检测功
  2. 集成测试

    • 与sprd_fchg_extcon集成
    • 与charger-manager交互
    • 事件通知机制
  3. 异常处理测试

    • 硬件错误处理
    • 超时处理
    • 回退机制
调试方法
// 添加调试日志
#define DEBUG_CUSTOM_FCHG 1

#if DEBUG_CUSTOM_FCHG
#define custom_fchg_dbg(fmt, ...) \
    dev_info(info->dev, "[custom_fchg] " fmt, ##__VA_ARGS__)
#else
#define custom_fchg_dbg(fmt, ...)
#endif

// 状态监
static void custom_fchg_monitor_status(struct custom_fchg_info *info)
{
    custom_fchg_dbg("Status: online=%d, fchg=%d, voltage=%d, current=%d",
                   info->is_online, info->is_fast_charge, 
                   info->voltage, info->current);
}

7. 方案问题与限制分析(AI给的修改建议)

7.1 技术问题

7.1.1 协议兼容性问题

问题描述:

  • CUSTOM 18W协议是专有协议,与标准快充协议(QC、PD、SFCP)不兼容
  • 充电器必须支持CUSTOM协议才能实现18W快充,通用性较差

影响分析:

// 在custom_fchg_dpdm_set函数中的兼容性检查
if (ret == 0 && vbus > 7000000) { // 7V阈值
    voltage_ok = true;
    break;
} else {
    // 不支持CUSTOM协议的充电器无法触发快充
    dev_err(cm_public->dev, "[debug] custom_fchg: voltage check failed\n");
    ret = -EINVAL;
}

解决方案:

  • 实现多协议检测机制,优先检测标准协议
  • 提供协议降级机制,不支持CUSTOM时回退到DCP模式
7.1.2 时序控制问题

问题描述:

  • DP/DM电平切换时序要求严格,时序错误会导致协议握手失败
  • 硬件响应时间不确定,可能导致检测失败

代码分析:

// 在sd76930_charger_set_custom_chg中的时序控制
msleep(10); // 等待10ms - 固定延时可能不够精确
reg_val = SD76930_REG_DPVOL_3V3 | SD76930_REG_DMVOL_0V;
ret = sd76930_update_bits(info, SD76930_REG_4, 
             SD76930_REG_DPVOL_MASK | SD76930_REG_DMVOL_MASK, 
             reg_val);
msleep(10); // 再次等待10ms

潜在问题:

  • 固定延时可能在某些硬件上不够或过多
  • 没有动态调整机制
  • 时序错误可能导致充电器无法正确识别协议
7.1.3 电压检测可靠性问题

问题描述:

  • 电压检测只进行3次,可能因为瞬时干扰导致误判
  • 7V阈值固定,没有考虑充电器电压波动

代码分析:

// 在custom_fchg_dpdm_set中的电压检测
for (j = 0; j < 3; j++) {
    msleep(600); // 等待600ms
    ret = get_charger_voltage(cm_public, &vbus);
    if (ret == 0 && vbus > 7000000) { // 7V阈值
        voltage_ok = true;
        break;
    }
}

改进建议:

  • 增加检测次数和容错机制
  • 实现动态阈值调整
  • 添加电压稳定性检查

7.2 系统集成问题

7.2.1 工作队列管理问题

问题描述:

  • 检测和使能工作队列可能存在竞态条件
  • 延时工作队列在系统休眠时可能被延迟执行

代码分析:

// 在custom_set_prop中的工作队列管理
if (val->intval == 1) {
    cancel_delayed_work_sync(&info->detect_work);
    info->is_detecting = true;
    schedule_delayed_work(&info->detect_work, msecs_to_jiffies(2000));
}

潜在问题:

  • is_detecting标志可能被多个工作队列同时修改
  • 2秒延时在系统负载高时可能不够
  • 没有考虑系统休眠/唤醒对工作队列的影响
7.2.2 状态同步问题

问题描述:

  • Power Supply属性状态与实际硬件状态可能不同步
  • 多个模块同时修改状态可能导致不一致

代码分析:

// 状态管理分散在多个函数中
info->is_fast_charge = true;           // 在enable_work中设置
info->is_fast_charge_susport = true;   // 在detect_work中设置
power_supply_changed(info->psy);       // 通知属性变化

改进建议:

  • 实现统一的状态管理机制
  • 添加状态一致性检查
  • 使用原子操作保护状态变量

7.3 硬件限制问题

7.3.1 寄存器操作风险

问题描述:

  • 直接操作PMIC寄存器可能影响其他功能
  • 寄存器位操作错误可能导致系统不稳定

代码分析:

// 在custom_dcp_switch_en中的寄存器操作
ret = regmap_update_bits(info->pmic, info->det_offset,
              BIT_DP_DM_BC_ENB_MASK,
              enable << BIT_DP_DM_BC_ENB_SHIFT);

风险分析:

  • 如果det_offset错误,可能操作错误的寄存器
  • 位操作可能影响其他功能模块
  • 没有寄存器操作的互斥保护
7.3.2 电流限制问题

问题描述:

  • 检测期间将电流限制为500mA,可能影响充电效率
  • 没有考虑电池电量对电流限制的影响

代码分析:

// 在custom_fchg_dpdm_set中的电流限制
if (back_limit_cur > 500000) {
    val.intval = 500000; // 固定500mA
    ret = power_supply_set_property(psy, POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, &val);
}

7.4 调试和维护问题

7.4.1 调试信息不足

问题描述:

  • 调试信息分散,难以追踪完整的执行流程
  • 缺少性能监控和统计信息

当前调试信息:

dev_info(info->dev, "[debug] custom_fchg Starting 18W fast charge detection only");
dev_info(info->dev, "[debug] custom_fchg 18W fast charge detection successful");

改进建议:

  • 添加执行时间统计
  • 实现状态机日志
  • 提供性能指标监控
7.4.2 错误处理不完善

问题描述:

  • 某些错误情况下没有完整的恢复机制
  • 错误码不够详细,难以定位问题

代码分析:

if (ret) {
    dev_err(info->dev, "Failed to disable DCP mode: %d\n", ret);
    return; // 直接返回,没有清理已分配的资源
}

7.5 性能问题

7.5.1 检测延迟问题

问题描述:

  • 检测过程需要多次延时,总耗时较长
  • 2秒的检测延时可能影响用户体验

时间分析:

检测总时间 = 2秒(启动延时) + 3×600ms(电压检测) + 硬件响应时间
          ≈ 3.8秒 + 硬件响应时间
7.5.2 功耗问题

问题描述:

  • 检测期间需要维持DP=3.3V电平,增加功耗
  • 频繁的寄存器操作可能影响系统功耗

7.6 改进建议

7.6.1 技术改进
  1. 增强协议兼容性

    // 建议实现多协议检测
    static int detect_fast_charge_protocol(struct custom_18w_info *info)
    {
        // 1. 检测QC协议
        if (detect_qc_protocol(info) == 0)
            return QC_PROTOCOL;
        
        // 2. 检测PD协议
        if (detect_pd_protocol(info) == 0)
            return PD_PROTOCOL;
        
        // 3. 检测CUSTOM协议
        if (detect_custom_protocol(info) == 0)
            return CUSTOM_PROTOCOL;
        
        return NO_PROTOCOL;
    }
    
  2. 优化时序控制

    // 建议实现动态时序调整
    static int set_dpdm_with_retry(struct custom_18w_info *info, bool enable)
    {
        int retry_count = 0;
        int max_retries = 5;
        
        while (retry_count < max_retries) {
            ret = set_dpdm_levels(info, enable);
            if (ret == 0)
                break;
            
            msleep(10 * (retry_count + 1)); // 递增延时
            retry_count++;
        }
        
        return ret;
    }
    
  3. 增强状态管理

    // 建议使用状态机管理
    enum fchg_state {
        FCHG_STATE_IDLE,
        FCHG_STATE_DETECTING,
        FCHG_STATE_ENABLING,
        FCHG_STATE_ACTIVE,
        FCHG_STATE_ERROR
    };
    
    static void fchg_state_machine(struct custom_18w_info *info, enum fchg_event event)
    {
        // 状态机逻辑
    }
    
7.6.2 系统改进
  1. 添加配置选项

    // 建议添加可配置参数
    struct custom_18w_config {
        u32 detect_delay_ms;
        u32 voltage_threshold_uv;
        u32 max_retry_count;
        bool enable_debug;
    };
    
  2. 增强错误处理

    // 建议实现完整的错误恢复
    static int custom_fchg_error_recovery(struct custom_18w_info *info)
    {
        // 1. 停止所有工作队列
        // 2. 恢复硬件状态
        // 3. 重置软件状态
        // 4. 记录错误信息
        // 5. 通知上层系统
    }
    
  3. 添加性能监控

    // 建议添加性能统计
    struct custom_18w_stats {
        u32 detect_count;
        u32 success_count;
        u32 fail_count;
        u32 total_detect_time_ms;
        u32 avg_detect_time_ms;
    };
    

7.7 问题总结

CUSTOM 18W快充方案虽然实现了基本的快充功能,但在协议兼容性、时序控制、状态管理、错误处理等方面还存在一些问题。通过上述分析和改进建议,可以显著提升方案的稳定性、可靠性和用户体验。

关键改进点:

  1. 增强协议兼容性和降级机制
  2. 优化时序控制和重试机制
  3. 完善状态管理和错误处理
  4. 添加性能监控和调试支持
  5. 提高代码的可维护性和可扩展性

这些改进将使快充方案更加健壮和实用。

8. 总结

7.1 关键要点

  1. 模块化设:将快充功能分解为检测、使能、控制等独立模块
  2. 状态管理:使用工作队列管理异步操作,避免阻塞
  3. 错误处理:实现完善的回退机制和错误恢
  4. 系统集成:通过sprd_fchg_extcon与现有系统无缝集

7.2 最佳实现

  1. 硬件抽象:将硬件相关操作封装为独立接
  2. 状态同步:确保Power Supply状态与实际硬件状态
  3. 资源管理:正确管理内存、中断、工作队列等资源
  4. 调试支持:提供充分的调试信息和状态监

7.3 扩展性考虑

  1. 协议支持:可以轻松添加新的快充协
  2. 硬件适配:通过设备树配置适配不同硬件
  3. 参数调整:支持运行时参数调整和优
  4. 性能监控:提供性能指标和统计信
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐