static void smb347_set_charging_state(struct smb_charger_callbacks *ptr,
		int cable_status)
{
	struct smb347_chg_data *chg = container_of(ptr,
			struct smb347_chg_data, callbacks);

	if (cable_status) {
		/* Init smb347 charger */
		smb347_charger_init(chg);

		switch (cable_status) {
		case CABLE_TYPE_AC:
			/* Input current limit : DCIN 1800mA, USBIN HC 1800mA */
			smb347_i2c_write(chg->client,
				SMB347_INPUT_CURRENTLIMIT, 0x66);

			/* CommandB : High-current mode */
			smb347_i2c_write(chg->client, SMB347_COMMAND_B, 0x03);

			pr_info("%s : 1.8A charging enable\n", __func__);
			break;
		case CABLE_TYPE_USB:
			/* CommandB : USB5 */
			smb347_i2c_write(chg->client, SMB347_COMMAND_B, 0x02);
			pr_info("%s : LOW(USB5) charging enable\n", __func__);
			break;
		default:
			/* CommandB : USB1 */
			smb347_i2c_write(chg->client, SMB347_COMMAND_B, 0x00);
			pr_info("%s : LOW(USB1) charging enable\n", __func__);
			break;
		}
	}
}
void smb347_set_charging_current(int set_current)
{
	struct smb347_chg_data *chg = smb347_chg;

	if (set_current > 450) {
		/* CommandB : High-current mode */
		smb347_i2c_write(chg->client, SMB347_COMMAND_B, 0x03);
		udelay(10);
	} else {
		/* CommandB : USB5 */
		smb347_i2c_write(chg->client, SMB347_COMMAND_B, 0x02);
		udelay(10);
	}
	pr_debug("%s: Set charging current as %dmA.\n", __func__, set_current);
}
Exemplo n.º 3
0
static void smb347_i2c_write_array(struct i2c_client *client,
				u8 *buf, int size)
{
	int i;
	for (i = 0; i < size; i += 3)
		smb347_i2c_write(client, (u8) (*(buf + i)), (buf + i) + 1);
}
static void smb347_set_charging_state(int enable, int charging_mode)
{
	struct smb347_chg_data *chg = smb347_chg;
	pr_info("%s : enable(%d), charging_mode(%d)\n",
		__func__, enable, charging_mode);

	if (enable) {
		/* Only for P4C rev0.2, Check vbus for opeartion charger */
		if (!smb347_check_powersource(chg))
			return;

		/* Init smb347 charger */
		smb347_charger_init(chg);

		switch (charging_mode) {
		case CABLE_TYPE_TA:
			/* Input current limit : DCIN 1800mA, USBIN HC 1800mA */
			smb347_i2c_write(chg->client,
				SMB347_INPUT_CURRENTLIMIT, 0x66);

			/* CommandB : High-current mode */
			smb347_i2c_write(chg->client, SMB347_COMMAND_B, 0x03);

			pr_info("%s : 1.8A charging enable\n", __func__);
			break;
		case CABLE_TYPE_DESKDOCK:
			/* Input current limit : DCIN 1500mA, USBIN HC 1500mA */
			smb347_i2c_write(chg->client,
				SMB347_INPUT_CURRENTLIMIT, 0x55);

			/* CommandB : High-current mode */
			smb347_i2c_write(chg->client, SMB347_COMMAND_B, 0x03);
			pr_info("%s : 1.5A charging enable\n", __func__);
			break;
		case CABLE_TYPE_USB:
			/* CommandB : USB5 */
			smb347_i2c_write(chg->client, SMB347_COMMAND_B, 0x02);
			pr_info("%s : LOW(USB5) charging enable\n", __func__);
			break;
		default:
			/* CommandB : USB1 */
			smb347_i2c_write(chg->client, SMB347_COMMAND_B, 0x00);
			pr_info("%s : LOW(USB1) charging enable\n", __func__);
			break;
		}

		smb347_enable_charging(chg);
	} else {
		smb347_disable_charging(chg);
	}

	smb347_test_read();
}
Exemplo n.º 5
0
static void smb347_allow_volatile_writes(struct i2c_client *client)
{
	int val, reg;
	u8 data;
	reg = SMB347_COMMAND_A;
	val = smb347_i2c_read(client, reg, &data);
	if ((val >= 0) && !(data & 0x80)) {
		dev_dbg(&client->dev,
			"%s : reg(0x%02x): 0x%02x", __func__, reg, data);
		data |= (0x1 << 7);
		if (smb347_i2c_write(client, reg, &data) < 0)
			dev_err(&client->dev, "%s : error!\n", __func__);
		val = smb347_i2c_read(client, reg, &data);
		if (val >= 0) {
			data = (u8) data;
			dev_dbg(&client->dev, " => 0x%02x\n", data);
		}
	}
}
Exemplo n.º 6
0
static void smb347_set_command(struct i2c_client *client,
				int reg, int datum)
{
	int val;
	u8 data = 0;
	val = smb347_i2c_read(client, reg, &data);
	if (val >= 0) {
		dev_dbg(&client->dev, "%s : reg(0x%02x): 0x%02x",
			__func__, reg, data);
		if (data != datum) {
			data = datum;
			if (smb347_i2c_write(client, reg, &data) < 0)
				dev_err(&client->dev,
					"%s : error!\n", __func__);
			val = smb347_i2c_read(client, reg, &data);
			if (val >= 0)
				dev_dbg(&client->dev, " => 0x%02x\n", data);
		}
	}
}
Exemplo n.º 7
0
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;
			smb347_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);
			smb347_i2c_write(chg->client,
				chg->reg_addr, &data);
			ret = count;
		}
		break;
	default:
		ret = -EINVAL;
		break;
	}

	return ret;
}
static void smb347_charger_init(struct smb347_chg_data *chg)
{
	/* Allow volatile writes to CONFIG registers */
	smb347_i2c_write(chg->client, SMB347_COMMAND_A, 0x80);

	/* Command B : USB1 mode, USB mode */
	smb347_i2c_write(chg->client, SMB347_COMMAND_B, 0x00);

	/* Charge curr : Fast-chg 2200mA */
	/* Pre-charge curr 250mA, Term curr 250mA */
	smb347_i2c_write(chg->client, SMB347_CHARGE_CURRENT, 0xDD);

	/* Pin enable control : Charger enable control EN Pin - Active Low */
	/*  : USB5/1/HC or USB9/1.5/HC Control - Register Control */
	/*  : USB5/1/HC Input state - Tri-state Input */
	smb347_i2c_write(chg->client, SMB347_PIN_ENABLE_CONTROL, 0x60);

	/* Input current limit : DCIN 1800mA, USBIN HC 1800mA */
	smb347_i2c_write(chg->client, SMB347_INPUT_CURRENTLIMIT, 0x66);

	/* Various func. : USBIN primary input, VCHG func. enable */
	smb347_i2c_write(chg->client, SMB347_VARIOUS_FUNCTIONS, 0x87);

	/* Float voltage : 4.2V */
	smb347_i2c_write(chg->client, SMB347_FLOAT_VOLTAGE, 0x63);

	/* Charge control : Auto recharge disable, APSD disable */
	smb347_i2c_write(chg->client, SMB347_CHARGE_CONTROL, 0x80);

	/* STAT, Timer control : STAT active low, Complete time out 1527min. */
	smb347_i2c_write(chg->client, SMB347_STAT_TIMERS_CONTROL, 0x1A);

	/* Therm control : Therm monitor disable */
	smb347_i2c_write(chg->client, SMB347_THERM_CONTROL_A, 0x7F);

	/* USB selection : USB2.0(100mA/500mA), INOK polarity */
	/* Active low */
	smb347_i2c_write(chg->client, SMB347_SYSOK_USB30_SELECTION, 0x08);

	/* Other control */
	smb347_i2c_write(chg->client, SMB347_OTHER_CONTROL_A, 0x1D);

	/* OTG tlim therm control */
	smb347_i2c_write(chg->client, SMB347_OTG_TLIM_THERM_CONTROL, 0x3F);

	/* Limit cell temperature */
	smb347_i2c_write(chg->client,
			SMB347_LIMIT_CELL_TEMPERATURE_MONITOR, 0x01);

	/* Fault interrupt : Clear */
	smb347_i2c_write(chg->client, SMB347_FAULT_INTERRUPT, 0x00);

	/* STATUS ingerrupt : Clear */
	smb347_i2c_write(chg->client, SMB347_STATUS_INTERRUPT, 0x00);
	msleep(50);
}
static void smb347_charger_init(struct smb347_chg_data *chg)
{
	pr_info("%s\n", __func__);

	/* Only for P4C rev0.2, Check vbus for opeartion charger */
	if (!smb347_check_powersource(chg))
		return;

	/* Set GPIO_TA_EN as HIGH, charging disable */
	smb347_disable_charging(chg);
	mdelay(100);

	/* Allow volatile writes to CONFIG registers */
	smb347_i2c_write(chg->client, SMB347_COMMAND_A, 0x80);

	/* Command B : USB1 mode, USB mode */
	smb347_i2c_write(chg->client, SMB347_COMMAND_B, 0x00);

	/* Charge curr : Fast-chg 2200mA */
	/* Pre-charge curr 250mA, Term curr 250mA */
	smb347_i2c_write(chg->client, SMB347_CHARGE_CURRENT, 0xDD);

	/* Pin enable control : Charger enable control EN Pin - Active Low */
	/*  : USB5/1/HC or USB9/1.5/HC Control - Register Control */
	/*  : USB5/1/HC Input state - Tri-state Input */
	smb347_i2c_write(chg->client, SMB347_PIN_ENABLE_CONTROL, 0x60);

	/* Input current limit : DCIN 1800mA, USBIN HC 1800mA */
	smb347_i2c_write(chg->client, SMB347_INPUT_CURRENTLIMIT, 0x66);

	/* Various func. : USBIN primary input, VCHG func. enable */
	smb347_i2c_write(chg->client, SMB347_VARIOUS_FUNCTIONS, 0xA7);

	/* Float voltage : 4.2V */
	smb347_i2c_write(chg->client, SMB347_FLOAT_VOLTAGE, 0x63);

	/* Charge control : Auto recharge disable, APSD disable */
	smb347_i2c_write(chg->client, SMB347_CHARGE_CONTROL, 0x80);

	/* STAT, Timer control : STAT active low, Complete time out 1527min. */
	smb347_i2c_write(chg->client, SMB347_STAT_TIMERS_CONTROL, 0x1A);

	/* Therm control : Therm monitor disable */
	smb347_i2c_write(chg->client, SMB347_THERM_CONTROL_A, 0xBF);

	/* USB selection : USB2.0(100mA/500mA), INOK polarity */
	if ((system_rev >= 2) && (system_rev <= 5)) {
		/* Active high */
		smb347_i2c_write(chg->client, SMB347_SYSOK_USB30_SELECTION,
		0x09);
	} else {
		/* Active low */
		smb347_i2c_write(chg->client, SMB347_SYSOK_USB30_SELECTION,
		0x08);
	}

	/* Other control */
	smb347_i2c_write(chg->client, SMB347_OTHER_CONTROL_A, 0x0D);

	/* OTG tlim therm control */
	smb347_i2c_write(chg->client, SMB347_OTG_TLIM_THERM_CONTROL, 0x3F);

	/* Limit cell temperature */
	smb347_i2c_write(chg->client, SMB347_LIMIT_CELL_TEMPERATURE_MONITOR,
	0x01);

	/* Fault interrupt : Clear */
	smb347_i2c_write(chg->client, SMB347_FAULT_INTERRUPT, 0x00);

	/* STATUS ingerrupt : Clear */
	smb347_i2c_write(chg->client, SMB347_STATUS_INTERRUPT, 0x00);
}