Exemplo n.º 1
0
static int bq_capacity_pulling_filter(int curr_capacity, struct bq_bci_device_info *di)
{
    int index = 0;
    di->bat_exist = is_hisi_battery_exist();

    if((!di->bat_exist)||(is_fake_battery)){
        curr_capacity = calc_capacity_from_voltage();
        return curr_capacity;
    }
    index = di->capacity_filter_count%WINDOW_LEN;

    capacity_sum -= capacity_filter[index];
    capacity_filter[index] = curr_capacity;
    capacity_sum += capacity_filter[index];

    if (++di->capacity_filter_count >= WINDOW_LEN) {
        di->capacity_filter_count = 0;
    }

    /*rounding-off 0.5 method*/
    curr_capacity = (capacity_sum*10)/WINDOW_LEN;
    curr_capacity = (curr_capacity+5)/10;

    return curr_capacity;
}
Exemplo n.º 2
0
static int bq_bci_battery_probe(struct platform_device *pdev)
{
    struct bq_bci_device_info *di;
    struct battery_charge_param_s param;
    int low_bat_flag = 0;
    int ret = 0;
    unsigned int i = 0;

    di = kzalloc(sizeof(*di), GFP_KERNEL);
    if (!di)
        return -ENOMEM;
    g_bq_bci_dev = di;

    ret = hisi_battery_charge_param(&param);
    if(!ret){
        param.max_voltagemV = 4200;
    }

    di->bat_max_volt = param.max_voltagemV;
    di->monitoring_interval = NORMAL_SAMPLE_INTERVAL;
    di->dev = &pdev->dev;
    di->bat.name = "Battery";
    di->bat.supplied_to = bq_bci_supplied_to;
    di->bat.num_supplicants = ARRAY_SIZE(bq_bci_supplied_to);
    di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
    di->bat.properties = bq_bci_battery_props;
    di->bat.num_properties = ARRAY_SIZE(bq_bci_battery_props);
    di->bat.get_property = bq_bci_battery_get_property;
    di->bat_health = POWER_SUPPLY_HEALTH_GOOD;
    di->bat_exist = is_hisi_battery_exist();
    di->bat_err = 0;

    di->usb.name = "USB";
    di->usb.type = POWER_SUPPLY_TYPE_USB;
    di->usb.properties = bq_usb_props;
    di->usb.num_properties = ARRAY_SIZE(bq_usb_props);
    di->usb.get_property = bq_usb_get_property;
    di->power_supply_status = POWER_SUPPLY_HEALTH_GOOD;

    di->ac.name = "Mains";
    di->ac.type = POWER_SUPPLY_TYPE_MAINS;
    di->ac.properties = bq_ac_props;
    di->ac.num_properties = ARRAY_SIZE(bq_ac_props);
    di->ac.get_property = bq_ac_get_property;

    di->charge_status = POWER_SUPPLY_STATUS_DISCHARGING;

    di->bk_bat.name = "bq_bk_battery";
    di->bk_bat.type = POWER_SUPPLY_TYPE_UPS;
    di->bk_bat.properties = bq_bk_bci_battery_props;
    di->bk_bat.num_properties = ARRAY_SIZE(bq_bk_bci_battery_props);
    di->bk_bat.get_property = bq_bk_bci_battery_get_property;

    di->capacity = -1;
    di->capacity_filter_count = 0;
    di->charge_full_count = 0;

    for(i=0;i<WINDOW_LEN;i++) {
            capacity_filter[i] = hisi_battery_capacity();
            capacity_sum += capacity_filter[i];
    }

    bq_get_battery_info(di);

    platform_set_drvdata(pdev, di);

    wake_lock_init(&low_power_lock, WAKE_LOCK_SUSPEND, "low_power_wake_lock");

    low_bat_flag = is_hisi_battery_reach_threshold();
    if(( low_bat_flag & BQ27510_FLAG_LOCK ) == BQ27510_FLAG_LOCK) {
        wake_lock(&low_power_lock);
        is_low_power_locked = 1;
    }

    ret = power_supply_register(&pdev->dev, &di->bat);
    if (ret) {
        dev_dbg(&pdev->dev, "failed to register main battery\n");
        goto batt_failed;
    }

    ret = power_supply_register(&pdev->dev, &di->usb);
    if (ret) {
        dev_dbg(&pdev->dev, "failed to register usb power supply\n");
        goto usb_failed;
    }

    ret = power_supply_register(&pdev->dev, &di->ac);
    if (ret) {
        dev_dbg(&pdev->dev, "failed to register ac power supply\n");
        goto ac_failed;
    }

    ret = power_supply_register(&pdev->dev, &di->bk_bat);
    if (ret) {
        dev_dbg(&pdev->dev, "failed to register backup battery\n");
        goto bk_batt_failed;
    }

    INIT_DELAYED_WORK(&di->bq_bci_monitor_work,
                bq_bci_battery_work);
    schedule_delayed_work(&di->bq_bci_monitor_work, 0);

    di->nb.notifier_call = bq_charger_event;
    bq_register_notifier(&di->nb, 1);
    dev_err(&pdev->dev, "bq_bci probe ok!\n");

	if (!battery_dclient) {
		battery_dclient = dsm_register_client(&dsm_battery);
	}

    return 0;

bk_batt_failed:
    cancel_delayed_work(&di->bq_bci_monitor_work);
    power_supply_unregister(&di->ac);
ac_failed:
    power_supply_unregister(&di->usb);
usb_failed:
    power_supply_unregister(&di->bat);
batt_failed:
    wake_lock_destroy(&low_power_lock);
    platform_set_drvdata(pdev, NULL);
    kfree(di);
    di = NULL;
    return ret;
}
Exemplo n.º 3
0
int bq_get_error_info(struct bq_bci_device_info *di)
{
    static int pre_bat_err =0, archive_state = 1;
    static unsigned long timeout_jiffies = 0;
    static int first_in = 1;
    static int pre_uf_capacity = 0;
    static int pre_capacity = 0;
    static int capacity_stay_count = 0;
    static int online_delay_count = 0;
    int bat_uf_capacity = 0;
    int curr_by_coultype = 1;
	int dsm_bci_battery_err_offset = 0;

    if (COUL_HISI_HI6421V300 == hisi_coulometer_type())
        curr_by_coultype = -1;

    di->bat_err = 0;

    if(!is_hisi_battery_exist())
        di->bat_err |= ERROR_BATT_NOT_EXIST;

    if(hisi_battery_temperature()< BQ2419x_COLD_BATTERY_THRESHOLD
           || hisi_battery_temperature()>= BQ2419x_HOT_BATTERY_THRESHOLD)
    {
        if(di->charge_status == POWER_SUPPLY_STATUS_NOT_CHARGING)
            di->bat_err |= ERROR_BATT_TEMP_STOP;
        if(di->charge_status == POWER_SUPPLY_STATUS_CHARGING)
            di->bat_err |= ERROR_BATT_TEMP_CHARGE;

        di->bat_err |= ERROR_BATT_TEMP_OUT;
        dev_info(di->dev,"batt temp = %d\n ", hisi_battery_temperature());
    }

    if(di->charge_status == POWER_SUPPLY_STATUS_NOT_CHARGING
        && !(bq2419x_get_factory_flag())) {
        if(di->power_supply_status == POWER_SUPPLY_HEALTH_OVERVOLTAGE)
            di->bat_err |= ERROR_VBUS_OVERVOLTAGE;
        if(hisi_battery_voltage() > BATT_OVERVOLTAGE_THRES)
            di->bat_err |= ERROR_BATT_OVERVOLTAGE;

        di->bat_err |= ERROR_BATT_NOT_CHARGING;
    } else {
        if(hisi_battery_voltage() > BATT_OVERVOLTAGE_THRES
           || hisi_battery_voltage() < BATT_LOWVOLTAGE_THRES) {
            di->bat_err |= ERROR_BATT_VOLTAGE;
            dev_info(di->dev,"batt volt = %d\n ", hisi_battery_voltage());
        }
    }

    if(di->chargedone_stat && hisi_battery_capacity() <= CHG_CANT_FULL_THRESHOLD){
        di->bat_err |= ERROR_PRE_CHARGEDONE;
        dev_info(di->dev,"batt capacity = %d\n ", hisi_battery_capacity());
    }

    if(di->charge_status == POWER_SUPPLY_STATUS_CHARGING
       && hisi_battery_current_avg() <= 50
       && hisi_battery_current_avg() >= 10
       && (curr_by_coultype*hisi_battery_current()) <= 50
       && (curr_by_coultype*hisi_battery_current()) >= 10
       && di->capacity == 100) {
        di->bat_err |= ERROR_NO_CHARGEDONE;
        dev_info(di->dev,"batt curr = %d batt curr_avg = %d\n ",
                         (curr_by_coultype*hisi_battery_current()), hisi_battery_current_avg());
    }

    if((!di->usb_online) && (!di->ac_online)){
        if((-hisi_battery_current() > 0) && (online_delay_count++ == 1)){
             di->bat_err |= ERROR_BAD_CURR_SENSOR;
             online_delay_count = 0;
             dev_info(di->dev,"batt curr = %d\n ", (-hisi_battery_current()));
        }
    } else {
        online_delay_count = 0;
    }

    bat_uf_capacity = hisi_battery_unfiltered_capacity();
    if(first_in){
        pre_uf_capacity = bat_uf_capacity;
        pre_capacity = di->capacity;
        first_in = 0;
    } else {
        if (abs(pre_uf_capacity - bat_uf_capacity) >= 3) {
            if (100 != bat_uf_capacity) {
                di->bat_err |= ERROR_UFCAPCITY_DEBOUNCE_OTHER;
            }
            else {
                if (abs(pre_uf_capacity - bat_uf_capacity) > 10)
                    di->bat_err |= ERROR_UFCAPCITY_DEBOUNCE_100;
            }
            hisi_hi6421v300_print_cc_reg(2); //debug
        }
        pre_uf_capacity = bat_uf_capacity;
    }

    if(di->charge_status == POWER_SUPPLY_STATUS_NOT_CHARGING
       || di->charge_status == POWER_SUPPLY_STATUS_DISCHARGING) {
        if(pre_capacity > 0 && di->capacity != pre_capacity) {
            if(di->capacity > REACH_FULL_RESAMPLE_THRESHOLD) {
                if(capacity_stay_count <= 2) {
                    di->bat_err |= ERROR_CAPACITY_CHANGE_FAST;
                    capacity_stay_count = 0;
                }
            } else if (di->capacity < REACH_EMPTY_RESAMPLE_THRESHOLD) {
                if(capacity_stay_count <= 12) {
                    di->bat_err |= ERROR_CAPACITY_CHANGE_FAST;
                    capacity_stay_count = 0;
                }
            } else {
                if(capacity_stay_count <= 6) {
                    di->bat_err |= ERROR_CAPACITY_CHANGE_FAST;
                    capacity_stay_count = 0;
                }
            }
            capacity_stay_count = 0;
        } else {
            capacity_stay_count++;
        }
    }
    pre_capacity = di->capacity;

    if (is_hisi_hi6421v300_fcc_debounce()) {
        di->bat_err |= ERROR_FCC_DEBOUNCE;
    }

    if(di->bat_err != pre_bat_err && archive_state == 1){
        timeout_jiffies = jiffies + msecs_to_jiffies(LOG_ARCH_DELAY_TIME);
        archive_state = 0;
        dev_info(di->dev,"(%s) BATT ERR = %x\n", hisi_battery_brand(), di->bat_err);
    }
    pre_bat_err = di->bat_err;

    if(time_is_before_jiffies(timeout_jiffies) &&  di->bat_err != 0x0 && archive_state == 0){
        //bq_log_exception_archive(di->bat_err);
		if (dsm_client_ocuppy(battery_dclient)) {
			dsm_client_record(battery_dclient, "battery error = %x.\n", di->bat_err);
			dsm_bci_battery_err_offset = get_bit(di->bat_err);
			dsm_client_notify(battery_dclient, DSM_BATTERY_ERROR_NO + dsm_bci_battery_err_offset);
		}
		archive_state = 1;
    }

    return di->bat_err;
}
Exemplo n.º 4
0
static int capacity_changed(struct bq_bci_device_info *di)
{
    int curr_capacity = 0;
    int low_bat_flag = is_hisi_battery_reach_threshold();

    di->bat_exist = is_hisi_battery_exist();

    /* if battery is not present we assume it is on battery simulator
    *  if we are in factory mode, BAT FW is not updated yet, we use volt2Capacity
    */
    if ((!di->bat_exist) || (is_fake_battery) ||
            (strstr(saved_command_line, "androidboot.swtype=factory") && (COUL_BQ27510 == hisi_coulometer_type()))
         ){
        curr_capacity = calc_capacity_from_voltage();
    } else {
        curr_capacity = hisi_battery_capacity();
    }

    if((low_bat_flag & BQ27510_FLAG_LOCK) != BQ27510_FLAG_LOCK && is_low_power_locked){
        wake_unlock(&low_power_lock);
        is_low_power_locked = 0;
    }

    /* Debouncing of power on init. */
    if (di->capacity == -1) {
        di->capacity = curr_capacity;
        di->prev_capacity = curr_capacity;
        return 1;
    }

    if (modem_off) {
        dev_info(di->dev," modem off so shut down AP and curr_capacity = %d \n", curr_capacity);
        di->capacity = 0;
        return 1;
    }
    /*Only availability if the capacity changed*/
    if (curr_capacity != di->prev_capacity) {
        if (abs(di->prev_capacity -curr_capacity) >= CHG_ODD_CAPACITY){
            dev_info(di->dev,"prev_capacity = %d \n"
            "curr_capacity = %d \n" "curr_voltage = %d \n",
            di->prev_capacity, curr_capacity,hisi_battery_voltage());
        }
    }

    if (curr_capacity < 2 )
    {
        int battery_volt;

        battery_volt = hisi_battery_voltage();
        if (battery_volt < BAT_VOL_3500)
        {
            di->capacity = curr_capacity;
            return 1;
        }
        dev_err(di->dev, "error capacity reported, capacity = %d\n", curr_capacity);
        return 0;
    }

    switch(di->charge_status) {
    case POWER_SUPPLY_STATUS_CHARGING:
        curr_capacity = bq_force_full_timer(curr_capacity,di);
        break;

    case POWER_SUPPLY_STATUS_FULL:
        if(hisi_battery_current_avg() >= 0){
            if(hisi_battery_voltage() >= (di->bat_max_volt-RECHG_PROTECT_THRESHOLD)){
                curr_capacity = 100;
                dev_info(di->dev,"Force soc=100\n");
            }
        }
        di->charge_full_count = 0;
        break;

    case POWER_SUPPLY_STATUS_DISCHARGING:
    case POWER_SUPPLY_STATUS_NOT_CHARGING:
        /*capacity-count will always decrease when discharging || notcharging*/
        if(di->prev_capacity < curr_capacity)
            return 0;
        di->charge_full_count = 0;
        break;

    default:
        dev_err(di->dev, "%s defualt run.\n", __func__);
        break;
    }

    /*change monitoring interval from 10s to 30s when capacity greater than 90%*/
    if(curr_capacity > REACH_FULL_RESAMPLE_THRESHOLD) {
        di->monitoring_interval = REACH_FULL_SAMPLE_INTERVAL;
    } else if(curr_capacity < REACH_EMPTY_RESAMPLE_THRESHOLD) {
        di->monitoring_interval = REACH_EMPTY_SAMPLE_INTERVAL;
    } else {
        di->monitoring_interval = NORMAL_SAMPLE_INTERVAL;
    }
    /*filter*/
    curr_capacity = bq_capacity_pulling_filter(curr_capacity,di);

    if(di->prev_capacity == curr_capacity)
        return 0;

    dev_info(di->dev,"Capacity Updated = %d, charge_full_count = %d, charge_status = %d\n",
                         curr_capacity, di->charge_full_count, di->charge_status);

    di->capacity = curr_capacity;
    di->prev_capacity = curr_capacity;
    return 1;
}
/**********************************************************
*  Function:       charge_core_parse_dts
*  Discription:    parse the module dts config value
*  Parameters:   np:device_node
*                      di:charge_core_info
*  return value:  0-sucess or others-fail
**********************************************************/
static int charge_core_parse_dts(struct device_node* np, struct charge_core_info *di)
{
    int ret = 0;
    int i = 0;
    int array_len = 0;
    int idata = 0;
    const char *chrg_data_string = NULL;

    /*ac charge current*/
    ret = of_property_read_u32(np, "iin_ac", &(di->data.iin_ac));
    if(ret)
    {
        hwlog_err("get iin_ac failed\n");
        return -EINVAL;
    }
    hwlog_debug("iin_ac = %d\n",di->data.iin_ac);
    ret = of_property_read_u32(np, "ichg_ac", &(di->data.ichg_ac));
    if(ret)
    {
        hwlog_err("get ichg_ac failed\n");
        return -EINVAL;
    }
    hwlog_debug("ichg_ac = %d\n",di->data.ichg_ac);

    /*fcp charge current */
    ret = of_property_read_u32(np,"iin_fcp",&(di->data.iin_fcp));
    if(ret)
    {
        hwlog_info("get iin_fcp failed ,use iin_ac's value instead \n");
        di->data.iin_fcp = di->data.iin_ac;
    }
    hwlog_debug("iin_fcp = %d\n",di->data.iin_fcp);
    ret = of_property_read_u32(np,"ichg_fcp",&(di->data.ichg_fcp));
    if(ret)
    {
        hwlog_info("get ichg_fcp failed ,use ichg_ac's value instead \n");
        di->data.ichg_fcp = di->data.ichg_ac;
    }
    hwlog_debug("ichg_fcp = %d\n",di->data.ichg_fcp);

    /*usb charge current*/
    ret = of_property_read_u32(np, "iin_usb", &(di->data.iin_usb));
    if(ret)
    {
        hwlog_err("get iin_usb failed\n");
        return -EINVAL;
    }
    hwlog_debug("iin_usb = %d\n",di->data.iin_usb);
    ret = of_property_read_u32(np, "ichg_usb", &(di->data.ichg_usb));
    if(ret)
    {
        hwlog_err("get ichg_usb failed\n");
        return -EINVAL;
    }
    hwlog_debug("ichg_usb = %d\n",di->data.ichg_usb);
    /*nonstandard charge current*/
    ret = of_property_read_u32(np, "iin_nonstd", &(di->data.iin_nonstd));
    if(ret)
    {
        hwlog_err("get iin_nonstd failed\n");
        return -EINVAL;
    }
    hwlog_debug("iin_nonstd = %d\n",di->data.iin_nonstd);
    ret = of_property_read_u32(np, "ichg_nonstd", &(di->data.ichg_nonstd));
    if(ret)
    {
        hwlog_err("get ichg_nonstd failed\n");
        return -EINVAL;
    }
    hwlog_debug("ichg_nonstd = %d\n",di->data.ichg_nonstd);
    /*Charging Downstream Port*/
    ret = of_property_read_u32(np, "iin_bc_usb", &(di->data.iin_bc_usb));
    if(ret)
    {
        hwlog_err("get iin_bc_usb failed\n");
        return -EINVAL;
    }
    hwlog_debug("iin_bc_usb = %d\n",di->data.iin_bc_usb);
    ret = of_property_read_u32(np, "ichg_bc_usb", &(di->data.ichg_bc_usb));
    if(ret)
    {
        hwlog_err("get ichg_bc_usb failed\n");
        return -EINVAL;
    }
    hwlog_debug("ichg_bc_usb = %d\n",di->data.ichg_bc_usb);
    /*terminal current*/
    ret = of_property_read_u32(np, "iterm", &(di->data.iterm));
    if(ret)
    {
        hwlog_err("get iterm failed\n");
        return -EINVAL;
    }
    hwlog_debug("iterm = %d\n",di->data.iterm);
    /*otg current*/
    ret = of_property_read_u32(np, "otg_curr", &(di->data.otg_curr));
    if(ret)
    {
        hwlog_err("get otg_curr failed\n");
        return -EINVAL;
    }
    hwlog_debug("otg_curr = %d\n",di->data.otg_curr);

    //vdpm_para
    array_len = of_property_count_strings(np, "vdpm_para");
    if ((array_len <= 0) || (array_len % VDPM_PARA_TOTAL != 0))
    {
        hwlog_err("vdpm_para is invaild,please check vdpm_para number!!\n");
        return -EINVAL;
    }

    if (array_len > VDPM_PARA_LEVEL * VDPM_PARA_TOTAL)
    {
        array_len = VDPM_PARA_LEVEL * VDPM_PARA_TOTAL;
        hwlog_err("vdpm_para is too long,use only front %d paras!!\n", array_len);
        return -EINVAL;
    }

    memset(di->vdpm_para, 0, VDPM_PARA_LEVEL * sizeof(struct charge_vdpm_data)); // data reset to 0

    for (i = 0; i < array_len; i++)
    {
        ret = of_property_read_string_index(np, "vdpm_para", i, &chrg_data_string);
        if (ret)
        {
            hwlog_err("get vdpm_para failed\n");
            return -EINVAL;
        }

        idata = simple_strtol(chrg_data_string, NULL, 10);
        switch (i % VDPM_PARA_TOTAL)
        {
        case VDPM_PARA_CAP_MIN:
            if ((idata < VDPM_CBAT_MIN) || (idata > VDPM_CBAT_MAX))
            {
                hwlog_err("the vdpm_para cap_min is out of range!!\n");
                return -EINVAL;
            }
            di->vdpm_para[ i/ (VDPM_PARA_TOTAL)].cap_min = idata;
            break;
        case VDPM_PARA_CAP_MAX:
            if((idata < VDPM_CBAT_MIN) || (idata > VDPM_CBAT_MAX))
            {
                hwlog_err("the vdpm_para cap_max is out of range!!\n");
                return -EINVAL;
            }
            di->vdpm_para[i / (VDPM_PARA_TOTAL)].cap_max = idata;
            break;
        case VDPM_PARA_DPM:
            if((idata < VDPM_VOLT_MIN) || (idata > VDPM_VOLT_MAX))
            {
                hwlog_err("the vdpm_para vin_dpm is out of range!!\n");
                return -EINVAL;
            }
            di->vdpm_para[i / (VDPM_PARA_TOTAL)].vin_dpm = idata;
            break;
        case VDPM_PARA_CAP_BACK:
            if((idata < 0) || (idata > VDPM_CAP_DETA))
            {
                hwlog_err("the vdpm_para cap_back is out of range!!\n");
                return -EINVAL;
            }
            di->vdpm_para[i / (VDPM_PARA_TOTAL)].cap_back = idata;
            break;
        default:
            hwlog_err("get vdpm_para failed\n");
        }
        hwlog_debug("di->vdpm_para[%d][%d] = %d\n", i / (VDPM_PARA_TOTAL),
                    i % (VDPM_PARA_TOTAL), idata);
    }

    /* inductance_para */
    memset(di->inductance_para, 0, INDUCTANCE_PARA_LEVEL * sizeof(struct charge_inductance_data)); // data reset to 0

    array_len = of_property_count_strings(np, "inductance_para");
    if ((array_len <= 0) || (array_len % INDUCTANCE_PARA_TOTAL != 0))
    {
        hwlog_err("inductance_para is invaild,please check inductance_para number!!\n");
        return -EINVAL;
    }
    if (array_len > INDUCTANCE_PARA_LEVEL * INDUCTANCE_PARA_TOTAL)
    {
        array_len = INDUCTANCE_PARA_LEVEL * INDUCTANCE_PARA_TOTAL;
        hwlog_err("inductance_para is too long,use only front %d paras!!\n", array_len);
        return -EINVAL;
    }

    for(i = 0; i < array_len ; i++)
    {
        ret = of_property_read_string_index(np, "inductance_para", i, &chrg_data_string);
        if (ret)
        {
            hwlog_err("get inductance_para failed\n");
            return -EINVAL;
        }

        idata = simple_strtol(chrg_data_string, NULL, 10);
        switch (i % INDUCTANCE_PARA_TOTAL)
        {
        case INDUCTANCE_PARA_CAP_MIN:
            if ((idata < INDUCTANCE_CBAT_MIN) || (idata > INDUCTANCE_CBAT_MAX))
            {
                hwlog_err("the inductance_para cap_min is out of range!!\n");
                return -EINVAL;
            }
            di->inductance_para[ i/ (INDUCTANCE_PARA_TOTAL)].cap_min = idata;
            break;
        case INDUCTANCE_PARA_CAP_MAX:
            if ((idata < INDUCTANCE_CBAT_MIN) || (idata > INDUCTANCE_CBAT_MAX))
            {
                hwlog_err("the inductance_para cap_max is out of range!!\n");
                return -EINVAL;
            }
            di->inductance_para[i / (INDUCTANCE_PARA_TOTAL)].cap_max = idata;
            break;
        case INDUCTANCE_PARA_IIN:
            if ((idata < INDUCTANCE_IIN_MIN) || (idata > INDUCTANCE_IIN_MAX))
            {
                hwlog_err("the inductance_para iin is out of range!!\n");
                return -EINVAL;
            }
            di->inductance_para[i / (INDUCTANCE_PARA_TOTAL)].iin_inductance= idata;
            break;
        case INDUCTANCE_PARA_CAP_BACK:
            if ((idata < 0) || (idata > INDUCTANCE_CAP_DETA))
            {
                hwlog_err("the inductance_para cap_back is out of range!!\n");
                return -EINVAL;
            }
            di->inductance_para[i / (INDUCTANCE_PARA_TOTAL)].cap_back = idata;
            break;
        default:
            hwlog_err("get vdpm_para failed\n");
        }
        hwlog_info("di->inductance_para[%d][%d] = %d\n", i / (INDUCTANCE_PARA_TOTAL),
                   i % (INDUCTANCE_PARA_TOTAL), idata);
    }

    if(strstr(saved_command_line, "androidboot.swtype=factory") && (!is_hisi_battery_exist()))
    {
        di->data.iin_ac = CHARGE_CURRENT_2000_MA;
        di->data.ichg_ac = CHARGE_CURRENT_1900_MA;
        di->data.iin_bc_usb = CHARGE_CURRENT_2000_MA;
        di->data.ichg_bc_usb = CHARGE_CURRENT_1900_MA;
        hwlog_info("factory version,iin_ac = %d mA,ichg_ac %d mA,iin_bc_usb = %d mA,ichg_bc_usb = %d mA\n",
                   di->data.iin_ac,di->data.ichg_ac,di->data.iin_bc_usb,di->data.ichg_bc_usb);
    }
    di->data.iin_max = di->data.iin_ac < di->data.iin_fcp ? di->data.iin_fcp :di->data.iin_ac;
    di->data.ichg_max = di->data.ichg_ac < di->data.ichg_fcp ? di->data.ichg_fcp :di->data.ichg_ac;
    hwlog_info("iin_max = %d mA,ichg_max %d mA\n",di->data.iin_max,di->data.ichg_max);
    return 0;
}
void sdhci_get_of_property(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct sdhci_host *host = platform_get_drvdata(pdev);
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	const __be32 *clk;
	u32 bus_width = 0;
	int size;
	int runmode_normal;
	int batterystate_exist;

	if (of_device_is_available(np)) {
		if (of_get_property(np, "sdhci,auto-cmd12", NULL))
			host->quirks |= SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12;

		if (of_get_property(np, "sdhci,1-bit-only", NULL) ||
		    (of_property_read_u32(np, "bus-width", &bus_width) == 0 &&
		    bus_width == 1))
			host->quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA;

		if (bus_width == 4)
			host->mmc->caps |= MMC_CAP_4_BIT_DATA;
		else if (bus_width == 8)
			host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA;

		if (sdhci_of_wp_inverted(np))
			host->quirks |= SDHCI_QUIRK_INVERTED_WRITE_PROTECT;

		if (of_get_property(np, "broken-cd", NULL))
			host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;

		if (of_find_property(np, "non-removable", NULL))
			host->mmc->caps |= MMC_CAP_NONREMOVABLE;

		if (of_get_property(np, "no-1-8-v", NULL))
			host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V;

		if (of_device_is_compatible(np, "fsl,p2020-rev1-esdhc"))
			host->quirks |= SDHCI_QUIRK_BROKEN_DMA;

		if (of_find_property(np, "use-pio", NULL))
		{
			host->quirks |= SDHCI_QUIRK_BROKEN_DMA;
			host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
		}

		if (of_find_property(np, "use-dma", NULL))
			host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;

		if (!of_find_property(np, "sdhci-adma-64bit", NULL))
			host->quirks2 |= SDHCI_QUIRK2_BROKEN_64_BIT_DMA;

		if (of_device_is_compatible(np, "fsl,p2020-esdhc") ||
		    of_device_is_compatible(np, "fsl,p1010-esdhc") ||
		    of_device_is_compatible(np, "fsl,t4240-esdhc") ||
		    of_device_is_compatible(np, "fsl,mpc8536-esdhc"))
			host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;

		clk = of_get_property(np, "clock-frequency", &size);
		if (clk && size == sizeof(*clk) && *clk)
			pltfm_host->clock = be32_to_cpup(clk);

		host->quirks2 |= SDHCI_QUIRK2_BROKEN_HS200;
		if (of_find_property(np, "caps2-mmc-ddr50-1_8v", NULL))
			host->mmc->caps |= MMC_CAP_1_8V_DDR;

		if (of_find_property(np, "caps2-mmc-ddr50-1_2v", NULL))
			host->mmc->caps |= MMC_CAP_1_2V_DDR;

		if (of_find_property(np, "caps2-mmc-hs200-1_8v", NULL)) {
			host->mmc->caps2 |= MMC_CAP2_HS200_1_8V_SDR;
			host->quirks2 &= ~SDHCI_QUIRK2_BROKEN_HS200;
		}

		if (of_find_property(np, "caps2-mmc-hs200-1_2v", NULL)) {
			host->mmc->caps2 |= MMC_CAP2_HS200_1_2V_SDR;
			host->quirks2 &= ~SDHCI_QUIRK2_BROKEN_HS200;
		}

		if (of_find_property(np, "caps2-mmc-hs400-1_8v", NULL)){
			host->mmc->caps2 |= MMC_CAP2_HS200_1_8V_SDR;
			host->mmc->caps2 |= MMC_CAP2_HS400_1_8V;
			host->quirks2 &= ~SDHCI_QUIRK2_BROKEN_HS200;
		}

		if (of_find_property(np, "caps2-mmc-hs400-1_2v", NULL)){
			host->mmc->caps2 |= MMC_CAP2_HS200_1_2V_SDR;
			host->mmc->caps2 |= MMC_CAP2_HS400_1_2V;
			host->quirks2 &= ~SDHCI_QUIRK2_BROKEN_HS200;
		}

		if (of_find_property(np, "caps2-mmc-packed-command", NULL))
			host->mmc->caps2 |= MMC_CAP2_PACKED_CMD;

		runmode_normal = !runmode_is_factory();

#ifdef CONFIG_HISI_COUL
		batterystate_exist = is_hisi_battery_exist();
#else 
		batterystate_exist = 0;
#endif	
		dev_info(&pdev->dev, "runmode_normal = %d batterystate_exist = %d\n", runmode_normal, batterystate_exist);

		if (of_find_property(np, "caps2-mmc-cache-ctrl", NULL))
		{
			dev_info(&pdev->dev, "caps2-mmc-cache-ctrl is set in dts.\n");
			if(runmode_normal || batterystate_exist)
			{
				dev_info(&pdev->dev, "cache ctrl on\n");
				host->mmc->caps2 |= MMC_CAP2_CACHE_CTRL;
			}
			else
			{
				dev_info(&pdev->dev, "cache ctrl off\n");
			}
		}

		if (of_find_property(np, "full-pwr-cycle", NULL))
			host->mmc->caps2 |= MMC_CAP2_FULL_PWR_CYCLE;

		if (of_find_property(np, "caps2-mmc-cmd-queue", NULL))
		{
			dev_info(&pdev->dev, "caps2-mmc-cmd-queue is set in dts.\n");
			if(runmode_normal || batterystate_exist)
			{
				dev_info(&pdev->dev, "caps2-mmc-cmd-queue on\n");
				host->mmc->caps2 |= MMC_CAP2_CMD_QUEUE;
			}
			else
			{
				dev_info(&pdev->dev, "caps2-mmc-cmd-queue off\n");
			}
		}

		if (of_find_property(np, "keep-power-in-suspend", NULL))
			host->mmc->pm_caps |= MMC_PM_KEEP_POWER;

		if (of_find_property(np, "enable-sdio-wakeup", NULL))
			host->mmc->pm_caps |= MMC_PM_WAKE_SDIO_IRQ;

		if (of_find_property(np, "caps2-mmc-enhanced_strobe-ctrl", NULL))
			host->mmc->caps2 |= MMC_CAP2_ENHANCED_STROBE;

		if (of_find_property(np, "caps2-mmc-cache_flush_barrier-ctrl", NULL))
			host->mmc->caps2 |= MMC_CAP2_CACHE_FLUSH_BARRIER;

		if (of_find_property(np, "caps2-mmc-bkops_auto-ctrl", NULL))
			host->mmc->caps2 |= MMC_CAP2_BKOPS_AUTO_CTRL;

		if (of_find_property(np, "caps2-mmc-HC-erase-size", NULL))
			host->mmc->caps2 |= MMC_CAP2_HC_ERASE_SZ;

	}
}