// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright 2012 ST Ericsson.
 *
 * Power supply driver for ST Ericsson pm2xxx_charger charger
 */

#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/regulator/consumer.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/workqueue.h>
#include <linux/mfd/abx500/ab8500.h>
#include <linux/mfd/abx500/ab8500-bm.h>
#include <linux/mfd/abx500/ux500_chargalg.h>
#include <linux/pm2301_charger.h>
#include <linux/gpio.h>
#include <linux/pm_runtime.h>
#include <linux/pm.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
#define PM2XXX_AUTOSUSPEND_DELAY 500

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 void set_lpn_pin(struct pm2xxx_charger *pm2)
{
	if (!pm2->ac.charger_connected && gpio_is_valid(pm2->lpn_pin)) {
		gpio_set_value(pm2->lpn_pin, 1);
		usleep_range(SLEEP_MIN, SLEEP_MAX);
	}
}

static void clear_lpn_pin(struct pm2xxx_charger *pm2)
{
	if (!pm2->ac.charger_connected && gpio_is_valid(pm2->lpn_pin))
		gpio_set_value(pm2->lpn_pin, 0);
}

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

	/* wake up the device */
	pm_runtime_get_sync(pm2->dev);

	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;

	pm_runtime_put_sync(pm2->dev);

	return ret;
}

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

	/* wake up the device */
	pm_runtime_get_sync(pm2->dev);

	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;

	pm_runtime_put_sync(pm2->dev);

	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;
}


static 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 expired\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 occurred 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 ,
			"charging 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;

	/* wake up the device */
	pm_runtime_get_sync(pm2->dev);

	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);

	pm_runtime_mark_last_busy(pm2->dev);
	pm_runtime_put_autosuspend(pm2->dev);

	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->desc->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);

	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) {
			ret = regulator_enable(pm2->regu);
			if (ret)
				dev_warn(pm2->dev,
					"Failed to enable vddadc regulator\n");
			else
				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->desc->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 __maybe_unused pm2xxx_wall_charger_resume(struct device *dev)
{
	struct i2c_client *i2c_client = to_i2c_client(dev);
	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 __maybe_unused pm2xxx_wall_charger_suspend(struct device *dev)
{
	struct i2c_client *i2c_client = to_i2c_client(dev);
	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 __maybe_unused pm2xxx_runtime_suspend(struct device *dev)
{
	struct i2c_client *pm2xxx_i2c_client = to_i2c_client(dev);
	struct pm2xxx_charger *pm2;

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

	return 0;
}

static int __maybe_unused pm2xxx_runtime_resume(struct device *dev)
{
	struct i2c_client *pm2xxx_i2c_client = to_i2c_client(dev);
	struct pm2xxx_charger *pm2;

	pm2 = (struct pm2xxx_charger *)i2c_get_clientdata(pm2xxx_i2c_client);

	if (gpio_is_valid(pm2->lpn_pin) && gpio_get_value(pm2->lpn_pin) == 0)
		set_lpn_pin(pm2);

	return 0;
}

static const struct dev_pm_ops pm2xxx_pm_ops __maybe_unused = {
	SET_SYSTEM_SLEEP_PM_OPS(pm2xxx_wall_charger_suspend,
		pm2xxx_wall_charger_resume)
	SET_RUNTIME_PM_OPS(pm2xxx_runtime_suspend, pm2xxx_runtime_resume, NULL)
};

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 power_supply_config psy_cfg = {};
	struct pm2xxx_charger *pm2;
	int ret = 0;
	u8 val;
	int i;

	if (!pl_data) {
		dev_err(&i2c_client->dev, "No platform data supplied\n");
		return -EINVAL;
	}

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

	/* get parent data */
	pm2->dev = &i2c_client->dev;

	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;

	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_desc.name = pm2->pdata->label;
	pm2->ac_chg_desc.type = POWER_SUPPLY_TYPE_MAINS;
	pm2->ac_chg_desc.properties = pm2xxx_charger_ac_props;
	pm2->ac_chg_desc.num_properties = ARRAY_SIZE(pm2xxx_charger_ac_props);
	pm2->ac_chg_desc.get_property = pm2xxx_charger_ac_get_property;

	psy_cfg.supplied_to = pm2->pdata->supplied_to;
	psy_cfg.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 = alloc_ordered_workqueue("pm2xxx_charger_wq",
						  WQ_MEM_RECLAIM);
	if (pm2->charger_wq == NULL) {
		ret = -ENOMEM;
		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 */
	pm2->ac_chg.psy = power_supply_register(pm2->dev, &pm2->ac_chg_desc,
						&psy_cfg);
	if (IS_ERR(pm2->ac_chg.psy)) {
		dev_err(pm2->dev, "failed to register AC charger\n");
		ret = PTR_ERR(pm2->ac_chg.psy);
		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;
	}

	ret = pm_runtime_set_active(pm2->dev);
	if (ret)
		dev_err(pm2->dev, "set active Error\n");

	pm_runtime_enable(pm2->dev);
	pm_runtime_set_autosuspend_delay(pm2->dev, PM2XXX_AUTOSUSPEND_DELAY);
	pm_runtime_use_autosuspend(pm2->dev);
	pm_runtime_resume(pm2->dev);

	/* 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);

	if (gpio_is_valid(pm2->pdata->lpn_gpio)) {
		/* get lpn GPIO from platform data */
		pm2->lpn_pin = pm2->pdata->lpn_gpio;

		/*
		 * 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:
	if (gpio_is_valid(pm2->lpn_pin))
		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 pm_runtime */
	pm_runtime_disable(pm2->dev);
	/* 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);

	if (gpio_is_valid(pm2->lpn_pin))
		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,
	.driver = {
		.name = "pm2xxx-wall_charger",
		.pm = IS_ENABLED(CONFIG_PM) ? &pm2xxx_pm_ops : NULL,
	},
	.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);
}

device_initcall_sync(pm2xxx_charger_init);
module_exit(pm2xxx_charger_exit);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Rajkumar kasirajan, Olivier Launay");
MODULE_DESCRIPTION("PM2xxx charger management driver");
