/* soc should be 0.01% unit */ static int adc_get_soc(struct i2c_client *client) { struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client); int soc; soc = adc_get_data_by_adc(fuelgauge, get_battery_data(fuelgauge).ocv2soc_table, get_battery_data(fuelgauge).ocv2soc_table_size, fuelgauge->info.voltage_ocv); return soc; }
static int adc_get_vcell(struct i2c_client *client) { struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client); int vcell; vcell = adc_get_data_by_adc(fuelgauge, get_battery_data(fuelgauge).adc2vcell_table, get_battery_data(fuelgauge).adc2vcell_table_size, adc_get_adc_value(fuelgauge, SEC_BAT_ADC_CHANNEL_VOLTAGE_NOW)); return vcell; }
static int adc_get_current(struct i2c_client *client) { union power_supply_propval value; struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client); int current_now; current_now = adc_get_data_by_adc(fuelgauge, get_battery_data(fuelgauge).adc2current_table, get_battery_data(fuelgauge).adc2current_table_size, adc_get_adc_value(fuelgauge, SEC_BAT_ADC_CHANNEL_CURRENT_NOW)); if (!current_now) { psy_do_property("sec-charger", get, POWER_SUPPLY_PROP_CURRENT_NOW, value); current_now = value.intval; } return current_now; }
static int get_cable_compensation_voltage( struct sec_fuelgauge_info *fuelgauge, int vcell) { int comp_value; comp_value = 0; comp_value = adc_get_data_by_adc(fuelgauge, get_battery_data(fuelgauge).cable_comp_voltage, get_battery_data(fuelgauge).cable_comp_voltage_size, vcell); /* no need to reset SOC with 0mA charging current */ if (!fuelgauge->info.current_now) fuelgauge->info.reset_percentage = 0; /* rescale by charging current */ comp_value = comp_value * fuelgauge->info.current_now / 1000; dev_dbg(&fuelgauge->client->dev, "%s: cable comp value (%dmV, current %dmA)\n", __func__, comp_value, fuelgauge->info.current_now); return comp_value; }
static int adc_get_vcell(struct i2c_client *client) { union power_supply_propval cable; union power_supply_propval event; union power_supply_propval is_charging; struct sec_fuelgauge_info *fuelgauge = i2c_get_clientdata(client); int vcell, vcell_raw; vcell = adc_get_data_by_adc(fuelgauge, get_battery_data(fuelgauge).adc2vcell_table, get_battery_data(fuelgauge).adc2vcell_table_size, adc_get_adc_value(fuelgauge, SEC_BAT_ADC_CHANNEL_VOLTAGE_NOW)); vcell_raw = vcell; psy_do_property("battery", get, POWER_SUPPLY_PROP_ONLINE, cable); /* get current event status */ event.intval = BATT_EVENT; psy_do_property("battery", get, POWER_SUPPLY_PROP_TECHNOLOGY, event); psy_do_property("battery", get, POWER_SUPPLY_PROP_CHARGE_NOW, is_charging); if (is_charging.intval != SEC_BATTERY_CHARGING_NONE) { /* compensate voltage by cable only in charging status */ if (cable.intval != POWER_SUPPLY_TYPE_BATTERY) vcell += get_cable_compensation_voltage( fuelgauge, vcell); } else { /* need compensation before cable detection * in power-off charging */ if ((cable.intval == POWER_SUPPLY_TYPE_BATTERY) && (fuelgauge->pdata->is_lpm() || fuelgauge->pdata->check_vbus_status())) { dev_dbg(&client->dev, "%s: VBUS compensation\n", __func__); vcell += get_cable_compensation_voltage( fuelgauge, vcell); } } if (event.intval) { if (fuelgauge->pdata->check_vbus_status() && (event.intval & EVENT_BOOTING)) dev_dbg(&client->dev, "%s: no event compensation " "in booting with charging\n", __func__); else vcell += get_event_compensation_voltage( fuelgauge, event.intval); } #if defined(SEC_FUELGAUGE_ADC_DELTA_COMPENSATION) if (!fuelgauge->pdata->monitor_initial_count) vcell += get_delta_compensation_voltage( fuelgauge, vcell, vcell_raw); #endif return vcell; }
static int get_delta_compensation_voltage( struct sec_fuelgauge_info *fuelgauge, int vcell, int vcell_raw) { int last_time, delta_time, delta_voltage_now, delta_current_now; int delta_voltage_now_in_sec, delta_compensation_voltage; delta_compensation_voltage = 0; last_time = fuelgauge->info.last_vcell_check_time.tv_sec; do_gettimeofday(&(fuelgauge->info.last_vcell_check_time)); if (last_time) { delta_time = fuelgauge->info.last_vcell_check_time.tv_sec - last_time; if (delta_time > get_battery_data(fuelgauge).delta_reset_time) { dev_dbg(&fuelgauge->client->dev, "%s: reset delta compensation\n", __func__); delta_voltage_now = 0; delta_current_now = 0; fuelgauge->info.current_compensation = 0; goto no_delta_compensation; } /* to get compensation voltage, * use raw vcell without compensation */ delta_compensation_voltage = adc_get_data_by_adc(fuelgauge, get_battery_data(fuelgauge).cable_comp_voltage, get_battery_data(fuelgauge).cable_comp_voltage_size, vcell_raw) * fuelgauge->info.current_compensation / 1000; delta_voltage_now = vcell + delta_compensation_voltage - fuelgauge->info.voltage_now; fuelgauge->info.delta_voltage_now_in_sec = delta_voltage_now * 1000 / delta_time; if (delta_voltage_now < 0) delta_voltage_now_in_sec = -(fuelgauge->info.delta_voltage_now_in_sec); else delta_voltage_now_in_sec = fuelgauge->info.delta_voltage_now_in_sec; if ((delta_time < get_battery_data(fuelgauge).delta_check_time) && (delta_voltage_now_in_sec > get_battery_data(fuelgauge).delta_comp_limit)) { /* to get delta current, * use raw vcell without compensation */ delta_current_now = -(delta_voltage_now * 1000 / adc_get_data_by_adc(fuelgauge, get_battery_data(fuelgauge).cable_comp_voltage, get_battery_data(fuelgauge).cable_comp_voltage_size, vcell)); /* to show compensation value, added minus */ dev_dbg(&fuelgauge->client->dev, "%s: delta compensation (%dmA)\n", __func__, -delta_current_now); fuelgauge->info.current_compensation += delta_current_now; /* to get compensation voltage, * use raw vcell without compensation */ delta_compensation_voltage = adc_get_data_by_adc(fuelgauge, get_battery_data(fuelgauge).cable_comp_voltage, get_battery_data(fuelgauge).cable_comp_voltage_size, vcell_raw) * fuelgauge->info.current_compensation / 1000; } else delta_current_now = fuelgauge->info.current_compensation; if (!delta_compensation_voltage) { dev_dbg(&fuelgauge->client->dev, "%s: no need delta compensation " "vcell raw %dmV, comp vol %dmV, dv %dmV\n", __func__, vcell_raw, delta_compensation_voltage, delta_voltage_now); fuelgauge->info.current_compensation = 0; } no_delta_compensation: dev_dbg(&fuelgauge->client->dev, "%s: dtime %dsec, dvoltage %dmV, dcurrent %dmA, " "dvoltage/sec %duV, delta comp voltage %dmV, " "compensation current %dmA\n", __func__, delta_time, delta_voltage_now, delta_current_now, fuelgauge->info.delta_voltage_now_in_sec, delta_compensation_voltage, fuelgauge->info.current_compensation); } return delta_compensation_voltage; }