/*
 * Copyright 2012 ST Ericsson.
 *
 * Power supply driver for ST Ericsson pm2xxx_charger charger
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/completion.h>
#include <linux/regulator/consumer.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/workqueue.h>
#include <linux/kobject.h>
#include <linux/mfd/abx500.h>
#include <linux/mfd/abx500/ab8500.h>
#include <linux/mfd/abx500/ab8500-bm.h>
#include <linux/mfd/abx500/ab8500-gpadc.h>
#include <linux/mfd/abx500/ux500_chargalg.h>
#include <linux/pm2301_charger.h>
#include <linux/gpio.h>

#include "pm2301_charger.h"

#define to_pm2xxx_charger_ac_device_info(x) container_of((x), \
		struct pm2xxx_charger, ac_chg)
#define SLEEP_MIN		50
#define SLEEP_MAX		100

static int pm2xxx_interrupt_registers[] = {
	PM2XXX_REG_INT1,
	PM2XXX_REG_INT2,
	PM2XXX_REG_INT3,
	PM2XXX_REG_INT4,
	PM2XXX_REG_INT5,
	PM2XXX_REG_INT6,
};

static enum power_supply_property pm2xxx_charger_ac_props[] = {
	POWER_SUPPLY_PROP_HEALTH,
	POWER_SUPPLY_PROP_PRESENT,
	POWER_SUPPLY_PROP_ONLINE,
	POWER_SUPPLY_PROP_VOLTAGE_AVG,
};

static int pm2xxx_charger_voltage_map[] = {
	3500,
	3525,
	3550,
	3575,
	3600,
	3625,
	3650,
	3675,
	3700,
	3725,
	3750,
	3775,
	3800,
	3825,
	3850,
	3875,
	3900,
	3925,
	3950,
	3975,
	4000,
	4025,
	4050,
	4075,
	4100,
	4125,
	4150,
	4175,
	4200,
	4225,
	4250,
	4275,
	4300,
};

static int pm2xxx_charger_current_map[] = {
	200,
	200,
	400,
	600,
	800,
	1000,
	1200,
	1400,
	1600,
	1800,
	2000,
	2200,
	2400,
	2600,
	2800,
	3000,
};

static const struct i2c_device_id pm2xxx_ident[] = {
	{ "pm2301", 0 },
	{ }
};

static void set_lpn_pin(struct pm2xxx_charger *pm2)
{
	gpio_set_value(pm2->lpn_pin, 1);
	usleep_range(SLEEP_MIN, SLEEP_MAX);

	return;
}

static void clear_lpn_pin(struct pm2xxx_charger *pm2)
{
	gpio_set_value(pm2->lpn_pin, 0);

	return;
}

static int pm2xxx_reg_read(struct pm2xxx_charger *pm2, int reg, u8 *val)
{
	int ret;
	/*
	 * When AC adaptor is unplugged, the host
	 * must put LPN high to be able to
	 * communicate by I2C with PM2301
	 * and receive I2C "acknowledge" from PM2301.
	 */
	mutex_lock(&pm2->lock);

	ret = i2c_smbus_read_i2c_block_data(pm2->config.pm2xxx_i2c, reg,
				1, val);
	if (ret < 0)
		dev_err(pm2->dev, "Error reading register at 0x%x\n", reg);
	else
		ret = 0;
	mutex_unlock(&pm2->lock);

	return ret;
}

static int pm2xxx_reg_write(struct pm2xxx_charger *pm2, int reg, u8 val)
{
	int ret;
	/*
	 * When AC adaptor is unplugged, the host
	 * must put LPN high to be able to
	 * communicate by I2C with PM2301
	 * and receive I2C "acknowledge" from PM2301.
	 */
	mutex_lock(&pm2->lock);

	ret = i2c_smbus_write_i2c_block_data(pm2->config.pm2xxx_i2c, reg,
				1, &val);
	if (ret < 0)
		dev_err(pm2->dev, "Error writing register at 0x%x\n", reg);
	else
		ret = 0;
	mutex_unlock(&pm2->lock);

	return ret;
}

static int pm2xxx_charging_enable_mngt(struct pm2xxx_charger *pm2)
{
	int ret;

	/* Enable charging */
	ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG2,
			(PM2XXX_CH_AUTO_RESUME_EN | PM2XXX_CHARGER_ENA));

	return ret;
}

static int pm2xxx_charging_disable_mngt(struct pm2xxx_charger *pm2)
{
	int ret;

	/* Disable SW EOC ctrl */
	ret = pm2xxx_reg_write(pm2, PM2XXX_SW_CTRL_REG, PM2XXX_SWCTRL_HW);
	if (ret < 0) {
		dev_err(pm2->dev, "%s pm2xxx write failed\n", __func__);
		return ret;
	}

	/* Disable charging */
	ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG2,
			(PM2XXX_CH_AUTO_RESUME_DIS | PM2XXX_CHARGER_DIS));
	if (ret < 0) {
		dev_err(pm2->dev, "%s pm2xxx write failed\n", __func__);
		return ret;
	}

	return 0;
}

static int pm2xxx_charger_batt_therm_mngt(struct pm2xxx_charger *pm2, int val)
{
	queue_work(pm2->charger_wq, &pm2->check_main_thermal_prot_work);

	return 0;
}


int pm2xxx_charger_die_therm_mngt(struct pm2xxx_charger *pm2, int val)
{
	queue_work(pm2->charger_wq, &pm2->check_main_thermal_prot_work);

	return 0;
}

static int pm2xxx_charger_ovv_mngt(struct pm2xxx_charger *pm2, int val)
{
	dev_err(pm2->dev, "Overvoltage detected\n");
	pm2->flags.ovv = true;
	power_supply_changed(&pm2->ac_chg.psy);

	/* Schedule a new HW failure check */
	queue_delayed_work(pm2->charger_wq, &pm2->check_hw_failure_work, 0);

	return 0;
}

static int pm2xxx_charger_wd_exp_mngt(struct pm2xxx_charger *pm2, int val)
{
	dev_dbg(pm2->dev , "20 minutes watchdog occured\n");

	pm2->ac.wd_expired = true;
	power_supply_changed(&pm2->ac_chg.psy);

	return 0;
}

static int pm2xxx_charger_vbat_lsig_mngt(struct pm2xxx_charger *pm2, int val)
{
	int ret;

	switch (val) {
	case PM2XXX_INT1_ITVBATLOWR:
		dev_dbg(pm2->dev, "VBAT grows above VBAT_LOW level\n");
		/* Enable SW EOC ctrl */
		ret = pm2xxx_reg_write(pm2, PM2XXX_SW_CTRL_REG,
							PM2XXX_SWCTRL_SW);
		if (ret < 0) {
			dev_err(pm2->dev, "%s pm2xxx write failed\n", __func__);
			return ret;
		}
		break;

	case PM2XXX_INT1_ITVBATLOWF:
		dev_dbg(pm2->dev, "VBAT drops below VBAT_LOW level\n");
		/* Disable SW EOC ctrl */
		ret = pm2xxx_reg_write(pm2, PM2XXX_SW_CTRL_REG,
							PM2XXX_SWCTRL_HW);
		if (ret < 0) {
			dev_err(pm2->dev, "%s pm2xxx write failed\n", __func__);
			return ret;
		}
		break;

	default:
		dev_err(pm2->dev, "Unknown VBAT level\n");
	}

	return 0;
}

static int pm2xxx_charger_bat_disc_mngt(struct pm2xxx_charger *pm2, int val)
{
	dev_dbg(pm2->dev, "battery disconnected\n");

	return 0;
}

static int pm2xxx_charger_detection(struct pm2xxx_charger *pm2, u8 *val)
{
	int ret;

	ret = pm2xxx_reg_read(pm2, PM2XXX_SRCE_REG_INT2, val);

	if (ret < 0) {
		dev_err(pm2->dev, "Charger detection failed\n");
		goto out;
	}

	*val &= (PM2XXX_INT2_S_ITVPWR1PLUG | PM2XXX_INT2_S_ITVPWR2PLUG);

out:
	return ret;
}

static int pm2xxx_charger_itv_pwr_plug_mngt(struct pm2xxx_charger *pm2, int val)
{

	int ret;
	u8 read_val;

	/*
	 * Since we can't be sure that the events are received
	 * synchronously, we have the check if the main charger is
	 * connected by reading the interrupt source register.
	 */
	ret = pm2xxx_charger_detection(pm2, &read_val);

	if ((ret == 0) && read_val) {
		pm2->ac.charger_connected = 1;
		pm2->ac_conn = true;
		queue_work(pm2->charger_wq, &pm2->ac_work);
	}


	return ret;
}

static int pm2xxx_charger_itv_pwr_unplug_mngt(struct pm2xxx_charger *pm2,
								int val)
{
	pm2->ac.charger_connected = 0;
	queue_work(pm2->charger_wq, &pm2->ac_work);

	return 0;
}

static int pm2_int_reg0(void *pm2_data, int val)
{
	struct pm2xxx_charger *pm2 = pm2_data;
	int ret = 0;

	if (val & PM2XXX_INT1_ITVBATLOWR) {
		ret = pm2xxx_charger_vbat_lsig_mngt(pm2,
						PM2XXX_INT1_ITVBATLOWR);
		if (ret < 0)
			goto out;
	}

	if (val & PM2XXX_INT1_ITVBATLOWF) {
		ret = pm2xxx_charger_vbat_lsig_mngt(pm2,
						PM2XXX_INT1_ITVBATLOWF);
		if (ret < 0)
			goto out;
	}

	if (val & PM2XXX_INT1_ITVBATDISCONNECT) {
		ret = pm2xxx_charger_bat_disc_mngt(pm2,
				PM2XXX_INT1_ITVBATDISCONNECT);
		if (ret < 0)
			goto out;
	}
out:
	return ret;
}

static int pm2_int_reg1(void *pm2_data, int val)
{
	struct pm2xxx_charger *pm2 = pm2_data;
	int ret = 0;

	if (val & (PM2XXX_INT2_ITVPWR1PLUG | PM2XXX_INT2_ITVPWR2PLUG)) {
		dev_dbg(pm2->dev , "Main charger plugged\n");
		ret = pm2xxx_charger_itv_pwr_plug_mngt(pm2, val &
			(PM2XXX_INT2_ITVPWR1PLUG | PM2XXX_INT2_ITVPWR2PLUG));
	}

	if (val &
		(PM2XXX_INT2_ITVPWR1UNPLUG | PM2XXX_INT2_ITVPWR2UNPLUG)) {
		dev_dbg(pm2->dev , "Main charger unplugged\n");
		ret = pm2xxx_charger_itv_pwr_unplug_mngt(pm2, val &
						(PM2XXX_INT2_ITVPWR1UNPLUG |
						PM2XXX_INT2_ITVPWR2UNPLUG));
	}

	return ret;
}

static int pm2_int_reg2(void *pm2_data, int val)
{
	struct pm2xxx_charger *pm2 = pm2_data;
	int ret = 0;

	if (val & PM2XXX_INT3_ITAUTOTIMEOUTWD)
		ret = pm2xxx_charger_wd_exp_mngt(pm2, val);

	if (val & (PM2XXX_INT3_ITCHPRECHARGEWD |
				PM2XXX_INT3_ITCHCCWD | PM2XXX_INT3_ITCHCVWD)) {
		dev_dbg(pm2->dev,
			"Watchdog occured for precharge, CC and CV charge\n");
	}

	return ret;
}

static int pm2_int_reg3(void *pm2_data, int val)
{
	struct pm2xxx_charger *pm2 = pm2_data;
	int ret = 0;

	if (val & (PM2XXX_INT4_ITCHARGINGON)) {
		dev_dbg(pm2->dev ,
			"chargind operation has started\n");
	}

	if (val & (PM2XXX_INT4_ITVRESUME)) {
		dev_dbg(pm2->dev,
			"battery discharged down to VResume threshold\n");
	}

	if (val & (PM2XXX_INT4_ITBATTFULL)) {
		dev_dbg(pm2->dev , "battery fully detected\n");
	}

	if (val & (PM2XXX_INT4_ITCVPHASE)) {
		dev_dbg(pm2->dev, "CV phase enter with 0.5C charging\n");
	}

	if (val & (PM2XXX_INT4_ITVPWR2OVV | PM2XXX_INT4_ITVPWR1OVV)) {
		pm2->failure_case = VPWR_OVV;
		ret = pm2xxx_charger_ovv_mngt(pm2, val &
			(PM2XXX_INT4_ITVPWR2OVV | PM2XXX_INT4_ITVPWR1OVV));
		dev_dbg(pm2->dev, "VPWR/VSYSTEM overvoltage detected\n");
	}

	if (val & (PM2XXX_INT4_S_ITBATTEMPCOLD |
				PM2XXX_INT4_S_ITBATTEMPHOT)) {
		ret = pm2xxx_charger_batt_therm_mngt(pm2, val &
			(PM2XXX_INT4_S_ITBATTEMPCOLD |
			PM2XXX_INT4_S_ITBATTEMPHOT));
		dev_dbg(pm2->dev, "BTEMP is too Low/High\n");
	}

	return ret;
}

static int pm2_int_reg4(void *pm2_data, int val)
{
	struct pm2xxx_charger *pm2 = pm2_data;
	int ret = 0;

	if (val & PM2XXX_INT5_ITVSYSTEMOVV) {
		pm2->failure_case = VSYSTEM_OVV;
		ret = pm2xxx_charger_ovv_mngt(pm2, val &
						PM2XXX_INT5_ITVSYSTEMOVV);
		dev_dbg(pm2->dev, "VSYSTEM overvoltage detected\n");
	}

	if (val & (PM2XXX_INT5_ITTHERMALWARNINGFALL |
				PM2XXX_INT5_ITTHERMALWARNINGRISE |
				PM2XXX_INT5_ITTHERMALSHUTDOWNFALL |
				PM2XXX_INT5_ITTHERMALSHUTDOWNRISE)) {
		dev_dbg(pm2->dev, "BTEMP die temperature is too Low/High\n");
		ret = pm2xxx_charger_die_therm_mngt(pm2, val &
			(PM2XXX_INT5_ITTHERMALWARNINGFALL |
			PM2XXX_INT5_ITTHERMALWARNINGRISE |
			PM2XXX_INT5_ITTHERMALSHUTDOWNFALL |
			PM2XXX_INT5_ITTHERMALSHUTDOWNRISE));
	}

	return ret;
}

static int pm2_int_reg5(void *pm2_data, int val)
{
	struct pm2xxx_charger *pm2 = pm2_data;
	int ret = 0;

	if (val & (PM2XXX_INT6_ITVPWR2DROP | PM2XXX_INT6_ITVPWR1DROP)) {
		dev_dbg(pm2->dev, "VMPWR drop to VBAT level\n");
	}

	if (val & (PM2XXX_INT6_ITVPWR2VALIDRISE |
			PM2XXX_INT6_ITVPWR1VALIDRISE |
			PM2XXX_INT6_ITVPWR2VALIDFALL |
			PM2XXX_INT6_ITVPWR1VALIDFALL)) {
		dev_dbg(pm2->dev, "Falling/Rising edge on WPWR1/2\n");
	}

	return ret;
}

static irqreturn_t  pm2xxx_irq_int(int irq, void *data)
{
	struct pm2xxx_charger *pm2 = data;
	struct pm2xxx_interrupts *interrupt = pm2->pm2_int;
	int i;

	do {
		for (i = 0; i < PM2XXX_NUM_INT_REG; i++) {
			pm2xxx_reg_read(pm2,
				pm2xxx_interrupt_registers[i],
				&(interrupt->reg[i]));

			if (interrupt->reg[i] > 0)
				interrupt->handler[i](pm2, interrupt->reg[i]);
		}
	} while (gpio_get_value(pm2->pdata->gpio_irq_number) == 0);

	return IRQ_HANDLED;
}

static int pm2xxx_charger_get_ac_cv(struct pm2xxx_charger *pm2)
{
	int ret = 0;
	u8 val;

	if (pm2->ac.charger_connected && pm2->ac.charger_online) {

		ret = pm2xxx_reg_read(pm2, PM2XXX_SRCE_REG_INT4, &val);
		if (ret < 0) {
			dev_err(pm2->dev, "%s pm2xxx read failed\n", __func__);
			goto out;
		}

		if (val & PM2XXX_INT4_S_ITCVPHASE)
			ret = PM2XXX_CONST_VOLT;
		else
			ret = PM2XXX_CONST_CURR;
	}
out:
	return ret;
}

static int pm2xxx_current_to_regval(int curr)
{
	int i;

	if (curr < pm2xxx_charger_current_map[0])
		return 0;

	for (i = 1; i < ARRAY_SIZE(pm2xxx_charger_current_map); i++) {
		if (curr < pm2xxx_charger_current_map[i])
			return (i - 1);
	}

	i = ARRAY_SIZE(pm2xxx_charger_current_map) - 1;
	if (curr == pm2xxx_charger_current_map[i])
		return i;
	else
		return -EINVAL;
}

static int pm2xxx_voltage_to_regval(int curr)
{
	int i;

	if (curr < pm2xxx_charger_voltage_map[0])
		return 0;

	for (i = 1; i < ARRAY_SIZE(pm2xxx_charger_voltage_map); i++) {
		if (curr < pm2xxx_charger_voltage_map[i])
			return i - 1;
	}

	i = ARRAY_SIZE(pm2xxx_charger_voltage_map) - 1;
	if (curr == pm2xxx_charger_voltage_map[i])
		return i;
	else
		return -EINVAL;
}

static int pm2xxx_charger_update_charger_current(struct ux500_charger *charger,
		int ich_out)
{
	int ret;
	int curr_index;
	struct pm2xxx_charger *pm2;
	u8 val;

	if (charger->psy.type == POWER_SUPPLY_TYPE_MAINS)
		pm2 = to_pm2xxx_charger_ac_device_info(charger);
	else
		return -ENXIO;

	curr_index = pm2xxx_current_to_regval(ich_out);
	if (curr_index < 0) {
		dev_err(pm2->dev,
			"Charger current too high, charging not started\n");
		return -ENXIO;
	}

	ret = pm2xxx_reg_read(pm2, PM2XXX_BATT_CTRL_REG6, &val);
	if (ret >= 0) {
		val &= ~PM2XXX_DIR_CH_CC_CURRENT_MASK;
		val |= curr_index;
		ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG6, val);
		if (ret < 0) {
			dev_err(pm2->dev,
				"%s write failed\n", __func__);
		}
	}
	else
		dev_err(pm2->dev, "%s read failed\n", __func__);

	return ret;
}

static int pm2xxx_charger_ac_get_property(struct power_supply *psy,
	enum power_supply_property psp,
	union power_supply_propval *val)
{
	struct pm2xxx_charger *pm2;

	pm2 = to_pm2xxx_charger_ac_device_info(psy_to_ux500_charger(psy));

	switch (psp) {
	case POWER_SUPPLY_PROP_HEALTH:
		if (pm2->flags.mainextchnotok)
			val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
		else if (pm2->ac.wd_expired)
			val->intval = POWER_SUPPLY_HEALTH_DEAD;
		else if (pm2->flags.main_thermal_prot)
			val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
		else if (pm2->flags.ovv)
			val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
		else
			val->intval = POWER_SUPPLY_HEALTH_GOOD;
		break;
	case POWER_SUPPLY_PROP_ONLINE:
		val->intval = pm2->ac.charger_online;
		break;
	case POWER_SUPPLY_PROP_PRESENT:
		val->intval = pm2->ac.charger_connected;
		break;
	case POWER_SUPPLY_PROP_VOLTAGE_AVG:
		pm2->ac.cv_active = pm2xxx_charger_get_ac_cv(pm2);
		val->intval = pm2->ac.cv_active;
		break;
	default:
		return -EINVAL;
	}
	return 0;
}

static int pm2xxx_charging_init(struct pm2xxx_charger *pm2)
{
	int ret = 0;

	/* enable CC and CV watchdog */
	ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG3,
		(PM2XXX_CH_WD_CV_PHASE_60MIN | PM2XXX_CH_WD_CC_PHASE_60MIN));
	if( ret < 0)
		return ret;

	/* enable precharge watchdog */
	ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG4,
					PM2XXX_CH_WD_PRECH_PHASE_60MIN);

	/* Disable auto timeout */
	ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG5,
					PM2XXX_CH_WD_AUTO_TIMEOUT_20MIN);

	/*
     * EOC current level = 100mA
	 * Precharge current level = 100mA
	 * CC current level = 1000mA
	 */
	ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG6,
		(PM2XXX_DIR_CH_CC_CURRENT_1000MA |
		PM2XXX_CH_PRECH_CURRENT_100MA |
		PM2XXX_CH_EOC_CURRENT_100MA));

	/*
     * recharge threshold = 3.8V
	 * Precharge to CC threshold = 2.9V
	 */
	ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG7,
		(PM2XXX_CH_PRECH_VOL_2_9 | PM2XXX_CH_VRESUME_VOL_3_8));

	/* float voltage charger level = 4.2V */
	ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG8,
		PM2XXX_CH_VOLT_4_2);

	/* Voltage drop between VBAT and VSYS in HW charging = 300mV */
	ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG9,
		(PM2XXX_CH_150MV_DROP_300MV | PM2XXX_CHARCHING_INFO_DIS |
		PM2XXX_CH_CC_REDUCED_CURRENT_IDENT |
		PM2XXX_CH_CC_MODEDROP_DIS));

	/* Input charger level of over voltage = 10V */
	ret = pm2xxx_reg_write(pm2, PM2XXX_INP_VOLT_VPWR2,
					PM2XXX_VPWR2_OVV_10);
	ret = pm2xxx_reg_write(pm2, PM2XXX_INP_VOLT_VPWR1,
					PM2XXX_VPWR1_OVV_10);

	/* Input charger drop */
	ret = pm2xxx_reg_write(pm2, PM2XXX_INP_DROP_VPWR2,
		(PM2XXX_VPWR2_HW_OPT_DIS | PM2XXX_VPWR2_VALID_DIS |
		PM2XXX_VPWR2_DROP_DIS));
	ret = pm2xxx_reg_write(pm2, PM2XXX_INP_DROP_VPWR1,
		(PM2XXX_VPWR1_HW_OPT_DIS | PM2XXX_VPWR1_VALID_DIS |
		PM2XXX_VPWR1_DROP_DIS));

	/* Disable battery low monitoring */
	ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_LOW_LEV_COMP_REG,
		PM2XXX_VBAT_LOW_MONITORING_ENA);

	/* Disable LED */
	ret = pm2xxx_reg_write(pm2, PM2XXX_LED_CTRL_REG,
		PM2XXX_LED_SELECT_DIS);

	return ret;
}

static int pm2xxx_charger_ac_en(struct ux500_charger *charger,
	int enable, int vset, int iset)
{
	int ret;
	int volt_index;
	int curr_index;
	u8 val;

	struct pm2xxx_charger *pm2 = to_pm2xxx_charger_ac_device_info(charger);

	if (enable) {
		if (!pm2->ac.charger_connected) {
			dev_dbg(pm2->dev, "AC charger not connected\n");
			return -ENXIO;
		}

		dev_dbg(pm2->dev, "Enable AC: %dmV %dmA\n", vset, iset);
		if (!pm2->vddadc_en_ac) {
			regulator_enable(pm2->regu);
			pm2->vddadc_en_ac = true;
		}

		ret = pm2xxx_charging_init(pm2);
		if (ret < 0) {
			dev_err(pm2->dev, "%s charging init failed\n",
					__func__);
			goto error_occured;
		}

		volt_index = pm2xxx_voltage_to_regval(vset);
		curr_index = pm2xxx_current_to_regval(iset);

		if (volt_index < 0 || curr_index < 0) {
			dev_err(pm2->dev,
				"Charger voltage or current too high, "
				"charging not started\n");
			return -ENXIO;
		}

		ret = pm2xxx_reg_read(pm2, PM2XXX_BATT_CTRL_REG8, &val);
		if (ret < 0) {
			dev_err(pm2->dev, "%s pm2xxx read failed\n", __func__);
			goto error_occured;
		}
		val &= ~PM2XXX_CH_VOLT_MASK;
		val |= volt_index;
		ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG8, val);
		if (ret < 0) {
			dev_err(pm2->dev, "%s pm2xxx write failed\n", __func__);
			goto error_occured;
		}

		ret = pm2xxx_reg_read(pm2, PM2XXX_BATT_CTRL_REG6, &val);
		if (ret < 0) {
			dev_err(pm2->dev, "%s pm2xxx read failed\n", __func__);
			goto error_occured;
		}
		val &= ~PM2XXX_DIR_CH_CC_CURRENT_MASK;
		val |= curr_index;
		ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG6, val);
		if (ret < 0) {
			dev_err(pm2->dev, "%s pm2xxx write failed\n", __func__);
			goto error_occured;
		}

		if (!pm2->bat->enable_overshoot) {
			ret = pm2xxx_reg_read(pm2, PM2XXX_LED_CTRL_REG, &val);
			if (ret < 0) {
				dev_err(pm2->dev, "%s pm2xxx read failed\n",
								__func__);
				goto error_occured;
			}
			val |= PM2XXX_ANTI_OVERSHOOT_EN;
			ret = pm2xxx_reg_write(pm2, PM2XXX_LED_CTRL_REG, val);
			if (ret < 0) {
				dev_err(pm2->dev, "%s pm2xxx write failed\n",
								__func__);
				goto error_occured;
			}
		}

		ret = pm2xxx_charging_enable_mngt(pm2);
		if (ret < 0) {
			dev_err(pm2->dev, "Failed to enable"
						"pm2xxx ac charger\n");
			goto error_occured;
		}

		pm2->ac.charger_online = 1;
	} else {
		pm2->ac.charger_online = 0;
		pm2->ac.wd_expired = false;

		/* Disable regulator if enabled */
		if (pm2->vddadc_en_ac) {
			regulator_disable(pm2->regu);
			pm2->vddadc_en_ac = false;
		}

		ret = pm2xxx_charging_disable_mngt(pm2);
		if (ret < 0) {
			dev_err(pm2->dev, "failed to disable"
						"pm2xxx ac charger\n");
			goto error_occured;
		}

		dev_dbg(pm2->dev, "PM2301: " "Disabled AC charging\n");
	}
	power_supply_changed(&pm2->ac_chg.psy);

error_occured:
	return ret;
}

static int pm2xxx_charger_watchdog_kick(struct ux500_charger *charger)
{
	int ret;
	struct pm2xxx_charger *pm2;

	if (charger->psy.type == POWER_SUPPLY_TYPE_MAINS)
		pm2 = to_pm2xxx_charger_ac_device_info(charger);
	else
		return -ENXIO;

	ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_WD_KICK, WD_TIMER);
	if (ret)
		dev_err(pm2->dev, "Failed to kick WD!\n");

	return ret;
}

static void pm2xxx_charger_ac_work(struct work_struct *work)
{
	struct pm2xxx_charger *pm2 = container_of(work,
		struct pm2xxx_charger, ac_work);


	power_supply_changed(&pm2->ac_chg.psy);
	sysfs_notify(&pm2->ac_chg.psy.dev->kobj, NULL, "present");
};

static void pm2xxx_charger_check_hw_failure_work(struct work_struct *work)
{
	u8 reg_value;

	struct pm2xxx_charger *pm2 = container_of(work,
		struct pm2xxx_charger, check_hw_failure_work.work);

	if (pm2->flags.ovv) {
		pm2xxx_reg_read(pm2, PM2XXX_SRCE_REG_INT4, &reg_value);

		if (!(reg_value & (PM2XXX_INT4_S_ITVPWR1OVV |
					PM2XXX_INT4_S_ITVPWR2OVV))) {
			pm2->flags.ovv = false;
			power_supply_changed(&pm2->ac_chg.psy);
		}
	}

	/* If we still have a failure, schedule a new check */
	if (pm2->flags.ovv) {
		queue_delayed_work(pm2->charger_wq,
			&pm2->check_hw_failure_work, round_jiffies(HZ));
	}
}

static void pm2xxx_charger_check_main_thermal_prot_work(
	struct work_struct *work)
{
	int ret;
	u8 val;

	struct pm2xxx_charger *pm2 = container_of(work, struct pm2xxx_charger,
					check_main_thermal_prot_work);

	/* Check if die temp warning is still active */
	ret = pm2xxx_reg_read(pm2, PM2XXX_SRCE_REG_INT5, &val);
	if (ret < 0) {
		dev_err(pm2->dev, "%s pm2xxx read failed\n", __func__);
		return;
	}
	if (val & (PM2XXX_INT5_S_ITTHERMALWARNINGRISE
			| PM2XXX_INT5_S_ITTHERMALSHUTDOWNRISE))
		pm2->flags.main_thermal_prot = true;
	else if (val & (PM2XXX_INT5_S_ITTHERMALWARNINGFALL
				| PM2XXX_INT5_S_ITTHERMALSHUTDOWNFALL))
		pm2->flags.main_thermal_prot = false;

	power_supply_changed(&pm2->ac_chg.psy);
}

static struct pm2xxx_interrupts pm2xxx_int = {
	.handler[0] = pm2_int_reg0,
	.handler[1] = pm2_int_reg1,
	.handler[2] = pm2_int_reg2,
	.handler[3] = pm2_int_reg3,
	.handler[4] = pm2_int_reg4,
	.handler[5] = pm2_int_reg5,
};

static struct pm2xxx_irq pm2xxx_charger_irq[] = {
	{"PM2XXX_IRQ_INT", pm2xxx_irq_int},
};

static int pm2xxx_wall_charger_resume(struct i2c_client *i2c_client)
{
	struct pm2xxx_charger *pm2;

	pm2 =  (struct pm2xxx_charger *)i2c_get_clientdata(i2c_client);
	set_lpn_pin(pm2);

	/* If we still have a HW failure, schedule a new check */
	if (pm2->flags.ovv)
		queue_delayed_work(pm2->charger_wq,
				&pm2->check_hw_failure_work, 0);

	return 0;
}

static int pm2xxx_wall_charger_suspend(struct i2c_client *i2c_client,
	pm_message_t state)
{
	struct pm2xxx_charger *pm2;

	pm2 =  (struct pm2xxx_charger *)i2c_get_clientdata(i2c_client);
	clear_lpn_pin(pm2);

	/* Cancel any pending HW failure check */
	if (delayed_work_pending(&pm2->check_hw_failure_work))
		cancel_delayed_work(&pm2->check_hw_failure_work);

	flush_work(&pm2->ac_work);
	flush_work(&pm2->check_main_thermal_prot_work);

	return 0;
}

static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client,
		const struct i2c_device_id *id)
{
	struct pm2xxx_platform_data *pl_data = i2c_client->dev.platform_data;
	struct pm2xxx_charger *pm2;
	int ret = 0;
	u8 val;
	int i;

	pm2 = kzalloc(sizeof(struct pm2xxx_charger), GFP_KERNEL);
	if (!pm2) {
		dev_err(pm2->dev, "pm2xxx_charger allocation failed\n");
		return -ENOMEM;
	}

	/* get parent data */
	pm2->dev = &i2c_client->dev;
	pm2->gpadc = ab8500_gpadc_get("ab8500-gpadc.0");

	pm2->pm2_int = &pm2xxx_int;

	/* get charger spcific platform data */
	if (!pl_data->wall_charger) {
		dev_err(pm2->dev, "no charger platform data supplied\n");
		ret = -EINVAL;
		goto free_device_info;
	}

	pm2->pdata = pl_data->wall_charger;

	/* get battery specific platform data */
	if (!pl_data->battery) {
		dev_err(pm2->dev, "no battery platform data supplied\n");
		ret = -EINVAL;
		goto free_device_info;
	}

	pm2->bat = pl_data->battery;

	/*get lpn GPIO from platform data*/
	if (!pm2->pdata->lpn_gpio) {
		dev_err(pm2->dev, "no lpn gpio data supplied\n");
		ret = -EINVAL;
		goto free_device_info;
	}
	pm2->lpn_pin = pm2->pdata->lpn_gpio;

	if (!i2c_check_functionality(i2c_client->adapter,
			I2C_FUNC_SMBUS_BYTE_DATA |
			I2C_FUNC_SMBUS_READ_WORD_DATA)) {
		ret = -ENODEV;
		dev_info(pm2->dev, "pm2301 i2c_check_functionality failed\n");
		goto free_device_info;
	}

	pm2->config.pm2xxx_i2c = i2c_client;
	pm2->config.pm2xxx_id = (struct i2c_device_id *) id;
	i2c_set_clientdata(i2c_client, pm2);

	/* AC supply */
	/* power_supply base class */
	pm2->ac_chg.psy.name = pm2->pdata->label;
	pm2->ac_chg.psy.type = POWER_SUPPLY_TYPE_MAINS;
	pm2->ac_chg.psy.properties = pm2xxx_charger_ac_props;
	pm2->ac_chg.psy.num_properties = ARRAY_SIZE(pm2xxx_charger_ac_props);
	pm2->ac_chg.psy.get_property = pm2xxx_charger_ac_get_property;
	pm2->ac_chg.psy.supplied_to = pm2->pdata->supplied_to;
	pm2->ac_chg.psy.num_supplicants = pm2->pdata->num_supplicants;
	/* pm2xxx_charger sub-class */
	pm2->ac_chg.ops.enable = &pm2xxx_charger_ac_en;
	pm2->ac_chg.ops.kick_wd = &pm2xxx_charger_watchdog_kick;
	pm2->ac_chg.ops.update_curr = &pm2xxx_charger_update_charger_current;
	pm2->ac_chg.max_out_volt = pm2xxx_charger_voltage_map[
		ARRAY_SIZE(pm2xxx_charger_voltage_map) - 1];
	pm2->ac_chg.max_out_curr = pm2xxx_charger_current_map[
		ARRAY_SIZE(pm2xxx_charger_current_map) - 1];
	pm2->ac_chg.wdt_refresh = WD_KICK_INTERVAL;
	pm2->ac_chg.enabled = true;
	pm2->ac_chg.external = true;

	/* Create a work queue for the charger */
	pm2->charger_wq =
		create_singlethread_workqueue("pm2xxx_charger_wq");
	if (pm2->charger_wq == NULL) {
		dev_err(pm2->dev, "failed to create work queue\n");
		goto free_device_info;
	}

	/* Init work for charger detection */
	INIT_WORK(&pm2->ac_work, pm2xxx_charger_ac_work);

	/* Init work for checking HW status */
	INIT_WORK(&pm2->check_main_thermal_prot_work,
		pm2xxx_charger_check_main_thermal_prot_work);

	/* Init work for HW failure check */
	INIT_DEFERRABLE_WORK(&pm2->check_hw_failure_work,
		pm2xxx_charger_check_hw_failure_work);

	/*
	 * VDD ADC supply needs to be enabled from this driver when there
	 * is a charger connected to avoid erroneous BTEMP_HIGH/LOW
	 * interrupts during charging
	 */
	pm2->regu = regulator_get(pm2->dev, "vddadc");
	if (IS_ERR(pm2->regu)) {
		ret = PTR_ERR(pm2->regu);
		dev_err(pm2->dev, "failed to get vddadc regulator\n");
		goto free_charger_wq;
	}

	/* Register AC charger class */
	ret = power_supply_register(pm2->dev, &pm2->ac_chg.psy);
	if (ret) {
		dev_err(pm2->dev, "failed to register AC charger\n");
		goto free_regulator;
	}

	/* Register interrupts */
	ret = request_threaded_irq(gpio_to_irq(pm2->pdata->gpio_irq_number),
				NULL,
				pm2xxx_charger_irq[0].isr,
				pm2->pdata->irq_type,
				pm2xxx_charger_irq[0].name, pm2);

	if (ret != 0) {
		dev_err(pm2->dev, "failed to request %s IRQ %d: %d\n",
		pm2xxx_charger_irq[0].name,
			gpio_to_irq(pm2->pdata->gpio_irq_number), ret);
		goto unregister_pm2xxx_charger;
	}
	/* pm interrupt can wake up system */
	ret = enable_irq_wake(gpio_to_irq(pm2->pdata->gpio_irq_number));
	if (ret) {
		dev_err(pm2->dev, "failed to set irq wake\n");
		goto unregister_pm2xxx_interrupt;
	}

	mutex_init(&pm2->lock);

	/*
	 * Charger detection mechanism requires pulling up the LPN pin
	 * while i2c communication if Charger is not connected
	 * LPN pin of PM2301 is GPIO60 of AB9540
	 */
	ret = gpio_request(pm2->lpn_pin, "pm2301_lpm_gpio");
	if (ret < 0) {
		dev_err(pm2->dev, "pm2301_lpm_gpio request failed\n");
		goto disable_pm2_irq_wake;
	}
	ret = gpio_direction_output(pm2->lpn_pin, 0);
	if (ret < 0) {
		dev_err(pm2->dev, "pm2301_lpm_gpio direction failed\n");
		goto free_gpio;
	}

	set_lpn_pin(pm2);

	/* read  interrupt registers */
	for (i = 0; i < PM2XXX_NUM_INT_REG; i++)
		pm2xxx_reg_read(pm2,
			pm2xxx_interrupt_registers[i],
			&val);

	ret = pm2xxx_charger_detection(pm2, &val);

	if ((ret == 0) && val) {
		pm2->ac.charger_connected = 1;
		ab8500_override_turn_on_stat(~AB8500_POW_KEY_1_ON,
					     AB8500_MAIN_CH_DET);
		pm2->ac_conn = true;
		power_supply_changed(&pm2->ac_chg.psy);
		sysfs_notify(&pm2->ac_chg.psy.dev->kobj, NULL, "present");
	}

	return 0;

free_gpio:
	gpio_free(pm2->lpn_pin);
disable_pm2_irq_wake:
	disable_irq_wake(gpio_to_irq(pm2->pdata->gpio_irq_number));
unregister_pm2xxx_interrupt:
	/* disable interrupt */
	free_irq(gpio_to_irq(pm2->pdata->gpio_irq_number), pm2);
unregister_pm2xxx_charger:
	/* unregister power supply */
	power_supply_unregister(&pm2->ac_chg.psy);
free_regulator:
	/* disable the regulator */
	regulator_put(pm2->regu);
free_charger_wq:
	destroy_workqueue(pm2->charger_wq);
free_device_info:
	kfree(pm2);

	return ret;
}

static int pm2xxx_wall_charger_remove(struct i2c_client *i2c_client)
{
	struct pm2xxx_charger *pm2 = i2c_get_clientdata(i2c_client);

	/* Disable AC charging */
	pm2xxx_charger_ac_en(&pm2->ac_chg, false, 0, 0);

	/* Disable wake by pm interrupt */
	disable_irq_wake(gpio_to_irq(pm2->pdata->gpio_irq_number));

	/* Disable interrupts */
	free_irq(gpio_to_irq(pm2->pdata->gpio_irq_number), pm2);

	/* Delete the work queue */
	destroy_workqueue(pm2->charger_wq);

	flush_scheduled_work();

	/* disable the regulator */
	regulator_put(pm2->regu);

	power_supply_unregister(&pm2->ac_chg.psy);

	gpio_free(pm2->lpn_pin);

	kfree(pm2);

	return 0;
}

static const struct i2c_device_id pm2xxx_id[] = {
	{ "pm2301", 0 },
	{ }
};

MODULE_DEVICE_TABLE(i2c, pm2xxx_id);

static struct i2c_driver pm2xxx_charger_driver = {
	.probe = pm2xxx_wall_charger_probe,
	.remove = pm2xxx_wall_charger_remove,
	.suspend = pm2xxx_wall_charger_suspend,
	.resume = pm2xxx_wall_charger_resume,
	.driver = {
		.name = "pm2xxx-wall_charger",
		.owner = THIS_MODULE,
	},
	.id_table = pm2xxx_id,
};

static int __init pm2xxx_charger_init(void)
{
	return i2c_add_driver(&pm2xxx_charger_driver);
}

static void __exit pm2xxx_charger_exit(void)
{
	i2c_del_driver(&pm2xxx_charger_driver);
}

subsys_initcall_sync(pm2xxx_charger_init);
module_exit(pm2xxx_charger_exit);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Rajkumar kasirajan, Olivier Launay");
MODULE_ALIAS("platform:pm2xxx-charger");
MODULE_DESCRIPTION("PM2xxx charger management driver");
