/*
 *  bq24260_charger.c
 *  Samsung bq24260 Charger 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.
 *
 */
#define DEBUG

#include <linux/battery/sec_charger.h>

static int bq24260_i2c_write(struct i2c_client *client,
				int reg, u8 *buf)
{
	int ret;
	ret = i2c_smbus_write_i2c_block_data(client, reg, 1, buf);
	if (ret < 0)
		dev_err(&client->dev, "%s: Error(%d)\n", __func__, ret);
	return ret;
}

static int bq24260_i2c_read(struct i2c_client *client,
				int reg, u8 *buf)
{
	int ret;
	ret = i2c_smbus_read_i2c_block_data(client, reg, 1, buf);
	if (ret < 0)
		dev_err(&client->dev, "%s: Error(%d)\n", __func__, ret);
	return ret;
}

static void bq24260_i2c_write_array(struct i2c_client *client,
				u8 *buf, int size)
{
	int i;
	for (i = 0; i < size; i += 3)
		bq24260_i2c_write(client, (u8) (*(buf + i)), (buf + i) + 1);
}

static void bq24260_set_command(struct i2c_client *client,
				int reg, int datum)
{
	int val;
	u8 data = 0;
	val = bq24260_i2c_read(client, reg, &data);
	if (val >= 0) {
		dev_dbg(&client->dev, "%s : reg(0x%02x): 0x%02x(0x%02x)",
			__func__, reg, data, datum);
		if (data != datum) {
			data = datum;
			if (bq24260_i2c_write(client, reg, &data) < 0)
				dev_err(&client->dev,
					"%s : error!\n", __func__);
			val = bq24260_i2c_read(client, reg, &data);
			if (val >= 0)
				dev_dbg(&client->dev, " => 0x%02x\n", data);
		}
	}
}

static void bq24260_test_read(struct i2c_client *client)
{
	u8 data = 0;
	u32 addr = 0;
	for (addr = 0; addr <= 0x06; addr++) {
		bq24260_i2c_read(client, addr, &data);
		dev_dbg(&client->dev,
			"bq24260 addr : 0x%02x data : 0x%02x\n", addr, data);
	}
}

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

	for (addr = 0; addr <= 0x06; addr++) {
		bq24260_i2c_read(client, addr, &data);
		sprintf(str+strlen(str), "0x%x, ", data);
	}
}


static int bq24260_get_charging_status(struct i2c_client *client)
{
	int status = POWER_SUPPLY_STATUS_UNKNOWN;
	u8 data = 0;

	bq24260_i2c_read(client, BQ24260_STATUS, &data);
	dev_info(&client->dev,
		"%s : charger status(0x%02x)\n", __func__, data);

	data = (data & 0x30);

	switch (data) {
	case 0x00:
		status = POWER_SUPPLY_STATUS_DISCHARGING;
		break;
	case 0x10:
		status = POWER_SUPPLY_STATUS_CHARGING;
		break;
	case 0x20:
		status = POWER_SUPPLY_STATUS_FULL;
		break;
	case 0x30:
		status = POWER_SUPPLY_STATUS_NOT_CHARGING;
		break;
	}

	return (int)status;
}

static int bq24260_get_charging_health(struct i2c_client *client)
{
	int health = POWER_SUPPLY_HEALTH_GOOD;
	u8 data = 0;

	bq24260_i2c_read(client, BQ24260_STATUS, &data);
	dev_info(&client->dev,
		"%s : charger status(0x%02x)\n", __func__, data);

	if ((data & 0x30) == 0x30) {	/* check for fault */
		data = (data & 0x07);

		switch (data) {
		case 0x01:
			health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
			break;
		case 0x02:
			health = POWER_SUPPLY_HEALTH_UNDERVOLTAGE;
			break;
		}
	}

	return (int)health;
}

static u8 bq24260_get_float_voltage_data(
			int float_voltage)
{
	u8 data;

	if (float_voltage < 3500)
		float_voltage = 3500;

	data = (float_voltage - 3500) / 20;

	return data << 2;
}

static u8 bq24260_get_input_current_limit_data(
			int input_current)
{
	u8 data = 0x00;

	if (input_current <= 100)
		data = 0x00;
	else if (input_current <= 150)
		data = 0x01;
	else if (input_current <= 500)
		data = 0x02;
	else if (input_current <= 900)
		data = 0x03;
	else if (input_current <= 1000)
		data = 0x04;
	else if (input_current <= 2000)/* will be set as 1950mA */
		data = 0x06;
	else	/* No limit */
		data = 0x07;

	return data << 4;
}

static u8 bq24260_get_termination_current_limit_data(
			int termination_current)
{
	u8 data;

	/* default offset 50mA, max 300mA */
	data = (termination_current - 50) / 50;

	return data;
}

static u8 bq24260_get_fast_charging_current_data(
			int fast_charging_current)
{
	u8 data;

	/* default offset 500mA */
	if (fast_charging_current < 500)
		fast_charging_current = 500;

	data = (fast_charging_current - 500) / 100;

	return data << 3;
}

static void bq24260_charger_function_conrol(
				struct i2c_client *client)
{
	struct sec_charger_info *charger = i2c_get_clientdata(client);
	union power_supply_propval val;
	int full_check_type;
	u8 data;
	if (charger->charging_current < 0) {
		dev_dbg(&client->dev,
			"%s : OTG is activated. Ignore command!\n", __func__);
		return;
	}

	if (charger->cable_type ==
		POWER_SUPPLY_TYPE_BATTERY) {
		data = 0x00;
		bq24260_i2c_read(client, BQ24260_CONTROL, &data);
		data |= 0x2;
		data &= 0x7f; /* Prevent register reset */
		bq24260_set_command(client,
			BQ24260_CONTROL, data);
	} else {
		data = 0x00;
		bq24260_i2c_read(client, BQ24260_CONTROL, &data);
		/* Enable charging */
		data &= 0x7d; /*default enabled*/
		psy_do_property("battery", get,
			POWER_SUPPLY_PROP_CHARGE_NOW, val);
		if (val.intval == SEC_BATTERY_CHARGING_1ST)
			full_check_type = charger->pdata->full_check_type;
		else
			full_check_type = charger->pdata->full_check_type_2nd;
		/* Termination setting */
		switch (full_check_type) {
		case SEC_BATTERY_FULLCHARGED_CHGGPIO:
		case SEC_BATTERY_FULLCHARGED_CHGINT:
		case SEC_BATTERY_FULLCHARGED_CHGPSY:
			/* Enable Current Termination */
			data |= 0x04;
			break;
		default:
			data &= 0x7b;
			break;
		}
		/* Input current limit */
		dev_dbg(&client->dev, "%s : input current (%dmA)\n",
			__func__, charger->pdata->charging_current
			[charger->cable_type].input_current_limit);
		data &= 0x0F;
		data |= bq24260_get_input_current_limit_data(
			charger->pdata->charging_current
			[charger->cable_type].input_current_limit);
		bq24260_set_command(client,
			BQ24260_CONTROL, data);

		data = 0x00;
		/* Float voltage */
		dev_dbg(&client->dev, "%s : float voltage (%dmV)\n",
			__func__, charger->pdata->chg_float_voltage);
		data |= bq24260_get_float_voltage_data(
			charger->pdata->chg_float_voltage);
		bq24260_set_command(client,
			BQ24260_VOLTAGE, data);

		data = 0x00;
		/* Fast charge and Termination current */
		dev_dbg(&client->dev, "%s : fast charging current (%dmA)\n",
				__func__, charger->charging_current);
		data |= bq24260_get_fast_charging_current_data(
			charger->charging_current);
		dev_dbg(&client->dev, "%s : termination current (%dmA)\n",
			__func__, charger->pdata->charging_current[
			charger->cable_type].full_check_current_1st >= 300 ?
			300 : charger->pdata->charging_current[
			charger->cable_type].full_check_current_1st);
		data |= bq24260_get_termination_current_limit_data(
			charger->pdata->charging_current[
			charger->cable_type].full_check_current_1st);
		bq24260_set_command(client,
			BQ24260_CURRENT, data);

		/* Special Charger Voltage
		 * Normal charge current
		 */
		bq24260_i2c_read(client, BQ24260_SPECIAL, &data);
		data &= 0xdf;
		bq24260_set_command(client,
			BQ24260_SPECIAL, data);
	}
}

static void bq24260_charger_otg_conrol(
				struct i2c_client *client)
{
	struct sec_charger_info *charger = i2c_get_clientdata(client);
	u8 data;
	if (charger->cable_type ==
		POWER_SUPPLY_TYPE_BATTERY) {
		dev_info(&client->dev, "%s : turn off OTG\n", __func__);
		/* turn off OTG */
		bq24260_i2c_read(client, BQ24260_STATUS, &data);
		data &= 0xbf;
		bq24260_set_command(client,
			BQ24260_STATUS, data);
	} else {
		dev_info(&client->dev, "%s : turn on OTG\n", __func__);
		/* turn on OTG */
		bq24260_i2c_read(client, BQ24260_STATUS, &data);
		data |= 0x40;
		bq24260_set_command(client,
			BQ24260_STATUS, data);
	}
}

static int bq24260_get_charge_type(struct i2c_client *client)
{
	int ret;
	u8 data;

	bq24260_i2c_read(client, BQ24260_STATUS, &data);
	data = (data & 0x30)>>4;

	switch (data) {
	case 0x01:
		ret = POWER_SUPPLY_CHARGE_TYPE_FAST;
		break;
	default:
		ret = POWER_SUPPLY_CHARGE_TYPE_NONE;
		break;
	}

	return ret;
}

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

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

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

bool sec_hal_chg_get_property(struct i2c_client *client,
			      enum power_supply_property psp,
			      union power_supply_propval *val)
{
	struct sec_charger_info *charger = i2c_get_clientdata(client);
	u8 data;

	switch (psp) {
	case POWER_SUPPLY_PROP_STATUS:
		val->intval = bq24260_get_charging_status(client);
		break;
	case POWER_SUPPLY_PROP_CHARGE_TYPE:
		val->intval = bq24260_get_charge_type(client);
		break;
	case POWER_SUPPLY_PROP_HEALTH:
		val->intval = bq24260_get_charging_health(client);
		break;
	case POWER_SUPPLY_PROP_CURRENT_NOW:
		if (charger->charging_current) {
			/* Rsns 0.068 Ohm */
			bq24260_i2c_read(client, BQ24260_CURRENT, &data);
			val->intval = (data >> 3) * 100 + 500;
		} else
			val->intval = 0;
		dev_dbg(&client->dev,
			"%s : set-current(%dmA), current now(%dmA)\n",
			__func__, charger->charging_current, val->intval);
		break;
	default:
		return false;
	}
	return true;
}

bool sec_hal_chg_set_property(struct i2c_client *client,
			      enum power_supply_property psp,
			      const union power_supply_propval *val)
{
	struct sec_charger_info *charger = i2c_get_clientdata(client);

	switch (psp) {
	/* val->intval : type */
	case POWER_SUPPLY_PROP_ONLINE:
		if (charger->pdata->chg_gpio_en) {
			if (gpio_request(charger->pdata->chg_gpio_en,
				"CHG_EN") < 0) {
				dev_err(&client->dev,
					"failed to request vbus_in gpio\n");
				break;
			}
			if (charger->cable_type ==
				POWER_SUPPLY_TYPE_BATTERY)
				gpio_set_value_cansleep(
					charger->pdata->chg_gpio_en,
					charger->pdata->chg_polarity_en ?
					0 : 1);
			else
				gpio_set_value_cansleep(
					charger->pdata->chg_gpio_en,
					charger->pdata->chg_polarity_en ?
					1 : 0);
			gpio_free(charger->pdata->chg_gpio_en);
		}
	/* val->intval : charging current */
	case POWER_SUPPLY_PROP_CURRENT_NOW:
		if (charger->charging_current < 0)
			bq24260_charger_otg_conrol(client);
		else if (charger->charging_current > 0)
			bq24260_charger_function_conrol(client);
		else {
			bq24260_charger_function_conrol(client);
			bq24260_charger_otg_conrol(client);
		}
		bq24260_test_read(client);
		break;
	default:
		return false;
	}
	return true;
}

ssize_t sec_hal_chg_show_attrs(struct device *dev,
				const ptrdiff_t offset, char *buf)
{
	struct power_supply *psy = dev_get_drvdata(dev);
	struct sec_charger_info *chg =
		container_of(psy, struct sec_charger_info, psy_chg);
	int i = 0;
	char *str = NULL;

	switch (offset) {
	case CHG_REG:
		i += scnprintf(buf + i, PAGE_SIZE - i, "%x\n",
			chg->reg_addr);
		break;
	case CHG_DATA:
		i += scnprintf(buf + i, PAGE_SIZE - i, "%x\n",
			chg->reg_data);
		break;
	case CHG_REGS:
		str = kzalloc(sizeof(char)*1024, GFP_KERNEL);
		if (!str)
			return -ENOMEM;

		bq24260_read_regs(chg->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_chg_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_charger_info *chg =
		container_of(psy, struct sec_charger_info, psy_chg);
	int ret = 0;
	int x = 0;
	u8 data = 0;

	switch (offset) {
	case CHG_REG:
		if (sscanf(buf, "%x\n", &x) == 1) {
			chg->reg_addr = x;
			bq24260_i2c_read(chg->client,
				chg->reg_addr, &data);
			chg->reg_data = data;
			dev_dbg(dev, "%s: (read) addr = 0x%x, data = 0x%x\n",
				__func__, chg->reg_addr, chg->reg_data);
			ret = count;
		}
		break;
	case CHG_DATA:
		if (sscanf(buf, "%x\n", &x) == 1) {
			data = (u8)x;
			dev_dbg(dev, "%s: (write) addr = 0x%x, data = 0x%x\n",
				__func__, chg->reg_addr, data);
			bq24260_i2c_write(chg->client,
				chg->reg_addr, &data);
			ret = count;
		}
		break;
	default:
		ret = -EINVAL;
		break;
	}

	return ret;
}
