static void smsc375x_pwrsrc_event_worker(struct work_struct *work)
{
	struct smsc375x_chip *chip =
	    container_of(work, struct smsc375x_chip, vbus_work);
	int ret;

	pm_runtime_get_sync(&chip->client->dev);

	if (chip->id_short && chip->pdata->is_vbus_online()) {
		/*
		 * only after reading the status register
		 * MUX path is being closed. And by default
		 * MUX is to connected Host mode path.
		 */
		ret = smsc375x_read_reg(chip->client, SMSC375X_REG_STAT);
		if (ret < 0)
			dev_warn(&chip->client->dev,
				"status read failed%d\n", ret);
		else
			dev_info(&chip->client->dev, "Stat:%x\n", ret);
	} else {
		smsc375x_detect_dev(chip);
	}

	pm_runtime_put_sync(&chip->client->dev);
}
static void smsc375x_pwrsrc_event_worker(struct work_struct *work)
{
	struct smsc375x_chip *chip =
	    container_of(work, struct smsc375x_chip, vbus_work);
	int ret;

	pm_runtime_get_sync(&chip->client->dev);

	/*
	 * Sometimes SMSC INT triggering is only
	 * happening after reading the status bits.
	 * So we are reading the status register as WA
	 * to invoke teh MUX INT in case of connect events.
	 */
	if (!chip->pdata->is_vbus_online())
		ret = smsc375x_detect_dev(chip);
	else
		ret = smsc375x_read_reg(chip->client, SMSC375X_REG_STAT);
	if (ret < 0)
		dev_warn(&chip->client->dev, "pwrsrc evt error\n");

	pm_runtime_put_sync(&chip->client->dev);
}
static int smsc375x_detect_dev(struct smsc375x_chip *chip)
{
	struct i2c_client *client = chip->client;
	static bool notify_otg, notify_charger;
	static char *cable;
	static struct power_supply_cable_props cable_props;
	int stat, cfg, ret, vbus_mask = 0;
	u8 chrg_type;
	bool vbus_attach = false;

	dev_info(&chip->client->dev, "%s\n", __func__);
	/*
	 * get VBUS status from external IC like
	 * PMIC or Charger as SMSC375x chip can not
	 * be accessed with out VBUS.
	 */
	ret = chip->pdata->is_vbus_online();
	if (ret < 0) {
		dev_info(&chip->client->dev, "get vbus stat error\n");
		return ret;
	}

	if (ret) {
		dev_info(&chip->client->dev, "VBUS present\n");
		vbus_attach = true;
	} else {
		dev_info(&chip->client->dev, "VBUS NOT present\n");
		vbus_attach = false;
		cable_props.ma = 0;
		cable_props.chrg_evt = POWER_SUPPLY_CHARGER_EVENT_DISCONNECT;
		goto notify_otg_em;
	}

	/* dont proceed with charger detection in host mode */
	if (chip->id_short) {
		/*
		 * only after reading the status register
		 * MUX path is being closed. And by default
		 * MUX is to connected Host mode path.
		 */
		ret = smsc375x_read_reg(client, SMSC375X_REG_STAT);
		return ret;
	}
	/* check charger detection completion status */
	ret = smsc375x_read_reg(client, SMSC375X_REG_STAT);
	if (ret < 0)
		goto dev_det_i2c_failed;
	else
		stat = ret;

	if (!(stat & STAT_CHRG_DET_DONE)) {
		dev_info(&chip->client->dev, "DET failed");
		return -EFAULT;
	}


	ret = smsc375x_read_reg(client, SMSC375X_REG_CFG);
	if (ret < 0)
		goto dev_det_i2c_failed;
	else
		cfg = ret;

	dev_info(&client->dev, "Stat:%x, Cfg:%x\n", stat, cfg);

	chrg_type = stat & STAT_CHRG_TYPE_MASK;
	chip->is_sdp = false;

	if (chrg_type == STAT_CHRG_TYPE_SDP) {
		dev_info(&chip->client->dev,
				"SDP cable connecetd\n");
		notify_otg = true;
		vbus_mask = 1;
		notify_charger = true;
		chip->is_sdp = true;
		cable = SMSC375X_EXTCON_SDP;
		cable_props.chrg_evt = POWER_SUPPLY_CHARGER_EVENT_CONNECT;
		cable_props.chrg_type = POWER_SUPPLY_CHARGER_TYPE_USB_SDP;
		if (chip->pdata->charging_compliance_override)
			cable_props.ma = SMSC_CHARGE_CUR_SDP_500;
		else
			cable_props.ma = SMSC_CHARGE_CUR_SDP_100;
	} else if (chrg_type == STAT_CHRG_TYPE_CDP) {
		dev_info(&chip->client->dev,
				"CDP cable connecetd\n");
		notify_otg = true;
		vbus_mask = 1;
		notify_charger = true;
		cable = SMSC375X_EXTCON_CDP;
		cable_props.chrg_evt = POWER_SUPPLY_CHARGER_EVENT_CONNECT;
		cable_props.chrg_type = POWER_SUPPLY_CHARGER_TYPE_USB_CDP;
		cable_props.ma = SMSC_CHARGE_CUR_CDP;
	} else if ((chrg_type == STAT_CHRG_TYPE_DCP) ||
			(chrg_type == STAT_CHRG_TYPE_SE1L) ||
			(chrg_type == STAT_CHRG_TYPE_SE1H)) {
		dev_info(&chip->client->dev,
				"DCP/SE1 cable connecetd\n");
		notify_charger = true;
		cable = SMSC375X_EXTCON_DCP;
		cable_props.chrg_evt = POWER_SUPPLY_CHARGER_EVENT_CONNECT;
		cable_props.chrg_type = POWER_SUPPLY_CHARGER_TYPE_USB_DCP;
		cable_props.ma = SMSC_CHARGE_CUR_DCP;
		if (!wake_lock_active(&chip->wakelock))
			wake_lock(&chip->wakelock);
	} else {
		dev_warn(&chip->client->dev,
			"disconnect or unknown or ID event\n");
		cable_props.ma = 0;
		cable_props.chrg_evt = POWER_SUPPLY_CHARGER_EVENT_DISCONNECT;
	}

notify_otg_em:
	if (!vbus_attach) {	/* disconnevt event */
		if (notify_otg) {
			atomic_notifier_call_chain(&chip->otg->notifier,
						USB_EVENT_VBUS, &vbus_mask);
			notify_otg = false;
		}
		if (notify_charger) {
			/*
			 * not supporting extcon events currently.
			 * extcon_set_cable_state(chip->edev, cable, false);
			 */
			atomic_notifier_call_chain(&power_supply_notifier,
					POWER_SUPPLY_CABLE_EVENT, &cable_props);
			notify_charger = false;
			cable = NULL;
		}
		if (wake_lock_active(&chip->wakelock))
			wake_unlock(&chip->wakelock);
	} else {
		if (notify_otg) {
			/* close mux path to enable device mode */
			ret = smsc375x_write_reg(client, SMSC375X_REG_CFG,
					(cfg & ~CFG_EN_MUX1) | CFG_EN_MUX2);
			if (ret < 0)
				goto dev_det_i2c_failed;
			atomic_notifier_call_chain(&chip->otg->notifier,
						USB_EVENT_VBUS, &vbus_mask);
		}

		if (notify_charger) {
			/*
			 * not supporting extcon events currently.
			 * extcon_set_cable_state(chip->edev, cable, true);
			 */
			atomic_notifier_call_chain(&power_supply_notifier,
					POWER_SUPPLY_CABLE_EVENT, &cable_props);
		}
	}

	return 0;

dev_det_i2c_failed:
	if (chip->pdata->is_vbus_online())
		dev_err(&chip->client->dev,
				"vbus present: i2c read failed:%d\n", ret);
	else
		dev_info(&chip->client->dev,
				"vbus removed: i2c read failed:%d\n", ret);
	return ret;
}