static int smb136_get_charging_state(void)
{
	struct smb136_chg_data *chg = smb136_chg;
	int status = POWER_SUPPLY_STATUS_UNKNOWN;
	u8 command_a_data, statue_e_data, statue_h_data;

	smb136_i2c_read(chg->client, SMB_CommandA, &command_a_data);
	smb136_i2c_read(chg->client, SMB_StatusE, &statue_e_data);
	smb136_i2c_read(chg->client, SMB_StatusH, &statue_h_data);

	if (statue_h_data & 0x01) {
		pr_debug("%s: POWER_SUPPLY_STATUS_CHARGING\n", __func__);
		return POWER_SUPPLY_STATUS_CHARGING;
	} else {
		if (!(statue_e_data & 0x06)) {
			pr_debug("%s: POWER_SUPPLY_STATUS_DISCHARGING\n"
				, __func__);
			return POWER_SUPPLY_STATUS_DISCHARGING;
		} else if ((statue_e_data & 0xc0)) {
			pr_debug("%s: POWER_SUPPLY_STATUS_FULL\n", __func__);
			return POWER_SUPPLY_STATUS_FULL;
		}
	}

	pr_info("%s: POWER_SUPPLY_STATUS_UNKNOWN\n", __func__);
	pr_info("%s: 0x31h(0x%02x), 0x36h(0x%02x), 0x39h(0x%02x)\n",
		__func__, command_a_data, statue_e_data, statue_h_data);
	return (int)status;
}
Beispiel #2
0
static ssize_t command_read(struct device *dev, struct device_attribute *attr, char *buf)
{
  struct smb136_chg_data *chg = smb136_chg;
  struct i2c_client *client = chg->client;
  u8 d1, d2;

  smb136_i2c_read(client, SMB_CommandA, &d1);
  smb136_i2c_read(client, SMB_ChargeCurrent, &d2);
  return sprintf(buf,"cmd=0x%x current=0x%x\n", d1, d2);
}
static void smb136_test_read(struct i2c_client *client)
{
	u8 data = 0;
	u32 addr = 0;
	for (addr = 0; addr <= 0x0C; addr++) {
		smb136_i2c_read(client, addr, &data);
		dev_dbg(&client->dev,
			"smb136 addr : 0x%02x data : 0x%02x\n", addr, data);
	}
	for (addr = 0x31; addr <= 0x3D; addr++) {
		smb136_i2c_read(client, addr, &data);
		dev_dbg(&client->dev,
			"smb136 addr : 0x%02x data : 0x%02x\n", addr, data);
	}
}
Beispiel #4
0
static irqreturn_t smb136_irq_thread(int irq, void *data)
{
	struct smb136_chip *chip = data;
#if defined (CONFIG_MACH_Q1_CHN) && defined (CONFIG_SMB136_CHARGER)
	int ret = 0;
	u8 data1=0;
#endif

	dev_info(&chip->client->dev, "%s\n", __func__);

	smb136_test_read(chip->client);
#if defined (CONFIG_MACH_Q1_CHN) && defined (CONFIG_SMB136_CHARGER)
	smb136_i2c_read(chip->client, 0x33, &data1);

	if (data1 & 0x02) {
		if(is_ovp_status == false) {
			is_ovp_status = true;
			if (chip->pdata->ovp_cb)
				ret = chip->pdata->ovp_cb(true);
			dev_info(&chip->client->dev, "$s OVP!!\n");
		}
	}
	else {
		if(is_ovp_status == true) {
			is_ovp_status = false;
			if(chip->pdata->ovp_cb)
				ret = chip->pdata->ovp_cb(false);
			dev_info(&chip->client->dev, "$s ovp status released!!\n");
		}
	}
#endif

	return IRQ_HANDLED;
}
static int smb136_get_charging_current(void)
{
	struct smb136_chg_data *chg = smb136_chg;
	u8 data = 0;
	int get_current = 0;

	smb136_i2c_read(chg->client, SMB_ChargeCurrent, &data);
	switch (data >> 5) {
	case 0:
		get_current = 500;	break;
	case 1:
		get_current = 650;	break;
	case 2:
		get_current = 750;	break;
	case 3:
		get_current = 850;	break;
	case 4:
		get_current = 950;	break;
	case 5:
		get_current = 1100;	break;
	case 6:
		get_current = 1300;	break;
	case 7:
		get_current = 1500;	break;
	default:
		get_current = 500;
		break;
	}
	pr_debug("%s: Get charging current as %dmA.\n", __func__, get_current);
	return get_current;
}
Beispiel #6
0
static int smb136_get_property(struct power_supply *psy,
			    enum power_supply_property psp,
			    union power_supply_propval *val)
{
	struct smb136_chip *chip = container_of(psy,
						  struct smb136_chip,
						  charger);
	u8 data;

	switch (psp) {
	case POWER_SUPPLY_PROP_STATUS:
		val->intval = smb136_get_charging_status(chip->client);
		break;
	case POWER_SUPPLY_PROP_CHARGE_TYPE:
		val->intval = chip->cable_type;
		break;
	case POWER_SUPPLY_PROP_ONLINE:
		val->intval = chip->is_enable;
		break;
	case POWER_SUPPLY_PROP_CURRENT_NOW:
		smb136_i2c_read(chip->client, SMB_ChargeCurrent, &data);
		switch (data >> 5) {
		case 0:
			val->intval = 500;
			break;
		case 1:
			val->intval = 650;
			break;
		case 2:
			val->intval = 750;
			break;
		case 3:
			val->intval = 850;
			break;
		case 4:
			val->intval = 950;
			break;
		case 5:
			val->intval = 1100;
			break;
		case 6:
			val->intval = 1300;
			break;
		case 7:
			val->intval = 1500;
			break;
		}
		break;
	default:
		return -EINVAL;
	}

	dev_info(&chip->client->dev, "%s: smb136_get_property (%d,%d)\n",
		__func__, psp, val->intval);

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

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

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

	for (addr = 0x30; addr <= 0x3D; addr++) {
		smb136_i2c_read(client, addr, &data);
		sprintf(str+strlen(str), "0x%x, ", data);
	}
}
Beispiel #8
0
static void smb136_test_read(struct i2c_client *client)
{
	struct smb136_chip * chg = i2c_get_clientdata(client);
	u8 data = 0;
	u32 addr = 0;

	for(addr=0;addr<0x0c;addr++)
	{
		smb136_i2c_read(chg->client, addr, &data);
		dev_info(&client->dev, "SMB136 addr : 0x%02x data : 0x%02x\n", addr,data);
	}

	for(addr=0x31;addr<0x3D;addr++)
	{
		smb136_i2c_read(chg->client, addr, &data);
		dev_info(&client->dev, "SMB136 addr : 0x%02x data : 0x%02x\n", addr,data);
	}
}
static void smb136_allow_volatile_writes(struct i2c_client *client)
{
	int val, reg;
	u8 data;
	reg = SMB136_COMMAND_A;
	val = smb136_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 (smb136_i2c_write(client, reg, &data) < 0)
			dev_err(&client->dev, "%s : error!\n", __func__);
		val = smb136_i2c_read(client, reg, &data);
		if (val >= 0) {
			data = (u8) data;
			dev_dbg(&client->dev, " => 0x%02x\n", data);
		}
	}
}
static void smb136_set_command(struct i2c_client *client,
				int reg, int datum)
{
	int val;
	u8 data = 0;
	val = smb136_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 (smb136_i2c_write(client, reg, &data) < 0)
				dev_err(&client->dev,
					"%s : error!\n", __func__);
			val = smb136_i2c_read(client, reg, &data);
			if (val >= 0)
				dev_dbg(&client->dev, " => 0x%02x\n", data);
		}
	}
}
static int smb136_get_charging_health(struct i2c_client *client)
{
	int health = POWER_SUPPLY_HEALTH_GOOD;
	u8 data_d = 0;
	u8 data_e = 0;

	smb136_i2c_read(client, SMB136_STATUS_D, &data_d);
	dev_info(&client->dev,
		"%s : charger status D(0x%02x)\n", __func__, data_d);
	smb136_i2c_read(client, SMB136_STATUS_E, &data_e);
	dev_info(&client->dev,
		"%s : charger status E(0x%02x)\n", __func__, data_e);

	/* Is enabled ? */
	if (data_e & 0x01) {
		if ((data_d & 0x40) != 0x40)	/* Input current is NOT OK */
			health = POWER_SUPPLY_HEALTH_UNDERVOLTAGE;
	}
	return (int)health;
}
Beispiel #12
0
u32 smb136_is_already_fullcharged(void)
{
	u8 data=0;
	smb136_i2c_read(smb136_i2c_client, 0x36, &data);		
	printk("SMB136 addr : 0x36 data : 0x%02x\n",data);

	if((data & 0xc0) == 0xc0)	// At least one charge cycle terminated, Charge current < Termination Current
		return 1;
	else
		return 0;
}
Beispiel #13
0
u32 smb136_is_fullcharging(void)
{
	u8 data=0;
	smb136_i2c_read(smb136_i2c_client, 0x36, &data);		
	printk("SMB136 addr : 0x36 data : 0x%02x\n",data);

	if(data & 0x40)	// Charge current < Termination Current
		return 1;
	else
		return 0;
}
Beispiel #14
0
u32 smb136_is_charging_active(void)
{
	u8 data=0;
	smb136_i2c_read(smb136_i2c_client, 0x39, &data);		
	printk("SMB136 addr : 0x39 data : 0x%02x\n",data);

	if(data & 0x01)
		return 1;
	else
		return 0;
}
static void smb136_test_read(void)
{
	struct smb136_chg_data *chg = smb136_chg;
	u8 data = 0;
	u32 addr = 0;

	if (!charger_i2c_init) {
		pr_info("%s : smb136 charger IC i2c is not initialized!!\n"
			, __func__);
		return ;
	}

	for (addr = 0; addr < 0x0c; addr++) {
		smb136_i2c_read(chg->client, addr, &data);
		pr_info("SMB136 addr : 0x%02x data : 0x%02x\n", addr, data);
	}

	for (addr = 0x31; addr < 0x3D; addr++) {
		smb136_i2c_read(chg->client, addr, &data);
		pr_info("SMB136 addr : 0x%02x data : 0x%02x\n", addr, data);
	}
}
Beispiel #16
0
int smb136_get_charging_status(void)
{
	struct smb136_chg_data *chg = smb136_chg;
	enum charging_status_type_t status = CHARGING_STATUS_NONE;
	u8 data1 = 0;
	u8 data2 = 0;

	smb136_i2c_read(chg->client, 0x36, &data1);
	smb136_i2c_read(chg->client, 0x39, &data2);
	printk("%s : 0x36h(0x%02x), 0x39h(0x%02x)\n", __func__, data1, data2);

	if(data2 & 0x01)
		status = CHARGING_STATUS_ACTIVE;
	else {
		if ((data1 & 0x08) == 0x08)  // if error bit check, ignore the status of charger-ic
			status = CHARGING_STATUS_ERROR;
		else if((data1 & 0xc0) == 0xc0)  // At least one charge cycle terminated, Charge current < Termination Current
			status = CHARGING_STATUS_FULL;
	}

	return (int)status;
}
static int smb136_get_charging_status(struct i2c_client *client)
{
	int status = POWER_SUPPLY_STATUS_UNKNOWN;
	u8 data_d = 0;
	u8 data_e = 0;

	smb136_i2c_read(client, SMB136_STATUS_D, &data_d);
	dev_info(&client->dev,
		"%s : charger status D(0x%02x)\n", __func__, data_d);
	smb136_i2c_read(client, SMB136_STATUS_E, &data_e);
	dev_info(&client->dev,
		"%s : charger status E(0x%02x)\n", __func__, data_e);

	/* At least one charge cycle terminated,
	 * Charge current < Termination Current
	 */
	if ((data_e & 0x40) == 0x40) {
		/* top-off by full charging */
		status = POWER_SUPPLY_STATUS_FULL;
		goto charging_status_end;
	}

	/* Is enabled ? */
	if (data_e & 0x01) {
		/* check for 0x06 : no charging (0b00) */
		/* not charging */
		if (!(data_e & 0x06)) {
			status = POWER_SUPPLY_STATUS_NOT_CHARGING;
			goto charging_status_end;
		} else {
			status = POWER_SUPPLY_STATUS_CHARGING;
			goto charging_status_end;
		}
	} else
		status = POWER_SUPPLY_STATUS_DISCHARGING;
charging_status_end:
	return (int)status;
}
u32 smb136_is_fullcharging(void)
{
	u8 data=0;
	smb136_i2c_read(smb136_i2c_client, 0x36, &data);		
	printk("SMB136 addr : 0x36 data : 0x%02x\n",data);

	if ((data & 0x08) == 0x08) // if error bit check, ignore the status of charger-ic
  		return 0;

	if(data & 0x40)	// Charge current < Termination Current
		return 1;
	else
		return 0;
}
Beispiel #19
0
void smb136_test_read(void)
{
	u8 data;
	u32 addr;

	if(!charger_i2c_init) {
		printk("%s : smb136 charger IC i2c is not initialized!!\n", __func__);
		return ;
	}

	for(addr=0;addr<0x0c;addr++)
	{
		smb136_i2c_read(smb136_i2c_client, addr, &data);		
		printk("SMB136 addr : 0x%02x data : 0x%02x\n", addr,data);
	}

	for(addr=0x31;addr<0x3D;addr++)
	{
		smb136_i2c_read(smb136_i2c_client, addr, &data);		
		printk("SMB136 addr : 0x%02x data : 0x%02x\n", addr,data);
	}

}
Beispiel #20
0
static int smb136_get_charging_status(struct i2c_client *client)
{
	struct smb136_chip *chg = i2c_get_clientdata(client);
	int status = POWER_SUPPLY_STATUS_UNKNOWN;
	u8 data1 = 0;
	u8 data2 = 0;

	smb136_i2c_read(chg->client, 0x36, &data1);
	smb136_i2c_read(chg->client, 0x39, &data2);
	dev_info(&client->dev, "%s : 0x36h(0x%02x), 0x39h(0x%02x)\n",
		__func__, data1, data2);

	if(data2 & 0x01)
		status = POWER_SUPPLY_STATUS_CHARGING;
	else {
		if ((data1 & 0x08) == 0x08)  // if error bit check, ignore the status of charger-ic
			status = POWER_SUPPLY_STATUS_NOT_CHARGING;
		else if((data1 & 0xc0) == 0xc0)  // At least one charge cycle terminated, Charge current < Termination Current
			status = POWER_SUPPLY_STATUS_FULL;
	}

	return (int)status;
}
Beispiel #21
0
u32 smb136_is_already_fullcharged(void)
{
	u8 data=0;
	smb136_i2c_read(smb136_i2c_client, 0x36, &data);		
	printk("SMB136 addr : 0x36 data : 0x%02x\n",data);

#ifdef CONFIG_TARGET_LOCALE_VZW
	if ((data & 0x08) == 0x08)	// hanapark_P1 : return if charge error (2010-10-02)
		return 0;
#endif

	if((data & 0xc0) == 0xc0)	// At least one charge cycle terminated, Charge current < Termination Current
		return 1;
	else 
		return 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;
			smb136_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);
			smb136_i2c_write(chg->client,
				chg->reg_addr, &data);
			ret = count;
		}
		break;
	default:
		ret = -EINVAL;
		break;
	}

	return ret;
}
static void smb136_charger_function_conrol(
				struct i2c_client *client)
{
	struct sec_charger_info *charger = i2c_get_clientdata(client);
	u8 data;
	u8 cur_reg;
	u8 chg_cur_reg;

	if (charger->charging_current < 0) {
		dev_dbg(&client->dev,
			"%s : OTG is activated. Ignore command!\n", __func__);
		return;
	}
	smb136_allow_volatile_writes(client);

	if (charger->cable_type ==
		POWER_SUPPLY_TYPE_BATTERY) {
		/* turn off charger */
		smb136_set_command(client,
			SMB136_COMMAND_A, 0x80);
	} else {
		/* Pre-charge curr 250mA */
		dev_dbg(&client->dev,
			"%s : fast charging current (%dmA)\n",
			__func__, charger->charging_current);
		dev_dbg(&client->dev,
			"%s : termination current (%dmA)\n",
			__func__, charger->pdata->charging_current[
			charger->cable_type].full_check_current_1st);

		smb136_i2c_read(client, SMB136_CHARGE_CURRENT, &chg_cur_reg);
		chg_cur_reg &= 0x18;
		data = smb136_get_fast_charging_current_data(
			charger->charging_current) | chg_cur_reg;
		data |= smb136_get_termination_current_limit_data(
			charger->pdata->charging_current[
			charger->cable_type].full_check_current_1st);
		smb136_set_command(client,
			SMB136_CHARGE_CURRENT, data);

		/* Pin enable control */
		/* DCIN Input Pre-bias Enable */
		smb136_i2c_read(client, SMB136_PIN_ENABLE_CONTROL, &data);
		if (charger->pdata->chg_gpio_en)
			data |= 0x40;
		smb136_set_command(client,
			SMB136_PIN_ENABLE_CONTROL, data);

		/* Input current limit */
		dev_dbg(&client->dev, "%s : input current (%dmA)\n",
			__func__, charger->pdata->charging_current
			[charger->cable_type].input_current_limit);
		data = 0;
		data = smb136_get_input_current_limit_data(
			charger,
			charger->pdata->charging_current
			[charger->cable_type].input_current_limit);
		smb136_i2c_read(client, SMB136_INPUT_CURRENTLIMIT, &cur_reg);
		data |= (cur_reg & 0xF);
		smb136_set_command(client,
			SMB136_INPUT_CURRENTLIMIT, data);

		/* Float voltage, Vprechg : 2.4V */
		dev_dbg(&client->dev, "%s : float voltage (%dmV)\n",
				__func__, charger->pdata->chg_float_voltage);
		data = 0;
		data |= smb136_get_float_voltage_data(
			charger->pdata->chg_float_voltage);
		smb136_set_command(client,
			SMB136_FLOAT_VOLTAGE, data);

		/* 4. Automatic Recharge Disabed */
		data = 0x8C;
		smb136_i2c_write(client, SMB136_CHARGE_CONTROL_A, &data);

		/* 5. Safty timer Disabled */
		data = 0x28;
		smb136_i2c_write(client, SMB136_CHARGE_CONTROL_B, &data);

		/* 6. Disable USB D+/D- Detection */
		data = 0x28;
		smb136_i2c_write(client, SMB136_OTG_CONTROL, &data);

		/* 9. Re-load Enable */
		data = 0x4B;
		smb136_i2c_write(client, SMB136_SAFTY, &data);

		/* HC or USB5 mode */
		smb136_i2c_read(client, SMB136_COMMAND_A, &data);
		data &= 0xF3;
		switch (charger->cable_type) {
		case POWER_SUPPLY_TYPE_MAINS:
		case POWER_SUPPLY_TYPE_MISC:
			/* High-current mode */
			data |= 0x0C;
			break;
		case POWER_SUPPLY_TYPE_USB:
		case POWER_SUPPLY_TYPE_USB_DCP:
		case POWER_SUPPLY_TYPE_USB_CDP:
		case POWER_SUPPLY_TYPE_USB_ACA:
			/* USB5 */
			data |= 0x08;
			break;
		default:
			/* USB1 */
			data = 0x00;
			break;
		}
		smb136_set_command(client,
			SMB136_COMMAND_A, data);
	}
}
Beispiel #24
0
void smb136_set_otg_mode(int enable)
{
	struct i2c_client *client = smb136_i2c_client;
	u8 data;

	printk("[SMB136] %s (enable : %d)\n", __func__, enable);

	if(!charger_i2c_init) {
		printk("%s : smb136 charger IC i2c is not initialized!!\n", __func__);
		return ;
	}

	if(enable)  // Enable OTG Mode
	{
		// 1. Set OTG Mode (Clear Bit5 of Pin Control)
		smb136_i2c_read(client, SMB_PinControl, &data);
		data &= ~(0x1 << 5);
		smb136_i2c_write(client, SMB_PinControl, data);
		udelay(10);

		// 2. Enable OTG Mode (Set Bit1 of Command Register A)
		smb136_i2c_read(client, SMB_CommandA, &data);
		data |= (0x1 << 1);
		smb136_i2c_write(client, SMB_CommandA, data);
		udelay(10);
	}
	else  // Re-init charger IC
	{
		// 1. Allow volatile writes to 00~09h, USB 500mA Mode, USB5/1 Mode
		data = 0x88;
		smb136_i2c_write(client, SMB_CommandA, data);
		udelay(10);

		// 2. Change USB5/1/HC Control from Pin to I2C
		data = 0x08;
		smb136_i2c_write(client, SMB_PinControl, data);
		udelay(10);

		// 3. Allow volatile writes to 00~09h, USB 500mA Mode, USB5/1 Mode
		data = 0x88;
		smb136_i2c_write(client, SMB_CommandA, data);
		udelay(10);

		// 4. Disable Automatic Input Current Limit
		data = 0xe6;
		smb136_i2c_write(client, SMB_InputCurrentLimit, data);
		udelay(10);

		//5. Fast Charge Current set 500mA
#ifdef CONFIG_TARGET_LOCALE_VZW
		data = 0xf2;
#else 
		data = 0xf4;
#endif
		smb136_i2c_write(client, SMB_ChargeCurrent, data);
		udelay(10);

		//6. Automatic Recharge Disabed
		data = 0x8c;
		smb136_i2c_write(client, SMB_ControlA, data);
		udelay(10);

		//7. Safty timer Disabled
		data = 0x28;
		smb136_i2c_write(client, SMB_ControlB, data);
		udelay(10);

		//8. Disable USB D+/D- Detection
		data = 0x28;
		smb136_i2c_write(client, SMB_OTGControl, data);
		udelay(10);

		//9. Set Output Polarity for STAT
		data = 0xca;
		smb136_i2c_write(client, SMB_FloatVoltage, data);
		udelay(10);

		//10. Re-load Enable
		data = 0x4b;
		smb136_i2c_write(client, SMB_SafetyTimer, data);
		udelay(10);
	}

	smb136_test_read();
}
Beispiel #25
0
static int smb136_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
	struct smb136_chip *chip;
	int ret = 0;
	int gpio = 0;
	u8 data;

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
		return -EIO;

	if (smb136_i2c_read(client, 0x36, &data)<0)	/* check HW */
		return -EIO;

	dev_info(&client->dev, "%s : SMB136 Charger Driver Loading\n", __func__);

	chip = kzalloc(sizeof(struct smb136_chip), GFP_KERNEL);
	if (!chip)
		return -ENOMEM;

	chip->client = client;
	chip->pdata = client->dev.platform_data;

	i2c_set_clientdata(client, chip);

	if (!chip->pdata) {
		dev_err(&client->dev, "%s : No platform data supplied\n", __func__);
		ret = -EINVAL;
		goto err_pdata;
	}

	if (chip->pdata->set_charger_name)
		chip->pdata->set_charger_name();

	chip->is_enable = false;
	chip->cable_type = CABLE_TYPE_NONE;

	chip->charger.name		= "smb136-charger";
	chip->charger.type		= POWER_SUPPLY_TYPE_BATTERY;
	chip->charger.get_property	= smb136_get_property;
	chip->charger.set_property	= smb136_set_property;
	chip->charger.properties	= smb136_charger_props;
	chip->charger.num_properties	= ARRAY_SIZE(smb136_charger_props);

	ret = power_supply_register(&client->dev, &chip->charger);
	if (ret) {
		dev_err(&client->dev, "failed: power supply register\n");
		kfree(chip);
		return ret;
	}

	
	/* CHG_EN pin control - active low */
	if (chip->pdata->gpio_chg_en) {
		s3c_gpio_cfgpin(chip->pdata->gpio_chg_en, S3C_GPIO_OUTPUT);
		s3c_gpio_setpull(chip->pdata->gpio_chg_en, S3C_GPIO_PULL_NONE);

		gpio = gpio_request(chip->pdata->gpio_chg_en, "CHG_EN");
		if (!gpio) {
			gpio_direction_output(chip->pdata->gpio_chg_en, GPIO_LEVEL_HIGH);
			gpio_free(chip->pdata->gpio_chg_en);
		} else
			dev_err(&client->dev,
			"faile to request gpio(CHG_EN)\n");
	}

	if (chip->pdata->gpio_otg_en) {
		s3c_gpio_cfgpin(chip->pdata->gpio_otg_en, S3C_GPIO_OUTPUT);
		s3c_gpio_setpull(chip->pdata->gpio_otg_en, S3C_GPIO_PULL_NONE);

		gpio = gpio_request(chip->pdata->gpio_otg_en, "OTG_EN");
		if (!gpio) {
			gpio_direction_output(chip->pdata->gpio_otg_en, GPIO_LEVEL_LOW);
			gpio_free(chip->pdata->gpio_otg_en);
		} else
			dev_err(&client->dev,
			"faile to request gpio(OTG_EN)\n");
	}

	if (chip->pdata->gpio_ta_nconnected) {
		s3c_gpio_cfgpin(chip->pdata->gpio_ta_nconnected, S3C_GPIO_INPUT);
		s3c_gpio_setpull(chip->pdata->gpio_ta_nconnected, S3C_GPIO_PULL_NONE);
	}

	if (chip->pdata->gpio_chg_ing) {
#if 1
#if defined (CONFIG_MACH_Q1_CHN) && defined (CONFIG_SMB136_CHARGER)
		s3c_gpio_cfgpin(chip->pdata->gpio_chg_ing, S3C_GPIO_SFN(0xf));
#endif
		client->irq = gpio_to_irq(chip->pdata->gpio_chg_ing);
		ret = smb136_irq_init(chip);
		if (ret)
			goto err_pdata;
#else
		s3c_gpio_cfgpin(chip->pdata->gpio_chg_ing, S3C_GPIO_INPUT);
		s3c_gpio_setpull(chip->pdata->gpio_chg_ing, S3C_GPIO_PULL_NONE);
#endif
	}

	smb136_test_read(client);

	return 0;

err_pdata:
	kfree(chip);
	return ret;
}