/*
 * max77665-charger.c - Battery charger driver
 *
 *  Copyright (C) 2012 nVIDIA corporation
 *  Syed Rafiuddin <srafiuddin@nvidia.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <linux/err.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/power_supply.h>
#include <linux/mfd/max77665.h>
#include <linux/max77665-charger.h>
#include <linux/power/max17042_battery.h>

/* fast charge current in mA */
static const uint32_t chg_cc[]  = {
	0, 33, 66, 99, 133, 166, 199, 233, 266, 299,
	333, 366, 399, 432, 466, 499, 532, 566, 599, 632,
	666, 699, 732, 765, 799, 832, 865, 899, 932, 965,
	999, 1032, 1065, 1098, 1132, 1165, 1198, 1232, 1265,
	1298, 1332, 1365, 1398, 1421, 1465, 1498, 1531, 1565,
	1598, 1631, 1665, 1698, 1731, 1764, 1798, 1831, 1864,
	1898, 1931, 1964, 1998, 2031, 2064, 2097,
};

/* primary charge termination voltage in mV */
static const uint32_t chg_cv_prm[] = {
	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, 4325, 4340, 4350,
	4375, 4400,
};

/* maxim input current limit in mA*/
static const uint32_t chgin_ilim[] = {
	0, 100, 200, 300, 400, 500, 600, 700,
	800, 900, 1000, 1100, 1200, 1300, 1400,
	1500, 1600, 1700, 1800, 1900, 2000, 2100,
	2200, 2300, 2400, 2500,
};

struct max77665_charger {
	struct device		*dev;
	struct power_supply	ac;
	struct power_supply	usb;
	struct max77665_charger_plat_data *plat_data;
	uint8_t ac_online;
	uint8_t usb_online;
	uint8_t num_cables;
	struct extcon_dev *edev;
};

static enum power_supply_property max77665_ac_props[] = {
	POWER_SUPPLY_PROP_ONLINE,
};

static enum power_supply_property max77665_usb_props[] = {
	POWER_SUPPLY_PROP_ONLINE,
};

static int max77665_write_reg(struct max77665_charger *charger,
	uint8_t reg, uint8_t value)
{
	int ret = 0;
	struct device *dev = charger->dev;

	ret = max77665_write(dev->parent, MAX77665_I2C_SLAVE_PMIC, reg, value);
	if (ret < 0)
		return ret;
	return ret;
}

static int max77665_read_reg(struct max77665_charger *charger,
	uint8_t reg, uint32_t *value)
{
	int ret = 0;
	uint8_t read_val;

	struct device *dev = charger->dev;

	ret = max77665_read(dev->parent, MAX77665_I2C_SLAVE_PMIC,
			reg, &read_val);
	if (!ret)
		*value = read_val;

	return ret;
}

static int max77665_update_reg(struct max77665_charger *charger,
	uint8_t reg, uint8_t value)
{
	int ret = 0;
	uint8_t read_val;

	struct device *dev = charger->dev;

	ret = max77665_read(dev->parent, MAX77665_I2C_SLAVE_PMIC,
			reg, &read_val);
	if (ret < 0)
		return ret;

	ret = max77665_write(dev->parent, MAX77665_I2C_SLAVE_PMIC, reg,
			read_val | value);
	if (ret < 0)
		return ret;

	return ret;
}

/* Convert current to register value using lookup table */
static int convert_to_reg(const unsigned int *tbl, size_t size,
		unsigned int val)
{
	size_t i;

	for (i = 0; i < size; i++)
		if (val < tbl[i])
			break;
	return i > 0 ? i - 1 : -EINVAL;
}

static int max77665_ac_get_property(struct power_supply *psy,
		enum power_supply_property psp,
				union power_supply_propval *val)
{
	struct max77665_charger *chip = container_of(psy,
				struct max77665_charger, ac);

	if (psp == POWER_SUPPLY_PROP_ONLINE)
		val->intval = chip->ac_online;
	else
		return -EINVAL;

	return 0;
}

static int max77665_usb_get_property(struct power_supply *psy,
				enum power_supply_property psp,
				union power_supply_propval *val)
{
	struct max77665_charger *chip = container_of(psy,
					struct max77665_charger, usb);

	if (psp == POWER_SUPPLY_PROP_ONLINE)
		val->intval = chip->usb_online;
	else
		return -EINVAL;

	return 0;
}

static int max77665_enable_write(struct max77665_charger *charger, int access)
{
	int ret = 0;

	if (access) {
		/* enable write acces to registers */
		ret = max77665_write_reg(charger, MAX77665_CHG_CNFG_06, 0x0c);
		if (ret < 0) {
			dev_err(charger->dev, "Failed to write to reg 0x%x\n",
				MAX77665_CHG_CNFG_06);
			return ret;
		}
	} else {
		/* Disable write acces to registers */
		ret = max77665_write_reg(charger, MAX77665_CHG_CNFG_06, 0x00);
		if (ret < 0) {
			dev_err(charger->dev, "Failed to write to reg 0x%x\n",
				MAX77665_CHG_CNFG_06);
			return ret;
		}
	}
	return 0;
}

static int max77665_charger_enable(struct max77665_charger *charger,
		enum max77665_mode mode)
{
	int ret;

	ret = max77665_enable_write(charger, true);
	if (ret < 0) {
		dev_err(charger->dev, "failed to enable write acess\n");
		return ret;
	}

	if (mode == CHARGER) {
		/* enable charging */
		ret = max77665_write_reg(charger, MAX77665_CHG_CNFG_00, 0x05);
		if (ret < 0) {
			dev_err(charger->dev, "Failed in wirting to register 0x%x:\n",
					MAX77665_CHG_CNFG_00);
			return ret;
		}
	} else if (mode == OTG) {
		/* enable OTG mode */
		ret = max77665_write_reg(charger, MAX77665_CHG_CNFG_00, 0x2A);
		if (ret < 0) {
			dev_err(charger->dev, "Failed in writing to register 0x%x:\n",
					 MAX77665_CHG_CNFG_00);
			return ret;
		}
	}

	ret = max77665_enable_write(charger, false);
	if (ret < 0) {
		dev_err(charger->dev, "failed to disable write acess\n");
		return ret;
	}
	return 0;
}

static int max77665_charger_init(struct max77665_charger *charger)
{
	int ret = 0;
	uint8_t read_val;

	ret = max77665_enable_write(charger, true);
	if (ret < 0) {
		dev_err(charger->dev, "failed to enable write acess\n");
		goto error;
	}

	ret = max77665_update_reg(charger, MAX77665_CHG_CNFG_01, 0xa4);
	if (ret < 0) {
		dev_err(charger->dev, "Failed in writing to register 0x%x\n",
			MAX77665_CHG_CNFG_01);
		goto error;
	}

	if (charger->plat_data->fast_chg_cc) {
		ret = convert_to_reg(chg_cc, ARRAY_SIZE(chg_cc),
					charger->plat_data->fast_chg_cc);
		if (ret < 0)
			goto error;

		ret = max77665_update_reg(charger, MAX77665_CHG_CNFG_02, ret);
		if (ret < 0) {
			dev_err(charger->dev, "Failed in writing to register 0x%x\n",
				MAX77665_CHG_CNFG_02);
			goto error;
		}
	}

	if (charger->plat_data->term_volt) {
		ret = convert_to_reg(chg_cv_prm, ARRAY_SIZE(chg_cv_prm),
					charger->plat_data->term_volt);
		if (ret < 0)
			goto error;

		ret = max77665_update_reg(charger,
				MAX77665_CHG_CNFG_04, ret+1);
		if (ret < 0) {
			dev_err(charger->dev, "Failed writing to reg:0x%x\n",
				MAX77665_CHG_CNFG_04);
			goto error;
		}
	}

	if (charger->plat_data->curr_lim) {
		ret = convert_to_reg(chgin_ilim, ARRAY_SIZE(chgin_ilim),
					charger->plat_data->curr_lim);
		if (ret < 0)
			goto error;

		ret = max77665_write_reg(charger,
				MAX77665_CHG_CNFG_09, ret*5);
		if (ret < 0) {
			dev_err(charger->dev, "Failed writing to reg:0x%x\n",
				MAX77665_CHG_CNFG_09);
			goto error;
		}
	}
error:
	ret = max77665_enable_write(charger, false);
	if (ret < 0) {
		dev_err(charger->dev, "failed to enable write acess\n");
		return ret;
	}
	return ret;
}

static int max77665_enable_charger(struct max77665_charger *charger)
{
	int ret = 0;

	if (extcon_get_cable_state(charger->edev, "USB")) {

		ret = max77665_charger_enable(charger, CHARGER);
		if (ret < 0)
			goto error;

		charger->usb_online = 1;
		power_supply_changed(&charger->usb);
		charger->plat_data->curr_lim = 500;
	}

	if (extcon_get_cable_state(charger->edev, "USB-Host")) {
		ret = max77665_charger_enable(charger, OTG);
		if (ret < 0)
			goto error;
	}

	if (extcon_get_cable_state(charger->edev, "TA")) {
		ret = max77665_charger_enable(charger, CHARGER);
		if (ret < 0)
			goto error;

		charger->ac_online = 1;
		power_supply_changed(&charger->ac);
	}

	ret = max77665_charger_init(charger);
	if (ret < 0) {
		dev_err(charger->dev, "failed to initialize charger\n");
		goto error;
	}

	return 0;
error:
	return ret;
}

static int charger_extcon_notifier(struct notifier_block *self,
		unsigned long event, void *ptr)
{
	return NOTIFY_DONE;
}

static __devinit int max77665_battery_probe(struct platform_device *pdev)
{
	int ret = 0;
	uint8_t j;
	uint32_t read_val;
	struct max77665_charger *charger;

	charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL);
	if (!charger) {
		dev_err(&pdev->dev, "failed to allocate memory status\n");
		return -ENOMEM;
	}

	charger->dev = &pdev->dev;

	charger->plat_data = pdev->dev.platform_data;
	dev_set_drvdata(&pdev->dev, charger);

	/* modify OTP setting of input current limit to 100ma */
	ret = max77665_write_reg(charger, MAX77665_CHG_CNFG_09, 0x05);
	if (ret < 0) {
		dev_err(charger->dev, "failed to write to reg: 0x%x\n",
				MAX77665_CHG_CNFG_09);
		goto error;
	}

	/* check for battery presence */
	ret = max77665_read_reg(charger, MAX77665_CHG_DTLS_01, &read_val);
	if (ret < 0) {
		dev_err(&pdev->dev, "error in reading register 0x%x\n",
				MAX77665_CHG_DTLS_01);
		return -ENODEV;
	} else if (!(read_val & 0xe0)) {
		dev_err(&pdev->dev, "Battery not detected exiting driver..\n");
		return -ENODEV;
	}

	/* differentiate between E1236 and E1587*/
	ret = maxim_get_temp();
	if (ret == 0xff) {
		dev_err(&pdev->dev, "failed in reading temperaure\n");
		return -ENODEV;
	} else if ((ret < MIN_TEMP) || (ret > MAX_TEMP)) {
			dev_err(&pdev->dev, "E1236 detected exiting driver....\n");
			return -ENODEV;
	}

	charger->ac.name		= "ac";
	charger->ac.type		= POWER_SUPPLY_TYPE_MAINS;
	charger->ac.get_property	= max77665_ac_get_property;
	charger->ac.properties		= max77665_ac_props;
	charger->ac.num_properties	= ARRAY_SIZE(max77665_ac_props);

	ret = power_supply_register(charger->dev, &charger->ac);
	if (ret) {
		dev_err(charger->dev, "failed: power supply register\n");
		goto error;
	}

	charger->usb.name		= "usb";
	charger->usb.type		= POWER_SUPPLY_TYPE_USB;
	charger->usb.get_property	= max77665_usb_get_property;
	charger->usb.properties		= max77665_usb_props;
	charger->usb.num_properties	= ARRAY_SIZE(max77665_usb_props);

	ret = power_supply_register(charger->dev, &charger->usb);
	if (ret) {
		dev_err(charger->dev, "failed: power supply register\n");
		goto pwr_sply_error;
	}

	for (j = 0 ; j < charger->plat_data->num_cables; j++) {
		struct max77665_charger_cable *cable =
				&charger->plat_data->cables[j];

		cable->nb.notifier_call = charger_extcon_notifier;
		ret = extcon_register_interest(&cable->extcon_dev,
				"max77665-muic", cable->name, &cable->nb);

		if (ret < 0) {
			dev_err(charger->dev, "Cannot register for cable: %s\n",
				cable->name);
			ret = -EINVAL;
		}
	}

	charger->edev = extcon_get_extcon_dev("max77665-muic");
	if (!charger->edev)
		return -ENODEV;

	ret = max77665_enable_charger(charger);
	if (ret < 0) {
		dev_err(charger->dev, "failed to initialize charger\n");
		goto chrg_error;
	}

	return 0;

chrg_error:
	power_supply_unregister(&charger->usb);
pwr_sply_error:
	power_supply_unregister(&charger->ac);
error:
	return ret;
}

static int __devexit max77665_battery_remove(struct platform_device *pdev)
{
	struct max77665_charger *charger = platform_get_drvdata(pdev);

	power_supply_unregister(&charger->ac);
	power_supply_unregister(&charger->usb);

	return 0;
}

static struct platform_driver max77665_battery_driver = {
	.driver = {
		.name = "max77665-charger",
		.owner = THIS_MODULE,
	},
	.probe = max77665_battery_probe,
	.remove = __devexit_p(max77665_battery_remove),

};

static int __init max77665_battery_init(void)
{
	return platform_driver_register(&max77665_battery_driver);
}

static void __exit max77665_battery_exit(void)
{
	platform_driver_unregister(&max77665_battery_driver);
}

late_initcall(max77665_battery_init);
module_exit(max77665_battery_exit);

MODULE_DESCRIPTION("MAXIM MAX77665 battery charging driver");
MODULE_AUTHOR("Syed Rafiuddin <srafiuddin@nvidia.com>");
MODULE_LICENSE("GPL v2");
