/*
 *  max17048_fuelgauge.c
 *  Samsung MAX17048 Fuel Gauge Driver
 *
 *  Copyright (C) 2012 Samsung Electronics
 *
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 * 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.
 *
 */

#include <linux/battery/sec_fuelgauge.h>
#include <linux/sec_batt.h>

#if 0
static int max17048_write_reg(struct i2c_client *client, int reg, u8 value)
{
	int ret;

	ret = i2c_smbus_write_byte_data(client, reg, value);

	if (ret < 0)
		dev_err(&client->dev, "%s: err %d\n", __func__, ret);

	return ret;
}
#endif

static int max17048_read_reg(struct i2c_client *client, int reg)
{
	int ret;

	ret = i2c_smbus_read_byte_data(client, reg);

	if (ret < 0)
		dev_err(&client->dev, "%s: err %d\n", __func__, ret);

	return ret;
}

static int max17048_read_word(struct i2c_client *client, int reg)
{
	int ret;

	ret = i2c_smbus_read_word_data(client, reg);
	if (ret < 0)
		dev_err(&client->dev, "%s: err %d\n", __func__, ret);

	return ret;
}

static int max17048_write_word(struct i2c_client *client, int reg, u16 buf)
{
	int ret;

	ret = i2c_smbus_write_word_data(client, reg, buf);
	if (ret < 0)
		dev_err(&client->dev, "%s: err %d\n", __func__, ret);

	return ret;
}

static void max17048_reset(struct i2c_client *client)
{
	u16 mode, reset_cmd;

	mode = max17048_read_word(client, MAX17048_MODE_MSB);

	mode = swab16(mode);
	reset_cmd = swab16(mode | 0x4000);

	i2c_smbus_write_word_data(client, MAX17048_MODE_MSB, reset_cmd);

	msleep(300);
}

static int max17048_get_vcell(struct i2c_client *client)
{
	u32 vcell;
	u16 w_data;
	u32 temp;

	temp = max17048_read_word(client, MAX17048_VCELL_MSB);

	w_data = swab16(temp);

	temp = ((w_data & 0xFFF0) >> 4) * 1250;
	vcell = temp / 1000;

	dev_dbg(&client->dev,
		"%s : vcell (%d)\n", __func__, vcell);

	return vcell;
}

static int max17048_get_avg_vcell(struct i2c_client *client)
{
	u32 vcell_data = 0;
	u32 vcell_max = 0;
	u32 vcell_min = 0;
	u32 vcell_total = 0;
	u32 i;

	for (i = 0; i < AVER_SAMPLE_CNT; i++) {
		vcell_data = max17048_get_vcell(client);

		if (i != 0) {
			if (vcell_data > vcell_max)
				vcell_max = vcell_data;
			else if (vcell_data < vcell_min)
				vcell_min = vcell_data;
		} else {
			vcell_max = vcell_data;
			vcell_min = vcell_data;
		}
		vcell_total += vcell_data;
	}

	return (vcell_total - vcell_max - vcell_min) / (AVER_SAMPLE_CNT-2);
}

static int max17048_get_ocv(struct i2c_client *client)
{
	u32 ocv;
	u16 w_data;
	u32 temp;
	u16 cmd;

	cmd = swab16(0x4A57);
	max17048_write_word(client, 0x3E, cmd);

	temp = max17048_read_word(client, MAX17048_OCV_MSB);

	w_data = swab16(temp);

	temp = ((w_data & 0xFFF0) >> 4) * 1250;
	ocv = temp / 1000;

	cmd = swab16(0x0000);
	max17048_write_word(client, 0x3E, cmd);

	dev_dbg(&client->dev,
		"%s : ocv (%d)\n", __func__, ocv);

	return ocv;
}

/* soc should be 0.01% unit */
static int max17048_get_soc(struct i2c_client *client)
{
	struct sec_fuelgauge_info *fuelgauge =
				i2c_get_clientdata(client);
	u8 data[2] = {0, 0};
	int temp, soc;
	u64 psoc64 = 0;
	u64 temp64;
	u32 divisor = 10000000;

	temp = max17048_read_word(client, MAX17048_SOC_MSB);

	if (get_battery_data(fuelgauge).is_using_model_data) {
		/* [ TempSOC = ((SOC1 * 256) + SOC2) * 0.001953125 ] */
		temp64 = swab16(temp);
		psoc64 = temp64 * 1953125;
		psoc64 = div_u64(psoc64, divisor);
		soc = psoc64 & 0xffff;
	} else {
		data[0] = temp & 0xff;
		data[1] = (temp & 0xff00) >> 8;

		soc = (data[0] * 100) + (data[1] * 100 / 256);
	}

	dev_dbg(&client->dev,
		"%s : raw capacity (%d), data(0x%04x)\n",
		__func__, soc, (data[0]<<8) | data[1]);

	return soc;
}

static int max17048_get_current(struct i2c_client *client)
{
	union power_supply_propval value;

	psy_do_property("sec-charger", get,
		POWER_SUPPLY_PROP_CURRENT_NOW, value);

	return value.intval;
}

#define DISCHARGE_SAMPLE_CNT 5
static int discharge_cnt=0;
static int all_vcell[5] = {0,};

/* if ret < 0, discharge */
static int sec_bat_check_discharge(int vcell)
{
	int i, cnt, ret = 0;

	all_vcell[discharge_cnt++] = vcell;
	if (discharge_cnt >= DISCHARGE_SAMPLE_CNT)
		discharge_cnt = 0;

	cnt = discharge_cnt;

	/* check after last value is set */
	if (all_vcell[cnt] == 0)
		return 0;

	for (i = 0; i < DISCHARGE_SAMPLE_CNT; i++) {
		if (cnt == i)
			continue;
		if (all_vcell[cnt] > all_vcell[i])
			ret--;
		else
			ret++;
	}
	return ret;
}

/* judge power off or not by current_avg */
static int max17048_get_current_average(struct i2c_client *client)
{
	union power_supply_propval value_bat;
	union power_supply_propval value_chg;
	int vcell, soc, curr_avg;
	int check_discharge;

	psy_do_property("sec-charger", get,
		POWER_SUPPLY_PROP_CURRENT_NOW, value_chg);
	psy_do_property("battery", get,
		POWER_SUPPLY_PROP_HEALTH, value_bat);
	vcell = max17048_get_vcell(client);
	soc = max17048_get_soc(client) / 100;
	check_discharge = sec_bat_check_discharge(vcell);

	/* if 0% && under 3.4v && low power charging(1000mA), power off */
	if (!lpcharge && (soc <= 0) && (vcell < 3400) &&
	    (check_discharge < 0) &&
	    (((value_bat.intval == POWER_SUPPLY_HEALTH_OVERHEAT) ||
	      (value_bat.intval == POWER_SUPPLY_HEALTH_COLD)))) {
		pr_info("%s: SOC(%d), Vnow(%d), Inow(%d)\n",
			__func__, soc, vcell, value_chg.intval);
		curr_avg = -1;
	} else {
		curr_avg = value_chg.intval;
	}

	return curr_avg;
}

void sec_bat_reset_discharge(struct i2c_client *client)
{
	int i;

	for (i = 0; i < DISCHARGE_SAMPLE_CNT ; i++)
		all_vcell[i] = 0;
	discharge_cnt = 0;
}

static void max17048_get_version(struct i2c_client *client)
{
	u16 w_data;
	int temp;

	temp = max17048_read_word(client, MAX17048_VER_MSB);

	w_data = swab16(temp);

	dev_info(&client->dev,
		"MAX17048 Fuel-Gauge Ver 0x%04x\n", w_data);
}

static u16 max17048_get_rcomp(struct i2c_client *client)
{
	u16 w_data;
	int temp;

	temp = max17048_read_word(client, MAX17048_RCOMP_MSB);

	w_data = swab16(temp);

	dev_dbg(&client->dev,
		"%s : current rcomp = 0x%04x\n",
		__func__, w_data);

	return w_data;
}

static void max17048_set_rcomp(struct i2c_client *client, u16 new_rcomp)
{
	i2c_smbus_write_word_data(client,
		MAX17048_RCOMP_MSB, swab16(new_rcomp));
}

static void max17048_rcomp_update(struct i2c_client *client, int temp)
{
	struct sec_fuelgauge_info *fuelgauge =
				i2c_get_clientdata(client);
	union power_supply_propval value;

	int starting_rcomp = 0;
	int new_rcomp = 0;
	int rcomp_current = 0;

	rcomp_current = max17048_get_rcomp(client);

	psy_do_property("battery", get,
		POWER_SUPPLY_PROP_STATUS, value);

	if (value.intval == POWER_SUPPLY_STATUS_CHARGING) /* in charging */
		starting_rcomp = get_battery_data(fuelgauge).RCOMP_charging;
	else
		starting_rcomp = get_battery_data(fuelgauge).RCOMP0;

	if (temp > RCOMP0_TEMP)
		new_rcomp = starting_rcomp + ((temp - RCOMP0_TEMP) *
			get_battery_data(fuelgauge).temp_cohot / 1000);
	else if (temp < RCOMP0_TEMP)
		new_rcomp = starting_rcomp + ((temp - RCOMP0_TEMP) *
			get_battery_data(fuelgauge).temp_cocold / 1000);
	else
		new_rcomp = starting_rcomp;

	if (new_rcomp > 255)
		new_rcomp = 255;
	else if (new_rcomp < 0)
		new_rcomp = 0;

	new_rcomp <<= 8;
	new_rcomp &= 0xff00;
	/* not related to RCOMP */
	new_rcomp |= (rcomp_current & 0xff);

	if (rcomp_current != new_rcomp) {
		dev_dbg(&client->dev,
			"%s : RCOMP 0x%04x -> 0x%04x (0x%02x)\n",
			__func__, rcomp_current, new_rcomp,
			new_rcomp >> 8);
		max17048_set_rcomp(client, new_rcomp);
	}
}

#ifdef CONFIG_OF
static int max17048_parse_dt(struct device *dev,
			     struct sec_fuelgauge_info *fuelgauge)
{
	struct device_node *np = dev->of_node;
	int ret;
	int value;

	if (np == NULL) {
		pr_err("%s np NULL\n", __func__);
	} else {
		ret = of_property_read_u32(np, "fuelgauge,rcomp0",
					   &value);
		pr_err("%s value %d\n",
		       __func__, value);
		get_battery_data(fuelgauge).RCOMP0 = (u8)value;
		if (ret < 0)
			pr_err("%s error reading rcomp0 %d\n",
			       __func__, ret);
		ret = of_property_read_u32(np, "fuelgauge,rcomp_charging",
					   &value);
		pr_err("%s value %d\n",
		       __func__, value);
		get_battery_data(fuelgauge).RCOMP_charging = (u8)value;
		if (ret < 0)
			pr_err("%s error reading rcomp_charging %d\n",
			       __func__, ret);
		ret = of_property_read_u32(np, "fuelgauge,temp_cohot",
				   &get_battery_data(fuelgauge).temp_cohot);
		if (ret < 0)
			pr_err("%s error reading temp_cohot %d\n",
			       __func__, ret);
		ret = of_property_read_u32(np, "fuelgauge,temp_cocold",
				   &get_battery_data(fuelgauge).temp_cocold);
		if (ret < 0)
			pr_err("%s error reading temp_cocold %d\n",
			       __func__, ret);
		get_battery_data(fuelgauge).is_using_model_data = of_property_read_bool(np,
				"fuelgauge,is_using_model_data");
		ret = of_property_read_string(np, "fuelgauge,type_str",
				(const char **)&get_battery_data(fuelgauge).type_str);
		if (ret < 0)
			pr_err("%s error reading temp_cocold %d\n",
			       __func__, ret);

		pr_info("%s RCOMP0: 0x%x, RCOMP_charging: 0x%x, temp_cohot: %d,"
			"temp_cocold: %d, is_using_model_data: %d, "
			"type_str: %s,\n", __func__,
			get_battery_data(fuelgauge).RCOMP0,
			get_battery_data(fuelgauge).RCOMP_charging,
			get_battery_data(fuelgauge).temp_cohot,
			get_battery_data(fuelgauge).temp_cocold,
			get_battery_data(fuelgauge).is_using_model_data,
			get_battery_data(fuelgauge).type_str
			);
	}

	return 0;
}
#endif

static void fg_read_regs(struct i2c_client *client, char *str)
{
	int data = 0;
	u32 addr = 0;

	for (addr = 0x02; addr <= 0x04; addr += 2) {
		data = max17048_read_word(client, addr);
		sprintf(str + strlen(str), "0x%04x, ", data);
	}

	/* "#" considered as new line in application */
	sprintf(str+strlen(str), "#");

	for (addr = 0x08; addr <= 0x1a; addr += 2) {
		data = max17048_read_word(client, addr);
		sprintf(str + strlen(str), "0x%04x, ", data);
	}
}

bool sec_hal_fg_init(struct i2c_client *client)
{
#ifdef CONFIG_OF
	struct sec_fuelgauge_info *fuelgauge =
		i2c_get_clientdata(client);
	int error;

	error = max17048_parse_dt(&client->dev, fuelgauge);

	if (error) {
		dev_err(&client->dev,
			"%s : Failed to get max17048 fuel_init\n", __func__);
		return false;
	}
#endif
	pr_info("%s\n", __func__);

	max17048_get_version(client);

	return true;
}

bool sec_hal_fg_suspend(struct i2c_client *client)
{
	return true;
}

bool sec_hal_fg_resume(struct i2c_client *client)
{
	return true;
}

bool sec_hal_fg_fuelalert_init(struct i2c_client *client, int soc)
{
	u16 temp;
	u8 data;

	temp = max17048_get_rcomp(client);
	data = 32 - soc; /* set soc for fuel alert */
	temp &= 0xff00;
	temp += data;

	dev_dbg(&client->dev,
		"%s : new rcomp = 0x%04x\n",
		__func__, temp);

	max17048_set_rcomp(client, temp);

	return true;
}

bool sec_hal_fg_is_fuelalerted(struct i2c_client *client)
{
	u16 temp;

	temp = max17048_get_rcomp(client);

	if (temp & 0x20)	/* ALRT is asserted */
		return true;

	return false;
}

bool sec_hal_fg_fuelalert_process(void *irq_data, bool is_fuel_alerted)
{
	return true;
}

bool sec_hal_fg_full_charged(struct i2c_client *client)
{
	return true;
}

bool sec_hal_fg_reset(struct i2c_client *client)
{
	max17048_reset(client);
	return true;
}

bool sec_hal_fg_get_property(struct i2c_client *client,
			     enum power_supply_property psp,
			     union power_supply_propval *val)
{
	int i, pr_cnt = 1;
	union power_supply_propval value_bat;

	switch (psp) {
	case POWER_SUPPLY_PROP_STATUS:
		val->intval = 0;
		break;
		/* Cell voltage (VCELL, mV) */
	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
		val->intval = max17048_get_vcell(client);
		break;
		/* Additional Voltage Information (mV) */
	case POWER_SUPPLY_PROP_VOLTAGE_AVG:
		switch (val->intval) {
		case SEC_BATTEY_VOLTAGE_AVERAGE:
			val->intval = max17048_get_avg_vcell(client);
			break;
		case SEC_BATTEY_VOLTAGE_OCV:
			val->intval = max17048_get_ocv(client);
			break;
		}
		break;
		/* Current (mA) */
	case POWER_SUPPLY_PROP_CURRENT_NOW:
		psy_do_property("battery", get,
			POWER_SUPPLY_PROP_STATUS, value_bat);
		if(value_bat.intval == POWER_SUPPLY_STATUS_DISCHARGING)
			val->intval = -max17048_get_current(client);
		else
			val->intval = max17048_get_current(client);
		break;
		/* Average Current (mA) */
	case POWER_SUPPLY_PROP_CURRENT_AVG:
		val->intval = max17048_get_current_average(client);
		break;
	case POWER_SUPPLY_PROP_CHARGE_FULL:
		break;
	case POWER_SUPPLY_PROP_ENERGY_NOW:
		break;
		/* SOC (%) */
	case POWER_SUPPLY_PROP_CAPACITY:
		if (val->intval == SEC_FUELGAUGE_CAPACITY_TYPE_RAW) {
                        val->intval = max17048_get_soc(client);
                } else {
                        val->intval = max17048_get_soc(client) / 10;
			if (!(pr_cnt++ % 10)) {
				pr_cnt = 1;
				for (i = 0x02; i < 0x1C; i++)
					printk("0x%02x(0x%02x), ",
					i, max17048_read_reg(client, i));
				printk("\n");
			}
                }
		break;
		/* Battery Temperature */
	case POWER_SUPPLY_PROP_TEMP:
		/* Target Temperature */
	case POWER_SUPPLY_PROP_TEMP_AMBIENT:
		break;
	default:
		return false;
	}
	return true;
}

bool sec_hal_fg_set_property(struct i2c_client *client,
			     enum power_supply_property psp,
			     const union power_supply_propval *val)
{
	switch (psp) {
	case POWER_SUPPLY_PROP_ONLINE:
		sec_bat_reset_discharge(client);
		break;
		/* Battery Temperature */
	case POWER_SUPPLY_PROP_TEMP:
		/* Target Temperature */
		/* temperature is 0.1 degree, should be divide by 10 */
		max17048_rcomp_update(client, val->intval / 10);
		break;
	case POWER_SUPPLY_PROP_TEMP_AMBIENT:		
		break;
	default:
		return false;
	}
	return true;
}

ssize_t sec_hal_fg_show_attrs(struct device *dev,
				const ptrdiff_t offset, char *buf)
{
	struct power_supply *psy = dev_get_drvdata(dev);
	struct sec_fuelgauge_info *fg =
		container_of(psy, struct sec_fuelgauge_info, psy_fg);
	int i = 0;
	char *str = NULL;

	switch (offset) {
	case FG_DATA:
		i += scnprintf(buf + i, PAGE_SIZE - i, "%02x%02x\n",
			fg->reg_data[1], fg->reg_data[0]);
		break;
	case FG_REGS:
		str = kzalloc(sizeof(char)*1024, GFP_KERNEL);
		if (!str)
			return -ENOMEM;

		fg_read_regs(fg->client, str);
		i += scnprintf(buf + i, PAGE_SIZE - i, "%s\n",
			str);

		kfree(str);
		break;
	default:
		i = -EINVAL;
		break;
	}

	return i;
}

ssize_t sec_hal_fg_store_attrs(struct device *dev,
				const ptrdiff_t offset,
				const char *buf, size_t count)
{
	struct power_supply *psy = dev_get_drvdata(dev);
	struct sec_fuelgauge_info *fg =
		container_of(psy, struct sec_fuelgauge_info, psy_fg);
	int ret = 0;
	int x = 0;
	u16 data;

	switch (offset) {
	case FG_REG:
		if (sscanf(buf, "%x\n", &x) == 1) {
			fg->reg_addr = x;
			data = max17048_read_word(
				fg->client, fg->reg_addr);
			fg->reg_data[0] = (data & 0xff00) >> 8;
			fg->reg_data[1] = (data & 0x00ff);

			dev_dbg(&fg->client->dev,
				"%s: (read) addr = 0x%x, data = 0x%02x%02x\n",
				 __func__, fg->reg_addr,
				 fg->reg_data[1], fg->reg_data[0]);
			ret = count;
		}
		break;
	case FG_DATA:
		if (sscanf(buf, "%x\n", &x) == 1) {
			dev_dbg(&fg->client->dev,
				"%s: (write) addr = 0x%x, data = 0x%04x\n",
				__func__, fg->reg_addr, x);
			i2c_smbus_write_word_data(fg->client,
				fg->reg_addr, swab16(x));
			ret = count;
		}
		break;
	default:
		ret = -EINVAL;
		break;
	}

	return ret;
}
