static void android_bat_charge_source_changed(struct android_bat_callbacks *ptr,
					      int charge_source)
{
	struct android_bat_data *battery =
		container_of(ptr, struct android_bat_data, callbacks);

	wake_lock(&battery->charger_wake_lock);
	mutex_lock(&android_bat_state_lock);
	battery->charge_source = charge_source;

	pr_info("battery: charge source type was changed: %s\n",
		charge_source_str(battery->charge_source));

	switch (battery->charge_source) {
	case CHARGE_SOURCE_NONE:
		slide2wake_change(10);
		break;
	case CHARGE_SOURCE_USB:
		slide2wake_change(11);
		break;
	case CHARGE_SOURCE_AC:
		slide2wake_change(11);
		break;
	}

	mutex_unlock(&android_bat_state_lock);
	queue_work(battery->monitor_wqueue, &battery->charger_work);
}
static int android_bat_enable_charging(struct android_bat_data *battery,
				       bool enable)
{
	if (enable && (battery->batt_health != POWER_SUPPLY_HEALTH_GOOD)) {
		battery->charging_status =
		    POWER_SUPPLY_STATUS_NOT_CHARGING;
		return -EPERM;
	}

	if (enable) {
		if (battery->pdata && battery->pdata->set_charging_current)
			battery->pdata->set_charging_current
			(battery->charge_source);
	}

	if (battery->pdata && battery->pdata->set_charging_enable)
		battery->pdata->set_charging_enable(enable);

	android_bat_set_charge_time(battery, enable);
	pr_info("battery: enable=%d charger: %s\n", enable,
		charge_source_str(battery->charge_source));

	switch (battery->charge_source) {
	case CHARGE_SOURCE_USB:
		slide2wake_change(11);
		break;
	case CHARGE_SOURCE_AC:
		slide2wake_change(11);
		break;
	}
		
	return 0;
}
static void android_bat_charge_source_changed(struct android_bat_callbacks *ptr,
					      int charge_source)
{
	struct android_bat_data *battery =
		container_of(ptr, struct android_bat_data, callbacks);

	wake_lock(&battery->charger_wake_lock);
	mutex_lock(&android_bat_state_lock);
	battery->charge_source = charge_source;

	pr_info("battery: charge source type was changed: %s\n",
		charge_source_str(battery->charge_source));

	mutex_unlock(&android_bat_state_lock);
	queue_work(battery->monitor_wqueue, &battery->charger_work);
}
static int android_power_debug_dump(struct seq_file *s, void *unused)
{
	struct android_bat_data *battery = s->private;
	struct timespec cur_time;

	android_bat_update_data(battery);
	get_monotonic_boottime(&cur_time);
	mutex_lock(&android_bat_state_lock);
	seq_printf(s, "l=%d v=%d c=%d temp=%s%ld.%ld h=%d st=%d%s ct=%lu type=%s\n",
		   battery->batt_soc, battery->batt_vcell/1000,
		   battery->batt_current, battery->batt_temp < 0 ? "-" : "",
		   abs(battery->batt_temp / 10), abs(battery->batt_temp % 10),
		   battery->batt_health, battery->charging_status,
		   battery->recharging ? "r" : "",
		   battery->charging_start_time ?
		   cur_time.tv_sec - battery->charging_start_time : 0,
		   charge_source_str(battery->charge_source));
	mutex_unlock(&android_bat_state_lock);
	return 0;
}
static void android_bat_monitor_work(struct work_struct *work)
{
	struct android_bat_data *battery =
		container_of(work, struct android_bat_data, monitor_work);
	struct timespec cur_time;

	wake_lock(&battery->monitor_wake_lock);
	android_bat_update_data(battery);
	mutex_lock(&android_bat_state_lock);

	switch (battery->charging_status) {
	case POWER_SUPPLY_STATUS_FULL:
		if (battery->batt_vcell < battery->pdata->recharging_voltage &&
		    !battery->recharging) {
			battery->recharging = true;
			android_bat_enable_charging(battery, true);
			pr_info("battery: start recharging, v=%d\n",
				battery->batt_vcell/1000);
		}
		break;
	case POWER_SUPPLY_STATUS_DISCHARGING:
		break;
	case POWER_SUPPLY_STATUS_CHARGING:
		switch (battery->batt_health) {
		case POWER_SUPPLY_HEALTH_OVERHEAT:
		case POWER_SUPPLY_HEALTH_COLD:
		case POWER_SUPPLY_HEALTH_OVERVOLTAGE:
		case POWER_SUPPLY_HEALTH_DEAD:
		case POWER_SUPPLY_HEALTH_UNSPEC_FAILURE:
			battery->charging_status =
				POWER_SUPPLY_STATUS_NOT_CHARGING;
			android_bat_enable_charging(battery, false);

			pr_info("battery: Not charging, health=%d\n",
				battery->batt_health);
			break;
		default:
			break;
		}
		break;
	case POWER_SUPPLY_STATUS_NOT_CHARGING:
		if (battery->batt_health == POWER_SUPPLY_HEALTH_GOOD) {
			pr_info("battery: battery health recovered\n");
			if (battery->charge_source != CHARGE_SOURCE_NONE) {
				android_bat_enable_charging(battery, true);
				battery->charging_status
					= POWER_SUPPLY_STATUS_CHARGING;
			} else {
				battery->charging_status
					= POWER_SUPPLY_STATUS_DISCHARGING;
			}
		}
		break;
	default:
		pr_err("%s: Undefined battery status: %d\n", __func__,
		       battery->charging_status);
		break;
	}

	android_bat_charging_timer(battery);
	get_monotonic_boottime(&cur_time);
	pr_info("battery: l=%d v=%d c=%d temp=%s%ld.%ld h=%d st=%d%s ct=%lu type=%s\n",
		battery->batt_soc, battery->batt_vcell/1000,
		battery->batt_current, battery->batt_temp < 0 ? "-" : "",
		abs(battery->batt_temp / 10), abs(battery->batt_temp % 10),
		battery->batt_health, battery->charging_status,
		   battery->recharging ? "r" : "",
		   battery->charging_start_time ?
		   cur_time.tv_sec - battery->charging_start_time : 0,
		charge_source_str(battery->charge_source));
	mutex_unlock(&android_bat_state_lock);
	power_supply_changed(&battery->psy_bat);
	battery->last_poll = ktime_get_boottime();
	android_bat_monitor_set_alarm(battery, FAST_POLL);
	wake_unlock(&battery->monitor_wake_lock);
	return;
}