Example #1
0
static int setup_supply_data(struct device_node *node, struct ricoh_pmu_init_data *s_data)
{
    int err;
    struct device_node *b_node;
    struct battery_parameter *battery;
    phandle fhandle;

    err = of_property_read_bool(node, "reset-to-system");
    if (err) {
        s_data->reset_to_system = 1;
    }
    PARSE_UINT32_PROPERTY(node, "soft_limit_to99", s_data->soft_limit_to99, parse_failed);
    PARSE_UINT32_PROPERTY(node, "board_battery",   fhandle,                 parse_failed);
    PARSE_UINT32_PROPERTY(node, "vbus_dcin_short_connect", s_data->vbus_dcin_short_connect, parse_failed);
    b_node = of_find_node_by_phandle(fhandle);
    if (!b_node) {
        DBG("find battery node failed, current:%s\n", node->name);
    }
    ALLOC_DEVICES(battery, sizeof(*battery), GFP_KERNEL);
    if (parse_battery_parameters(b_node, battery)) {
        DBG("failed to parse battery parameter, node:%s\n", b_node->name);
        kfree(battery);
    } else {
        s_data->board_battery = battery;                                // attach to axp_supply_init_data
    }
    return 0;

parse_failed:
    return -EINVAL;
}
Example #2
0
int axp202_get_charging_percent(void)
{
	//uint8_t val;
	//struct axp_adc_res axp_adc;
    extern int config_battery_rdc;
    extern struct battery_curve config_battery_curve[];
    int i;
    int ocv = 0;
    int ocv_diff, percent_diff, ocv_diff2;
    int charge_status = axp_charger_get_charging_status();
    int percent1, percent2;
    int rest_vol;
    int avg_voltage, avg_current;
    static int ocv_full  = 0;
    static int ocv_empty = 0;
    static int battery_rdc;
    static struct battery_curve *battery_curve;

    if (get_battery_para_flag() == PARA_UNPARSED) {
        /*
         * this code runs earlier than get_battery_para(), 
         * we need to know battery parameters first.
         */
        if (parse_battery_parameters() > 0) {
            set_battery_para_flag(PARA_PARSE_SUCCESS);
            for (i = 0; i < 16; i++) {                  	// find out full & empty ocv in battery curve
                if (!ocv_empty && board_battery_para.pmu_bat_curve[i].discharge_percent > 0) {
                    ocv_empty = board_battery_para.pmu_bat_curve[i - 1].ocv;    
                }
                if (!ocv_full && board_battery_para.pmu_bat_curve[i].discharge_percent == 100) {
                    ocv_full = board_battery_para.pmu_bat_curve[i].ocv;    
                }
            }
            battery_rdc   = board_battery_para.pmu_battery_rdc;
            battery_curve = board_battery_para.pmu_bat_curve;
        } else {
            set_battery_para_flag(PARA_PARSE_FAILED);
        }
    }
    if (get_battery_para_flag() != PARA_PARSE_SUCCESS && !ocv_full) {
        /*
         * parse battery parameters failed, use configured parameters
         */
        battery_rdc   = config_battery_rdc;
        battery_curve = config_battery_curve;
        for (i = 0; i < 16; i++) {                  	// find out full & empty ocv in battery curve
            if (!ocv_empty && battery_curve[i].discharge_percent > 0) {
                ocv_empty = battery_curve[i - 1].ocv;    
            }
            if (!ocv_full && battery_curve[i].discharge_percent == 100) {
                ocv_full = battery_curve[i].ocv;    
            }
        }
    }
    avg_voltage = 0;
    avg_current = 0;
    for (i = 0; i < 8; i++) {                           // calculate average ocv
        ocv += axp_calculate_ocv(charge_status, battery_rdc);
        udelay(2000); 
    }
    ocv = ocv / 8;
    avg_voltage /= 8;
    avg_current /= 8;
    printf("charge status:%04x, voltage:%4d, current:%4d, ocv is %4d, ", 
           status_reg,
           avg_voltage, 
           avg_current * (charge_status ? 1 : -1), 
           ocv);
    if (ocv >= ocv_full) {
        return 100;    
    } else if (ocv <= ocv_empty) {
        return 0;
    }
    for (i = 0; i < 15; i++) {                          // find which range this ocv is in
        if (ocv >= battery_curve[i].ocv &&
            ocv <  battery_curve[i + 1].ocv) {
            break;
        }
    }
    percent1 = (battery_curve[i + 1].charge_percent + 
                battery_curve[i + 1].discharge_percent) / 2;
    percent2 = (battery_curve[i].charge_percent + 
                battery_curve[i].discharge_percent) / 2;
    percent_diff = percent1 - percent2; 
    ocv_diff  = battery_curve[i + 1].ocv -
                battery_curve[i].ocv;
    ocv_diff2 = ocv - battery_curve[i].ocv;
    rest_vol  = (percent_diff * ocv_diff2 + ocv_diff / 2)/ocv_diff;
    rest_vol += percent2; 
    if (rest_vol > 100) {
        rest_vol = 100;    
    } else if (rest_vol < 0) {
        rest_vol = 0;    
    }
    return rest_vol;
}