/* 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_event_compensation_voltage( struct sec_fuelgauge_info *fuelgauge, int event) { int i, comp_value; comp_value = 0; for (i = 0; i < BATT_EVENT_NUM; i++) { if (event & (0x1 << i)) { comp_value += get_battery_data(fuelgauge). event_comp_voltage[i]; dev_dbg(&fuelgauge->client->dev, "%s: event number (%d), comp value (%d)\n", __func__, i, get_battery_data(fuelgauge). event_comp_voltage[i]); } } dev_dbg(&fuelgauge->client->dev, "%s: event comp value (%dmV)\n", __func__, comp_value); return comp_value; }
void board_fuelgauge_init(struct sec_fuelgauge_info *fuelgauge) { sec_fuelgauge = fuelgauge; if (!fuelgauge->pdata->battery_data) { pr_info("%s : assign battery data\n", __func__); fuelgauge->pdata->battery_data = (void *)samsung_battery_data; } fuelgauge->pdata->capacity_max = CAPACITY_MAX; fuelgauge->pdata->capacity_max_margin = CAPACITY_MAX_MARGIN; fuelgauge->pdata->capacity_min = CAPACITY_MIN; #if defined(CONFIG_FUELGAUGE_MAX17048) pr_info("%s: RCOMP0: 0x%x, RCOMP_charging: 0x%x, " "temp_cohot: %d, temp_cocold: %d, " "is_using_model_data: %d, type_str: %s, " "capacity_max: %d, capacity_max_margin: %d, " "capacity_min: %d, \n", __func__ , get_battery_data(fuelgauge).RCOMP0, get_battery_data(fuelgauge).RCOMP_charging, get_battery_data(fuelgauge).temp_cohot, get_battery_data(fuelgauge).temp_cocold, get_battery_data(fuelgauge).is_using_model_data, get_battery_data(fuelgauge).type_str, fuelgauge->pdata->capacity_max, fuelgauge->pdata->capacity_max_margin, fuelgauge->pdata->capacity_min ); #endif }
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_adc_value( struct sec_fuelgauge_info *fuelgauge, int channel) { int adc; adc = adc_get_adc_data(fuelgauge, channel, get_battery_data(fuelgauge).adc_check_count); if (adc < 0) { dev_err(&fuelgauge->client->dev, "%s: Error in ADC\n", __func__); return adc; } return adc; }
static void adc_monitor_work(struct work_struct *work) { struct sec_fuelgauge_info *fuelgauge = container_of(work, struct sec_fuelgauge_info, info.monitor_work.work); fuelgauge->info.current_now = adc_get_current(fuelgauge->client); fuelgauge->info.voltage_now = adc_get_vcell(fuelgauge->client); if (fuelgauge->info.reset_percentage) adc_reset_voltage_avg(fuelgauge->client, fuelgauge->info.voltage_now, fuelgauge->info.reset_percentage); fuelgauge->info.voltage_avg = adc_get_avg_vcell(fuelgauge->client); if (fuelgauge->info.reset_percentage) { adc_reset_voltage_ocv(fuelgauge->client, fuelgauge->info.voltage_avg); fuelgauge->info.reset_percentage = 0; } fuelgauge->info.voltage_ocv = adc_get_ocv(fuelgauge->client); fuelgauge->info.current_avg = adc_get_current_average(fuelgauge->client); fuelgauge->info.capacity = adc_get_soc(fuelgauge->client); dev_info(&fuelgauge->client->dev, "%s:Vnow(%dmV),Vavg(%dmV),Vocv(%dmV)," "Inow(%dmA),Iavg(%dmA),SOC(%d%%)\n", __func__, fuelgauge->info.voltage_now, fuelgauge->info.voltage_avg, fuelgauge->info.voltage_ocv, fuelgauge->info.current_now, fuelgauge->info.current_avg, fuelgauge->info.capacity); if (fuelgauge->pdata->monitor_initial_count) schedule_delayed_work(&fuelgauge->info.monitor_work, HZ); else schedule_delayed_work(&fuelgauge->info.monitor_work, HZ * get_battery_data(fuelgauge).monitor_polling_time); if (fuelgauge->info.is_init) { fuelgauge->info.is_init--; adc_get_reset_percentage(fuelgauge); } /* save time of monitor */ do_gettimeofday(&(fuelgauge->info.last_vcell_check_time)); }
jstring Java_com_cloudminds_smartrobot_fragment_HomeFragment_getBatteryData(JNIEnv* env, jobject thiz, jobject obj) { struct battery_data battery; get_battery_data(&battery); jfieldID jfield; jclass objectClass = (*env)->FindClass(env, "com/cloudminds/smartrobot/bean/BatteryData"); jfield = (*env)->GetFieldID(env, objectClass, "seq", "I"); (*env)->SetIntField(env, obj, jfield, battery.seq); jfield = (*env)->GetFieldID(env, objectClass, "capacity", "F"); (*env)->SetFloatField(env, obj, jfield, battery.capacity); jfield = (*env)->GetFieldID(env, objectClass, "residue_capacity", "F"); (*env)->SetFloatField(env, obj, jfield, battery.residue_capacity); jfield = (*env)->GetFieldID(env, objectClass, "voltage", "F"); (*env)->SetFloatField(env, obj, jfield, battery.voltage); jfield = (*env)->GetFieldID(env, objectClass, "current", "F"); (*env)->SetFloatField(env, obj, jfield, battery.current); jfield = (*env)->GetFieldID(env, objectClass, "status", "I"); (*env)->SetIntField(env, obj, jfield, battery.status); return (*env)->NewStringUTF(env, "getUltrasonicData"); }
static void adc_monitor_work(struct work_struct *work) { struct sec_fuelgauge_info *fuelgauge = container_of(work, struct sec_fuelgauge_info, info.monitor_work.work); fuelgauge->info.voltage_now = adc_get_vcell(fuelgauge->client); fuelgauge->info.voltage_avg = adc_get_avg_vcell(fuelgauge->client); fuelgauge->info.voltage_ocv = adc_get_ocv(fuelgauge->client); fuelgauge->info.current_now = adc_get_current(fuelgauge->client); fuelgauge->info.current_avg = adc_get_current_average(fuelgauge->client); fuelgauge->info.capacity = adc_get_soc(fuelgauge->client); dev_info(&fuelgauge->client->dev, "%s:Vnow(%dmV),Vavg(%dmV),Vocv(%dmV)," "Inow(%dmA),Iavg(%dmA),SOC(%d%%)\n", __func__, fuelgauge->info.voltage_now, fuelgauge->info.voltage_avg, fuelgauge->info.voltage_ocv, fuelgauge->info.current_now, fuelgauge->info.current_avg, fuelgauge->info.capacity); schedule_delayed_work(&fuelgauge->info.monitor_work, HZ * get_battery_data(fuelgauge).monitor_polling_time); }
void board_fuelgauge_init(struct sec_fuelgauge_info *fuelgauge) { sec_fuelgauge = fuelgauge; if (!fuelgauge->pdata->battery_data) { pr_info("%s : assign battery data\n", __func__); fuelgauge->pdata->battery_data = (void *)samsung_battery_data; } fuelgauge->pdata->capacity_max = CAPACITY_MAX; fuelgauge->pdata->capacity_max_margin = CAPACITY_MAX_MARGIN; fuelgauge->pdata->capacity_min = CAPACITY_MIN; #if defined(CONFIG_SEC_VIENNA_PROJECT) || defined(CONFIG_SEC_V2_PROJECT) ||\ defined(CONFIG_MACH_PICASSO_LTE) || defined(CONFIG_MACH_MONDRIAN) fuelgauge->pdata->temp_adc_table = temp_table; fuelgauge->pdata->temp_adc_table_size = sizeof(temp_table)/sizeof(sec_bat_adc_table_data_t); #endif #if defined(CONFIG_FUELGAUGE_MAX17048) pr_info("%s: RCOMP0: 0x%x, RCOMP_charging: 0x%x, " "temp_cohot: %d, temp_cocold: %d, " "is_using_model_data: %d, type_str: %s, " "capacity_max: %d, capacity_max_margin: %d, " "capacity_min: %d, \n", __func__ , get_battery_data(fuelgauge).RCOMP0, get_battery_data(fuelgauge).RCOMP_charging, get_battery_data(fuelgauge).temp_cohot, get_battery_data(fuelgauge).temp_cocold, get_battery_data(fuelgauge).is_using_model_data, get_battery_data(fuelgauge).type_str, fuelgauge->pdata->capacity_max, fuelgauge->pdata->capacity_max_margin, fuelgauge->pdata->capacity_min ); #endif }
static int __devinit sec_fuelgauge_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct sec_fuelgauge_info *fuelgauge; int ret = 0; union power_supply_propval raw_soc_val; dev_dbg(&client->dev, "%s: SEC Fuelgauge Driver Loading\n", __func__); if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) return -EIO; fuelgauge = kzalloc(sizeof(*fuelgauge), GFP_KERNEL); if (!fuelgauge) return -ENOMEM; mutex_init(&fuelgauge->fg_lock); fuelgauge->client = client; fuelgauge->pdata = client->dev.platform_data; i2c_set_clientdata(client, fuelgauge); fuelgauge->psy_fg.name = "sec-fuelgauge"; fuelgauge->psy_fg.type = POWER_SUPPLY_TYPE_UNKNOWN; fuelgauge->psy_fg.get_property = sec_fg_get_property; fuelgauge->psy_fg.set_property = sec_fg_set_property; fuelgauge->psy_fg.properties = sec_fuelgauge_props; fuelgauge->psy_fg.num_properties = ARRAY_SIZE(sec_fuelgauge_props); fuelgauge->capacity_max = fuelgauge->pdata->capacity_max; raw_soc_val.intval = SEC_FUELGAUGE_CAPACITY_TYPE_RAW; sec_hal_fg_get_property(fuelgauge->client, POWER_SUPPLY_PROP_CAPACITY, &raw_soc_val); raw_soc_val.intval /= 10; fuelgauge->is_reset = false; if(raw_soc_val.intval > fuelgauge->pdata->capacity_max) sec_fg_calculate_dynamic_scale(fuelgauge); if (!fuelgauge->pdata->fg_gpio_init()) { dev_err(&client->dev, "%s: Failed to Initialize GPIO\n", __func__); goto err_free; } if (!sec_hal_fg_init(fuelgauge->client)) { dev_err(&client->dev, "%s: Failed to Initialize Fuelgauge\n", __func__); goto err_free; } ret = power_supply_register(&client->dev, &fuelgauge->psy_fg); if (ret) { dev_err(&client->dev, "%s: Failed to Register psy_fg\n", __func__); goto err_free; } if (fuelgauge->pdata->fg_irq) { INIT_DEFERRABLE_WORK( &fuelgauge->isr_work, sec_fg_isr_work); ret = request_threaded_irq(fuelgauge->pdata->fg_irq, NULL, sec_fg_irq_thread, fuelgauge->pdata->fg_irq_attr | IRQF_ONESHOT, "fuelgauge-irq", fuelgauge); if (ret) { dev_err(&client->dev, "%s: Failed to Reqeust IRQ\n", __func__); goto err_supply_unreg; } ret = enable_irq_wake(fuelgauge->pdata->fg_irq); if (ret < 0) dev_err(&client->dev, "%s: Failed to Enable Wakeup Source(%d)\n", __func__, ret); } fuelgauge->is_fuel_alerted = false; if (fuelgauge->pdata->fuel_alert_soc >= 0) { if (sec_hal_fg_fuelalert_init(fuelgauge->client, fuelgauge->pdata->fuel_alert_soc)) wake_lock_init(&fuelgauge->fuel_alert_wake_lock, WAKE_LOCK_SUSPEND, "fuel_alerted"); else { dev_err(&client->dev, "%s: Failed to Initialize Fuel-alert\n", __func__); goto err_irq; } } fuelgauge->initial_update_of_soc = true; ret = sec_fg_create_attrs(fuelgauge->psy_fg.dev); if (ret) { dev_err(&client->dev, "%s : Failed to create_attrs\n", __func__); goto err_irq; } pr_info("%s: fg_irq: %d, capacity_max: %d, " "cpacity_max_margin: %d, capacity_min: %d," "calculation_type: 0x%x, fuel_alert_soc: %d,\n" "repeated_fuelalert: %d, RCOMP0: 0x%x," "RCOMP_charging: 0x%x, temp_cohot: %d," "temp_cocold: %d, is_using_model_data: %d," "type_str: %s,\n", __func__, fuelgauge->pdata->fg_irq, fuelgauge->pdata->capacity_max, fuelgauge->pdata->capacity_max_margin, fuelgauge->pdata->capacity_min, fuelgauge->pdata->capacity_calculation_type, fuelgauge->pdata->fuel_alert_soc, fuelgauge->pdata->repeated_fuelalert, get_battery_data(fuelgauge).RCOMP0, get_battery_data(fuelgauge).RCOMP_charging, get_battery_data(fuelgauge).temp_cohot, get_battery_data(fuelgauge).temp_cocold, get_battery_data(fuelgauge).is_using_model_data, get_battery_data(fuelgauge).type_str ); dev_dbg(&client->dev, "%s: SEC Fuelgauge Driver Loaded\n", __func__); return 0; err_irq: if (fuelgauge->pdata->fg_irq) free_irq(fuelgauge->pdata->fg_irq, fuelgauge); wake_lock_destroy(&fuelgauge->fuel_alert_wake_lock); err_supply_unreg: power_supply_unregister(&fuelgauge->psy_fg); err_free: mutex_destroy(&fuelgauge->fg_lock); kfree(fuelgauge); return ret; }
static void STBCFG01_ChargerControl(struct sec_charger_info *charger) { int IFast, ITerm, ILim, VFloat; int termination_current; int charger_en; union power_supply_propval val; pr_info("[%s]cable_type = %d\n", __func__, charger->cable_type); if (charger->cable_type == POWER_SUPPLY_TYPE_BATTERY) { gpio_direction_output(ChargerData.GPIO_cd, 1); } else { if((charger->cable_type == POWER_SUPPLY_TYPE_MAINS) || (charger->cable_type == POWER_SUPPLY_TYPE_USB)) { psy_do_property("battery", get, POWER_SUPPLY_PROP_CHARGE_NOW, val); if (val.intval == SEC_BATTERY_CHARGING_1ST) { termination_current = charger->pdata->charging_current[ charger->cable_type].full_check_current_1st; } else if (val.intval == SEC_BATTERY_CHARGING_2ND) { termination_current = charger->pdata->charging_current[ charger->cable_type].full_check_current_2nd; } pr_info("[%s]charging_mode = %d\n", __func__, val.intval); IFast = STBCFG01_get_fast_current_limit_data( charger->pdata->charging_current[ charger->cable_type].fast_charging_current); ITerm = STBCFG01_get_termination_current_limit_data( termination_current, val); ChargerData.Cfg1 = (IFast & 0x07) | ((get_battery_data(charger).IPre & 0x01) <<3) | ((ITerm & 0x0F) << 4); VFloat = STBCFG01_get_float_voltage_data( charger->pdata->chg_float_voltage); ChargerData.Cfg2 = (VFloat & 0x3F) | ((get_battery_data(charger).ARChg & 0x01) << 6) & 0x7F; ILim = STBCFG01_get_input_current_limit_data( charger->pdata->charging_current[ charger->cable_type].input_current_limit); ChargerData.Cfg3 = (ILim & 0x07) | ((get_battery_data(charger).DICL_en & 0x01) << 3) | ((get_battery_data(charger).VDICL & 0x03) << 4) | ((get_battery_data(charger).IBat_lim & 0x03) << 6); ChargerData.Cfg4 = (get_battery_data(charger).TPre & 0x01) | ((get_battery_data(charger).TFast & 0x01) << 1) | (0x01 << 2) | ((get_battery_data(charger).PreB_en & 0x01) << 3) | ((get_battery_data(charger).LDO_UVLO_th & 0x01) << 5) | ((get_battery_data(charger).LDO_en & 0x01) << 6) | ((get_battery_data(charger).WD & 0x01) << 7); ChargerData.Cfg5 = ((get_battery_data(charger).FSW & 0x01) << 1) | ((get_battery_data(charger).DIChg_adj & 0x01) << 2); // STBCFG01_BatChg_Start(charger->client); STBCFG01_WriteChargerCnfData(charger->client, &ChargerData); STBCFG01_ReadChargerData(charger->client, &ChargerData); gpio_direction_output(ChargerData.GPIO_cd, 0); } } #ifdef STBCFG01_DEBUG_MESSAGES_EXTRA_REGISTERS printk(" Cfg1=%x, Cfg2=%x, Cfg3=%x, Cfg4=%x, Cfg5=%x, Sts1=%x, Sts2=%x, Ien1=%x, Ien2=%x\n", ChargerData.Cfg1, ChargerData.Cfg2, ChargerData.Cfg3, ChargerData.Cfg4, ChargerData.Cfg5, ChargerData.Status1, ChargerData.Status2, ChargerData.IntEn1, ChargerData.IntEn2); #endif }
bool sec_hal_chg_init(struct sec_charger_info *charger) { int ret; /* init battery charger data structure */ if (charger->pdata->battery_data) { ChargerData.GPIO_cd = get_battery_data(charger).GPIO_cd; ChargerData.GPIO_shdn = get_battery_data(charger).GPIO_shdn; } else { ChargerData.GPIO_cd = 0; ChargerData.GPIO_shdn = 0; } if (ChargerData.GPIO_cd) { ret = gpio_request(ChargerData.GPIO_cd, "stbcfg01_cd_pin"); if (ret) { dev_err(&charger->client->dev, "STBCFG01 : Unable to get cd pin %d\n", ChargerData.GPIO_cd); return (ret); } } else { printk("STBCFG01 : CD pin not assigned in platformdata, will not be used\n"); } ChargerData.Cfg1 = (get_battery_data(charger).IFast & 0x07) | ((get_battery_data(charger).IPre & 0x01) <<3) | ((get_battery_data(charger).ITerm & 0x0F) << 4); ChargerData.Cfg2 = (get_battery_data(charger).VFloat & 0x3F) | ((get_battery_data(charger).ARChg & 0x01) << 6) & 0x7F; ChargerData.Cfg3 = (get_battery_data(charger).Iin_lim & 0x07) | ((get_battery_data(charger).DICL_en & 0x01) << 3) | ((get_battery_data(charger).VDICL & 0x03) << 4) | ((get_battery_data(charger).IBat_lim & 0x03) << 6); ChargerData.Cfg4 = (get_battery_data(charger).TPre & 0x01) | ((get_battery_data(charger).TFast & 0x01) << 1) | (0x01 << 2) | ((get_battery_data(charger).PreB_en & 0x01) << 3) | ((get_battery_data(charger).LDO_UVLO_th & 0x01) << 5) | ((get_battery_data(charger).LDO_en & 0x01) << 6) | ((get_battery_data(charger).WD & 0x01) << 7); ChargerData.Cfg5 = ((get_battery_data(charger).FSW & 0x01) << 1) | ((get_battery_data(charger).DIChg_adj & 0x01) << 2); STBCFG01_BatChg_Start(charger->client); #ifdef STBCFG01_DEBUG_MESSAGES_EXTRA_REGISTERS printk(" Cfg1=%x, Cfg2=%x, Cfg3=%x, Cfg4=%x, Cfg5=%x, Sts1=%x, Sts2=%x, Ien1=%x, Ien2=%x\n", ChargerData.Cfg1, ChargerData.Cfg2, ChargerData.Cfg3, ChargerData.Cfg4, ChargerData.Cfg5, ChargerData.Status1, ChargerData.Status2, ChargerData.IntEn1, ChargerData.IntEn2); #endif return true; }
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; }
static int fuelgauge_parse_dt(struct device *dev, struct sec_fuelgauge_info *fuelgauge) { struct device_node *np = dev->of_node; sec_battery_platform_data_t *pdata = fuelgauge->pdata; /* reset, irq gpio info */ if (np == NULL) pr_err("%s np NULL\n", __func__); else { int ret; ret = pdata->fg_irq = of_get_named_gpio(np, "fuelgauge,fuel_int", 0); if (ret < 0) pr_err("%s error reading fg_irq = %d\n", __func__, pdata->fg_irq); #if defined(CONFIG_FUELGAUGE_MAX17050) ret = of_property_read_u32(np, "fuelgauge,jig_gpio", &pdata->jig_irq); if (ret < 0) pr_err("%s error reading jig_gpio %d\n", __func__, ret); ret = of_get_named_gpio(np, "fuelgauge,bat_int", 0); ta_int_gpio = ret; sec_battery_pdata.bat_irq = gpio_to_irq(ret); if (ret < 0) pr_err("%s error reading bat_int = %d\n", __func__, ret); pr_err("%s: ta_int_gpio(%d), bat_irq(%d)\n", __func__, ret, sec_battery_pdata.bat_irq); pr_info("%s fg_irq: %d, jig_irq: %d, capacity_max: %d, " "cpacity_max_margin: %d, capacity_min: %d, " "calculation_type: 0x%x, fuel_alert_soc: %d,\n" "repeated_fuelalert: %d, Capacity: 0x%x, " "low_battery_comp_voltage: 0x%x, " "type_str: %s\n", __func__, pdata->fg_irq, pdata->jig_irq, pdata->capacity_max, pdata->capacity_max_margin, pdata->capacity_min, pdata->capacity_calculation_type, pdata->fuel_alert_soc, pdata->repeated_fuelalert, get_battery_data(fuelgauge).Capacity, get_battery_data(fuelgauge).low_battery_comp_voltage, get_battery_data(fuelgauge).type_str ); #else ret = of_get_named_gpio(np, "fuelgauge,bat_int", 0); if (ret > 0) { sec_battery_pdata.bat_irq_gpio = ret; sec_battery_pdata.bat_irq = gpio_to_irq(ret); pr_info("%s reading bat_int_gpio = %d\n", __func__, ret); } pr_info("%s: fg_irq: %d, capacity_max: %d, " "cpacity_max_margin: %d, capacity_min: %d," "calculation_type: 0x%x, fuel_alert_soc: %d,\n" "repeated_fuelalert: %d, RCOMP0: 0x%x," "RCOMP_charging: 0x%x, temp_cohot: %d," "temp_cocold: %d, is_using_model_data: %d," "type_str: %s,\n", __func__, pdata->fg_irq, pdata->capacity_max, pdata->capacity_max_margin, pdata->capacity_min, pdata->capacity_calculation_type, pdata->fuel_alert_soc, pdata->repeated_fuelalert, get_battery_data(fuelgauge).RCOMP0, get_battery_data(fuelgauge).RCOMP_charging, get_battery_data(fuelgauge).temp_cohot, get_battery_data(fuelgauge).temp_cocold, get_battery_data(fuelgauge).is_using_model_data, get_battery_data(fuelgauge).type_str ); #endif } return 0; }