设为首页 加入收藏

TOP

高通电源管理qpnp-vm-bms驱动(一)
2019-09-30 16:44:37 】 浏览:169
Tags:高通 电源 管理 qpnp-vm-bms 驱动

1. compatible节点:

qpnp-vm-bms.c使用来控制电池曲线的和BMS功能的,其compatible节点是"qcom,qpnp-vm-bms"

2. probe函数:

qpnp_vm_bms_probe函数如下:

static int qpnp_vm_bms_probe(struct spmi_device *spmi)
{
    struct qpnp_bms_chip *chip;
    struct device_node *revid_dev_node;
    int rc, vbatt = 0;

    chip = devm_kzalloc(&spmi->dev, sizeof(*chip), GFP_KERNEL);
    if (!chip) {
        pr_err("kzalloc() failed.\n");
        return -ENOMEM;
    }

    //获取ADC的值,ADC是电流的大小,绑定vadc,并且获取温度,设备列表
    rc = bms_get_adc(chip, spmi);
    if (rc < 0) {
        pr_err("Failed to get adc rc=%d\n", rc);
        return rc;
    }

    //指向revision外围节点的phandle,vm-bus需要配置这个节点
    revid_dev_node = of_parse_phandle(spmi->dev.of_node,
                        "qcom,pmic-revid", 0);
    if (!revid_dev_node) {
        pr_err("Missing qcom,pmic-revid property\n");
        return -EINVAL;
    }
    
    //返回pmic的修订信息
    chip->revid_data = get_revid_data(revid_dev_node);
    if (IS_ERR(chip->revid_data)) {
        pr_err("revid error rc = %ld\n", PTR_ERR(chip->revid_data));
        return -EINVAL;
    }
    if ((chip->revid_data->pmic_subtype == PM8916_V2P0_SUBTYPE) &&
                chip->revid_data->rev4 == PM8916_V2P0_REV4)
        chip->workaround_flag |= WRKARND_PON_OCV_COMP;

    //查看是否是热启动的,热启动就是在不关闭设备的情况下,重启电脑
    rc = qpnp_pon_is_warm_reset();
    if (rc < 0) {
        pr_err("Error reading warm reset status rc=%d\n", rc);
        return rc;
    }
    chip->warm_reset = !!rc;

    //解析spmi设备的内容,并且在其中寻找它的中断基地址
    rc = parse_spmi_dt_properties(chip, spmi);
    if (rc) {
        pr_err("Error registering spmi resource rc=%d\n", rc);
        return rc;
    }

    //解析电池的参数,如v-cutoff-uv,关机电压,它不会读qcom的内容,会直接读qcom,后面的内容会有仔细说
    rc = parse_bms_dt_properties(chip);
    if (rc) {
        pr_err("Unable to read all bms properties, rc = %d\n", rc);
        return rc;
    }

    //查询错误的原因
    if (chip->dt.cfg_disable_bms) {
        pr_info("VMBMS disabled (disable-bms = 1)\n");
        rc = qpnp_masked_write_base(chip, chip->base + EN_CTL_REG,
                            BMS_EN_BIT, 0);
        if (rc)
            pr_err("Unable to disable VMBMS rc=%d\n", rc);
        return -ENODEV;
    }

    //读取存在pm?PM里读出来的未经修正的原始数据?
    rc = qpnp_read_wrapper(chip, chip->revision,
                chip->base + REVISION1_REG, 2);
    if (rc) {
        pr_err("Error reading version register rc=%d\n", rc);
        return rc;
    }

    pr_debug("BMS version: %hhu.%hhu\n",
            chip->revision[1], chip->revision[0]);

    dev_set_drvdata(&spmi->dev, chip);
    device_init_wakeup(&spmi->dev, 1);
    mutex_init(&chip->bms_data_mutex);
    mutex_init(&chip->bms_device_mutex);
    mutex_init(&chip->last_soc_mutex);
    mutex_init(&chip->state_change_mutex);
    init_waitqueue_head(&chip->bms_wait_q);     //初始化队列

    /* read battery-id and select the battery profile */
    //设置电池数据,也就是电池曲线
    rc = set_battery_data(chip);
    if (rc) {
        pr_err("Unable to read battery data %d\n", rc);
        goto fail_init;
    }

    /* set the battery profile */
    //设置电池的配置文件,其实也就是配置刚刚设置好的全局变量了
    rc = config_battery_data(chip->batt_data);
    if (rc) {
        pr_err("Unable to config battery data %d\n", rc);
        goto fail_init;
    }

    //初始化wakeup_source,内核睡眠机制
    wakeup_source_init(&chip->vbms_lv_wake_source.source, "vbms_lv_wake");
    wakeup_source_init(&chip->vbms_cv_wake_source.source, "vbms_cv_wake");
    wakeup_source_init(&ch
首页 上一页 1 2 3 4 5 6 7 下一页 尾页 1/11/11
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇嵌入式02 STM32 实验01 端口复用.. 下一篇嵌入式02 STM32 实验02 端口输入..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目