06.chrdet_int_handler

 
#define __SPIN_LOCK_UNLOCKED(lockname) \ (spinlock_t ) __SPIN_LOCK_INITIALIZER(lockname)
 
#define ATOMIC_NOTIFIER_INIT(name) {				\
		.lock = __SPIN_LOCK_UNLOCKED(name.lock),	\
		.head = NULL }

#define ATOMIC_NOTIFIER_HEAD(name)				\
	struct atomic_notifier_head name =			\
		ATOMIC_NOTIFIER_INIT(name)

ATOMIC_NOTIFIER_HEAD(power_supply_notifier); 展开为:

struct atomic_notifier_head power_supply_notifier = {

    .lock = (spinlock_t ) __SPIN_LOCK_INITIALIZER(power_supply_notifier.lock)

    .head = NULL }

};

struct atomic_notifier_head {

        spinlock_t lock;

        struct notifier_block __rcu *head;

};

ATOMIC_NOTIFIER_HEAD(power_supply_notifier);  //struct atomic_notifier_head

EXPORT_SYMBOL_GPL(power_supply_notifier);

int atomic_notifier_chain_register(struct atomic_notifier_head *nh, struct notifier_block *n)

int srcu_notifier_chain_register(struct srcu_notifier_head *nh, struct notifier_block *n)

static int notifier_chain_register(struct notifier_block **nl, struct notifier_block *n)  //static函数,外部不能使用

================================================================

int register_charger_manager_notifier(struct charger_consumer *consumer, struct notifier_block *nb)

  ->struct charger_manager *info = consumer->cm;

  ->srcu_notifier_chain_register(&info->evt_nh, nb);

      ->notifier_chain_register(&nh->head, n);

int power_supply_reg_notifier(struct notifier_block *nb)

  ->atomic_notifier_chain_register(&power_supply_notifier, nb);

      ->notifier_chain_register(&nh->head, n);

power_supply_changed_work

  atomic_notifier_call_chain(&power_supply_notifier, PSY_EVENT_PROP_CHANGED, psy);

  int atomic_notifier_call_chain(struct atomic_notifier_head *nh,unsigned long val, void *v)

================================================================

struct charger_manager {

        ... ...

        struct charger_device *chg1_dev;

        struct notifier_block chg1_nb;

        struct charger_data chg1_data;

        struct charger_consumer *chg1_consumer;

        enum charger_type chr_type;

        ... ...

          struct srcu_notifier_head evt_nh;

          ... ...

}

struct mt_charger

  ->struct chg_type_info *cti;

      ->struct charger_consumer *chg_consumer;

struct charger_consumer

  ->void *cm;   //pinfo

static struct charger_manager *pinfo;

static struct list_head consumer_head = LIST_HEAD_INIT(consumer_head);

mtk_charger_probe  //mtk_charger.c

  ->struct charger_manager *info = NULL;

  ->info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);

  ->pinfo = info;

  ->kthread_run(charger_routine_thread, info, "charger_thread");

  ->if (of_property_read_string(np, "algorithm_name", &info->algorithm_name) < 0) {

       info->algorithm_name = "SwitchCharging";  //如果没找到相应的节点,那么直接赋值

  ->mtk_charger_parse_dt(info, &pdev->dev);

      ->info->algorithm_name = "SwitchCharging";

      ->mtk_switch_charging_init(info);

          ->info->chg1_dev = get_charger_by_name("primary_chg");

          ->info->algorithm_data = swch_alg;

          ->info->do_algorithm = mtk_switch_charging_run;

          ->info->plug_in = mtk_switch_charging_plug_in;

          ->info->plug_out = mtk_switch_charging_plug_out;

          ->info->do_charging = mtk_switch_charging_do_charging;

          ->info->do_event = charger_dev_event;  //mtk_switch_charging.c

          ->info->change_current_setting = mtk_switch_charging_current;

  ->mtk_charger_init_timer(info);

  ->kthread_run(charger_routine_thread, info, "charger_thread");

  ->info->chg1_nb.notifier_call = info->do_event;

  ->register_charger_device_notifier(info->chg1_dev, &info->chg1_nb);

      ->srcu_notifier_chain_register(&chg_dev->evt_nh, nb);

          ->notifier_chain_register(&nh->head, n);

  ->charger_dev_set_drvdata(info->chg1_dev, info);

  ->info->psy_nb.notifier_call = charger_psy_event;  //mtk_charger.c

  ->power_supply_reg_notifier(&info->psy_nb);

      ->atomic_notifier_chain_register(&power_supply_notifier, nb);

          ->notifier_chain_register(&nh->head, n);

  ->srcu_init_notifier_head(&info->evt_nh);

  ->info->chg1_consumer = charger_manager_get_by_name(&pdev->dev, "charger_port1");

      ->struct charger_consumer *puser;

      ->puser->cm = pinfo;

  ->info->init_done = true;

  ->_wake_up_charger(info);

//通过power_supply_reg_notifier注册的内核通知链,在power_supply_changed的时候都会被回调

battery_probe  //mtk_battery.c

  ->mtk_battery_init(pdev);

      ->mtk_power_misc_init(pdev);

          ->kthread_run(power_misc_routine_thread, &sdc, "power_misc_thread");

          ->sdc.psy_nb.notifier_call = mtk_power_misc_psy_event;  //主要功能为获取"battery"的power_supply POWER_SUPPLY_PROP_TEMP  //mtk_power_misc.c

          ->power_supply_reg_notifier(&sdc.psy_nb);

  ->gm.pbat_consumer = charger_manager_get_by_name(&(pdev->dev), "charger");

  ->if (gm.pbat_consumer != NULL) {

      ->gm.bat_nb.notifier_call = battery_callback;  //只有中断时由mtk_charger_int_handler()调用,主要功能为battery_update(&battery_main);  //mtk_battery.c

      ->register_charger_manager_notifier(gm.pbat_consumer, &gm.bat_nb);

          ->srcu_notifier_chain_register(&info->evt_nh, nb);

              ->notifier_chain_register(&nh->head, n);

mt_charger_probe  //mtk_chg_type_det.c

  ->struct chg_type_info *cti = NULL;

  ->struct mt_charger *mt_chg = NULL;

  ->mt_chg = devm_kzalloc(&pdev->dev, sizeof(*mt_chg), GFP_KERNEL);

  ->cti = devm_kzalloc(&pdev->dev, sizeof(*cti), GFP_KERNEL);

  ->cti->chg_consumer = charger_manager_get_by_name(cti->dev,"charger_port1");

  ->mt_chg->cti = cti;

struct hl7019d_info

  ->struct charger_device *chg_dev

static int hl7019d_driver_probe(struct i2c_client *client, const struct i2c_device_id *id)

  ->struct hl7019d_info *info = NULL;

  ->info = devm_kzalloc(&client->dev, sizeof(struct hl7019d_info), GFP_KERNEL);

  ->info->chg_dev = charger_device_register(info->chg_dev_name, &client->dev, info, &hl7019d_chg_ops, &info->chg_props);

  ->struct charger_device *chg_dev = NULL;

  ->struct srcu_notifier_head *head = NULL;

  ->chg_dev = kzalloc(sizeof(*chg_dev), GFP_KERNEL);

  ->head = &chg_dev->evt_nh;

  ->srcu_init_notifier_head(head);

===========================================

static struct charger_manager *pinfo;

charger_manager_notifier(pinfo, CHARGER_NOTIFY_STOP_CHARGING)

charger_manager_notifier(pinfo, CHARGER_NOTIFY_START_CHARGING);

中断调用流程:

/kernel-4.14/drivers/misc/mediatek/pmic/mt6390/v1/pmic_chr_type_det_v2.c

pmic_chr_type_det_v2.c    pmic_chrdet_init

                                                        ->chrdet_int_handler

                                                            ->pmic_set_register_value(PMIC_RG_USBDL_RST, 1);

                                                            ->do_charger_detect()

                                                                ->mtk_pmic_enable_chr_type_det(pmic_get_register_value(PMIC_RGS_CHRDET))

                                                                    ->if (!mt_usb_is_device()) { return;}

                                                                    ->g_chr_type = hw_charging_get_charger_type();    //获取充电类型

                                                                    ->chrdet_inform_psy_changed(g_chr_type, 1);

power_supply_core.c                             ->static struct power_supply *chrdet_psy = power_supply_get_by_name("charger");    //pmic_chrdet_init(void)

                                                                       ->power_supply_set_property(chrdet_psy, POWER_SUPPLY_PROP_ONLINE, &propval)

                                                        ->power_supply_set_property(chrdet_psy, POWER_SUPPLY_PROP_CHARGE_TYPE, &propval)

                                                                             ->psy->desc->set_property      //psy->desc = &mt_chg->chg_desc

mtk_chg_type_det.c                                         ->mt_charger_set_property        //mt_chg->chg_desc.set_property = mt_charger_set_property

                                                                                      ->switch (psp) {

                                                                                      ->case POWER_SUPPLY_PROP_ONLINE:

                                                                                          ->mt_charger_online(mtk_chg);

                                                                                              ->if (!mtk_chg->chg_online) {    //如果充电器不存在

                                                                                                  ->boot_mode = get_boot_mode();

                                                                                                  ->if (boot_mode == KERNEL_POWER_OFF_CHARGING_BOOT || boot_mode == LOW_POWER_OFF_CHARGING_BOOT) {

                                                                                                      ->kernel_power_off()      //如果是关机充电模式,则关机

                                                                                                      ->orderly_poweroff(true)  //使用这个,上面的没作用

                                                                                      ->case POWER_SUPPLY_PROP_CHARGE_TYPE:

                                                                                          ->mtk_chg->chg_type = val->intval;      //将g_chr_type保存在struct mt_charger *mtk_chg,以供mt_get_charger_type()使用

                                                                                      ->queue_work(cti->chg_in_wq, &cti->chg_in_work);  //INIT_WORK(&cti->chg_in_work, charger_in_work_handler);

                                                                                          ->charger_in_work_handler

mtk_charger.c                                                                 ->mtk_charger_int_handler

                                                                                                  ->charger_manager_notifier(pinfo, CHARGER_NOTIFY_STOP_CHARGING);    //if (mt_get_charger_type() == CHARGER_UNKNOWN) {

                                                                                                  ->charger_manager_notifier(pinfo, CHARGER_NOTIFY_START_CHARGING);  //else

notifier.c                                                                                    ->srcu_notifier_call_chain(&info->evt_nh, event, NULL);  //int srcu_notifier_call_chain(struct srcu_notifier_head*nh, unsigned long val, void *v)

                                                                                                          ->battery_callback

                                                                                                  ->_wake_up_charger(pinfo)

                                                                                                      ->wake_up(&info->wait_que)

                                                                                                          ->charger_routine_thread

                                                                                                              ->chr_err("Vbat=%d,Ibat=%d,I=%d,VChr=%d,T=%d,Soc=%d:%d,CT:%d:%d hv:%d pd:%d:%d\n",

                                                                                                              ->is_charger_on = mtk_is_charger_on(info)

                                                                                                                  ->chr_type = mt_get_charger_type();    //去拿充电类型

                                                                                                                      ->return mtk_chg->chg_type;

                                                                                                                  ->if (chr_type == CHARGER_UNKNOWN && info->chr_type != CHARGER_UNKNOWN) {

                                                                                                                      ->mtk_charger_plug_out(info);

                                                                                                                         ->info->plug_out(info);

mtk_switch_charging.c                                                                               ->int mtk_switch_charging_plug_out(struct charger_manager *info)

                                                                                                                         ->info->chg1_dev = get_charger_by_name("primary_chg");    //int mtk_switch_charging_init(struct charger_manager *info)

charger_class.c                                                                                           ->charger_dev_set_input_current(info->chg1_dev, 100000);

                                                                                                                          ->charger_dev_plug_out(info->chg1_dev);

                                                                                                                              ->chg_dev->ops->plug_out(chg_dev)

                                                                                                                  ->else if (info->chr_type == CHARGER_UNKNOWN)

                                                                                                                      ->mtk_charger_plug_in(info, chr_type);

                                                                                                                         ->info->plug_in(info)

mtk_switch_charging.c                                                                               ->int mtk_switch_charging_plug_in(struct charger_manager *info)

                                                                                                                         ->info->chg1_dev = get_charger_by_name("primary_chg")    //int mtk_switch_charging_init(struct charger_manager *info)

charger_class.c                                                                                 ->charger_dev_set_input_current(info->chg1_dev, info->chg1_data.input_current_limit);

                                                                                                     ->charger_dev_plug_in(info->chg1_dev);

                                                                                                                             ->chg_dev->ops->plug_in(chg_dev)

                                                                                                                  ->charger_update_data(info)    //检查电池温度

                                                                                                                  ->check_battery_exist(info)

                                                                                                                  ->check_dynamic_mivr(info)

                                                                                                                  ->charger_check_status(info)

                                                                                                                  ->kpoc_power_off_check(info)

                                                                                                                  ->if (is_charger_on == true) {

                                                                                                                      ->info->do_algorithm(info);

                                                                                                                          ->mtk_switch_charging_run(struct charger_manager *info)

                                                                                                                                ->struct switch_charging_alg_data *swchgalg = info->algorithm_data

                                                                                                                                ->switch (swchgalg->state) {

                                                                                                                                    ->case CHR_CC:

                                                                                                                                        ->mtk_switch_chr_cc(info)

                                                                                                                                            ->swchg_turn_on_charging(info)

                                                                                                                                                ->swchg_select_charging_current_limit(info)      //如果不是META_BOOT

                                                                                                                                                    ->struct charger_data *pdata = &info->chg1_data;

                                                                                                                                                    ->charger_dev_set_input_current(info->chg1_dev, pdata->input_current_limit)

                                                                                                                                                        ->chg_dev->ops->set_input_current(chg_dev, uA)

                                                                                                                                                    ->charger_dev_set_charging_current(info->chg1_dev, pdata->charging_current_limit)

                                                                                                                                                        ->chg_dev->ops->set_charging_current(chg_dev, uA)

                                                                                                                                                    ->/*If thermal current limit is larger than charging IC's minimum current setting, enable the charger immediately*/

                                                                                                                                                        ->charger_dev_enable(info->chg1_dev, true);

                                                                                                                                                ->charger_dev_enable(info->chg1_dev, charging_enable)

                                                                                                                                                    ->chg_dev->ops->enable(chg_dev, en)

                                                                                                                                ->charger_dev_dump_registers(info->chg1_dev);

                                                                                                                                    ->chg_dev->ops->dump_registers(chg_dev)

                                                                                                                        ->wakeup_sc_algo_cmd(&pinfo->sc.data, SC_EVENT_CHARGING, 0);

                                                                                                                    ->if (is_charger_on == false) {

                                                                                                                        ->wakeup_sc_algo_cmd(&pinfo->sc.data, SC_EVENT_STOP_CHARGING, 0);

mtk_battery_core.c                                                       ->fg_charger_in_handler

mtk_chg_type_det.c                                                         ->mt_get_charger_type

mtk_battery.c                                                                      ->wakeup_fg_algo_atomic(FG_INTR_CHARGER_IN)

power_supply_core.c                                            ->power_supply_changed(mtk_chg->ac_psy);

                                                                                         ->schedule_work(&psy->changed_work)

                                                                               ->power_supply_changed(mtk_chg->usb_psy);

                                                                                          ->schedule_work(&psy->changed_work)    //INIT_WORK(&psy->changed_work, power_supply_changed_work);

                                                                                               ->power_supply_changed_work(struct work_struct *work)

notifier.c                                                                                  ->atomic_notifier_call_chain(&power_supply_notifier, PSY_EVENT_PROP_CHANGED, psy);

                                                                                                        ->__atomic_notifier_call_chain(nh, val, v, -1, NULL)

                                                                                                            ->notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);

mtk_power_misc.c                                                                          ->mtk_power_misc_psy_event(struct notifier_block *nb, unsigned long event, void *v)

                                                                                                                    ->if (strcmp(psy->desc->name, "battery") == 0) {

                                                                                                                        ->psy->desc->get_property(psy, POWER_SUPPLY_PROP_TEMP, &val);

mtk_battery.c                                                                                               ->int battery_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val)

 dts Code \kernel-4.14\arch\arm64\boot\dts\mediatek\mt8168.dtsi

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

/* /kernel-4.14/drivers/power/supply/mediatek/battery/mtk_battery.c */
    bat_gm30: battery {
        compatible = "mediatek,bat_gm30";
    };
    mt6357_gauge {
        compatible = "mediatek,mt6357_gauge";
        gauge_name = "gauge";
        alias_name = "MT6357";
    };
    /* kernel-4.14/drivers/power/supply/mediatek/charger/mtk_chg_type_det.c */
    mt_charger: mt_charger {
        compatible = "mediatek,mt-charger";
    };

    lk_charger: lk_charger {
        compatible = "mediatek,lk_charger";
        enable_anime;
        enable_pe_plus;
        power_path_support;
        max_charger_voltage = <6500000>;
        fast_charge_voltage = <3000000>;

        /* charging current */
        usb_charger_current = <500000>;
        ac_charger_current = <2050000>;
        ac_charger_input_current = <3200000>;
        non_std_ac_charger_current = <500000>;
        charging_host_charger_current = <1500000>;
        ta_ac_charger_current = <3000000>;
        pd_charger_current = <500000>;

        /* battery temperature protection */
        temp_t4_threshold = <50>;
        temp_t3_threshold = <45>;
        temp_t1_threshold = <0>;
    };
    /* kernel-4.14\drivers\misc\mediatek\pmic\mt6390\v1\mt6390_charger.c */
    mt6390_charger {
        compatible = "mediatek,mt6390_charger";
        charger_name = "primary_chg";  //mtk_linear_charging.c mtk_linear_charging_init 保存到struct charger_manager *info->struct charger_device *chg1_dev
        alias_name = "mt6390";
        ichg = <500000>; /* uA */
        cv = <4200000>; /* uV */
        vcdt_hv_thres = <7000000>; /* uV */
        vbat_ov_thres = <4450000>; /* uV */
    };
    /* kernel-4.14/drivers/power/supply/mediatek/charger/mtk_charger.c */
    charger: charger {
        compatible = "mediatek,charger";
        algorithm_name = "LinearCharging";  //mtk_charger.c  mtk_charger_parse_dt->mtk_linear_charging_init
        /* enable_sw_jeita; */
        enable_pe_plus;
        enable_type_c;
        power_path_support;

 C Code /kernel-4.14/drivers/power/supply/mediatek/charger/mtk_charger.c

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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137

static int mtk_charger_probe(struct platform_device *pdev)
{
    struct charger_manager *info = NULL;
    struct list_head *pos;
    struct list_head *phead = &consumer_head;
    struct charger_consumer *ptr;
    int ret;

    chr_err("%s: starts\n", __func__);

    info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
    if (!info)
        return -ENOMEM;

    pinfo = info;

    platform_set_drvdata(pdev, info);  //(&pdev->dev)->driver_data = info;
    info->pdev = pdev;
    mtk_charger_parse_dt(info, &pdev->dev);  //从dts获取客制化充电电流、电压、并调用mtk_linear_charging_init初始化

    mutex_init(&info->charger_lock);
    mutex_init(&info->charger_pd_lock);
    mutex_init(&info->cable_out_lock);
    atomic_set(&info->enable_kpoc_shdn, 1);
    wakeup_source_init(&info->charger_wakelock, "charger suspend wakelock");
    spin_lock_init(&info->slock);

    /* init thread */
    init_waitqueue_head(&info->wait_que);  //初始化等待队列
    info->polling_interval = CHARGING_INTERVAL;
    info->enable_dynamic_cv = true;

    info->chg1_data.thermal_charging_current_limit = -1;
    info->chg1_data.thermal_input_current_limit = -1;
    info->chg1_data.input_current_limit_by_aicl = -1;
    info->chg2_data.thermal_charging_current_limit = -1;
    info->chg2_data.thermal_input_current_limit = -1;

    info->sw_jeita.error_recovery_flag = true;

    mtk_charger_init_timer(info);  //初始化定时器

    kthread_run(charger_routine_thread, info, "charger_thread");  //开启充电线程

    if (info->chg1_dev != NULL && info->do_event != NULL) {
        info->chg1_nb.notifier_call = info->do_event;
        register_charger_device_notifier(info->chg1_dev,
                        &info->chg1_nb);
        charger_dev_set_drvdata(info->chg1_dev, info);
    }

    info->psy_nb.notifier_call = charger_psy_event;
    power_supply_reg_notifier(&info->psy_nb);

    srcu_init_notifier_head(&info->evt_nh);
    ret = mtk_charger_setup_files(pdev);
    if (ret)
        chr_err("Error creating sysfs interface\n");

    info->pd_adapter = get_adapter_by_name("pd_adapter");
    if (info->pd_adapter)
        chr_err("Found PD adapter [%s]\n",
            info->pd_adapter->props.alias_name);
    else
        chr_err("*** Error : can't find PD adapter ***\n");

    if (mtk_pe_init(info) < 0)
        info->enable_pe_plus = false;

    if (mtk_pe20_init(info) < 0)
        info->enable_pe_2 = false;

    if (mtk_pe40_init(info) == false)
        info->enable_pe_4 = false;

    mtk_pdc_init(info);
    charger_ftm_init();
    mtk_charger_get_atm_mode(info);

#ifdef CONFIG_MTK_CHARGER_UNLIMITED
    info->usb_unlimited = true;
    info->enable_sw_safety_timer = false;
    charger_dev_enable_safety_timer(info->chg1_dev, false);
#endif

    charger_debug_init();

    mutex_lock(&consumer_mutex);
    list_for_each(pos, phead) {
        ptr = container_of(pos, struct charger_consumer, list);
        ptr->cm = info;
        if (ptr->pnb != NULL) {
            srcu_notifier_chain_register(&info->evt_nh, ptr->pnb);
            ptr->pnb = NULL;
        }
    }
    mutex_unlock(&consumer_mutex);
    info->chg1_consumer =
        charger_manager_get_by_name(&pdev->dev, "charger_port1");
    info->init_done = true;
    _wake_up_charger(info);

    return 0;
}

static const struct of_device_id mtk_charger_of_match[] = {
    {.compatible = "mediatek,charger",},
    {},
};
MODULE_DEVICE_TABLE(of, mtk_charger_of_match);

static struct platform_driver charger_driver = {
    .probe = mtk_charger_probe,
    .remove = mtk_charger_remove,
    .shutdown = mtk_charger_shutdown,
    .driver = {
           .name = "charger",
           .of_match_table = mtk_charger_of_match,
    },
};

static int __init mtk_charger_init(void)
{
    return platform_driver_register(&charger_driver);
}
late_initcall(mtk_charger_init);

static void __exit mtk_charger_exit(void)
{
    platform_driver_unregister(&charger_driver);
}
module_exit(mtk_charger_exit);


MODULE_AUTHOR("wy.chuang <wy.chuang@mediatek.com>");
MODULE_DESCRIPTION("MTK Charger Driver");
MODULE_LICENSE("GPL");

 C Code /kernel-4.14/drivers/power/supply/mediatek/charger/mtk_charger.c

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

static int mtk_charger_parse_dt(struct charger_manager *info,
                struct device *dev)
{
    struct device_node *np = dev->of_node;
    u32 val;

    chr_err("%s: starts\n", __func__);

    if (!np) {
        chr_err("%s: no device node\n", __func__);
        return -EINVAL;
    }

    if (of_property_read_string(np, "algorithm_name",  //读取"mediatek,charger"节点内,algorithm_name子节点的名字
        &info->algorithm_name) < 0) {
        chr_err("%s: no algorithm_name name\n", __func__);
        info->algorithm_name = "SwitchCharging";       //如果没有读取到,则默认为"SwitchCharging"
    }

    if (strcmp(info->algorithm_name, "SwitchCharging") == 0) {
        chr_err("found SwitchCharging\n");
        mtk_switch_charging_init(info);
    }
#ifdef CONFIG_MTK_DUAL_CHARGER_SUPPORT
    if (strcmp(info->algorithm_name, "DualSwitchCharging") == 0) {
        pr_debug("found DualSwitchCharging\n");
        mtk_dual_switch_charging_init(info);
    }
#endif
    if (strcmp(info->algorithm_name, "LinearCharging") == 0) {
        pr_info("%s: LinearCharging\n", __func__);
        mtk_linear_charging_init(info);
    }
    ...
}

 C Code /kernel-4.14/drivers/power/supply/mediatek/charger/mtk_linear_charging.c

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

int mtk_linear_charging_init(struct charger_manager *info)
{
    struct linear_charging_alg_data *algo_data;

    algo_data = devm_kzalloc(&info->pdev->dev,
                sizeof(*algo_data), GFP_KERNEL);
    if (!algo_data)
        return -ENOMEM;

    info->chg1_dev = get_charger_by_name("primary_chg");  //struct charger_device *chg1_dev;
    if (info->chg1_dev)
        chr_err("Found primary charger [%s]\n",
            info->chg1_dev->props.alias_name);
    else
        chr_err("*** Error : can't find primary charger ***\n");

    info->algorithm_data = algo_data;
    mtk_linear_charger_parse_dt(info);

    mutex_init(&algo_data->ichg_access_mutex);

    info->do_algorithm = mtk_linear_charging_run;
    info->plug_in = mtk_linear_charging_plug_in;
    info->plug_out = mtk_linear_charging_plug_out;
    info->do_charging = mtk_linear_charging_do_charging;
    info->do_event = linear_charger_dev_event;
    info->change_current_setting = mtk_linear_charging_current;

    return 0;
}

 C Code /kernel-4.14/drivers/power/supply/mediatek/charger/charger_class.c

1
2
3
4
5
6
7
8
9
10
11
12
13

struct charger_device *get_charger_by_name(const char *name)
{
    struct device *dev;

    if (!name)
        return (struct charger_device *)NULL;
    dev = class_find_device(charger_class, NULL, name,
                charger_match_device_by_name);

    return dev ? to_charger_device(dev) : NULL;

}
EXPORT_SYMBOL(get_charger_by_name);

触发中断函数chrdet_int_handler

 C Code /kernel-4.14/drivers/misc/mediatek/include/mt-plat/mt8168/include/mach/upmu_sw.h

1
2
3
4
5
6
7
8
9
10

/*=============================================================================
 * PMIC IRQ ENUM define
 *=============================================================================
 */
enum PMIC_IRQ_ENUM {
    ...
    INT_CHRDET,    //53
    INT_CHRDET_EDGE,    //54
    ...
}

 C Code /kernel-4.14/drivers/misc/mediatek/pmic/mt6390/v1/pmic_chr_type_det_v2.c

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

static struct power_supply *chrdet_psy;
static int __init pmic_chrdet_init(void)
{
    mutex_init(&chrdet_lock);
    chrdet_psy = power_supply_get_by_name("charger");
    if (!chrdet_psy) {
        pr_notice("%s: get power supply failed\n", __func__);
        return -EINVAL;
    }

#ifdef __SW_CHRDET_IN_PROBE_PHASE__
    /* do charger detect here to prevent HW miss interrupt*/
    INIT_WORK(&chr_work, do_charger_detection_work);
    schedule_work(&chr_work);
#endif

#ifndef CONFIG_TCPC_CLASS  //CONFIG_TCPC_CLASS is not set
    pmic_register_interrupt_callback(INT_CHRDET_EDGE, chrdet_int_handler);
    pmic_enable_interrupt(INT_CHRDET_EDGE, 1, "PMIC");
#endif

    return 0;
}

late_initcall(pmic_chrdet_init);

 C Code /kernel-4.14/drivers/misc/mediatek/pmic/mt6390/v1/pmic_chr_type_det_v2.c

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

/* PMIC Int Handler */
void chrdet_int_handler(void)
{
    /*
     * pr_notice("[chrdet_int_handler]CHRDET status = %d....\n",
     *  pmic_get_register_value(PMIC_RGS_CHRDET));
     */
    if (!pmic_get_register_value(PMIC_RGS_CHRDET)) {
        int boot_mode = 0;

        hw_bc11_done();
        boot_mode = get_boot_mode();

        if (boot_mode == KERNEL_POWER_OFF_CHARGING_BOOT
            || boot_mode == LOW_POWER_OFF_CHARGING_BOOT) {
            pr_info("[%s] Unplug Charger/USB\n", __func__);
#ifndef CONFIG_TCPC_CLASS
            pr_info("%s: system_state=%d\n", __func__,
                system_state);
            if (system_state != SYSTEM_POWER_OFF)
                orderly_poweroff(true);
#else
            return;
#endif
        }
    }
    pmic_set_register_value(PMIC_RG_USBDL_RST, 1);

    do_charger_detect();
}

 /kernel-4.14/drivers/misc/mediatek/pmic/mt6390/v1/pmic_chr_type_det_v2.c

1
2
3
4
5
6
7
8

/* Charger Detection */
void do_charger_detect(void)
{
    if (pmic_get_register_value(PMIC_RGS_CHRDET))
        mtk_pmic_enable_chr_type_det(true);
    else
        mtk_pmic_enable_chr_type_det(false);
}

 /kernel-4.14/drivers/misc/mediatek/pmic/mt6390/v1/pmic_chr_type_det_v2.c

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

void mtk_pmic_enable_chr_type_det(bool en)
{
#ifndef CONFIG_TCPC_CLASS  //CONFIG_TCPC_CLASS is not set
    if (!mt_usb_is_device()) {  //判断是否为OTG模式
        g_chr_type = CHARGER_UNKNOWN;
        pr_info("charger type: UNKNOWN, Now is usb host mode. Skip detection\n");
        return;
    }
#endif

    mutex_lock(&chrdet_lock);

    if (en) {
        if (is_meta_mode()) {
            /* Skip charger type detection to speed up meta boot */
            pr_notice("charger type: force Standard USB Host in meta\n");
            g_chr_type = STANDARD_HOST;
            chrdet_inform_psy_changed(g_chr_type, 1);
        } else {
            pr_info("charger type: charger IN\n");  //充电器插入
            g_chr_type = hw_charging_get_charger_type();  //获取充电类型
            chrdet_inform_psy_changed(g_chr_type, 1);
        }
    } else {
        pr_info("charger type: charger OUT\n");  //充电器拔出
        g_chr_type = CHARGER_UNKNOWN;
        chrdet_inform_psy_changed(g_chr_type, 0);
    }

    mutex_unlock(&chrdet_lock);
}

 /kernel-4.14/drivers/usb/mtu3/mtu3_dr.c

1
2
3
4
5
6
7
8
9
10

bool mt_usb_is_device(void)
{
    int host_state = extcon_get_state(g_extcon_edev, EXTCON_USB_HOST);

    if (host_state == 1)
        return false;

    return true;
}
EXPORT_SYMBOL_GPL(mt_usb_is_device);

 /kernel-4.14/drivers/misc/mediatek/pmic/mt6390/v1/pmic_chr_type_det_v2.c 

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

static int chrdet_inform_psy_changed(enum charger_type chg_type,
                bool chg_online)
{
    int ret = 0;
    union power_supply_propval propval;

    pr_info("charger type: %s: online = %d, type = %d\n", __func__,
        chg_online, chg_type);

    /* Inform chg det power supply */
    if (chg_online) {
        propval.intval = chg_online;
        ret = power_supply_set_property(chrdet_psy,
                POWER_SUPPLY_PROP_ONLINE, &propval);
        if (ret < 0)
            pr_notice("%s: psy online failed, ret = %d\n",
                __func__, ret);

        propval.intval = chg_type;
        ret = power_supply_set_property(chrdet_psy,
                POWER_SUPPLY_PROP_CHARGE_TYPE, &propval);
        if (ret < 0)
            pr_notice("%s: psy type failed, ret = %d\n",
                __func__, ret);

        return ret;
    }

    propval.intval = chg_type;
    ret = power_supply_set_property(chrdet_psy,
                POWER_SUPPLY_PROP_CHARGE_TYPE, &propval);
    if (ret < 0)
        pr_notice("%s: psy type failed, ret(%d)\n", __func__, ret);

    propval.intval = chg_online;
    ret = power_supply_set_property(chrdet_psy, POWER_SUPPLY_PROP_ONLINE,
                &propval);
    if (ret < 0)
        pr_notice("%s: psy online failed, ret(%d)\n", __func__, ret);
    return ret;
}

 /kernel-4.14/drivers/power/supply/power_supply_core.c

1
2
3
4
5
6
7
8
9
10

int power_supply_set_property(struct power_supply *psy,
                enum power_supply_property psp,
                const union power_supply_propval *val)
{
    if (atomic_read(&psy->use_cnt) <= 0 || !psy->desc->set_property)
        return -ENODEV;

    return psy->desc->set_property(psy, psp, val);
}
EXPORT_SYMBOL_GPL(power_supply_set_property);

那么chrdet_psy是什么呢?

 /kernel-4.14/drivers/misc/mediatek/pmic/mt6390/v1/pmic_chr_type_det_v2.c

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

static struct power_supply *chrdet_psy;  //全局变量
static int __init pmic_chrdet_init(void)
{
    mutex_init(&chrdet_lock);
    chrdet_psy = power_supply_get_by_name("charger");
    if (!chrdet_psy) {
        pr_notice("%s: get power supply failed\n", __func__);
        return -EINVAL;
    }

#ifdef __SW_CHRDET_IN_PROBE_PHASE__
    /* do charger detect here to prevent HW miss interrupt*/
    INIT_WORK(&chr_work, do_charger_detection_work);
    schedule_work(&chr_work);
#endif

#ifndef CONFIG_TCPC_CLASS  //CONFIG_TCPC_CLASS is not set
    pmic_register_interrupt_callback(INT_CHRDET_EDGE, chrdet_int_handler);
    pmic_enable_interrupt(INT_CHRDET_EDGE, 1, "PMIC");
#endif

    return 0;
}

late_initcall(pmic_chrdet_init);

 /kernel-4.14/drivers/power/supply/power_supply_core.c  

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

/* exported for the APM Power driver, APM emulation */
struct class *power_supply_class;
EXPORT_SYMBOL_GPL(power_supply_class);

static int power_supply_match_device_by_name(struct device *dev, const void *data)
{
    const char *name = data;
    struct power_supply *psy = dev_get_drvdata(dev);

    return strcmp(psy->desc->name, name) == 0;
}

struct power_supply *power_supply_get_by_name(const char *name)
{
    struct power_supply *psy = NULL;
    struct device *dev = class_find_device(power_supply_class, NULL, name,
                    power_supply_match_device_by_name);

    if (dev) {
        psy = dev_get_drvdata(dev);
        atomic_inc(&psy->use_cnt);
    }

    return psy;
}
EXPORT_SYMBOL_GPL(power_supply_get_by_name);

static int __init power_supply_class_init(void)
{
    power_supply_class = class_create(THIS_MODULE, "power_supply");

    if (IS_ERR(power_supply_class))
        return PTR_ERR(power_supply_class);

    power_supply_class->dev_uevent = power_supply_uevent;
    power_supply_init_attrs(&power_supply_dev_type);

    return 0;
}
subsys_initcall(power_supply_class_init);

其实chrdet_psy是mt_charger_probe中注册的struct power_supply *chg_psy,其中struct power_supply_desc chg_desc.name = "charger";

在注册mt_charger_det_init平台驱动时,在mt_charger_probe会调用power_supply_register,然后赋值psy->desc = desc (实际上就是chrdet_psy->desc = &mt_chg->chg_desc)

而mt_chg->chg_desc.set_property = mt_charger_set_property

所以chrdet_psy->desc->set_property就能找到了

 C Code /kernel-4.14/drivers/power/supply/mediatek/charger/mtk_chg_type_det.c

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

static const struct of_device_id mt_charger_match[] = {
    { .compatible = "mediatek,mt-charger", },
    { },
};
static struct platform_driver mt_charger_driver = {
    .probe = mt_charger_probe,
    .remove = mt_charger_remove,
    .driver = {
        .name = "mt-charger-det",
        .owner = THIS_MODULE,
        .pm = &mt_charger_pm_ops,
        .of_match_table = mt_charger_match,
    },
};
static s32 __init mt_charger_det_init(void)
{
        return platform_driver_register(&mt_charger_driver);
}

static void __exit mt_charger_det_exit(void)
{
        platform_driver_unregister(&mt_charger_driver);
}

subsys_initcall(mt_charger_det_init);
module_exit(mt_charger_det_exit);

 C Code /kernel-4.14/drivers/power/supply/mediatek/charger/mtk_chg_type_det.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

struct mt_charger {
    struct device *dev;
    struct power_supply_desc chg_desc;
    struct power_supply_config chg_cfg;
    struct power_supply *chg_psy;
    struct power_supply_desc ac_desc;
    struct power_supply_config ac_cfg;
    struct power_supply *ac_psy;
    struct power_supply_desc usb_desc;
    struct power_supply_config usb_cfg;
    struct power_supply *usb_psy;
    struct chg_type_info *cti;
    #ifdef CONFIG_EXTCON_USB_CHG
    struct usb_extcon_info *extcon_info;
    struct delayed_work extcon_work;
    #endif
    bool chg_online; /* Has charger in or not */
    enum charger_type chg_type;
};

 C Code /kernel-4.14/drivers/power/supply/mediatek/charger/mtk_chg_type_det.c

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

static int mt_charger_probe(struct platform_device *pdev)
{
    int ret = 0;
    struct chg_type_info *cti = NULL;
    struct mt_charger *mt_chg = NULL;
    #ifdef CONFIG_EXTCON_USB_CHG
    struct usb_extcon_info *info;
    #endif

    pr_info("%s\n", __func__);

    mt_chg = devm_kzalloc(&pdev->dev, sizeof(*mt_chg), GFP_KERNEL);
    if (!mt_chg)
        return -ENOMEM;

    mt_chg->dev = &pdev->dev;
    mt_chg->chg_online = false;
    mt_chg->chg_type = CHARGER_UNKNOWN;

    mt_chg->chg_desc.name = "charger";  //这是GM3.0新增的
    mt_chg->chg_desc.type = POWER_SUPPLY_TYPE_UNKNOWN;
    mt_chg->chg_desc.properties = mt_charger_properties;
    mt_chg->chg_desc.num_properties = ARRAY_SIZE(mt_charger_properties);
    mt_chg->chg_desc.set_property = mt_charger_set_property;
    mt_chg->chg_desc.get_property = mt_charger_get_property;
    mt_chg->chg_cfg.drv_data = mt_chg;

    mt_chg->ac_desc.name = "ac";  //相当于以前battery_common.c的static struct ac_data ac_main
    mt_chg->ac_desc.type = POWER_SUPPLY_TYPE_MAINS;
    mt_chg->ac_desc.properties = mt_ac_properties;
    mt_chg->ac_desc.num_properties = ARRAY_SIZE(mt_ac_properties);
    mt_chg->ac_desc.get_property = mt_ac_get_property;
    mt_chg->ac_cfg.drv_data = mt_chg;

    mt_chg->usb_desc.name = "usb";  //相当于以前battery_common.c的static struct usb_data usb_main
    mt_chg->usb_desc.type = POWER_SUPPLY_TYPE_USB;
    mt_chg->usb_desc.properties = mt_usb_properties;
    mt_chg->usb_desc.num_properties = ARRAY_SIZE(mt_usb_properties);
    mt_chg->usb_desc.get_property = mt_usb_get_property;
    mt_chg->usb_cfg.drv_data = mt_chg;

    mt_chg->chg_psy = power_supply_register(&pdev->dev,
        &mt_chg->chg_desc, &mt_chg->chg_cfg);
    mt_chg->ac_psy = power_supply_register(&pdev->dev, &mt_chg->ac_desc,
        &mt_chg->ac_cfg);
    mt_chg->usb_psy = power_supply_register(&pdev->dev, &mt_chg->usb_desc,
        &mt_chg->usb_cfg);
    ...
    /* Init power off work */
    cti->pwr_off_wq = create_singlethread_workqueue("tcpc_power_off");
    INIT_WORK(&cti->pwr_off_work, tcpc_power_off_work_handler);

    cti->chg_in_wq = create_singlethread_workqueue("charger_in");
    INIT_WORK(&cti->chg_in_work, charger_in_work_handler);
    ...
}

 C Code /kernel-4.14/drivers/power/supply/power_supply_core.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14

static struct power_supply *__must_check
__power_supply_register(struct device *parent,
                   const struct power_supply_desc *desc,
                   const struct power_supply_config *cfg,
                   bool ws)
    struct power_supply *psy;
    psy = kzalloc(sizeof(*psy), GFP_KERNEL);
    if (!psy)
        return ERR_PTR(-ENOMEM);
    ...
    psy->desc = desc;
    ...
    return psy;
}

 C Code /kernel-4.14/drivers/power/supply/mediatek/charger/mtk_chg_type_det.c

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

static int mt_charger_set_property(struct power_supply *psy,
    enum power_supply_property psp, const union power_supply_propval *val)
{
    struct mt_charger *mtk_chg = power_supply_get_drvdata(psy);
    struct chg_type_info *cti;
    #ifdef CONFIG_EXTCON_USB_CHG
    struct usb_extcon_info *info;
    #endif

    pr_info("%s\n", __func__);

    if (!mtk_chg) {
        pr_notice("%s: no mtk chg data\n", __func__);
        return -EINVAL;
    }

#ifdef CONFIG_EXTCON_USB_CHG
    info = mtk_chg->extcon_info;
#endif

    switch (psp) {
    case POWER_SUPPLY_PROP_ONLINE:
        mtk_chg->chg_online = val->intval;
        mt_charger_online(mtk_chg);
        return 0;
    case POWER_SUPPLY_PROP_CHARGE_TYPE:
        mtk_chg->chg_type = val->intval;
        break;
    default:
        return -EINVAL;
    }

    dump_charger_name(mtk_chg->chg_type);

    cti = mtk_chg->cti;
    if (!cti->ignore_usb) {
        /* usb */
        if ((mtk_chg->chg_type == STANDARD_HOST) ||
            (mtk_chg->chg_type == CHARGING_HOST) ||
            (mtk_chg->chg_type == NONSTANDARD_CHARGER)) {
            mt_usb_connect();
            #ifdef CONFIG_EXTCON_USB_CHG
            info->vbus_state = 1;
            #endif
        } else {
            mt_usb_disconnect();
            #ifdef CONFIG_EXTCON_USB_CHG
            info->vbus_state = 0;
            #endif
        }
    }

    queue_work(cti->chg_in_wq, &cti->chg_in_work);
    #ifdef CONFIG_EXTCON_USB_CHG
    if (!IS_ERR(info->edev))
        queue_delayed_work(system_power_efficient_wq,
            &info->wq_detcable, info->debounce_jiffies);
    #endif

    power_supply_changed(mtk_chg->ac_psy);
    power_supply_changed(mtk_chg->usb_psy);

    return 0;
}

 C Code /kernel-4.14/drivers/power/supply/mediatek/charger/mtk_chg_type_det.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

static int mt_charger_online(struct mt_charger *mtk_chg)
{
    int ret = 0;
    int boot_mode = 0;

    if (!mtk_chg->chg_online) {
        boot_mode = get_boot_mode();
        if (boot_mode == KERNEL_POWER_OFF_CHARGING_BOOT ||
            boot_mode == LOW_POWER_OFF_CHARGING_BOOT) {
            pr_notice("%s: Unplug Charger/USB\n", __func__);
            pr_notice("%s: system_state=%d\n", __func__,
                system_state);
            if (system_state != SYSTEM_POWER_OFF)
                kernel_power_off();
        }
    }

    return ret;
}

 C Code /kernel-4.14/drivers/power/supply/mediatek/charger/mtk_chg_type_det.c

1
2
3
4
5

static void charger_in_work_handler(struct work_struct *work)
{
    mtk_charger_int_handler();  //唤醒线程
    fg_charger_in_handler();    //唤醒电量计
}

 C Code /kernel-4.14/drivers/power/supply/mediatek/charger/mtk_charger.c

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

void mtk_charger_int_handler(void)
{
    chr_err("%s\n", __func__);

    if (pinfo == NULL) {
        chr_err("charger is not rdy ,skip1\n");
        return;
    }

    if (pinfo->init_done != true) {
        chr_err("charger is not rdy ,skip2\n");
        return;
    }

    if (mt_get_charger_type() == CHARGER_UNKNOWN) {
        mutex_lock(&pinfo->cable_out_lock);
        pinfo->cable_out_cnt++;
        chr_err("cable_out_cnt=%d\n", pinfo->cable_out_cnt);
        mutex_unlock(&pinfo->cable_out_lock);
        charger_manager_notifier(pinfo, CHARGER_NOTIFY_STOP_CHARGING);
    } else
        charger_manager_notifier(pinfo, CHARGER_NOTIFY_START_CHARGING);

    chr_err("wake_up_charger\n");
    _wake_up_charger(pinfo);
}

 C Code /kernel-4.14/drivers/power/supply/mediatek/charger/mtk_charger.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14

void _wake_up_charger(struct charger_manager *info)
{
    unsigned long flags;

    if (info == NULL)
        return;

    spin_lock_irqsave(&info->slock, flags);
    if (!info->charger_wakelock.active)
        __pm_stay_awake(&info->charger_wakelock);
    spin_unlock_irqrestore(&info->slock, flags);
    info->charger_thread_timeout = true;
    wake_up(&info->wait_que);  //唤醒等待队列
}

 C Code /kernel-4.14/drivers/power/supply/mediatek/charger/mtk_charger.c

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

static int charger_routine_thread(void *arg)
{
    struct charger_manager *info = arg;
    unsigned long flags;
    bool is_charger_on;
    int bat_current, chg_current;

    while (1) {
        wait_event(info->wait_que,                    //等待队列
            (info->charger_thread_timeout == true));

        mutex_lock(&info->charger_lock);
        spin_lock_irqsave(&info->slock, flags);
        if (!info->charger_wakelock.active)
            __pm_stay_awake(&info->charger_wakelock);
        spin_unlock_irqrestore(&info->slock, flags);

        info->charger_thread_timeout = false;
        bat_current = battery_get_bat_current();
        chg_current = pmic_get_charging_current();
        chr_err("Vbat=%d,Ibat=%d,I=%d,VChr=%d,T=%d,Soc=%d:%d,CT:%d:%d hv:%d pd:%d:%d\n",
            battery_get_bat_voltage(), bat_current, chg_current,
            battery_get_vbus(), battery_get_bat_temperature(),
            battery_get_soc(), battery_get_uisoc(),
            mt_get_charger_type(), info->chr_type,
            info->enable_hv_charging, info->pd_type,
            info->pd_reset);

        if (info->pd_reset == true) {
            mtk_pe40_plugout_reset(info);
            info->pd_reset = false;
        }

        is_charger_on = mtk_is_charger_on(info);

        if (info->charger_thread_polling == true)
            mtk_charger_start_timer(info);

        charger_update_data(info);
        check_battery_exist(info);
        check_dynamic_mivr(info);
        charger_check_status(info);
        kpoc_power_off_check(info);

        if (is_disable_charger() == false) {
            if (is_charger_on == true) {
                if (info->do_algorithm)
                    info->do_algorithm(info);
            }
        } else
            chr_debug("disable charging\n");

        spin_lock_irqsave(&info->slock, flags);
        __pm_relax(&info->charger_wakelock);
        spin_unlock_irqrestore(&info->slock, flags);
        chr_debug("%s end , %d\n",
            __func__, info->charger_thread_timeout);
        mutex_unlock(&info->charger_lock);
    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值