static void battery_set_batt_id_param(struct battery_type * battery, struct poweralg_type* poweralg_ptr, int batt_id) { UINT32* fl_25; /* set new battery param depend on new batt id*/ battery->id_index = batt_id; if (NULL != (fl_25 = poweralg_ptr->pdata->batt_param->fl_25)) battery->charge_full_design_mAh = fl_25[battery->id_index]; else battery->charge_full_design_mAh = DS2746_FULL_CAPACITY_DEFAULT; battery->charge_full_real_mAh = battery->charge_full_design_mAh; if (NULL != poweralg_ptr->pdata->batt_param->m_param_tbl) { battery->dead_voltage_mV = get_dead_battery_voltage( poweralg_ptr->pdata->batt_param->m_param_tbl, battery->id_index); } else battery->dead_voltage_mV = BATTERY_DEAD_VOLTAGE_DEFAULT; printk(DRIVER_ZONE " assign dead battery voltage = %d.\n",battery->dead_voltage_mV); }
static void battery_id_detection(struct battery_type *battery) { INT32 batt_id_index; /*static int batt_id_stable_counter;*/ static int batt_id_unknown_stable_count = -1; struct poweralg_type* poweralg_ptr = container_of(battery, struct poweralg_type, battery); int r2_kOhm = 300; if (poweralg_ptr->pdata && poweralg_ptr->pdata->r2_kohm) r2_kOhm = poweralg_ptr->pdata->r2_kohm; battery->id_ohm = ((1000000*r2_kOhm) / ((1000000*2047)/battery->id_adc - (1000000*1))) * 1000; calibrate_id_ohm(battery); batt_id_index = get_id_index(battery); printk(DRIVER_ZONE "battery.id_ohm=%d, battery.id_index=%d, batt_id_index=%d, st_counter=%d\n",battery->id_ohm, battery->id_index, batt_id_index, batt_id_unknown_stable_count); if (-1 == batt_id_unknown_stable_count) { /* initial state, no matter what id we detected must set */ battery_set_batt_id_param(battery, poweralg_ptr, batt_id_index); batt_id_unknown_stable_count = 0; } else if ((batt_id_index != battery->id_index) && is_allow_batt_id_change) { if ((BATTERY_ID_UNKNOWN == batt_id_index) && (batt_id_unknown_stable_count < 2)) { batt_id_unknown_stable_count++; // do not switch to BATTERY_UNKNOWN state before it stable return; } battery_set_batt_id_param(battery, poweralg_ptr, batt_id_index); batt_id_unknown_stable_count = 0; } else { batt_id_unknown_stable_count = 0; } #if 0 if (is_allow_batt_id_change) { /*! TODO: batt_id changes immediately; may need to modify in future*/ if (batt_id_stable_counter >= 3 && batt_id_index != battery->id_index) { /* if batt_id is stable but is different from previous one*/ batt_id_stable_counter = 0; /* reset stable counter and set batt_id to new one*/ } } if (batt_id_stable_counter < 3) { if (batt_id_stable_counter == 0) { UINT32* fl_25; /* first time to get the batt id*/ battery->id_index = batt_id_index; if (NULL != (fl_25 = poweralg_ptr->pdata->batt_param->fl_25)) battery->charge_full_design_mAh = fl_25[battery->id_index]; else battery->charge_full_design_mAh = DS2746_FULL_CAPACITY_DEFAULT; battery->charge_full_real_mAh = battery->charge_full_design_mAh; if (NULL != poweralg_ptr->pdata->batt_param->m_param_tbl) { battery->dead_voltage_mV = get_dead_battery_voltage( poweralg_ptr->pdata->batt_param->m_param_tbl, batt_id_index); } else battery->dead_voltage_mV = BATTERY_DEAD_VOLTAGE_DEFAULT; printk(DRIVER_ZONE " assign dead battery voltage = %d.\n",battery->dead_voltage_mV); batt_id_stable_counter = 1; } else { /* 2nd and further time to get the batt id*/ if (batt_id_index == battery->id_index) batt_id_stable_counter++; else batt_id_stable_counter = 0; } } #endif }
static int ds2746_battery_probe(struct platform_device *pdev) { int rc; struct ds2746_device_info *di; ds2746_platform_data *pdata = pdev->dev.platform_data; // MATT: wait to remove pr_info("[BATT] %s: start\n", __func__); poweralg.pdata = pdev->dev.platform_data; poweralg.battery.thermal_id = pdata->func_get_thermal_id(); /* if func_get_battery_id is Null or it returns negative value => we need id detection */ if ((pdata->func_get_battery_id != NULL) && (0 < pdata->func_get_battery_id())) { poweralg.battery.id_index = pdata->func_get_battery_id(); if (NULL != poweralg.pdata->batt_param->fl_25) { poweralg.battery.charge_full_design_mAh = poweralg.pdata->batt_param->fl_25[poweralg.battery.id_index]; } else poweralg.battery.charge_full_design_mAh = DS2746_FULL_CAPACITY_DEFAULT; poweralg.battery.charge_full_real_mAh = poweralg.battery.charge_full_design_mAh; if (NULL != poweralg.pdata->batt_param->m_param_tbl) { poweralg.battery.dead_voltage_mV = get_dead_battery_voltage( poweralg.pdata->batt_param->m_param_tbl, poweralg.battery.id_index); } else poweralg.battery.dead_voltage_mV = BATTERY_DEAD_VOLTAGE_DEFAULT; is_need_battery_id_detection = FALSE; } else { poweralg.battery.id_index = BATTERY_ID_UNKNOWN; poweralg.battery.dead_voltage_mV = BATTERY_DEAD_VOLTAGE_DEFAULT; is_need_battery_id_detection = TRUE; } power_alg_preinit(); power_alg_init(&debug_config); // must set func hook after power_alg_init(). poweralg.protect_flags.func_update_charging_protect_flag = pdata->func_update_charging_protect_flag; di = kzalloc(sizeof(*di), GFP_KERNEL); if (!di){ rc = -ENOMEM; goto fail_register; } di->update_time = jiffies; platform_set_drvdata(pdev, di); di->dev = &pdev->dev; INIT_WORK(&di->monitor_work, ds2746_battery_work); di->monitor_wqueue = create_singlethread_workqueue(dev_name(&pdev->dev)); /* init to something sane */ di->last_poll = alarm_get_elapsed_realtime(); if (!di->monitor_wqueue){ rc = -ESRCH; goto fail_workqueue; } wake_lock_init(&di->work_wake_lock, WAKE_LOCK_SUSPEND, "ds2746-battery"); alarm_init(&di->alarm, ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, ds2746_battery_alarm); wake_lock(&di->work_wake_lock); queue_work(di->monitor_wqueue, &di->monitor_work); g_di_ptr = di; /* save di to global */ return 0; fail_workqueue : fail_register : kfree(di); return rc; }