1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| 入口函数: static int qpnp_vm_bms_probe(struct spmi_device *spmi) // 注册SMPI设备 chip = devm_kzalloc(&spmi->dev, sizeof(*chip), GFP_KERNEL); //给struct qpnp_bms_chip *chip(bms芯片设备)分配空间 rc = bms_get_adc(chip, spmi); // 获取adc设备 chip->vadc_dev = qpnp_get_vadc(&spmi->dev, "bms")// 获取vadc设备 spmi --> spmi_device chip->iadc_dev = qpnp_get_iadc(&spmi->dev, "bms") // 获取iadc设备 chip->adc_tm_dev = qpnp_get_adc_tm(&spmi->dev, "bms") // 获取temp adc设备 revid_dev_node = of_parse_phandle(spmi->dev.of_node,"qcom,pmic-revid", 0);//获取struct device_node *revid_dev_node,解析dtsi配置文件(RREVID_REVID_PM8916寄存器(chip variant))。 chip->revid_data = get_revid_data(revid_dev_node) // list_for_each_entry(revid_chip, &revid_chips, link) // 遍历链表获取revid_data rc = qpnp_pon_is_warm_reset(); //Checks if the PMIC went through a warm reset. chip->warm_reset = !!rc; // converts not 0 to 1, 0 to 0 rc = parse_spmi_dt_properties(chip, spmi) // 解析spmi的dtsi配置文件 rc = parse_bms_dt_properties(chip) // 解析bms的dtsi配置文件 if (chip->dt.cfg_disable_bms) rc = qpnp_masked_write_base(chip, chip->base + EN_CTL_REG,BMS_EN_BIT, 0); // disable VMBMS rc = qpnp_read_wrapper(chip, chip->revision,chip->base + REVISION1_REG, 2);//read version register dev_set_drvdata(&spmi->dev, chip) // 给spmi设备驱动赋值 device_init_wakeup(&spmi->dev, 1) // device wakeup initialization mutex_init(&chip->bms_xxx) // 初始化一个 chip->bms_xxx mutex_t init_waitqueue_head(&chip->bms_wait_q) // 初始化等待序列头 rc = set_battery_data(chip); //read battery-id and select the battery profile rc = config_battery_data(chip->batt_data) // set the battery profile wakeup_source_init(&chip->vbms_xxx_source.source, name) // 根据name prepare 一个wakeup source(chip->vbms_xxx_source.source)并添加入链表 INIT_DELAYED_WORK(&chip->monitor_soc_work, monitor_soc_work); // 注册电量监控函数并延时 INIT_DELAYED_WORK(&chip->voltage_soc_timeout_work,voltage_soc_timeout_work); bms_init_defaults(chip); // chip 初始化为默认值 bms_load_hw_defaults(chip); // load 写入设置chip硬件默认值 setup_vbat_monitoring(chip); //vbat monitoring setup qpnp_adc_tm_channel_measure(chip->adc_tm_dev,&chip->vbat_monitor_params) bms_request_irqs(chip) // chip 请求中断 battery_insertion_check(chip);// 电池插入检测 battery_status_check(chip); // 电池状态检测:charging start/stop/full, 并执行相应操作 charging_began(chip) // 开始充电 charging_ended(chip) // 停止充电 register_bms_char_device(chip) //character device to pass data to the userspace alloc_chrdev_region(&chip->dev_no, 0, 1, "vm_bms") // 为此设备分配空间 cdev_init(&chip->bms_cdev, &bms_fops) // 初始化此设备 cdev_add(&chip->bms_cdev, chip->dev_no, 1) // 加入设备链表 chip->bms_class = class_create(THIS_MODULE, "vm_bms") // create a class structure (class.c), be used in calls to device_create(); chip->bms_device = device_create(chip->bms_class,NULL, chip->dev_no,NULL, "vm_bms");//creates a device and registers it with sysfs calculate_initial_soc(chip) // calculate and initial the SOC (select soc form cutoff soc and current soc) read_and_update_ocv(chip, batt_temp, true) ... rc = read_shutdown_ocv_soc(chip); // 读取上次关机电量 xx = lookup_soc_ocv(chip, est_ocv,batt_temp); // 读取电量给相关变量赋值 if(chip->warm_reset) //重启 ... if(!shutdown_soc_invalid &&(abs(chip->shutdown_soc - chip->calculated_soc) <chip->dt.cfg_shutdown_soc_valid_limit) //如果关机SOC和现在的soc相差小于 cfg_shutdown_soc_valid_limit (msm-pm8916.dtsi 中定义:qcom,shutdown-soc-valid-limit = <5>;) ... ) /* setup & register the battery power supply */ .... chip->bms_psy.xxx = xxx; // 设置参数, 关联函数参照5.1 chip->bms_psy.getproperty= ppnp_vm_bms_power_get_property // 调用方式 chip->bms_psy->get_property(chip->bms_psy,POWER_SUPPLY_PROP_CAPACITY, &ret); get_prop_bms_capacity(struct qpnp_bms_chip *chip) report_state_of_charge(chip) report_vm_bms_soc(chip) power_supply_register(chip->dev, &chip->bms_psy) // power_supply_register get_battery_voltage(chip, &vbatt) // 获取电池电压 chip->debug_root = debugfs_create_dir("qpnp_vmbms", NULL) // 创建debug路径 ent = debugfs_create_file("bms_data", S_IFREG | S_IRUGO, chip->debug_root, chip,&bms_data_debugfs_ops);// 创建debugfile schedule_delayed_work(&chip->monitor_soc_work, 0); // 调度 SoC监控函数 static void monitor_soc_work(struct work_struct *work) /* schedule a work to check if the userspace vmbms module has registered. Fall-back to voltage-based-soc reporting if it has not. */ schedule_delayed_work(&chip->voltage_soc_timeout_work,msecs_to_jiffies(chip->dt.cfg_voltage_soc_timeout_ms))
/* Probe Success */
|