[RAMEN9610-12413][COMMON][9610] usbpd : update s2mu106 drivers for usbpd compliance
authorJunhan Bae <junhan84.bae@samsung.com>
Thu, 21 Feb 2019 09:10:01 +0000 (18:10 +0900)
committerCosmin Tanislav <demonsingur@gmail.com>
Mon, 22 Apr 2024 17:23:18 +0000 (20:23 +0300)
Change-Id: I88bfa9de57153f0d802d689c81f97ce452e5848e
Signed-off-by: Junhan Bae <junhan84.bae@samsung.com>
22 files changed:
arch/arm64/boot/dts/exynos/exynos9610_battery_data.dtsi
drivers/ccic/s2mu106-usbpd.c
drivers/ccic/usbpd.c
drivers/ccic/usbpd_manager.c
drivers/ccic/usbpd_policy.c
drivers/ifconn/ifconn_notifier.c
drivers/mfd/s2mu106_core.c
drivers/mfd/s2mu106_irq.c
drivers/muic/muic_manager.c
drivers/muic/s2mu106-muic-afc.c
drivers/power/supply/Kconfig
drivers/power/supply/Makefile
drivers/power/supply/s2mu00x_battery.c
drivers/power/supply/s2mu106_charger.c
drivers/power/supply/s2mu106_pmeter.c
drivers/usb/notify/usb_notifier.c
include/linux/ccic/usbpd-s2mu106.h
include/linux/ccic/usbpd.h
include/linux/ccic/usbpd_ext.h
include/linux/ccic/usbpd_msg.h
include/linux/power/s2mu106_pmeter.h
include/linux/power_supply.h

index 27cb51483cc81072c3a2225f5d394c82094258ae..5d17568a16c575074fcd99255f28e5728307166b 100644 (file)
                                 * POWER_SUPPLY_TYPE_ of power_supply.h
                                 */
                                battery,input_current_limit =
-                                       <500 450 500 3000 500 1200 1200 1000 1000 2000
+                                       <500 450 500 3000 500 1200 1200 1000 1000 3000
                                        1000 500 500 3000 2000 500 450>;
                                battery,fast_charging_current =
-                                       <500 450 500 3000 500 1200 1200 1000 1000 2000
+                                       <500 450 500 3000 500 1200 1200 1000 1000 3000
                                        1000 500 500 3000 2000 500 450>;
                                battery,full_check_current =
                                        <300 0 300 300 300 300 300 300 300 300
index 133ce1c6fde787c1043d8ab978b39fb6083f1234..4784cd7c6bcb1708d784d9af251da89d63e32899 100644 (file)
 #include <linux/ccic/usbpd.h>
 #include <linux/ccic/usbpd-s2mu106.h>
 
+#if defined(CONFIG_PM_S2MU106)
+#include <linux/power/s2mu106_pmeter.h>
+#endif
+
 #include <linux/muic/muic.h>
 #if defined(CONFIG_MUIC_NOTIFIER)
 #include <linux/muic/muic_notifier.h>
@@ -156,6 +160,12 @@ void vbus_turn_on_ctrl(struct s2mu106_usbpd_data *usbpd_data, bool enable)
        int ret = 0, retry_cnt = 0;
 
        pr_info("%s %d, enable=%d\n", __func__, __LINE__, enable);
+
+       if (usbpd_data->detach_valid) {
+               dev_info(usbpd_data->dev, "%s, ignore vbus control\n", __func__);
+               return;
+       }
+
        psy_otg = power_supply_get_by_name("otg");
 
        if (psy_otg) {
@@ -187,6 +197,114 @@ void vbus_turn_on_ctrl(struct s2mu106_usbpd_data *usbpd_data, bool enable)
 
 }
 
+#ifdef CONFIG_PM_S2MU106
+static void s2mu106_usbpd_set_pmeter_mode(struct s2mu106_usbpd_data *pdic_data,
+                                                                                                                               int mode)
+{
+       struct power_supply *psy_pm = pdic_data->psy_pm;
+       union power_supply_propval val;
+       int ret = 0;
+
+       pr_info("%s, mode=%d\n", __func__, mode);
+
+       if (psy_pm) {
+               val.intval = mode;
+               ret = psy_pm->desc->set_property(psy_pm,
+                                                       POWER_SUPPLY_PROP_CO_ENABLE, &val);
+       } else {
+               pr_err("%s: Fail to get pmeter\n", __func__);
+               return;
+       }
+
+       if (ret) {
+               pr_err("%s: Fail to set pmeter\n", __func__);
+               return;
+       }
+}
+
+static int s2mu106_usbpd_get_pmeter_volt(struct s2mu106_usbpd_data *pdic_data)
+{
+
+       struct power_supply *psy_pm = pdic_data->psy_pm;
+       union power_supply_propval val;
+       int ret = 0;
+
+       if (psy_pm) {
+               ret = psy_pm->desc->get_property(psy_pm, POWER_SUPPLY_PROP_VCHGIN, &val);
+       } else {
+               pr_err("%s: Fail to get pmeter\n", __func__);
+               return -1;
+       }
+
+       if (ret) {
+                       pr_err("%s: fail to set power_suppy pmeter property(%d)\n",
+               __func__, ret);
+               return -1;
+       }
+
+       pdic_data->pm_chgin = val.intval;
+
+       return 0;
+}
+
+static int s2mu106_usbpd_check_vbus(struct s2mu106_usbpd_data *pdic_data,
+                                                                                               int volt, CCIC_VBUS_SEL mode)
+{
+       int delay = 20;
+       int retry = 100;
+       int i = 0;
+       int ret = 0;
+
+       if (mode == VBUS_OFF) {
+               for (i = 0; i < retry; i++) {
+                       ret = s2mu106_usbpd_get_pmeter_volt(pdic_data);
+                       if (ret < 0)
+                               return ret;
+
+                       if (pdic_data->pm_chgin < volt) {
+                               pr_info("%s chgin volt(%d) finish!\n", __func__,
+                                                                                               pdic_data->pm_chgin);
+                               return true;
+                       } else {
+                               pr_info("%s chgin volt(%d) waiting 400ms!\n",
+                                                                               __func__, pdic_data->pm_chgin);
+                               msleep(400);
+                               return true;
+                       }
+                       msleep(delay);
+               }
+       } else if (mode == VBUS_ON) {
+               ret = s2mu106_usbpd_get_pmeter_volt(pdic_data);
+               if (ret < 0)
+                       return ret;
+               if (pdic_data->pm_chgin > volt)
+                       return true;
+       }
+
+       pr_info("%s failed check vbus volt(%d->%d) mode(%d)!\n",
+                                       __func__, volt, pdic_data->pm_chgin, mode);
+
+       return false;
+}
+#endif
+
+static int s2mu106_usbpd_check_accessory(struct s2mu106_usbpd_data *pdic_data)
+{
+       struct i2c_client *i2c = pdic_data->i2c;
+       u8 val, cc1_val, cc2_val;
+
+       s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PLUG_MON1, &val);
+
+       cc1_val = val & S2MU106_REG_CTRL_MON_CC1_MASK;
+       cc2_val = (val & S2MU106_REG_CTRL_MON_CC2_MASK) >> S2MU106_REG_CTRL_MON_CC2_SHIFT;
+
+       if ((cc1_val == USBPD_Rd && cc2_val == USBPD_Rd) ||
+                       (cc1_val == USBPD_Ra && cc2_val == USBPD_Ra))
+               return -1;
+
+       return 0;
+}
+
 #if defined(CONFIG_IFCONN_NOTIFIER)
 static void process_dr_swap(struct s2mu106_usbpd_data *usbpd_data)
 {
@@ -196,8 +314,6 @@ static void process_dr_swap(struct s2mu106_usbpd_data *usbpd_data)
        if (usbpd_data->is_host == HOST_ON) {
                ifconn_event_work(usbpd_data, IFCONN_NOTIFY_USB,
                                        IFCONN_NOTIFY_ID_USB, IFCONN_NOTIFY_EVENT_DETACH, NULL);
-               ifconn_event_work(usbpd_data, IFCONN_NOTIFY_MUIC,
-                                       IFCONN_NOTIFY_ID_ATTACH, IFCONN_NOTIFY_EVENT_DETACH, NULL);
                ifconn_event_work(usbpd_data, IFCONN_NOTIFY_USB, IFCONN_NOTIFY_ID_USB,
                                                                IFCONN_NOTIFY_EVENT_USB_ATTACH_UFP, NULL);
                usbpd_data->is_host = HOST_OFF;
@@ -205,8 +321,6 @@ static void process_dr_swap(struct s2mu106_usbpd_data *usbpd_data)
        } else if (usbpd_data->is_client == CLIENT_ON) {
                ifconn_event_work(usbpd_data, IFCONN_NOTIFY_USB, IFCONN_NOTIFY_ID_USB,
                                                                        IFCONN_NOTIFY_EVENT_DETACH, NULL);
-               ifconn_event_work(usbpd_data, IFCONN_NOTIFY_MUIC, IFCONN_NOTIFY_ID_ATTACH,
-                                                                       IFCONN_NOTIFY_EVENT_ATTACH, NULL);
                ifconn_event_work(usbpd_data, IFCONN_NOTIFY_USB, IFCONN_NOTIFY_ID_USB,
                                                        IFCONN_NOTIFY_EVENT_USB_ATTACH_DFP, NULL);
                usbpd_data->is_host = HOST_ON;
@@ -217,6 +331,31 @@ static void process_dr_swap(struct s2mu106_usbpd_data *usbpd_data)
 }
 #endif
 
+static void s2mu106_pr_swap(void *_data, int val)
+{
+       struct usbpd_data *data = (struct usbpd_data *) _data;
+       struct s2mu106_usbpd_data *pdic_data = data->phy_driver_data;
+
+       if (val == USBPD_SINK_OFF)
+               ifconn_event_work(pdic_data, IFCONN_NOTIFY_BATTERY,
+                                                               IFCONN_NOTIFY_ID_DETACH, 0, 0);
+       else if (val == USBPD_SOURCE_ON) {
+#if defined(CONFIG_DUAL_ROLE_USB_INTF)
+               pdic_data->power_role_dual = DUAL_ROLE_PROP_PR_SRC;
+               ifconn_event_work(pdic_data, IFCONN_NOTIFY_MUIC,
+                                                               IFCONN_NOTIFY_ID_ROLE_SWAP, 1/* source */, 0);
+#endif
+       } else if (val == USBPD_SOURCE_OFF) {
+               ifconn_event_work(pdic_data, IFCONN_NOTIFY_BATTERY,
+                                                               IFCONN_NOTIFY_ID_DETACH, 0, 0);
+#if defined(CONFIG_DUAL_ROLE_USB_INTF)
+               pdic_data->power_role_dual = DUAL_ROLE_PROP_PR_SNK;
+               ifconn_event_work(pdic_data, IFCONN_NOTIFY_MUIC,
+                                                               IFCONN_NOTIFY_ID_ROLE_SWAP, 0/* sink */, 0);
+#endif
+       }
+}
+
 static int s2mu106_usbpd_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest)
 {
        int ret;
@@ -585,10 +724,8 @@ static bool s2mu106_poll_status(void *_data)
                s2mu106_set_irq_enable(pdic_data, ENABLED_INT_0, ENABLED_INT_1,
                                ENABLED_INT_2, ENABLED_INT_3, ENABLED_INT_4, ENABLED_INT_5);
 
-       if (intr[5] & S2MU106_REG_INT_STATUS5_HARD_RESET) {
+       if (intr[5] & S2MU106_REG_INT_STATUS5_HARD_RESET)
                status_reg_val |= MSG_HARDRESET;
-               goto out;
-       }
 
        /* when occur detach & attach atomic */
        if (intr[4] & S2MU106_REG_INT_STATUS4_USB_DETACH) {
@@ -614,6 +751,7 @@ static bool s2mu106_poll_status(void *_data)
                mutex_unlock(&pdic_data->lpm_mutex);
        }
 
+       pdic_data->check_msg_pass = 1;
 #ifdef CONFIG_CCIC_VDM
        /* function that support dp control */
        if (pdic_data->check_msg_pass) {
@@ -701,7 +839,7 @@ static bool s2mu106_poll_status(void *_data)
 #ifdef CONFIG_CCIC_VDM
        /* read message if data object message */
        if (status_reg_val &
-                       (MSG_REQUEST | MSG_SNK_CAP
+                       (MSG_PSRDY | MSG_REQUEST | MSG_SNK_CAP
                        | VDM_DISCOVER_IDENTITY | VDM_DISCOVER_SVID
                        | VDM_DISCOVER_MODE | VDM_ENTER_MODE | VDM_EXIT_MODE
                        | VDM_ATTENTION | MSG_PASS)) {
@@ -712,7 +850,7 @@ static bool s2mu106_poll_status(void *_data)
 #else
        /* read message if data object message */
        if (status_reg_val &
-                       (MSG_REQUEST | MSG_SNK_CAP
+                       (MSG_PSRDY | MSG_REQUEST | MSG_SNK_CAP
                        | VDM_DISCOVER_IDENTITY | VDM_DISCOVER_SVID
                        | VDM_DISCOVER_MODE | VDM_ENTER_MODE | VDM_EXIT_MODE
                        | VDM_ATTENTION)) {
@@ -731,6 +869,15 @@ out:
        return 0;
 }
 
+static void s2mu106_soft_reset(void *_data)
+{
+       struct usbpd_data *data = (struct usbpd_data *) _data;
+       struct s2mu106_usbpd_data *pdic_data = data->phy_driver_data;
+       struct i2c_client *i2c = pdic_data->i2c;
+
+       s2mu106_self_soft_reset(i2c);
+}
+
 static int s2mu106_hard_reset(void *_data)
 {
        struct usbpd_data *data = (struct usbpd_data *) _data;
@@ -738,6 +885,7 @@ static int s2mu106_hard_reset(void *_data)
        struct i2c_client *i2c = pdic_data->i2c;
        int ret;
        u8 reg;
+       u8 Read_Value = 0;
 
        if (pdic_data->rid != REG_RID_UNDF && pdic_data->rid != REG_RID_MAX)
                return 0;
@@ -748,16 +896,22 @@ static int s2mu106_hard_reset(void *_data)
                        | S2MU106_REG_MSG_SEND_CON_OP_MODE);
        if (ret < 0)
                goto fail;
-       udelay(5);
+
        ret = s2mu106_usbpd_write_reg(i2c, reg, S2MU106_REG_MSG_SEND_CON_SOP_HardRST
                        | S2MU106_REG_MSG_SEND_CON_OP_MODE
                        | S2MU106_REG_MSG_SEND_CON_SEND_MSG_EN);
        if (ret < 0)
                goto fail;
+
+    /* USB PD CC Off*/
+       Read_Value &= ~S2MU106_REG_PLUG_CTRL_CC_MANUAL_MASK;
+       Read_Value |= S2MU106_REG_PLUG_CTRL_CC_MANUAL_EN;
+       s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL_CC12, Read_Value);
+
+       ret = s2mu106_usbpd_write_reg(i2c, reg, S2MU106_REG_MSG_SEND_CON_OP_MODE
+                                                                               | S2MU106_REG_MSG_SEND_CON_HARD_EN);
        udelay(1);
-       ret = s2mu106_usbpd_write_reg(i2c, reg, S2MU106_REG_MSG_SEND_CON_OP_MODE);
-       udelay(1);
-       ret = s2mu106_usbpd_write_reg(i2c, reg, S2MU106_RESET_REG_00);
+       ret = s2mu106_usbpd_write_reg(i2c, reg, S2MU106_REG_MSG_SEND_CON_HARD_EN);
        if (ret < 0)
                goto fail;
 
@@ -804,8 +958,7 @@ static int s2mu106_tx_msg(void *_data,
        u8 reg_data = 0;
        u8 msg_id = 0;
 
-       mutex_lock(&pdic_data->_mutex);
-
+       mutex_lock(&pdic_data->cc_mutex);
        /* if there is no attach, skip tx msg */
        if (pdic_data->detach_valid)
                goto done;
@@ -829,11 +982,8 @@ static int s2mu106_tx_msg(void *_data,
 
        s2mu106_send_msg(i2c);
 
-       pdic_data->status_reg = 0;
-       data->wait_for_msg_arrived = 0;
-
 done:
-       mutex_unlock(&pdic_data->_mutex);
+       mutex_unlock(&pdic_data->cc_mutex);
        return ret;
 }
 
@@ -864,20 +1014,67 @@ static int s2mu106_set_otg_control(void *_data, int val)
        struct usbpd_data *data = (struct usbpd_data *) _data;
        struct s2mu106_usbpd_data *pdic_data = data->phy_driver_data;
 
+       mutex_lock(&pdic_data->cc_mutex);
        if (val)
                vbus_turn_on_ctrl(pdic_data, VBUS_ON);
        else
                vbus_turn_on_ctrl(pdic_data, VBUS_OFF);
+       mutex_unlock(&pdic_data->cc_mutex);
 
        return 0;
 }
 
 static int s2mu106_set_cc_control(void *_data, int val)
+{
+       struct usbpd_data *data = (struct usbpd_data *) _data;
+       struct s2mu106_usbpd_data *pdic_data = data->phy_driver_data;
+       int ret = 0;
+
+       mutex_lock(&pdic_data->cc_mutex);
+       ret = s2mu106_usbpd_set_cc_control(pdic_data, val);
+       mutex_unlock(&pdic_data->cc_mutex);
+
+       return ret;
+}
+
+static int s2mu106_vbus_on_check(void *_data)
 {
        struct usbpd_data *data = (struct usbpd_data *) _data;
        struct s2mu106_usbpd_data *pdic_data = data->phy_driver_data;
 
-       return s2mu106_usbpd_set_cc_control(pdic_data, val);
+       return s2mu106_usbpd_check_vbus(pdic_data, 4600, VBUS_ON);
+}
+
+static int s2mu106_check_bist_message(void *_data)
+{
+       struct usbpd_data *data = (struct usbpd_data *) _data;
+       struct s2mu106_usbpd_data *pdic_data = data->phy_driver_data;
+       struct i2c_client *i2c = pdic_data->i2c;
+       u8 reg_data = 0;
+       msg_header_type rx_msg_header;
+
+       /* 1) PD State Inform to AP */
+       dev_info(data->dev, "%s\n", __func__);
+
+       /* 2) Get Rx Message ID */
+       s2mu106_usbpd_read_reg(i2c, S2MU106_REG_MSG_RX_HEADER_H, &reg_data);
+       rx_msg_header.byte[1] = reg_data;
+       dev_info(data->dev, "rx_msg_header.byte[1] = 0x%02X.\n", rx_msg_header.byte[1]);
+
+       s2mu106_usbpd_read_reg(i2c, S2MU106_REG_MSG_RX_HEADER_L, &reg_data);
+       rx_msg_header.byte[0] = reg_data;
+       dev_info(data->dev, "rx_msg_header.byte[0] = 0x%02X.\n", rx_msg_header.byte[0]);
+
+       dev_info(data->dev, "rx_msg_header.word = 0x%04X.\n", rx_msg_header.word);
+
+       /* 3) Check Bist Message */
+       if ((rx_msg_header.msg_type == 3) && (rx_msg_header.num_data_objs != 0)) {
+               dev_info(data->dev, "got check_bist_message is BIST.\n");
+               return 0;
+       } else {
+               dev_info(data->dev, "got check_bist_message is NOT BIST.\n");
+               return -1;
+       }
 }
 
 #if defined(CONFIG_CHECK_CTYPE_SIDE) || defined(CONFIG_CCIC_SYSFS)
@@ -1056,13 +1253,6 @@ static int s2mu106_get_data_role(void *_data, int *val)
        return 0;
 }
 
-static void s2mu106_get_vbus_short_check(void *_data, bool *val)
-{
-       struct usbpd_data *data = (struct usbpd_data *) _data;
-       struct s2mu106_usbpd_data *pdic_data = data->phy_driver_data;
-       *val = pdic_data->vbus_short;
-}
-
 static int s2mu106_set_check_msg_pass(void *_data, int val)
 {
        struct usbpd_data *data = (struct usbpd_data *) _data;
@@ -1139,6 +1329,11 @@ int s2mu106_usbpd_check_vdm_msg(void *_data, u64 *val)
                return 0;
        }
 
+       if (data->protocol_rx.msg_header.msg_type == USBPD_Source_Capabilities) {
+               *val |= MSG_SRC_CAP;
+               return 0;
+       }
+
        if (data->protocol_rx.msg_header.msg_type != USBPD_Vendor_Defined) {
                dev_info(data->dev, "%s msg type is wrong\n", __func__);
                return 0;
@@ -1177,25 +1372,30 @@ static int s2mu106_usbpd_set_cc_control(struct s2mu106_usbpd_data  *pdic_data, i
        u8 data = 0;
 
        dev_info(pdic_data->dev, "%s, (%d)\n", __func__, val);
-       mutex_lock(&pdic_data->cc_mutex);
 
-       if (pdic_data->detach_valid)
-               goto out;
-
-       val = 1;
+       if (pdic_data->detach_valid) {
+               dev_info(pdic_data->dev, "%s, ignore cc control\n", __func__);
+               return 0;
+       }
 
        if (val) {
                s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PLUG_CTRL_CC12, &data);
                data &= ~S2MU106_REG_PLUG_CTRL_CC_MANUAL_MASK;
                s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL_CC12, data);
+
+               s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PLUG_CTRL, &data);
+               data |= S2MU106_REG_PLUG_CTRL_ECO_SRC_CAP_RDY;
+               s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL, data);
        } else {
                s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PLUG_CTRL_CC12, &data);
                data &= ~S2MU106_REG_PLUG_CTRL_CC_MANUAL_MASK;
                data |= S2MU106_REG_PLUG_CTRL_CC_MANUAL_EN;
                s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL_CC12, data);
+
+               s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PLUG_CTRL, &data);
+               data &= ~S2MU106_REG_PLUG_CTRL_ECO_SRC_CAP_RDY;
+               s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL, data);
        }
-out:
-       mutex_unlock(&pdic_data->cc_mutex);
 
        return 0;
 }
@@ -1724,7 +1924,7 @@ static void s2mu106_usbpd_otg_attach(struct s2mu106_usbpd_data *pdic_data)
 {
        struct i2c_client *i2c = pdic_data->i2c;
        struct device *dev = &i2c->dev;
-       
+
        /* otg */
        pdic_data->is_host = HOST_ON;
 #if defined(CONFIG_DUAL_ROLE_USB_INTF)
@@ -1734,6 +1934,9 @@ static void s2mu106_usbpd_otg_attach(struct s2mu106_usbpd_data *pdic_data)
        /* USB */
        ifconn_event_work(pdic_data, IFCONN_NOTIFY_USB, IFCONN_NOTIFY_ID_USB,
                                                                IFCONN_NOTIFY_EVENT_USB_ATTACH_DFP, NULL);
+#endif
+#ifdef CONFIG_PM_S2MU106
+               s2mu106_usbpd_check_vbus(pdic_data, 80, VBUS_OFF);
 #endif
        /* add to turn on external 5V */
        vbus_turn_on_ctrl(pdic_data, VBUS_ON);
@@ -1860,33 +2063,8 @@ EOH:
 }
 #endif
 
-#if defined(CONFIG_DUAL_ROLE_USB_INTF)
-static void s2mu106_usbpd_control_cc12_rd(struct s2mu106_usbpd_data *pdic_data,
-                                                                       bool enable)
-{
-       struct i2c_client *i2c = pdic_data->i2c;
-       u8 data = 0;
-
-       s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PLUG_CTRL_PORT, &data);
-       dev_info(pdic_data->dev, "%s, enable : %s current reg value(%x)\n", __func__,
-                                       enable ? "ON" : "OFF", data);
-
-       if (enable) {
-               s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PLUG_CTRL_PORT, &data);
-               data &= ~S2MU106_REG_PLUG_CTRL_MODE_MASK;
-               data |= S2MU106_REG_PLUG_CTRL_UFP;
-               s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL_PORT, data);
-       } else {
-               s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PLUG_CTRL_PORT, &data);
-               data &= ~S2MU106_REG_PLUG_CTRL_MODE_MASK;
-               data |= S2MU106_REG_PLUG_CTRL_DRP;
-               s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL_PORT, data);
-       }
-}
-#endif
-
 static void s2mu106_usbpd_prevent_watchdog_reset(
-                        struct s2mu106_usbpd_data *pdic_data)
+       struct s2mu106_usbpd_data *pdic_data)
 {
        struct i2c_client *i2c = pdic_data->i2c;
        u8 val = 0;
@@ -1904,13 +2082,14 @@ static void s2mu106_usbpd_prevent_watchdog_reset(
                                                ENABLED_INT_2_WAKEUP, ENABLED_INT_3, ENABLED_INT_4,
                                                                                                                        ENABLED_INT_5);
                        s2mu106_usbpd_set_vbus_wakeup(pdic_data, VBUS_WAKEUP_ENABLE);
+                       usleep_range(1000, 1200);
                        s2mu106_usbpd_read_reg(i2c, S2MU106_REG_INT_STATUS2, &val);
                        if (val & S2MU106_REG_INT_STATUS2_WAKEUP)
                                pr_info("%s auto wakeup success\n", __func__);
                        else
                                s2mu106_usbpd_set_mode(pdic_data, PD_NORMAL_MODE);
-                               s2mu106_set_irq_enable(pdic_data, ENABLED_INT_0, ENABLED_INT_1,
-                                                                       ENABLED_INT_2, ENABLED_INT_3, ENABLED_INT_4,
+                       s2mu106_set_irq_enable(pdic_data, ENABLED_INT_0, ENABLED_INT_1,
+                                                               ENABLED_INT_2, ENABLED_INT_3, ENABLED_INT_4,
                                                                                                                                ENABLED_INT_5);
                }
        }
@@ -1918,58 +2097,6 @@ static void s2mu106_usbpd_prevent_watchdog_reset(
        mutex_unlock(&pdic_data->lpm_mutex);
 }
 
-static void s2mu106_vbus_short_check(struct s2mu106_usbpd_data *pdic_data)
-{
-       struct i2c_client *i2c = pdic_data->i2c;
-       struct device *dev = pdic_data->dev;
-       u8 val = 0;
-       u8 cc1_val = 0, cc2_val = 0;
-       u8 rp_currentlvl = 0;
-
-       if (pdic_data->vbus_short_check)
-               return;
-
-       s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PLUG_FSM_MON, &val);
-
-       cc1_val = val & S2MU106_REG_CTRL_MON_CC1_MASK;
-       cc2_val = (val & S2MU106_REG_CTRL_MON_CC2_MASK) >> S2MU106_REG_CTRL_MON_CC2_SHIFT;
-
-       dev_info(dev, "%s, 10k check : cc1_val(%x), cc2_val(%x)\n",
-                                       __func__, cc1_val, cc2_val);
-
-       if (cc1_val == USBPD_10k || cc2_val == USBPD_10k)
-               rp_currentlvl = RP_CURRENT_LEVEL3;
-       else if (cc1_val == USBPD_22k || cc2_val == USBPD_22k)
-               rp_currentlvl = RP_CURRENT_LEVEL2;
-       else if (cc1_val == USBPD_56k || cc2_val == USBPD_56k)
-               rp_currentlvl = RP_CURRENT_LEVEL_DEFAULT;
-
-#ifdef CONFIG_IFCONN_NOTIFIER
-       pd_noti.sink_status.rp_currentlvl = rp_currentlvl;
-       pd_noti.event = IFCONN_NOTIFY_EVENT_ATTACH;
-       ifconn_event_work(pdic_data, IFCONN_NOTIFY_BATTERY,
-                                               IFCONN_NOTIFY_ID_POWER_STATUS,
-                                               IFCONN_NOTIFY_EVENT_ATTACH, &pd_noti);
-#endif
-       s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PLUG_MON1, &val);
-
-       cc1_val = val & S2MU106_REG_CTRL_MON_CC1_MASK;
-       cc2_val = (val & S2MU106_REG_CTRL_MON_CC2_MASK) >> S2MU106_REG_CTRL_MON_CC2_SHIFT;
-
-       dev_info(dev, "%s, vbus short check : cc1_val(%x), cc2_val(%x)\n",
-                                       __func__, cc1_val, cc2_val);
-
-       if (cc1_val == USBPD_Rp || cc2_val == USBPD_Rp) {
-               pdic_data->vbus_short = true;
-       } else {
-               pdic_data->vbus_short = false;
-               ifconn_event_work(pdic_data, IFCONN_NOTIFY_MUIC,
-                       IFCONN_NOTIFY_ID_TA, IFCONN_NOTIFY_EVENT_ATTACH, NULL);
-       }
-
-       pdic_data->vbus_short_check = true;
-}
-
 static void s2mu106_usbpd_detach_init(struct s2mu106_usbpd_data *pdic_data)
 {
        struct device *dev = pdic_data->dev;
@@ -1979,20 +2106,28 @@ static void s2mu106_usbpd_detach_init(struct s2mu106_usbpd_data *pdic_data)
 
        dev_info(dev, "%s\n", __func__);
 
+       mutex_lock(&pdic_data->cc_mutex);
        s2mu106_usbpd_set_cc_control(pdic_data, USBPD_CC_OFF);
-
+#if defined(CONFIG_DUAL_ROLE_USB_INTF)
+       if (pdic_data->power_role_dual == DUAL_ROLE_PROP_PR_SRC) {
+               vbus_turn_on_ctrl(pdic_data, VBUS_OFF);
+       }
+#endif
+       pdic_data->detach_valid = true;
+       mutex_unlock(&pdic_data->cc_mutex);
        usbpd_manager_plug_detach(dev, 0);
+
+       /* wait flushing policy engine work */
+       usbpd_cancel_policy_work(dev);
+
        pdic_data->status_reg = 0;
        usbpd_reinit(dev);
        /* for ccic hw detect */
        s2mu106_usbpd_write_reg(i2c, S2MU106_REG_MSG_SEND_CON, S2MU106_RESET_REG_00);
        pdic_data->rid = REG_RID_MAX;
        pdic_data->check_rid_wa = false;
-       pdic_data->detach_valid = true;
        pdic_data->is_factory_mode = false;
        pdic_data->is_pr_swap = false;
-       pdic_data->vbus_short_check = false;
-       pdic_data->vbus_short = false;
        if (pdic_data->regulator_en)
                ret = regulator_disable(pdic_data->regulator);
 #ifdef CONFIG_BATTERY_SAMSUNG
@@ -2009,12 +2144,6 @@ static void s2mu106_usbpd_detach_init(struct s2mu106_usbpd_data *pdic_data)
 static void s2mu106_usbpd_notify_detach(struct s2mu106_usbpd_data *pdic_data)
 {
        struct device *dev = pdic_data->dev;
-       struct usbpd_data *pd_data = dev_get_drvdata(pdic_data->dev);
-       struct usbpd_manager_data *manager = &pd_data->manager;
-
-       if (manager->dp_is_connect == 1)
-               usbpd_dp_detach(pd_data);
-
 #if defined(CONFIG_IFCONN_NOTIFIER)
        /* MUIC */
        ifconn_event_work(pdic_data, IFCONN_NOTIFY_MUIC, IFCONN_NOTIFY_ID_ATTACH,
@@ -2033,15 +2162,6 @@ static void s2mu106_usbpd_notify_detach(struct s2mu106_usbpd_data *pdic_data)
                        vbus_turn_on_ctrl(pdic_data, VBUS_OFF);
                }
                usbpd_manager_acc_detach(dev);
-#if defined(CONFIG_DUAL_ROLE_USB_INTF)
-               pr_info("%s, data_role (%d)\n", __func__, pdic_data->data_role_dual);
-               if (pdic_data->data_role_dual == IFCONN_NOTIFY_EVENT_USB_ATTACH_DFP &&
-                       !pdic_data->try_state_change) {
-                       s2mu106_usbpd_control_cc12_rd(pdic_data, true);
-                       msleep(S2MU106_WAIT_RD_DETACH_DELAY_MS);
-                       s2mu106_usbpd_control_cc12_rd(pdic_data, false);
-               }
-#endif
                /* usb or otg */
                dev_info(dev, "%s %d: is_host = %d, is_client = %d\n", __func__,
                                __LINE__, pdic_data->is_host, pdic_data->is_client);
@@ -2075,7 +2195,7 @@ static void s2mu106_usbpd_try_snk(struct s2mu106_usbpd_data *pdic_data)
        dev_info(dev, "%s\n", __func__);
 
        s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PLUG_CTRL_PORT, &data);
-       data &= ~ S2MU106_REG_PLUG_CTRL_MODE_MASK;
+       data &= ~S2MU106_REG_PLUG_CTRL_MODE_MASK;
        data |= S2MU106_REG_PLUG_CTRL_UFP;
        s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL_PORT, data);
 
@@ -2084,7 +2204,7 @@ static void s2mu106_usbpd_try_snk(struct s2mu106_usbpd_data *pdic_data)
        s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PLUG_MON2, &data);
        if ((data & S2MU106_PR_MASK) != S2MU106_PDIC_SINK) {
                s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PLUG_CTRL_PORT, &data);
-               data &= ~ S2MU106_REG_PLUG_CTRL_MODE_MASK;
+               data &= ~S2MU106_REG_PLUG_CTRL_MODE_MASK;
                data |= S2MU106_REG_PLUG_CTRL_DFP;
                s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL_PORT, data);
 
@@ -2098,13 +2218,7 @@ static void s2mu106_usbpd_try_snk(struct s2mu106_usbpd_data *pdic_data)
 static void s2mu106_usbpd_check_host(struct s2mu106_usbpd_data *pdic_data,
                                                        CCIC_HOST_REASON host)
 {
-       struct usbpd_data *pd_data = dev_get_drvdata(pdic_data->dev);
-       struct usbpd_manager_data *manager = &pd_data->manager;
-
        if (host == HOST_ON && pdic_data->is_host == HOST_ON) {
-               if (manager->dp_is_connect == 1)
-                       usbpd_dp_detach(pd_data);
-
                dev_info(pdic_data->dev, "%s %d: turn off host\n", __func__, __LINE__);
                ifconn_event_work(pdic_data, IFCONN_NOTIFY_MUIC,
                                IFCONN_NOTIFY_ID_ATTACH, IFCONN_NOTIFY_EVENT_DETACH, NULL);
@@ -2183,6 +2297,7 @@ static int s2mu106_check_port_detect(struct s2mu106_usbpd_data *pdic_data)
 #endif
        if ((data & S2MU106_PR_MASK) == S2MU106_PDIC_SINK) {
                dev_info(dev, "SINK\n");
+               pdic_data->detach_valid = false;
                pdic_data->power_role = PDIC_SINK;
                pdic_data->data_role = USBPD_UFP;
                s2mu106_snk(i2c);
@@ -2215,9 +2330,14 @@ static int s2mu106_check_port_detect(struct s2mu106_usbpd_data *pdic_data)
                        }
                }
 #endif
-               s2mu106_vbus_short_check(pdic_data);
        } else if ((data & S2MU106_PR_MASK) == S2MU106_PDIC_SOURCE) {
                dev_info(dev, "SOURCE\n");
+               ret = s2mu106_usbpd_check_accessory(pdic_data);
+               if (ret < 0) {
+                       dev_info(&i2c->dev, "%s attach accessory\n", __func__);
+                       return -1;
+               }
+               pdic_data->detach_valid = false;
                pdic_data->power_role = PDIC_SOURCE;
                pdic_data->data_role = USBPD_DFP;
                s2mu106_dfp(i2c);
@@ -2235,9 +2355,7 @@ static int s2mu106_check_port_detect(struct s2mu106_usbpd_data *pdic_data)
                                dev_err(&i2c->dev, "Failed to enable vconn LDO: %d\n", ret);
                }
 
-               s2mu106_set_vconn_source(pd_data, USBPD_VCONN_ON);
-
-               msleep(tTypeCSinkWaitCap); /* dont over 310~620ms(tTypeCSinkWaitCap) */
+               msleep(100);
        } else {
                dev_err(dev, "%s, PLUG Error\n", __func__);
 #ifdef CONFIG_CCIC_TRY_SNK
@@ -2249,8 +2367,6 @@ static int s2mu106_check_port_detect(struct s2mu106_usbpd_data *pdic_data)
                return -1;
        }
 
-       pdic_data->detach_valid = false;
-
        s2mu106_set_irq_enable(pdic_data, ENABLED_INT_0, ENABLED_INT_1,
                                ENABLED_INT_2, ENABLED_INT_3, ENABLED_INT_4, ENABLED_INT_5);
 
@@ -2315,15 +2431,6 @@ static irqreturn_t s2mu106_irq_thread(int irq, void *data)
        if (s2mu106_get_status(pd_data, MSG_NONE))
                goto out;
 
-       if (s2mu106_get_status(pd_data, MSG_HARDRESET)) {
-               s2mu106_usbpd_set_cc_control(pdic_data, USBPD_CC_OFF);
-               s2mu106_self_soft_reset(i2c);
-               pdic_data->status_reg = 0;
-               usbpd_rx_hard_reset(dev);
-               usbpd_kick_policy_work(dev);
-               goto out;
-       }
-
        if (s2mu106_get_status(pd_data, MSG_SOFTRESET))
                usbpd_rx_soft_reset(pd_data);
 
@@ -2362,6 +2469,18 @@ static irqreturn_t s2mu106_irq_thread(int irq, void *data)
                mutex_unlock(&pdic_data->lpm_mutex);
                goto out;
        }
+
+       if (s2mu106_get_status(pd_data, MSG_HARDRESET)) {
+               mutex_lock(&pdic_data->cc_mutex);
+               s2mu106_usbpd_set_cc_control(pdic_data, USBPD_CC_OFF);
+               mutex_unlock(&pdic_data->cc_mutex);
+               s2mu106_self_soft_reset(i2c);
+               pdic_data->status_reg = 0;
+               usbpd_rx_hard_reset(dev);
+               usbpd_kick_policy_work(dev);
+               goto out;
+       }
+
 #if defined(CONFIG_SEC_FACTORY)
 skip_detach:
 #endif /* CONFIG_SEC_FACTORY */
@@ -2410,17 +2529,17 @@ static int s2mu106_usbpd_set_property(struct power_supply *psy,
        u8 data = 0;
 
        switch (psp) {
-               case POWER_SUPPLY_PROP_AUTHENTIC:
-                       s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PLUG_CTRL_VBUS_MUX, &data);
-                       data &= ~(S2MU106_REG_RD_OR_VBUS_MUX_SEL);
-                       s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL_VBUS_MUX, data);
-                       break;
-               case POWER_SUPPLY_PROP_USBPD_RESET:
-                       s2mu106_usbpd_set_vbus_wakeup(pdic_data, VBUS_WAKEUP_DISABLE);
-                       s2mu106_usbpd_set_vbus_wakeup(pdic_data, VBUS_WAKEUP_ENABLE);
-                       break;
-               default:
-                       return -EINVAL;
+       case POWER_SUPPLY_PROP_AUTHENTIC:
+               s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PLUG_CTRL_VBUS_MUX, &data);
+               data &= ~(S2MU106_REG_RD_OR_VBUS_MUX_SEL);
+               s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL_VBUS_MUX, data);
+               break;
+       case POWER_SUPPLY_PROP_USBPD_RESET:
+               s2mu106_usbpd_set_vbus_wakeup(pdic_data, VBUS_WAKEUP_DISABLE);
+               s2mu106_usbpd_set_vbus_wakeup(pdic_data, VBUS_WAKEUP_ENABLE);
+               break;
+       default:
+               return -EINVAL;
        }
        return 0;
 }
@@ -2459,36 +2578,63 @@ static int s2mu106_usbpd_reg_init(struct s2mu106_usbpd_data *_data)
        struct i2c_client *i2c = _data->i2c;
        u8 data = 0;
 
-       s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PLUG_CTRL, &data);
-       data |= S2MU106_REG_PLUG_CTRL_VDM_DISABLE |
-                                       S2MU106_REG_PLUG_CTRL_ECO_SRC_CAP_RDY;
-       s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL, data);
-
        s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PHY_CTRL_IFG, &data);
        data |= S2MU106_PHY_IFG_35US << S2MU106_REG_IFG_SHIFT;
        s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PHY_CTRL_IFG, data);
 
+       s2mu106_usbpd_read_reg(i2c, S2MU106_REG_MSG_SEND_CON, &data);
+       data |= S2MU106_REG_MSG_SEND_CON_HARD_EN;
+       s2mu106_usbpd_write_reg(i2c, S2MU106_REG_MSG_SEND_CON, data);
+
+       /* for SMPL issue */
+       s2mu106_usbpd_read_reg(i2c, S2MU106_REG_ANALOG_OTP_0A, &data);
+       data |= S2MU106_REG_OVP_ON;
+       s2mu106_usbpd_write_reg(i2c, S2MU106_REG_ANALOG_OTP_0A, data);
+
        s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PD_CTRL_2, &data);
        data &= ~S2MU106_REG_CC_OCP_MASK;
        data |= S2MU106_CC_OCP_575MV << S2MU106_REG_CC_OCP_SHIFT;
        s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PD_CTRL_2, data);
 
+       /* enable Rd monitor status when cc is attached at sink */
+       s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PLUG_CTRL_SET_MON, &data);
+       data |= S2MU106_REG_PLUG_CTRL_SET_MON_RD;
+       s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL_SET_MON, data);
+
+       /* diable rd or vbus mux */
        s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PLUG_CTRL_VBUS_MUX, &data);
-       data &= ~S2MU106_REG_DET_RD_OR_VBUS;
+       data &= ~S2MU106_REG_RD_OR_VBUS_MUX_SEL;
        s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL_VBUS_MUX, data);
 
-       s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PLUG_CTRL_SET_RD, &data);
-       data |= S2MU106_REG_USB31_EN;
-       s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL_SET_RD, data);
-
-       s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PLUG_CTRL, &data);
-       data &= ~S2MU106_REG_PLUG_CTRL_UFP_ATTACH_OPT;
+       s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PHY_CTRL_00, 0x80);
+       s2mu106_usbpd_read_reg(i2c, S2MU106_REG_BMC_CTRL, &data);
+       data |= 0x01 << 2;
+       s2mu106_usbpd_write_reg(i2c, S2MU106_REG_BMC_CTRL, data);
+
+       /* set debounce time
+        devide by 300 and unit is ms */
+       s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL_CC_TIMER1, 0xe4);
+       s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL_CC_TIMER2, 0x0c);
+
+       /* enable support acc */
+       s2mu106_usbpd_read_reg(i2c, S2MU106_REG_PLUG_CTRL_CC_HOLD, &data);
+       data |= S2MU106_REG_PLUG_CTRL_SUPPORT_ACC;
+       s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL_CC_HOLD, data);
+
+       /* fix trim code */
+       s2mu106_usbpd_read_reg(i2c, 0x00, &data);
+       data |= 0x1 | 0x3 << 2;
+       s2mu106_usbpd_write_reg(i2c, 0x00, data);
+
+       data = 0;
+       data |= (S2MU106_REG_PLUG_CTRL_SSM_DISABLE |
+                                       S2MU106_REG_PLUG_CTRL_VDM_DISABLE);
        s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL, data);
 
        /* set Rd threshold to 400mV */
        s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL_SET_RD_2, S2MU106_THRESHOLD_600MV);
        s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL_SET_RP_2, S2MU106_THRESHOLD_1200MV);
-       s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL_SET_RD, S2MU106_THRESHOLD_214MV);
+       s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL_SET_RD, S2MU106_THRESHOLD_300MV | 0x40);
        s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL_SET_RP, S2MU106_THRESHOLD_2057MV);
 
        if (_data->vconn_en) {
@@ -2498,11 +2644,11 @@ static int s2mu106_usbpd_reg_init(struct s2mu106_usbpd_data *_data)
                data |= S2MU106_REG_PLUG_CTRL_VCONN_MANUAL_EN;
                s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL_RpRd, data);
        }
-
+#ifdef CONFIG_PM_S2MU106
+       s2mu106_usbpd_set_pmeter_mode(_data, PM_TYPE_VCHGIN);
+#endif
        s2mu106_usbpd_write_reg(i2c, S2MU106_REG_PLUG_CTRL_RpRd, S2MU106_RESET_REG_00);
 
-       s2mu106_usbpd_write_reg(i2c, S2MU106_REG_MSG_SEND_CON, S2MU106_RESET_REG_00);
-
        s2mu106_usbpd_set_vconn_manual(_data, true);
 
        return 0;
@@ -2587,8 +2733,7 @@ static void s2mu106_usbpd_pdic_data_init(struct s2mu106_usbpd_data *_data)
        _data->is_otg_vboost = false;
        _data->is_otg_reboost = false;
        _data->is_pr_swap = false;
-       _data->vbus_short = false;
-       _data->vbus_short_check = false;
+       _data->vbus_access = false;
 #ifndef CONFIG_SEC_FACTORY
        _data->lpcharge_water = false;
 #endif
@@ -2689,6 +2834,11 @@ static int s2mu106_usbpd_probe(struct i2c_client *i2c,
 
        usbpd_set_ops(dev, &s2mu106_ops);
 
+#ifdef CONFIG_PM_S2MU106
+       pdic_data->psy_pm = power_supply_get_by_name("s2mu106_pmeter");
+       if (!pdic_data->psy_pm)
+               pr_err("%s: Fail to get pmeter\n", __func__);
+#endif
        s2mu106_usbpd_reg_init(pdic_data);
 
        pdic_data->pdic_queue =
@@ -2833,6 +2983,7 @@ static usbpd_phy_ops_type s2mu106_ops = {
        .tx_msg                 = s2mu106_tx_msg,
        .rx_msg                 = s2mu106_rx_msg,
        .hard_reset             = s2mu106_hard_reset,
+       .soft_reset             = s2mu106_soft_reset,
        .set_power_role         = s2mu106_set_power_role,
        .get_power_role         = s2mu106_get_power_role,
        .set_data_role          = s2mu106_set_data_role,
@@ -2844,9 +2995,11 @@ static usbpd_phy_ops_type s2mu106_ops = {
        .poll_status            = s2mu106_poll_status,
        .driver_reset           = s2mu106_driver_reset,
        .set_otg_control        = s2mu106_set_otg_control,
-       .get_vbus_short_check   = s2mu106_get_vbus_short_check,
        .set_cc_control         = s2mu106_set_cc_control,
        .get_side_check         = s2mu106_get_side_check,
+       .pr_swap                        = s2mu106_pr_swap,
+       .vbus_on_check          = s2mu106_vbus_on_check,
+       .check_bist_message = s2mu106_check_bist_message,
 };
 
 #if defined CONFIG_PM
index 37cd7691db035ad1b2b46073627fd70faddeceb1..e1e8d5654c6860310e5c8264cdd25957476fec21 100644 (file)
 extern struct pdic_notifier_data pd_noti;
 #endif
 
+#define MS_TO_NS(msec)         ((msec) * 1000 * 1000)
+
+void usbpd_timer1_start(struct usbpd_data *pd_data)
+{
+       do_gettimeofday(&pd_data->time1);
+}
+
+int usbpd_check_time1(struct usbpd_data *pd_data)
+{
+       int ms = 0;
+       int sec = 0;
+       struct timeval time;
+
+       do_gettimeofday(&time);
+
+       sec = time.tv_sec - pd_data->time1.tv_sec;
+       ms = (time.tv_usec - pd_data->time1.tv_usec) / 1000;
+
+       return (sec * 1000) + ms;
+}
+
+void usbpd_timer2_start(struct usbpd_data *pd_data)
+{
+       do_gettimeofday(&pd_data->time2);
+}
+
+int usbpd_check_time2(struct usbpd_data *pd_data)
+{
+       int ms = 0;
+       int sec = 0;
+       struct timeval time;
+
+       do_gettimeofday(&time);
+
+       sec = time.tv_sec - pd_data->time2.tv_sec;
+       ms = (time.tv_usec - pd_data->time2.tv_usec) / 1000;
+
+       return (sec * 1000) + ms;
+}
+
 static void increase_message_id_counter(struct usbpd_data *pd_data)
 {
        pd_data->counter.message_id_counter++;
@@ -66,6 +106,7 @@ void usbpd_init_protocol(struct usbpd_data *pd_data)
 {
        rx_layer_init(&pd_data->protocol_rx);
        tx_layer_init(&pd_data->protocol_tx);
+       pd_data->id_matched = 0;
 }
 
 void usbpd_init_counters(struct usbpd_data *pd_data)
@@ -274,6 +315,7 @@ void usbpd_set_ops(struct device *dev, usbpd_phy_ops_type *ops)
        pd_data->phy_ops.tx_msg = ops->tx_msg;
        pd_data->phy_ops.rx_msg = ops->rx_msg;
        pd_data->phy_ops.hard_reset = ops->hard_reset;
+       pd_data->phy_ops.soft_reset = ops->soft_reset;
        pd_data->phy_ops.set_power_role = ops->set_power_role;
        pd_data->phy_ops.get_power_role = ops->get_power_role;
        pd_data->phy_ops.set_data_role = ops->set_data_role;
@@ -285,9 +327,11 @@ void usbpd_set_ops(struct device *dev, usbpd_phy_ops_type *ops)
        pd_data->phy_ops.poll_status = ops->poll_status;
        pd_data->phy_ops.driver_reset = ops->driver_reset;
        pd_data->phy_ops.set_otg_control = ops->set_otg_control;
-       pd_data->phy_ops.get_vbus_short_check = ops->get_vbus_short_check;
        pd_data->phy_ops.set_cc_control = ops->set_cc_control;
        pd_data->phy_ops.get_side_check = ops->get_side_check;
+       pd_data->phy_ops.pr_swap = ops->pr_swap;
+       pd_data->phy_ops.vbus_on_check = ops->vbus_on_check;
+       pd_data->phy_ops.check_bist_message = ops->check_bist_message;
 }
 
 protocol_state usbpd_protocol_rx_layer_reset_for_receive(struct protocol_data *rx)
@@ -322,8 +366,12 @@ protocol_state usbpd_protocol_rx_wait_for_phy_message(struct protocol_data *rx)
                        dev_err(pd_data->dev, "[Rx] Got SOFTRESET.\n");
                        state = PRL_Rx_Layer_Reset_for_Receive;
                } else {
-                       if (rx->stored_message_id == rx->msg_header.msg_id)
+                       if (rx->stored_message_id == rx->msg_header.msg_id) {
+                               pd_data->id_matched = 0;
                                return state;
+                       }
+
+                       pd_data->id_matched = 1;
 
                        dev_err(pd_data->dev, "[Rx] [0x%x] [0x%x]\n",
                                        rx->msg_header.word, rx->data_obj[0].object);
@@ -581,7 +629,7 @@ int usbpd_init(struct device *dev, void *phy_driver_data)
                ret = sysfs_create_group(&pd_data->ccic_dev->kobj, &ccic_sysfs_group);
                if (ret)
                        pr_err("%s: ccic sysfs fail, ret %d", __func__, ret);
-               else 
+               else
                        dev_set_drvdata(pd_data->ccic_dev, pd_data);
        }
 #endif
@@ -596,7 +644,13 @@ int usbpd_init(struct device *dev, void *phy_driver_data)
        usbpd_init_policy(pd_data);
        usbpd_init_manager(pd_data);
 
+       pd_data->policy_wqueue =
+               create_singlethread_workqueue(dev_name(dev));
+       if (!pd_data->policy_wqueue)
+               pr_err("%s: Fail to Create Workqueue\n", __func__);
+
        INIT_WORK(&pd_data->worker, usbpd_policy_work);
+
        init_completion(&pd_data->msg_arrived);
 
        return 0;
index bbdce419ef113fd3e5508985af2274154adc65e0..1aa4ab2f68f862705f85cba536951889a049a12b 100644 (file)
@@ -60,15 +60,6 @@ void s2mu106_select_pdo(int num)
 {
        struct usbpd_data *pd_data = pd_noti.pd_data;
        struct usbpd_manager_data *manager = &pd_data->manager;
-       bool vbus_short;
-
-       pd_data->phy_ops.get_vbus_short_check(pd_data, &vbus_short);
-
-       if (vbus_short) {
-               pr_info(" %s : PDO(%d) is ignored becasue of vbus short\n",
-                               __func__, pd_noti.sink_status.selected_pdo_num);
-               return;
-       }
 
        if (pd_noti.sink_status.selected_pdo_num == num)
                return;
@@ -142,6 +133,13 @@ void usbpd_manager_start_discover_msg_cancel(struct device *dev)
        cancel_delayed_work_sync(&manager->start_discover_msg_handler);
 }
 
+void usbpd_manager_send_pr_swap(struct device *dev)
+{
+       pr_info("%s: call send pr swap msg\n", __func__);
+
+       usbpd_manager_inform_event(pd_noti.pd_data, MANAGER_SEND_PR_SWAP);
+}
+
 static void init_source_cap_data(struct usbpd_manager_data *_data)
 {
 /*     struct usbpd_data *pd_data = manager_to_usbpd(_data);
@@ -187,12 +185,12 @@ static void init_sink_cap_data(struct usbpd_manager_data *_data)
        data_obj->power_data_obj_sink.usb_comm_capable = 1;
        data_obj->power_data_obj_sink.data_role_swap = 1;
        data_obj->power_data_obj_sink.voltage = 5000/50;
-       data_obj->power_data_obj_sink.op_current = 500/10;
+       data_obj->power_data_obj_sink.op_current = 3000/10;
 
        (data_obj + 1)->power_data_obj_variable.supply_type = POWER_TYPE_VARIABLE;
        (data_obj + 1)->power_data_obj_variable.max_voltage = _data->sink_cap_max_volt / 50;
        (data_obj + 1)->power_data_obj_variable.min_voltage = 5000 / 50;
-       (data_obj + 1)->power_data_obj_variable.max_current = 500 / 10;
+       (data_obj + 1)->power_data_obj_variable.max_current = 3000 / 10;
 }
 
 void usbpd_manager_receive_samsung_uvdm_message(struct usbpd_data *pd_data)
@@ -215,12 +213,24 @@ void usbpd_manager_plug_attach(struct device *dev)
        manager->template.data = &pd_noti.sink_status;
        ifconn_event_work(pdic_data, IFCONN_NOTIFY_MANAGER,
                IFCONN_NOTIFY_ID_POWER_STATUS, IFCONN_NOTIFY_EVENT_ATTACH, &pd_noti);
+       manager->pd_attached = 1;
 #endif
+       pr_info("%s: usbpd plug atached\n", __func__);
 }
 
 void usbpd_manager_plug_detach(struct device *dev, bool notify)
 {
+#if defined(CONFIG_IFCONN_NOTIFIER)
        struct usbpd_data *pd_data = dev_get_drvdata(dev);
+       struct s2mu106_usbpd_data *pdic_data = pd_data->phy_driver_data;
+       struct usbpd_manager_data *manager = &pd_data->manager;
+
+       if (manager->pd_attached && pdic_data->power_role == PDIC_SINK) {
+               ifconn_event_work(pdic_data, IFCONN_NOTIFY_BATTERY,
+                                                               IFCONN_NOTIFY_ID_DETACH, 0, 0);
+               manager->pd_attached = 0;
+       }
+#endif
 
        pr_info("%s: usbpd plug detached\n", __func__);
 
@@ -228,18 +238,18 @@ void usbpd_manager_plug_detach(struct device *dev, bool notify)
 }
 
 void usbpd_manager_acc_detach(struct device *dev)
-{      
+{
        struct usbpd_data *pd_data = dev_get_drvdata(dev);
        struct usbpd_manager_data *manager = &pd_data->manager;
 
        pr_info("%s\n", __func__);
-       if ( manager->acc_type != CCIC_DOCK_DETACHED ) {
+       if (manager->acc_type != CCIC_DOCK_DETACHED) {
                pr_info("%s: schedule_delayed_work \n", __func__);
-               if ( manager->acc_type == CCIC_DOCK_HMT )
+               if (manager->acc_type == CCIC_DOCK_HMT)
                        schedule_delayed_work(&manager->acc_detach_handler, msecs_to_jiffies(1000));
                else
                        schedule_delayed_work(&manager->acc_detach_handler, msecs_to_jiffies(0));
-       }       
+       }
 }
 
 int usbpd_manager_command_to_policy(struct device *dev,
@@ -316,6 +326,10 @@ void usbpd_manager_inform_event(struct usbpd_data *pd_data,
                usbpd_manager_command_to_policy(pd_data->dev,
                                        MANAGER_REQ_VDM_DISCOVER_IDENTITY);
                break;
+       case MANAGER_SEND_PR_SWAP:
+               usbpd_manager_command_to_policy(pd_data->dev,
+                                       MANAGER_REQ_PR_SWAP);
+               break;
        default:
                pr_info("%s: not matched event(%d)\n", __func__, event);
        }
@@ -513,7 +527,7 @@ static int usbpd_manager_check_accessory(struct usbpd_manager_data *manager)
                                break;
                        }
                } else if (vid == SAMSUNG_MPA_VENDOR_ID) {
-                       switch(pid) {
+                       switch (pid) {
                        case MPA_PRODUCT_ID:
                                acc_type = CCIC_DOCK_MPA;
                                pr_info("%s : Samsung MPA connected.\n", __func__);
@@ -525,10 +539,10 @@ static int usbpd_manager_check_accessory(struct usbpd_manager_data *manager)
                        }
                }
                manager->acc_type = acc_type;
-       } else 
+       } else
                acc_type = manager->acc_type;
 
-       if (acc_type != CCIC_DOCK_NEW) 
+       if (acc_type != CCIC_DOCK_NEW)
                usbpd_manager_send_dock_intent(acc_type);
 
        usbpd_manager_send_dock_uevent(vid, pid, acc_type);
@@ -704,27 +718,27 @@ int usbpd_manager_get_status(struct usbpd_data *pd_data)
                multi_func_preference = pd_obj->displayport_status.multi_function_preferred;
 
                if (multi_func_preference) {
-                       if(manager->pin_assignment & DP_PIN_ASSIGNMENT_D) {
+                       if (manager->pin_assignment & DP_PIN_ASSIGNMENT_D) {
                                pin_assignment = IFCONN_NOTIFY_DP_PIN_D;
-                       } else if(manager->pin_assignment & DP_PIN_ASSIGNMENT_B) {
+                       } else if (manager->pin_assignment & DP_PIN_ASSIGNMENT_B) {
                                pin_assignment = IFCONN_NOTIFY_DP_PIN_B;
-                       } else if(manager->pin_assignment & DP_PIN_ASSIGNMENT_F) {
+                       } else if (manager->pin_assignment & DP_PIN_ASSIGNMENT_F) {
                                pin_assignment = IFCONN_NOTIFY_DP_PIN_F;
                        } else {
                                pr_info("wrong pin assignment value\n");
                        }
                } else {
-                       if(manager->pin_assignment & DP_PIN_ASSIGNMENT_C) {
+                       if (manager->pin_assignment & DP_PIN_ASSIGNMENT_C) {
                                pin_assignment = IFCONN_NOTIFY_DP_PIN_C;
-                       } else if(manager->pin_assignment & DP_PIN_ASSIGNMENT_E) {
+                       } else if (manager->pin_assignment & DP_PIN_ASSIGNMENT_E) {
                                pin_assignment = IFCONN_NOTIFY_DP_PIN_E;
-                       } else if(manager->pin_assignment & DP_PIN_ASSIGNMENT_A) {
+                       } else if (manager->pin_assignment & DP_PIN_ASSIGNMENT_A) {
                                pin_assignment = IFCONN_NOTIFY_DP_PIN_A;
-                       } else if(manager->pin_assignment & DP_PIN_ASSIGNMENT_D) {
+                       } else if (manager->pin_assignment & DP_PIN_ASSIGNMENT_D) {
                                pin_assignment = IFCONN_NOTIFY_DP_PIN_D;
-                       } else if(manager->pin_assignment & DP_PIN_ASSIGNMENT_B) {
+                       } else if (manager->pin_assignment & DP_PIN_ASSIGNMENT_B) {
                                pin_assignment = IFCONN_NOTIFY_DP_PIN_B;
-                       } else if(manager->pin_assignment & DP_PIN_ASSIGNMENT_F) {
+                       } else if (manager->pin_assignment & DP_PIN_ASSIGNMENT_F) {
                                pin_assignment = IFCONN_NOTIFY_DP_PIN_F;
                        } else {
                                pr_info("wrong pin assignment value\n");
@@ -761,7 +775,7 @@ int usbpd_manager_get_configure(struct usbpd_data *pd_data)
                ifconn_event_work(pdic_data, IFCONN_NOTIFY_MANAGER,
                                                IFCONN_NOTIFY_ID_DP_LINK_CONF,
                                                IFCONN_NOTIFY_EVENT_ATTACH, manager);
-       
+
        return 0;
 }
 
@@ -790,27 +804,27 @@ int usbpd_manager_get_attention(struct usbpd_data *pd_data)
                multi_func_preference = pd_obj->displayport_status.multi_function_preferred;
 
                if (multi_func_preference) {
-                       if(manager->pin_assignment & DP_PIN_ASSIGNMENT_D) {
+                       if (manager->pin_assignment & DP_PIN_ASSIGNMENT_D) {
                                pin_assignment = IFCONN_NOTIFY_DP_PIN_D;
-                       } else if(manager->pin_assignment & DP_PIN_ASSIGNMENT_B) {
+                       } else if (manager->pin_assignment & DP_PIN_ASSIGNMENT_B) {
                                pin_assignment = IFCONN_NOTIFY_DP_PIN_B;
-                       } else if(manager->pin_assignment & DP_PIN_ASSIGNMENT_F) {
+                       } else if (manager->pin_assignment & DP_PIN_ASSIGNMENT_F) {
                                pin_assignment = IFCONN_NOTIFY_DP_PIN_F;
                        } else {
                                pr_info("wrong pin assignment value\n");
                        }
                } else {
-                       if(manager->pin_assignment & DP_PIN_ASSIGNMENT_C) {
+                       if (manager->pin_assignment & DP_PIN_ASSIGNMENT_C) {
                                pin_assignment = IFCONN_NOTIFY_DP_PIN_C;
-                       } else if(manager->pin_assignment & DP_PIN_ASSIGNMENT_E) {
+                       } else if (manager->pin_assignment & DP_PIN_ASSIGNMENT_E) {
                                pin_assignment = IFCONN_NOTIFY_DP_PIN_E;
-                       } else if(manager->pin_assignment & DP_PIN_ASSIGNMENT_A) {
+                       } else if (manager->pin_assignment & DP_PIN_ASSIGNMENT_A) {
                                pin_assignment = IFCONN_NOTIFY_DP_PIN_A;
-                       } else if(manager->pin_assignment & DP_PIN_ASSIGNMENT_D) {
+                       } else if (manager->pin_assignment & DP_PIN_ASSIGNMENT_D) {
                                pin_assignment = IFCONN_NOTIFY_DP_PIN_D;
-                       } else if(manager->pin_assignment & DP_PIN_ASSIGNMENT_B) {
+                       } else if (manager->pin_assignment & DP_PIN_ASSIGNMENT_B) {
                                pin_assignment = IFCONN_NOTIFY_DP_PIN_B;
-                       } else if(manager->pin_assignment & DP_PIN_ASSIGNMENT_F) {
+                       } else if (manager->pin_assignment & DP_PIN_ASSIGNMENT_F) {
                                pin_assignment = IFCONN_NOTIFY_DP_PIN_F;
                        } else {
                                pr_info("wrong pin assignment value\n");
@@ -943,7 +957,7 @@ int usbpd_manager_match_request(struct usbpd_data *pd_data)
 
        unsigned supply_type
        = pd_data->source_request_obj.power_data_obj_supply_type.supply_type;
-       unsigned mismatch, max_min, op, pos;
+       unsigned src_max_current,  mismatch, max_min, op, pos;
 
        if (supply_type == POWER_TYPE_FIXED) {
                pr_info("REQUEST: FIXED\n");
@@ -960,19 +974,26 @@ int usbpd_manager_match_request(struct usbpd_data *pd_data)
        }
 
 log_fixed_variable:
+    /* Tx Source PDO */
+    src_max_current = pd_data->source_data_obj.power_data_obj.max_current;
+
+    /* Rx Request RDO */
        mismatch = pd_data->source_request_obj.request_data_object.capability_mismatch;
        max_min = pd_data->source_request_obj.request_data_object.min_current;
        op = pd_data->source_request_obj.request_data_object.op_current;
        pos = pd_data->source_request_obj.request_data_object.object_position;
-       pr_info("Obj position: %d\n", pos);
-       pr_info("Mismatch: %d\n", mismatch);
-       pr_info("Operating Current: %d mA\n", op*10);
-       if (pd_data->source_request_obj.request_data_object.give_back)
-               pr_info("Min current: %d mA\n", max_min*10);
-       else
-               pr_info("Max current: %d mA\n", max_min*10);
 
-       return 0;
+       pr_info("%s %x\n", __func__, pd_data->source_request_obj.object);
+
+    /*src_max_current is already *10 value ex) src_max_current 500mA */
+       //pr_info("Tx SourceCap Current : %dmA\n", src_max_current*10);
+       //pr_info("Rx Request Current : %dmA\n", max_min*10);
+
+    /* Compare Pdo and Rdo */
+    if ((src_max_current >= max_min) && (pos == 1))
+               return 0;
+    else
+               return -1;
 
 log_battery:
        mismatch = pd_data->source_request_obj.request_data_object_battery.capability_mismatch;
@@ -1088,9 +1109,10 @@ int usbpd_init_manager(struct usbpd_data *pd_data)
 #endif
        mutex_init(&manager->vdm_mutex);
        manager->pd_data = pd_data;
+       manager->pd_attached = 0;
        manager->power_role_swap = true;
        manager->data_role_swap = true;
-       manager->vconn_source_swap = true;
+       manager->vconn_source_swap = false;
        manager->alt_sended = 0;
        manager->vdm_en = 0;
        manager->acc_type = 0;
index 88dccc42d706d6982e3be071ab60ba8a4ff17903..39010cc07c4fc30a18b5674e89bedd70948db976 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/ccic/usbpd.h>
 #include <linux/delay.h>
 #include <linux/completion.h>
-#include <linux/time.h>
 
 #include <linux/muic/muic.h>
 #if defined(CONFIG_MUIC_NOTIFIER)
 policy_state usbpd_policy_src_startup(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int ret = PE_SRC_Send_Capabilities;
+       int ms = 0;
 
+       /**********************************************
+       Actions on entry:
+       Reset CapsCounter
+       Reset Protocol Layer
+       Start SwapSourceStartTimer (only after Swap)
+       **********************************************/
+
+       /* 1) PD State Inform for AP */
        dev_info(pd_data->dev, "%s\n", __func__);
+
+       /* 2) CapsCounter Reset */
        pd_data->counter.caps_counter = 0;
+
+       /* 3) PD Protocol Initialization */
        usbpd_init_protocol(pd_data);
 
+       /* 4) Fro tSrcrecover after PE_SRC_Transition_to_default */
+       if (policy->txhardresetflag == 1) {
+               policy->txhardresetflag = 0;
+
+               usbpd_timer1_start(pd_data);
+               while (1) {
+                       if (policy->plug_valid == 0) {
+                               ret = PE_SRC_Startup;
+                               break;
+                       }
+                       ms = usbpd_check_time1(pd_data);
+                       if (ms >= 200)
+                               break;
+               }
+       }
+
+       /* 5) Configuration Channel On */
        pd_data->phy_ops.set_cc_control(pd_data, USBPD_CC_ON);
 
-       return PE_SRC_Send_Capabilities;
+       return ret;
 }
 
 policy_state usbpd_policy_src_discovery(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int ret = 0;
+       int ms = 0;
+
+       /**********************************************
+       Actions on entry:
+       Initialize and run SourceCapabilityTimer
+       **********************************************/
 
+       /* 1) PD State Inform for AP */
        dev_info(pd_data->dev, "%s\n", __func__);
-       msleep(tSendSourceCap);
+
+       /* 2) Delay*/
+       usbpd_timer1_start(pd_data);
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_SRC_Discovery;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               if (ms >= tTypeCSendSourceCap)
+                       break;
+       }
+
+       if (ret == PE_SRC_Discovery)
+               return ret;
+       /* 3) Caps Counter Check */
        if (pd_data->counter.caps_counter <= USBPD_nCapsCount)
                return PE_SRC_Send_Capabilities;
        else
@@ -66,126 +119,198 @@ policy_state usbpd_policy_src_discovery(struct policy_data *policy)
 policy_state usbpd_policy_src_send_capabilities(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       bool received_goodcrc = 0;
+       int ret = 0;
+       int ms = 0;
+
+       /**********************************************
+       Actions on entry:
+       Request present source capabilities from Device Policy Manager
+       Send PD Capabilities message
+       Increment CapsCounter (optional)
+       If GoodCRC received:
+       - stop NoResponseTimer
+       - reset HardResetCounter and CapsCounter
+       - initialize and run SenderResponseTimer
+       **********************************************/
+
+       /* 1) PD State Inform for AP */
+       dev_info(pd_data->dev, "%s\n", __func__);
 
+       /* 2) Source Capabilities PDO Read & Write */
        policy->tx_msg_header.word = pd_data->source_msg_header.word;
        policy->tx_data_obj[0].object = pd_data->source_data_obj.object;
 
-       dev_info(pd_data->dev, "%s\n", __func__);
-
+       /* 3) Interrupt Status Bit Clear  */
+       pd_data->phy_ops.get_status(pd_data, MSG_GOODCRC | MSG_REQUEST |
+                                                                                                                       MSG_GET_SNK_CAP);
+       /* 4) Add Caps Counter */
        pd_data->counter.caps_counter++;
-       if (usbpd_send_msg(pd_data, &policy->tx_msg_header,
-                               policy->tx_data_obj)) {
-               pd_data->policy.state = PE_SRC_Send_Capabilities;
-               if (usbpd_wait_msg(pd_data, MSG_REQUEST, tSenderResponseSRC)) {
-                       if (policy->rx_msg_header.msg_type == USBPD_Request &&
-                               policy->rx_msg_header.num_data_objs > 0) {
-                               pd_data->counter.hard_reset_counter = 0;
-                               pd_data->counter.caps_counter = 0;
-                               pd_data->source_request_obj.object
-                                       = policy->rx_data_obj[0].object;
-                               dev_info(pd_data->dev, "got Request.\n");
-                               return PE_SRC_Negotiate_Capability;
 
-                       } else {
-                               dev_err(pd_data->dev,
-                                       "Not get request object\n");
-                               goto hard_reset;
-                       }
-               } else if (pd_data->phy_ops.get_status(pd_data, MSG_GOODCRC)) {
-                       if (policy->abnormal_state)
-                               return PE_SRC_Send_Capabilities;
+       /* 5) Send Message */
+       usbpd_send_msg(pd_data, &policy->tx_msg_header, policy->tx_data_obj);
+
+       /* 6) Start Timer */
+       usbpd_timer1_start(pd_data);    // Setting 25ms is actual 25 ~ 29ms
+       /* 7) Wait Message or State */
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_SRC_Send_Capabilities;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               if (pd_data->phy_ops.get_status(pd_data, MSG_REQUEST)) {
+                       pd_data->counter.hard_reset_counter = 0;
                        pd_data->counter.caps_counter = 0;
-                       dev_err(pd_data->dev,
-                               "%s NoResponseTimer\n", __func__);
-                       goto hard_reset;
-               } else {        /* not receive good crc */
-                       if (policy->abnormal_state)
-                               return PE_SRC_Send_Capabilities;
-                       return PE_SRC_Discovery;
-               }
-       } else
-               return PE_SRC_Discovery;
-
-hard_reset:
-       if (pd_data->counter.hard_reset_counter > USBPD_nHardResetCount)
-               return Error_Recovery;
+                       usbpd_protocol_rx(pd_data);
+                       pd_data->source_request_obj.object
+                               = policy->rx_data_obj[0].object;
+                       dev_info(pd_data->dev, "got Request.\n");
+                       ret = PE_SRC_Negotiate_Capability;
+                       break;
+               }
 
-       return PE_SRC_Hard_Reset;
-}
-#if 0
-policy_state usbpd_policy_src_send_capabilities(struct policy_data *policy)
-{
-       struct usbpd_data *pd_data = policy_to_usbpd(policy);
+               if (pd_data->phy_ops.get_status(pd_data, MSG_GOODCRC))
+                       received_goodcrc = 1;
 
-       policy->tx_msg_header.word = pd_data->source_msg_header.word;
-       policy->tx_data_obj[0].object = pd_data->source_data_obj.object;
+               if (policy->rx_hardreset) {
+                       ret = 0;
+                       break;
+               }
 
-       dev_info(pd_data->dev, "%s 0x%x 0x%x\n", __func__
-                       , policy->tx_msg_header.word
-                       , policy->tx_data_obj[0].object);
+               /* TD.PD.SRC.E14 Atomic Message Sequence */
+               if (pd_data->phy_ops.get_status(pd_data, MSG_GET_SNK_CAP)) {
+                       ret = PE_SRC_Send_Soft_Reset;
+                       break;
+               }
 
-       pd_data->counter.caps_counter++;
-       if (usbpd_send_msg(pd_data, &policy->tx_msg_header,
-                               policy->tx_data_obj)) {
-               pd_data->counter.hard_reset_counter = 0;
-               pd_data->counter.caps_counter = 0;
-               if (usbpd_wait_msg(pd_data, MSG_REQUEST, tSenderResponse)) {
-                       if (policy->rx_msg_header.msg_type == USBPD_Request &&
-                               policy->rx_msg_header.num_data_objs > 0) {
-                                       pd_data->source_request_obj.object
-                                               = policy->rx_data_obj[0].object;
-                                       dev_info(pd_data->dev, "got Request.\n");
-                                       return PE_SRC_Negotiate_Capability;
-                       } else {
-                               dev_err(pd_data->dev,
-                                       "Not get request object\n");
-                               return Error_Recovery;
+               if (pd_data->phy_ops.get_status(pd_data, MSG_ERROR)) {
+                       ret = PE_SRC_Discovery;
+                       break;
+               }
+
+               if (pd_data->phy_ops.get_status(pd_data, MSG_PING)) {
+                       ret = PE_SRC_Send_Soft_Reset;
+                       break;
+               }
+
+               if (ms >= tSenderResponse) {
+                       if (received_goodcrc) {
+                               ret = PE_SRC_Hard_Reset;
+
+                               if (pd_data->counter.hard_reset_counter > USBPD_nHardResetCount)
+                                       ret = Error_Recovery;
+
+                               break;
                        }
-               } else {
-                       dev_err(pd_data->dev,
-                               "%s NoResponseTimer\n", __func__);
-                       return PE_SRC_Hard_Reset;
                }
-       } else
-               return PE_SRC_Discovery;
 
-       if (pd_data->counter.hard_reset_counter > USBPD_nHardResetCount)
-               return Error_Recovery;
+               if (ms >= 100) {
+                       ret = PE_SRC_Discovery;
+                       break;
+               }
+       }
 
-       return PE_SRC_Send_Capabilities;
+       return ret;
 }
-#endif
+
 policy_state usbpd_policy_src_negotiate_capability(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
-
+       int ret = PE_SRC_Negotiate_Capability;
+
+       /**********************************************
+       Actions on entry:
+       Get Device Policy Manager evaluation of sink request:
+       - Can be met
+       - Can??t be met
+       - Could be met later from Power Reserve
+       If the sink request for Operating Current or Operating Power can be met,
+       but the sink still requires more power Capability Mismatch this
+       information will be passed to Device Policy Manager
+       **********************************************/
+
+       /* 1) PD State Inform for AP */
        dev_info(pd_data->dev, "%s\n", __func__);
-       if (usbpd_manager_match_request(pd_data) == 0)
-               return PE_SRC_Transition_Supply; /* Accept */
-       else
-               return PE_SRC_Capability_Response; /* Reject */
+
+       /* 2) Analysis Received Request Message */
+       if (usbpd_manager_match_request(pd_data) == 0) {
+               usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, USBPD_Accept, USBPD_DFP, USBPD_SOURCE);
+               ret = PE_SRC_Transition_Supply; /* Accept */
+       } else {
+               ret = PE_SRC_Capability_Response; /* Reject */
+       }
+
+       return ret;
 }
 
 policy_state usbpd_policy_src_transition_supply(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int ret = PE_SRC_Ready;
+       int ms1 = 0, ms2 = 0;
+
+       /**********************************************
+       Actions on entry:
+       Initialize and run SourceActivityTimer (see Section 8.3.3.5)
+       If GotoMin send GotoMin message
+       Else send Accept message (within tReceiverResponse)
+       Wait tSrcTransition and request Device Policy Manager to transition Power Supply
+
+       Actions on exit:
+       Send PS_RDY message
+       **********************************************/
 
+       /* 1) PD State Inform for AP */
        dev_info(pd_data->dev, "%s\n", __func__);
-       /* TODO: If GotoMin send GotoMin message */
 
-       if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, USBPD_Accept,
-                       USBPD_DFP, USBPD_SOURCE)) {
-               msleep(tSrcTransition);
+       /* 2) Send Message */
+       // Move to PE_SRC_Nego
+       //usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, USBPD_Accept, USBPD_DFP, USBPD_SOURCE);
 
-               if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header,
-                       USBPD_PS_RDY, USBPD_DFP, USBPD_SOURCE))
-                       return PE_SRC_Ready;
-               else
-                       return PE_SRC_Send_Soft_Reset;
-       } else {
-               return PE_SRC_Send_Soft_Reset;
+       /* 3) Start Timer */
+       usbpd_timer1_start(pd_data);
+
+       /* 4) Wait Message or State */
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_SRC_Transition_Supply;
+                       break;
+               }
+               ms1 = usbpd_check_time1(pd_data);
+               if (pd_data->phy_ops.get_status(pd_data, MSG_GOODCRC)) {
+
+                       usbpd_timer2_start(pd_data);
+                       while (1) {
+                               if (policy->plug_valid == 0) {
+                                       ret = PE_SRC_Transition_Supply;
+                                       break;
+                               }
+                               ms2 = usbpd_check_time2(pd_data);
+                               if (ms2 > tSrcTransition)
+                                       break;
+                       }
+
+                       if (ret == PE_SRC_Transition_Supply)
+                               return ret;
+
+                       usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, USBPD_PS_RDY, USBPD_DFP, USBPD_SOURCE);
+                       ret = PE_SRC_Ready;
+                       break;
+               }
+
+               if (pd_data->phy_ops.get_status(pd_data, MSG_ERROR)) {
+                       ret = PE_SRC_Send_Soft_Reset;
+                       break;
+               }
+
+               if (ms1 >= 5) {
+                       ret = PE_SRC_Hard_Reset;
+                       break;
+               }
        }
-       return PE_SRC_Transition_Supply;
+
+       return ret;
 }
 
 policy_state usbpd_policy_src_ready(struct policy_data *policy)
@@ -193,12 +318,27 @@ policy_state usbpd_policy_src_ready(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int data_role = 0;
 
+       /**********************************************
+       Actions on entry:
+       Initialize and run SourceActivityTimer (see Section 8.3.3.5)
+       Initialize and run DiscoverIdentityTimer
+       **********************************************/
+
+       /* 1) PD State Inform for AP */
        dev_info(pd_data->dev, "%s\n", __func__);
+
+       policy->pd_support = 1;
+
+       /* 2) Wait Message or State */
        CHECK_MSG(pd_data, MSG_GET_SRC_CAP, PE_SRC_Give_Source_Cap);
        CHECK_MSG(pd_data, MSG_REQUEST, PE_SRC_Negotiate_Capability);
        CHECK_MSG(pd_data, MSG_PR_SWAP, PE_PRS_SRC_SNK_Evaluate_Swap);
        CHECK_MSG(pd_data, MSG_DR_SWAP, PE_DRS_Evaluate_Port);
        CHECK_MSG(pd_data, MSG_VCONN_SWAP, PE_VCS_Evaluate_Swap);
+       CHECK_MSG(pd_data, MSG_GET_SNK_CAP, PE_DR_SRC_Give_Sink_Cap);
+       CHECK_MSG(pd_data, MSG_SOFTRESET, PE_SRC_Soft_Reset);
+       CHECK_MSG(pd_data, MSG_ERROR, PE_SRC_Send_Soft_Reset);
+#if 0
        CHECK_MSG(pd_data, VDM_DISCOVER_IDENTITY, PE_UFP_VDM_Get_Identity);
        CHECK_MSG(pd_data, VDM_DISCOVER_SVID, PE_UFP_VDM_Get_SVIDs);
        CHECK_MSG(pd_data, VDM_DISCOVER_MODE, PE_UFP_VDM_Get_Modes);
@@ -207,7 +347,8 @@ policy_state usbpd_policy_src_ready(struct policy_data *policy)
        CHECK_MSG(pd_data, VDM_DP_STATUS_UPDATE, PE_UFP_VDM_Evaluate_Status);
        CHECK_MSG(pd_data, VDM_DP_CONFIGURE, PE_UFP_VDM_Evaluate_Configure);
        CHECK_MSG(pd_data, UVDM_MSG, PE_DFP_UVDM_Receive_Message);
-
+#endif
+    /* 3) Command Check from AP */
        CHECK_CMD(pd_data, MANAGER_REQ_GET_SNKCAP, PE_SRC_Get_Sink_Cap);
        CHECK_CMD(pd_data, MANAGER_REQ_GOTOMIN, PE_SRC_Transition_Supply);
        CHECK_CMD(pd_data, MANAGER_REQ_SRCCAP_CHANGE, PE_SRC_Send_Capabilities);
@@ -220,10 +361,20 @@ policy_state usbpd_policy_src_ready(struct policy_data *policy)
        CHECK_CMD(pd_data, MANAGER_REQ_VDM_DISCOVER_SVID, PE_DFP_VDM_SVIDs_Request);
        CHECK_CMD(pd_data, MANAGER_REQ_VDM_DISCOVER_MODE, PE_DFP_VDM_Modes_Request);
        CHECK_CMD(pd_data, MANAGER_REQ_VDM_ENTER_MODE, PE_DFP_VDM_Mode_Entry_Request);
+       CHECK_CMD(pd_data, MANAGER_REQ_VDM_EXIT_MODE, PE_DFP_VDM_Mode_Exit_Request);
        CHECK_CMD(pd_data, MANAGER_REQ_VDM_STATUS_UPDATE, PE_DFP_VDM_Status_Update);
        CHECK_CMD(pd_data, MANAGER_REQ_VDM_DisplayPort_Configure, PE_DFP_VDM_DisplayPort_Configure);
        CHECK_CMD(pd_data, MANAGER_REQ_VDM_ATTENTION, PE_UFP_VDM_Attention_Request);
 
+       /* 7) Check bist message */
+       if (pd_data->phy_ops.check_bist_message(pd_data) == 0)  {
+               dev_info(pd_data->dev, "check_bist_message : Rx_Msg is BIST\n");
+               return PE_BIST_Receive_Mode;
+       } else {
+               dev_info(pd_data->dev, "check_bist_message : Rx_Msg is NOT BIST\n");
+       }
+
+
 /*     for data role swap test
        if (usbpd_manager_vdm_request_enabled(pd_data)) {
                msleep(tDiscoverIdentity);
@@ -232,9 +383,10 @@ policy_state usbpd_policy_src_ready(struct policy_data *policy)
 */
        pd_data->phy_ops.get_data_role(pd_data, &data_role);
 
+#if 0
        if (data_role == USBPD_DFP)
                usbpd_manager_vdm_request_enabled(pd_data);
-
+#endif
        return PE_SRC_Ready;
 }
 
@@ -242,40 +394,109 @@ policy_state usbpd_policy_src_disabled(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
 
+       /**********************************************
+       Actions on entry:
+       Disable Power Delivery
+       **********************************************/
+
+       /* 1) PD State Inform for AP */
        dev_info(pd_data->dev, "%s\n", __func__);
+
        return PE_SRC_Disabled;
 }
 
 policy_state usbpd_policy_src_capability_response(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int ret = 0;
+       int data_role = 0;
+       int ms = 0;
 
+       /**********************************************
+       Actions on entry:
+       Send Reject message if request can't be met
+       Send Wait message if request could be met later from the Power
+       Reserve and present Contract is still valid
+       **********************************************/
+
+       /* 1) PD State Inform for AP */
        dev_info(pd_data->dev, "%s\n", __func__);
 
-       if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, USBPD_Reject,
-                               USBPD_DFP, USBPD_SOURCE)) {
-               return PE_SRC_Ready;
-               /* TODO: if (Contract Invalid)
-                  return(PE_SRC_Hard_Reset) */
+       pd_data->phy_ops.get_data_role(pd_data, &data_role);
+
+       /* 2) Send Message */
+       usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, USBPD_Reject,
+                                                                                               data_role, USBPD_SOURCE);
+
+       /* 3) Start Timer */
+       usbpd_timer1_start(pd_data);
+
+       /* 4) Wait Message or State */
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_SRC_Capability_Response;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               if (pd_data->phy_ops.get_status(pd_data, MSG_GOODCRC)) {
+                       ret = PE_SRC_Ready;
+                       break;
+               }
+
+               if (pd_data->phy_ops.get_status(pd_data, MSG_ERROR)) {
+                       ret = PE_SRC_Send_Soft_Reset;
+                       break;
+               }
+               if (ms >= 5) {
+                       ret = PE_SRC_Hard_Reset;
+                       break;
+               }
        }
-       /*
-       else if (no Explicit Contract && Reject message sent
-                       || Wait message sent)
-               return(PE_SRC_Wait_New_Capabilities);
-       */
-       return PE_SRC_Capability_Response;
+
+       return ret;
 }
 
 policy_state usbpd_policy_src_hard_reset(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int ret = PE_SRC_Transition_to_default;
+       int ms = 0;
 
-       dev_info(pd_data->dev, "%s\n", __func__);
+       /**********************************************
+       Actions on entry:
+       Generate Hard Reset signalling
+       Start PSHardResetTimer
+       Increment HardResetCounter
+       **********************************************/
 
-       msleep(tPSHardReset);
+       /* 1) PD State Inform for AP */
+       dev_info(pd_data->dev, "%s\n", __func__);
 
+       /* 2) Send Hardreset */
        pd_data->phy_ops.hard_reset(pd_data);
+
+       /* 3) Configuration Channel On */
        pd_data->phy_ops.set_cc_control(pd_data, USBPD_CC_OFF);
+
+       /* 4) Set Tx HardReset Flag After SRC_HADRESET */
+       policy->txhardresetflag = 1;
+
+       /* 5) Delay : Setting 25 is actual 57.3ms */
+       usbpd_timer1_start(pd_data);
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_SRC_Hard_Reset;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               if (ms >= tPSHardReset)
+                       break;
+       }
+
+       if (ret == PE_SRC_Hard_Reset)
+               return ret;
+
+       /* 6) Add Hardreset Counter */
        pd_data->counter.hard_reset_counter++;
 
        return PE_SRC_Transition_to_default;
@@ -284,10 +505,34 @@ policy_state usbpd_policy_src_hard_reset(struct policy_data *policy)
 policy_state usbpd_policy_src_hard_reset_received(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int ret = PE_SRC_Transition_to_default;
+       int ms = 0;
+
+       /**********************************************
+       Actions on entry:
+       Start PSHardResetTimer
+       **********************************************/
 
+       /* 1) PD State Inform for AP */
        dev_info(pd_data->dev, "%s\n", __func__);
 
-       msleep(tPSHardReset);
+       /* 2) Delay */
+       usbpd_timer1_start(pd_data);
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_SRC_Hard_Reset_Received;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               if (ms >= tPSHardReset)
+                       break;
+       }
+
+       if (ret == PE_SRC_Hard_Reset_Received)
+               return ret;
+
+       /* 3) Set Tx HardReset Flag After SRC_HADRESET */
+       policy->txhardresetflag = 1;
 
        return PE_SRC_Transition_to_default;
 }
@@ -295,10 +540,43 @@ policy_state usbpd_policy_src_hard_reset_received(struct policy_data *policy)
 policy_state usbpd_policy_src_transition_to_default(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int ret = PE_SRC_Startup;
+       int ms = 0;
+
+       /**********************************************
+       Actions on entry:
+       Request Device Policy Manager to request power
+       supply Hard Resets to vSafe5V via vSafe0V
+       Reset local HW
+       If Type-C request Device Policy Manager to set
+       Port Data Role to DFP and turn off VCONN
+       **********************************************/
 
+       /* 1) PD State Inform for AP */
        dev_info(pd_data->dev, "%s\n", __func__);
 
+       /* 2) VBUS Turn off */
+       pd_data->phy_ops.set_otg_control(pd_data, 0);
+
+       /* 3) Delay */
+       usbpd_timer1_start(pd_data);
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_SRC_Transition_to_default;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               if (ms >= tSrcRecover)
+                       break;
+       }
+
+       if (ret == PE_SRC_Transition_to_default)
+               return ret;
+
+       /* 4) initial reset */
        pd_data->phy_ops.driver_reset(pd_data);
+
+       pd_data->phy_ops.set_otg_control(pd_data, 1);
        /*
        Request Device Policy Manager to request power
        supply Hard Resets to vSafe5V via vSafe0V
@@ -312,27 +590,38 @@ policy_state usbpd_policy_src_transition_to_default(struct policy_data *policy)
        Initialize and start NoResponseTimer
        Inform Protocol Layer Hard Reset complete
        */
+
+       /* confirm VBUS ON : done by set_otg_control */
        return PE_SRC_Startup;
 }
 
 policy_state usbpd_policy_src_give_source_cap(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int ret = PE_SRC_Give_Source_Cap;
+       int data_role = 0;
+       int ms = 0;
+
+       /**********************************************
+       Action on entry :
+       Request source capabilities from Device Policy Manager
+       Send Capabilities message
+       **********************************************/
 
+       /* 1) PD State Inform for AP */
        dev_info(pd_data->dev, "%s\n", __func__);
 
-       /*
-       TODO: Request source capabilities from Device Policy Manager
-       Send Capabilities message
-       */
+       /* 2) Read Data Role */
+       pd_data->phy_ops.get_data_role(pd_data, &data_role);
 
+       /* 3) Message Setting */
        policy->tx_msg_header.msg_type = USBPD_Source_Capabilities;
-       policy->tx_msg_header.port_data_role = USBPD_DFP;
+       policy->tx_msg_header.port_data_role = data_role;
        policy->tx_msg_header.port_power_role = USBPD_SOURCE;
        policy->tx_msg_header.num_data_objs = 1;
 
-       policy->tx_data_obj[0].power_data_obj.max_current = 100;
-       policy->tx_data_obj[0].power_data_obj.voltage = 100;
+       policy->tx_data_obj[0].power_data_obj.max_current = 1500 / 10;
+       policy->tx_data_obj[0].power_data_obj.voltage = 5000 / 50;
        policy->tx_data_obj[0].power_data_obj.peak_current = 0;
        policy->tx_data_obj[0].power_data_obj.data_role_swap = 1;
        policy->tx_data_obj[0].power_data_obj.usb_comm_capable = 1;
@@ -341,35 +630,87 @@ policy_state usbpd_policy_src_give_source_cap(struct policy_data *policy)
        policy->tx_data_obj[0].power_data_obj.dual_role_power = 1;
        policy->tx_data_obj[0].power_data_obj.supply = 0;
 
-       if (usbpd_send_msg(pd_data, &policy->tx_msg_header,
-                               policy->tx_data_obj))
-               return PE_SRC_Ready;
-       else
-               return PE_SRC_Give_Source_Cap;
+       /* 4) Send Message */
+       usbpd_send_msg(pd_data, &policy->tx_msg_header, policy->tx_data_obj);
+
+       /* 5) Start Timer */
+       usbpd_timer1_start(pd_data);
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_SRC_Give_Source_Cap;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               if (pd_data->phy_ops.get_status(pd_data, MSG_REQUEST)) {
+                       ret = PE_SRC_Negotiate_Capability;
+                       break;
+               }
+               if (pd_data->phy_ops.get_status(pd_data, MSG_ERROR)) {
+                       ret = PE_SRC_Send_Soft_Reset;
+                       break;
+               }
+               if (ms >= tSenderResponse) {
+                       ret = PE_SRC_Hard_Reset;
+                       break;
+               }
+       }
+
+       return ret;
 }
 
 policy_state usbpd_policy_src_get_sink_cap(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int data_role = 0;
+       int ret = PE_SRC_Get_Sink_Cap;
+       int ms = 0;
+
+       /**********************************************
+       Actions on entry:
+       Send Get_Sink_Cap message
+       Initialize and run
+       SenderResponseTimer
+       **********************************************/
 
+       /* 1) PD State Inform for AP */
        dev_info(pd_data->dev, "%s\n", __func__);
 
+       pd_data->phy_ops.get_data_role(pd_data, &data_role);
 
-       if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header,
-                               USBPD_Get_Sink_Cap, USBPD_DFP, USBPD_SOURCE)) {
-               pd_data->policy.state = PE_SRC_Get_Sink_Cap;
-               if (usbpd_wait_msg(pd_data, MSG_SNK_CAP, tSenderResponse)) {
-                       /* TODO: pass sink cap to device policy manager */
+       /* 2) Send Message */
+       usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header,
+                               USBPD_Get_Sink_Cap, data_role, USBPD_SOURCE);
+
+       /* 3) Wait Message */
+       usbpd_timer1_start(pd_data);
+       while (1) {
+               if (policy->plug_valid == 0)
+                       break;
+               ms = usbpd_check_time1(pd_data);
+               if (pd_data->phy_ops.get_status(pd_data, MSG_SNK_CAP)) {
                        dev_info(pd_data->dev, "got SinkCap.\n");
+                       ret = PE_SRC_Ready;
+                       break;
+               }
+               if (ms >= tSenderResponse) {
+                       ret = PE_SRC_Ready;
+                       break;
                }
        }
-       return PE_SRC_Ready;
+
+       return ret;
 }
 
 policy_state usbpd_policy_src_wait_new_capabilities(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
 
+       /**********************************************
+       Actions on entry:
+       Wait for new Source Capabilities
+       **********************************************/
+
+       /* 1) PD State Inform for AP */
        dev_info(pd_data->dev, "%s\n", __func__);
 
        return PE_SRC_Send_Capabilities;
@@ -378,88 +719,260 @@ policy_state usbpd_policy_src_wait_new_capabilities(struct policy_data *policy)
 policy_state usbpd_policy_src_send_soft_reset(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int ret = PE_SRC_Send_Soft_Reset;
+       int data_role = 0;
+       int ms = 0;
+
+       /**********************************************
+       Actions on entry:
+       Reset Protocol Layer
+       Send Soft Reset message
+       Initialize and run SenderResponseTimer
+       **********************************************/
 
+       /* 1) PD State Inform for AP */
        dev_info(pd_data->dev, "%s\n", __func__);
 
+       /* 2) USB PD Protocol Initialization */
        usbpd_init_protocol(pd_data);
 
-       if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header,
-                               USBPD_Soft_Reset, USBPD_DFP, USBPD_SOURCE)) {
-               pd_data->policy.state = PE_SRC_Send_Soft_Reset;
-               if (usbpd_wait_msg(pd_data, MSG_ACCEPT, tSenderResponse))
-                       return PE_SRC_Send_Capabilities;
-               if (policy->abnormal_state)
-                       return PE_SRC_Send_Soft_Reset;
+       /* 3) Read Data Role */
+       pd_data->phy_ops.get_data_role(pd_data, &data_role);
+
+       /* 4) Self SoftReset */
+       pd_data->phy_ops.soft_reset(pd_data);
+
+       /* 5) Send Message */
+       usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, USBPD_Soft_Reset,
+                                                                                                       data_role, USBPD_SOURCE);
+
+       /* 6) Start Timer */
+       usbpd_timer1_start(pd_data);
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_SRC_Send_Soft_Reset;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               if (pd_data->phy_ops.get_status(pd_data, MSG_ACCEPT)) {
+                       ret = PE_SRC_Send_Capabilities;
+                       break;
+               }
+               if (pd_data->phy_ops.get_status(pd_data, MSG_ERROR)) {
+                       ret = PE_SRC_Hard_Reset;
+                       break;
+               }
+               if (ms >= tSenderResponse) {
+                       ret = PE_SRC_Hard_Reset;
+                       break;
+               }
        }
-       return PE_SRC_Hard_Reset;
+
+       return ret;
 }
 
 policy_state usbpd_policy_src_soft_reset(struct policy_data *policy)
 {
-#if 0
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int ret = PE_SRC_Soft_Reset;
+       int data_role = 0;
+       int ms = 0;
+       /**********************************************
+       Actions on entry:
+       Reset Protocol Layer
+       Send Accept message
+       **********************************************/
+
+       /* 1) PD State Inform for AP */
+       dev_info(pd_data->dev, "%s\n", __func__);
 
-       if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header,
-                               USBPD_Accept, USBPD_DFP, USBPD_SOURCE))
-               return PE_SRC_Send_Capabilities;
-       else
-               return PE_SRC_Hard_Reset;
-#endif
-       return PE_SRC_Send_Capabilities;
+       /* 2) USB PD Protocol Initialization */
+       usbpd_init_protocol(pd_data);
+
+       /* 3) Read Data Role */
+       pd_data->phy_ops.get_data_role(pd_data, &data_role);
+
+       /* 4) Self SoftReset */
+       pd_data->phy_ops.soft_reset(pd_data);
+
+       /* 5) Send Message */
+       usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, USBPD_Accept, data_role, USBPD_SOURCE);
+
+       /* 6) Start Timer */
+       usbpd_timer1_start(pd_data);
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_SRC_Soft_Reset;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               if (pd_data->phy_ops.get_status(pd_data, MSG_GOODCRC)) {
+                       ret = PE_SRC_Send_Capabilities;
+                       break;
+               }
+
+               if (pd_data->phy_ops.get_status(pd_data, MSG_ERROR)) {
+                       ret = PE_SRC_Hard_Reset;
+                       break;
+               }
+               if (ms >= 5) {
+                       ret = PE_SRC_Ready;
+                       break;
+               }
+       }
+
+       return ret;
 }
 
 policy_state usbpd_policy_snk_startup(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
 
+       /**********************************************
+       Actions on entry:
+       Reset Protocol Layer
+       **********************************************/
+
+       /* 1) PD State Inform for AP */
        dev_info(pd_data->dev, "%s\n", __func__);
+
+       /* 2) PD Protocol Initialization */
        usbpd_init_protocol(pd_data);
 
-       pd_data->phy_ops.set_cc_control(pd_data, USBPD_CC_ON);
+       /* 3) Configuration Channel On */
+       //pd_data->phy_ops.set_cc_control(pd_data, USBPD_CC_ON);
+       //Move to PE_SNK_Wait_for_Capabilities
 
        return PE_SNK_Discovery;
 }
 
 policy_state usbpd_policy_snk_discovery(struct policy_data *policy)
 {
+       struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int ret = 0;
+       int vbus_check = 0;
+       int ms = 0;
+
+       /**********************************************
+       Actions on entry:
+       Wait for VBUS
+       **********************************************/
+
        /* TODO: wait vbus */
        /* if coming from HardReset
           && NoResponseTimer timeout
           && HardResetCounter <= nHardResetCount,
           return(PE_SNK_Hard_Reset) */
-       return PE_SNK_Wait_for_Capabilities;
+
+       /* 1) PD State Inform for AP */
+       dev_info(pd_data->dev, "%s\n", __func__);
+
+       /* 2) Start Timer */
+       usbpd_timer1_start(pd_data);
+
+       /* 3) Wait Message or State */
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_SNK_Discovery;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+
+               vbus_check = pd_data->phy_ops.vbus_on_check(pd_data);
+               if (vbus_check < 0 || vbus_check > 0) {
+                       ret = PE_SNK_Wait_for_Capabilities;
+                       break;
+               }
+
+               /* TimeOver Check */
+               if (ms >= tNoResponse) {
+                       /* HardReset Count Check */
+                       if (pd_data->counter.hard_reset_counter <= USBPD_nHardResetCount) {
+                               ret = PE_SNK_Hard_Reset;
+                               break;
+                       } else {
+                               ret = Error_Recovery;
+                               break;
+                       }
+               }
+       }
+
+       return ret;
 }
 
 policy_state usbpd_policy_snk_wait_for_capabilities(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int ret = PE_SNK_Wait_for_Capabilities;
+       int ms = 0;
 
+       /**********************************************
+       Actions on entry:
+       Initialize and run SinkWaitCapTimer
+       **********************************************/
+
+       /* 1) PD State Inform for AP */
        dev_info(pd_data->dev, "%s\n", __func__);
 
-       pd_data->policy.state = PE_SNK_Wait_for_Capabilities;
-       if (usbpd_wait_msg(pd_data, MSG_SRC_CAP, tSinkWaitCap))
-               return PE_SNK_Evaluate_Capability;
+       /* Configuration Channel On */
+       pd_data->phy_ops.set_cc_control(pd_data, USBPD_CC_ON);
+
+       /* Start Timer */
+       usbpd_timer1_start(pd_data);
+
+       /* 4) Wait Message or State */
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_SNK_Wait_for_Capabilities;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               /* Rx Source Capabilities */
+               if (pd_data->phy_ops.get_status(pd_data, MSG_SRC_CAP)) {
+                       ret = PE_SNK_Evaluate_Capability;
+                       break;
+               }
 
-       if (policy->abnormal_state)
-               return PE_SNK_Wait_for_Capabilities;
 #if !defined(CONFIG_SEC_FACTORY)
-       if (pd_data->counter.hard_reset_counter <= USBPD_nHardResetCount)
-               return PE_SNK_Hard_Reset;
-       else
-               return Error_Recovery;
+               /* TimeOver Check */
+               if (ms >= tTypeCSinkWaitCap) {
+                       /* HardReset Count Check */
+                       if (pd_data->counter.hard_reset_counter <= USBPD_nHardResetCount) {
+                               ret = PE_SNK_Hard_Reset;
+                               break;
+                       } else {
+                               ret = Error_Recovery;
+                               break;
+                       }
+               }
 #endif
-       return PE_SNK_Wait_for_Capabilities;
+       }
+
+       return ret;
 }
 
 policy_state usbpd_policy_snk_evaluate_capability(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int sink_request_obj_num = 0;
+       int ret = PE_SNK_Evaluate_Capability;
+
+       /**********************************************
+       Actions on entry:
+       Reset HardResetCounter to zero.
+       Ask Device Policy Manager to evaluate the options based on supplied
+       capabilities, any Power Reserve that it needs, and respond indicating
+       the selected capability and, optionally, a Capability Mismatch
+       **********************************************/
 
+       /* 1) PD State Inform to AP */
        dev_info(pd_data->dev, "%s\n", __func__);
 
+       /* 3) Get Rx Buffer */
        usbpd_protocol_rx(pd_data);
-#ifdef CONFIG_IFCONN_NOTIFIER
+
+       /* 4) Select PDO */
+#if defined(CONFIG_IFCONN_NOTIFIER)
        if (pd_noti.sink_status.selected_pdo_num == 0) {
                pd_noti.sink_status.selected_pdo_num = 1;
                if (policy->sink_cap_received) {
@@ -468,68 +981,148 @@ policy_state usbpd_policy_snk_evaluate_capability(struct policy_data *policy)
                }
        }
 #endif
+       /* 5) Select Object Position */
        sink_request_obj_num = usbpd_manager_evaluate_capability(pd_data);
 
+       /* 6) Branch */
        if (sink_request_obj_num > 0)
-               return PE_SNK_Select_Capability;
+               ret = PE_SNK_Select_Capability;
        else
-               return PE_SNK_Hard_Reset;
+               ret = PE_SNK_Hard_Reset;
+
+       return ret;
 }
 
 policy_state usbpd_policy_snk_select_capability(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int ret = PE_SNK_Select_Capability;
+       int data_role = 0;
+       int ms = 0;
 
-       dev_info(pd_data->dev, "%s\n", __func__);
+       /**********************************************
+       Actions on entry:
+       Send Request based on Device Policy Manager response:
+       - Request from present capabilities
+       - Optionally Indicate that other capabilities would be preferred (Capability Mismatch)
+       Initialize and run SenderResponseTimer
+       **********************************************/
+
+       /* 1) PD State Inform to AP */
+       //dev_info(pd_data->dev, "%s\n", __func__);
 
+       pd_data->phy_ops.get_data_role(pd_data, &data_role);
+
+       /* 2) Message Header Setting */
        policy->tx_msg_header.msg_type = USBPD_Request;
-       policy->tx_msg_header.port_data_role = USBPD_UFP;
+       policy->tx_msg_header.port_data_role = data_role;
        policy->tx_msg_header.port_power_role = USBPD_SINK;
-       policy->tx_msg_header.num_data_objs = 1;
+       policy->tx_msg_header.num_data_objs = 1; /* Initial Select PDO = 1 */
 
+       /* 3) Select PDO */
        policy->tx_data_obj[0] = usbpd_manager_select_capability(pd_data);
 
-       if (usbpd_send_msg(pd_data, &policy->tx_msg_header,
-                               policy->tx_data_obj)) {
-               unsigned msg;
-               pd_data->policy.state = PE_SNK_Select_Capability;
-               msg = usbpd_wait_msg(pd_data, MSG_ACCEPT | MSG_REJECT
-                               | MSG_WAIT, tSenderResponse);
-               if (policy->abnormal_state)
-                       return PE_SNK_Select_Capability;
-               if (msg & MSG_ACCEPT)
-                       return PE_SNK_Transition_Sink;
-               else if (msg & (MSG_REJECT | MSG_WAIT))
-                       return PE_SNK_Ready;
-               else
-                       return PE_SNK_Hard_Reset;
+       /* 4) Send Message*/
+       usbpd_send_msg(pd_data, &policy->tx_msg_header, policy->tx_data_obj);
+
+       /* 5) Start Timer*/
+       usbpd_timer1_start(pd_data);
+
+       /* 6) Wait Message or State */
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_SNK_Select_Capability;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               if (pd_data->phy_ops.get_status(pd_data, MSG_GET_SNK_CAP)) {
+                       ret = PE_SNK_Send_Soft_Reset;
+                       break;
+               }
+
+               if (pd_data->phy_ops.get_status(pd_data, MSG_ACCEPT)) {
+                       ret = PE_SNK_Transition_Sink;
+                       break;
+               }
+
+               if (pd_data->phy_ops.get_status(pd_data, MSG_PSRDY)) {
+                       ret = PE_SNK_Ready;
+                       break;
+               }
+
+               if (pd_data->phy_ops.get_status(pd_data, MSG_REJECT | MSG_WAIT)) {
+                       /* 1st Power Negotiation Check */
+                       if (pd_noti.sink_status.selected_pdo_num == 0)
+                               ret = PE_SNK_Wait_for_Capabilities;
+                       else
+                               ret = PE_SNK_Ready;
+
+                       break;
+               }
 
-               /* If no explicit contract
-                  policy->state = PE_SNK_Wait_for_Capabilities;
-                */
+               /* TimeOver Check */
+               if (ms >= tSenderResponse) {
+                       ret = PE_SNK_Hard_Reset;
+                       break;
+               }
        }
-       return Error_Recovery;
+
+       return ret;
 }
 
+uint32_t RX_PS_READY_Message_ID;
+
 policy_state usbpd_policy_snk_transition_sink(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int ret  = PE_SNK_Transition_Sink;
+       int ms = 0;
+
+       /**********************************************
+       Actions on entry:
+       Initialize and run PSTransitionTimer
+       **********************************************/
 
+       /* 1) PD State Inform to AP */
        dev_info(pd_data->dev, "%s\n", __func__);
 
+       /* 2) Policy Engine State Setting */
        policy->state = PE_SNK_Transition_Sink;
-       if (usbpd_wait_msg(pd_data, MSG_PSRDY, tPSTransition)) {
-               dev_info(pd_data->dev, "got PS_READY.\n");
-#ifdef CONFIG_IFCONN_NOTIFIER
-               pd_noti.sink_status.current_pdo_num = pd_noti.sink_status.selected_pdo_num;
+
+       /* 3) Start Timer */
+       usbpd_timer1_start(pd_data);
+
+       /* 4) Wait Message or State */
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_SNK_Transition_Sink;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               /* PD Certification(Ellisys) : TD.PD.SNK.E10 GetSinkCap in place of PS_RDY */
+               if (pd_data->phy_ops.get_status(pd_data, MSG_GET_SNK_CAP)) {
+                       ret = PE_SNK_Hard_Reset;
+                       break;
+               }
+               if (pd_data->phy_ops.get_status(pd_data, MSG_PSRDY)) {
+                       /* Device Information */
+                       dev_info(pd_data->dev, "got PS_READY.\n");
+
+#if defined(CONFIG_IFCONN_NOTIFIER)
+                       pd_noti.sink_status.current_pdo_num = pd_noti.sink_status.selected_pdo_num;
 #endif
-               return PE_SNK_Ready;
-       }
+                       ret = PE_SNK_Ready;
+                       break;
+               }
 
-       if (policy->abnormal_state)
-               return PE_SNK_Transition_Sink;
+               /* TimeOver Check */
+               if (ms >= tPSTransition) {
+                       ret = PE_SNK_Hard_Reset;
+                       break;
+               }
+       }
 
-       return PE_SNK_Hard_Reset;
+       return ret;
 }
 
 policy_state usbpd_policy_snk_ready(struct policy_data *policy)
@@ -537,15 +1130,30 @@ policy_state usbpd_policy_snk_ready(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int data_role = 0;
 
+       /**********************************************
+       Actions on entry:
+       Initialize and run SinkActivityTimer2
+       Initialize and run SinkRequestTimer3 (on receiving Wait)
+       Initialize and run DiscoverIdentityTimer5
+       **********************************************/
+
+       /* 1) PD State Inform to AP */
        dev_info(pd_data->dev, "%s\n", __func__);
 
+       /* enable pd support for typec role swap */
+       policy->pd_support = 1;
+
+       /* 2) Notify Plug Attach */
        usbpd_manager_plug_attach(pd_data->dev);
 
+       /* 3) Message Check */
        CHECK_MSG(pd_data, MSG_GET_SNK_CAP, PE_SNK_Give_Sink_Cap);
-       CHECK_MSG(pd_data, MSG_SRC_CAP, PE_SNK_Evaluate_Capability);
        CHECK_MSG(pd_data, MSG_PR_SWAP, PE_PRS_SNK_SRC_Evaluate_Swap);
        CHECK_MSG(pd_data, MSG_DR_SWAP, PE_DRS_Evaluate_Port);
        CHECK_MSG(pd_data, MSG_VCONN_SWAP, PE_VCS_Evaluate_Swap);
+       CHECK_MSG(pd_data, MSG_GET_SRC_CAP, PE_DR_SNK_Give_Source_Cap);
+
+#if 0
        CHECK_MSG(pd_data, VDM_DISCOVER_IDENTITY, PE_UFP_VDM_Get_Identity);
        CHECK_MSG(pd_data, VDM_DISCOVER_SVID, PE_UFP_VDM_Get_SVIDs);
        CHECK_MSG(pd_data, VDM_DISCOVER_MODE, PE_UFP_VDM_Get_Modes);
@@ -554,7 +1162,9 @@ policy_state usbpd_policy_snk_ready(struct policy_data *policy)
        CHECK_MSG(pd_data, VDM_DP_STATUS_UPDATE, PE_UFP_VDM_Evaluate_Status);
        CHECK_MSG(pd_data, VDM_DP_CONFIGURE, PE_UFP_VDM_Evaluate_Configure);
        CHECK_MSG(pd_data, UVDM_MSG, PE_DFP_UVDM_Receive_Message);
+#endif
 
+       /* 5) Command Check from AP */
        CHECK_CMD(pd_data, MANAGER_REQ_NEW_POWER_SRC, PE_SNK_Select_Capability);
        CHECK_CMD(pd_data, MANAGER_REQ_PR_SWAP, PE_PRS_SNK_SRC_Send_Swap);
        CHECK_CMD(pd_data, MANAGER_REQ_DR_SWAP, PE_DRS_Evaluate_Send_Port);
@@ -566,92 +1176,304 @@ policy_state usbpd_policy_snk_ready(struct policy_data *policy)
        CHECK_CMD(pd_data, MANAGER_REQ_VDM_ENTER_MODE, PE_DFP_VDM_Mode_Entry_Request);
        CHECK_CMD(pd_data, MANAGER_REQ_VDM_STATUS_UPDATE, PE_DFP_VDM_Status_Update);
        CHECK_CMD(pd_data, MANAGER_REQ_VDM_DisplayPort_Configure, PE_DFP_VDM_DisplayPort_Configure);
-       CHECK_CMD(pd_data, MANAGER_REQ_UVDM_SEND_MESSAGE,PE_DFP_UVDM_Send_Message);
+       CHECK_CMD(pd_data, MANAGER_REQ_UVDM_SEND_MESSAGE, PE_DFP_UVDM_Send_Message);
 
+       /* 6) Data Role Check */
        pd_data->phy_ops.get_data_role(pd_data, &data_role);
 
+       /* 7) Check bist message */
+       if (pd_data->phy_ops.check_bist_message(pd_data) == 0)  {
+               dev_info(pd_data->dev, "check_bist_message : Rx_Msg is BIST\n");
+               return PE_BIST_Receive_Mode;
+       } else {
+               dev_info(pd_data->dev, "check_bist_message : Rx_Msg is NOT BIST\n");
+       }
+
+#if 0
        if (data_role == USBPD_DFP)
                usbpd_manager_vdm_request_enabled(pd_data);
+#endif
 
        return PE_SNK_Ready;
 }
 
-policy_state usbpd_policy_snk_hard_reset(struct policy_data *policy)
+policy_state usbpd_policy_snk_hard_reset(struct policy_data *policy)
+{
+       struct usbpd_data *pd_data = policy_to_usbpd(policy);
+
+       /**********************************************
+       Actions on entry:
+       Generate Hard Reset signalling.
+       Increment HardResetCounter.
+       **********************************************/
+
+       /* 1) PD State Inform to AP */
+       dev_info(pd_data->dev, "%s\n", __func__);
+
+       pd_data->phy_ops.hard_reset(pd_data);
+       pd_data->phy_ops.set_cc_control(pd_data, USBPD_CC_OFF);
+       /* increase hard reset counter */
+       pd_data->counter.hard_reset_counter++;
+
+       return PE_SNK_Transition_to_default;
+}
+
+policy_state usbpd_policy_snk_transition_to_default(struct policy_data *policy)
+{
+       struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int ret = PE_SNK_Startup;
+       int ms = 0;
+
+       /**********************************************
+       Hard reset signalling received
+
+       Actions on entry:
+       Request Device Policy Manager to request power sink transition to default
+       Reset local HW
+       If Type-C set Port Data Role to UFP and turn off VCONN
+       **********************************************/
+
+       /* 1) PD State Inform to AP */
+       dev_info(pd_data->dev, "%s\n", __func__);
+
+       /* 2) Driver Reset */
+       pd_data->phy_ops.driver_reset(pd_data);
+
+       /* 3) Vconn Off */
+       usbpd_manager_turn_off_vconn(pd_data);
+
+       /* 4) Wait 200ms */
+       usbpd_timer1_start(pd_data);
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_SNK_Transition_to_default;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               if (ms >= 200)
+                       break;
+       }
+
+       return ret;
+}
+
+policy_state usbpd_policy_snk_give_sink_cap(struct policy_data *policy)
+{
+       struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int ret = PE_SNK_Give_Sink_Cap;
+       int data_role = 0;
+       int ms = 0;
+       /**********************************************
+       Get Sink Cap Message received
+
+       Actions on entry:
+       Get present sink capabilities from Device Policy Manager
+       Send Capabilities message (based on Device Policy Manager response)
+       **********************************************/
+
+       /* 1) PD State Inform to AP */
+       dev_info(pd_data->dev, "%s\n", __func__);
+
+       pd_data->phy_ops.get_data_role(pd_data, &data_role);
+
+       /* 2) TODO JETSEO ????*/
+#if defined(CONFIG_IFCONN_NOTIFIER)
+       pd_noti.sink_status.selected_pdo_num = 0;
+#endif
+
+       /* 3) Sink Cap Message Setting */
+       policy->tx_msg_header.word = pd_data->sink_msg_header.word;
+       policy->tx_msg_header.port_data_role = data_role;
+       policy->tx_data_obj[0].object = pd_data->sink_data_obj[0].object;
+       policy->tx_data_obj[1].object = pd_data->sink_data_obj[1].object;
+
+       policy->sink_cap_received = 1;
+
+       /* 4) Send Message */
+       usbpd_send_msg(pd_data, &policy->tx_msg_header, policy->tx_data_obj);
+
+       /* 5) Start Timer */
+       usbpd_timer1_start(pd_data);
+
+       /* 6) Wait Message or State */
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_SNK_Give_Sink_Cap;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               if (pd_data->phy_ops.get_status(pd_data, MSG_GOODCRC)) {
+                       dev_info(pd_data->dev, "got snk_give_sink_cap MSG_GOODCRC.\n");
+                       ret = PE_SNK_Ready;
+                       break;
+               }
+
+               /* TimeOver Check */
+               if (ms >= 5) {
+                       dev_info(pd_data->dev, "got snk_give_sink_cap Timer1_overflag.\n");
+                       ret = PE_SNK_Send_Soft_Reset;
+                       break;
+               }
+       }
+
+       return ret;
+}
+
+policy_state usbpd_policy_snk_get_source_cap(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int ret = PE_SNK_Get_Source_Cap;
+       int data_role = 0;
+       int ms = 0;
+
+       /**********************************************
+       Actions on entry:
+       Send Get_Source_Cap message
+       **********************************************/
 
+       /* 1) PD State Inform to AP */
        dev_info(pd_data->dev, "%s\n", __func__);
 
-       pd_data->phy_ops.hard_reset(pd_data);
-       pd_data->phy_ops.set_cc_control(pd_data, USBPD_CC_OFF);
-       /* increase hard reset counter */
-       pd_data->counter.hard_reset_counter++;
+       pd_data->phy_ops.get_data_role(pd_data, &data_role);
 
-       return PE_SNK_Transition_to_default;
+       /* 2) Send Message*/
+       usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header,
+                                               USBPD_Get_Source_Cap, data_role, USBPD_SINK);
+
+       /* 3) Start Timer */
+       usbpd_timer1_start(pd_data);
+
+       /* 4) Wait Message or State */
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_SNK_Get_Source_Cap;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               if (pd_data->phy_ops.get_status(pd_data, MSG_GOODCRC)) {
+                       ret = PE_SNK_Ready;
+                       break;
+               }
+
+               /* TimeOver Check */
+               if (ms >= 5) {
+                       ret = PE_SNK_Get_Source_Cap;
+                       break;
+               }
+       }
+
+       return ret;
 }
 
-policy_state usbpd_policy_snk_transition_to_default(struct policy_data *policy)
+policy_state usbpd_policy_snk_send_soft_reset(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
-
+       int ret = PE_SNK_Send_Soft_Reset;
+       int data_role = 0;
+       int ms = 0;
+       /**********************************************
+       Actions on entry:
+       Reset Protocol Layer
+       Send Soft Reset message
+       Initialize and run SenderResponseTimer
+       **********************************************/
+
+       /* 1) PD State Inform for AP */
        dev_info(pd_data->dev, "%s\n", __func__);
 
-       pd_data->phy_ops.driver_reset(pd_data);
+       /* 2) USB PD Protocol Initialization */
+       usbpd_init_protocol(pd_data);
 
-       usbpd_manager_turn_off_vconn(pd_data);
+       /* 3) Read Data Role */
+       pd_data->phy_ops.get_data_role(pd_data, &data_role);
+
+       /* 4) Self SoftReset */
+       pd_data->phy_ops.soft_reset(pd_data);
+
+       /* 5) Send Message */
+       usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, USBPD_Soft_Reset,
+                                                                                                               data_role, USBPD_SINK);
+
+       /* 6) Start Timer */
+       usbpd_timer1_start(pd_data);
+
+       /* 7) Wait Message or State */
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_SNK_Send_Soft_Reset;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               if (pd_data->phy_ops.get_status(pd_data, MSG_ACCEPT)) {
+                       ret = PE_SNK_Wait_for_Capabilities;
+                       break;
+               }
 
-/*     pd_data->phy_ops.set_data_role(pd_data, USBPD_UFP);   */
+               /* TimeOver Check */
+               if (ms >= tSenderResponse) {
+                       ret = PE_SNK_Hard_Reset;
+                       break;
+               }
+       }
 
-       return PE_SNK_Startup;
+       return ret;
 }
 
-policy_state usbpd_policy_snk_give_sink_cap(struct policy_data *policy)
+policy_state usbpd_policy_snk_soft_reset(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int data_role = 0;
+       int ret = PE_SNK_Soft_Reset;
+       int ms = 0;
+
+       /**********************************************
+       Soft Reset message received
+
+       Actions on entry:
+       Reset Protocol Layer
+       Send Accept message
+       **********************************************/
 
+       /* 1) PD State Inform for AP */
        dev_info(pd_data->dev, "%s\n", __func__);
 
-#ifdef CONFIG_IFCONN_NOTIFIER
-       pd_noti.sink_status.selected_pdo_num = 0;
-#endif
-       policy->tx_msg_header.word = pd_data->sink_msg_header.word;
-       policy->tx_data_obj[0].object = pd_data->sink_data_obj[0].object;
-       policy->tx_data_obj[1].object = pd_data->sink_data_obj[1].object;
+       /* 2) USB PD Protocol Initialization */
+       usbpd_init_protocol(pd_data);
 
-       policy->sink_cap_received = 1;
+       /* 3) Read Data Role */
+       pd_data->phy_ops.get_data_role(pd_data, &data_role);
 
-       if (usbpd_send_msg(pd_data, &policy->tx_msg_header,
-                               policy->tx_data_obj))
-               return PE_SNK_Ready;
-       else
-               return PE_SNK_Give_Sink_Cap;
-}
+       /* 4) Send Message */
+       usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, USBPD_Accept,
+                                                                                                       data_role, USBPD_SINK);
 
-policy_state usbpd_policy_snk_get_source_cap(struct policy_data *policy)
-{
-       struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       /* 5) Start Timer */
+       usbpd_timer1_start(pd_data);
 
-       dev_info(pd_data->dev, "%s\n", __func__);
+       /* 6) Wait Message or State */
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_SNK_Soft_Reset;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               if (pd_data->phy_ops.get_status(pd_data, MSG_GOODCRC)) {
+                       ret = PE_SNK_Wait_for_Capabilities;
+                       break;
+               }
 
-       if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header,
-                               USBPD_Get_Source_Cap, USBPD_UFP, USBPD_SINK))
-               return PE_SNK_Ready;
-       else
-               return PE_SNK_Get_Source_Cap;
-}
+               if (pd_data->phy_ops.get_status(pd_data, MSG_ERROR)) {
+                       ret = PE_SNK_Hard_Reset;
+                       break;
+               }
 
-policy_state usbpd_policy_snk_soft_reset(struct policy_data *policy)
-{
-#if 0
-       struct usbpd_data *pd_data = policy_to_usbpd(policy);
+               if (ms >= 5) {
+                       ret = PE_SNK_Ready;
+                       break;
+               }
+       }
 
-       if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header,
-                               USBPD_Accept, USBPD_UFP, USBPD_SINK))
-               return PE_SNK_Wait_for_Capabilities;
-       else
-               return PE_SNK_Hard_Reset;
-#endif
-       return PE_SNK_Wait_for_Capabilities;
+       return ret;
 }
 
 policy_state usbpd_policy_drs_evaluate_port(struct policy_data *policy)
@@ -660,6 +1482,10 @@ policy_state usbpd_policy_drs_evaluate_port(struct policy_data *policy)
        int data_role = 0;
        int power_role = 0;
 
+       /**********************************************
+       **********************************************/
+
+       /* 1) PD State Inform for AP */
        dev_info(pd_data->dev, "%s\n", __func__);
 
        if (policy->modal_operation) {
@@ -685,6 +1511,10 @@ policy_state usbpd_policy_drs_evaluate_send_port(struct policy_data *policy)
        int data_role = 0;
        int power_role = 0;
 
+       /**********************************************
+       **********************************************/
+
+       /* 1) PD State Inform for AP */
        dev_info(pd_data->dev, "%s\n", __func__);
 
        if (policy->modal_operation) {
@@ -709,6 +1539,15 @@ policy_state usbpd_policy_drs_dfp_ufp_evaluate_dr_swap(struct policy_data *polic
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        bool drs_ok;
 
+       /**********************************************
+       DR_Swap message received & not in Modal Operation
+
+       Actions on entry:
+       Get evaluation of Data Role Swap
+       request from Device Policy Manager
+       **********************************************/
+
+       /* 1) PD State Inform for AP */
        dev_info(pd_data->dev, "%s\n", __func__);
 
        drs_ok = usbpd_manager_data_role_swap(pd_data);
@@ -724,6 +1563,11 @@ policy_state usbpd_policy_drs_dfp_ufp_accept_dr_swap(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       Actions on entry:
+       Send Accept message
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
@@ -741,6 +1585,12 @@ policy_state usbpd_policy_drs_dfp_ufp_change_to_ufp(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       Actions on entry:
+       Request Device Policy Manager to
+       change port to UFP
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.set_data_role(pd_data, USBPD_UFP);
@@ -756,21 +1606,44 @@ policy_state usbpd_policy_drs_dfp_ufp_send_dr_swap(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
+       int ret = 0;
+       int ms = 0;
+       /**********************************************
+       Actions on entry:
+       Send Swap DR message
+       Initialize and run SenderResponseTimer
+       **********************************************/
 
        dev_info(pd_data->dev, "%s\n", __func__);
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
 
        if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header,
                                USBPD_DR_Swap, USBPD_DFP, power_role)) {
-               unsigned msg;
-               pd_data->policy.state = PE_DRS_DFP_UFP_Send_DR_Swap;
-               msg = usbpd_wait_msg(pd_data, MSG_ACCEPT | MSG_REJECT
-                               | MSG_WAIT, tSenderResponse);
-               if (policy->abnormal_state)
-                       return PE_DRS_DFP_UFP_Send_DR_Swap;
-
-               if (msg & MSG_ACCEPT)
-                       return PE_DRS_DFP_UFP_Change_to_UFP;
+               usbpd_timer1_start(pd_data);
+               while (1) {
+                       if (policy->plug_valid == 0) {
+                               ret = PE_DRS_DFP_UFP_Send_DR_Swap;
+                               break;
+                       }
+                       ms = usbpd_check_time1(pd_data);
+                       if (pd_data->phy_ops.get_status(pd_data, MSG_ACCEPT)) {
+                               dev_info(pd_data->dev, "%s, got Accept\n", __func__);
+                               ret = PE_DRS_DFP_UFP_Change_to_UFP;
+                               break;
+                       }
+                       if (pd_data->phy_ops.get_status(pd_data, MSG_REJECT)) {
+                               dev_info(pd_data->dev, "%s, got Reject\n", __func__);
+                               break;
+                       }
+                       if (pd_data->phy_ops.get_status(pd_data, MSG_WAIT)) {
+                               dev_info(pd_data->dev, "%s, got Wait\n", __func__);
+                               break;
+                       }
+                       if (ms >= tSenderResponse)
+                               break;
+               }
+               if (ret > 0)
+                       return ret;
        }
 
        if (power_role == USBPD_SOURCE)
@@ -784,6 +1657,11 @@ policy_state usbpd_policy_drs_dfp_ufp_reject_dr_swap(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       Actions on entry:
+       Send Reject or Wait message as appropriate
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
 
@@ -803,6 +1681,12 @@ policy_state usbpd_policy_drs_ufp_dfp_evaluate_dr_swap(struct policy_data *polic
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        bool drs_ok;
 
+       /**********************************************
+       Actions on entry:
+       Get evaluation of Data Role Swap
+       request from Device Policy Manager
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        drs_ok = usbpd_manager_data_role_swap(pd_data);
@@ -818,6 +1702,11 @@ policy_state usbpd_policy_drs_ufp_dfp_accept_dr_swap(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       Actions on entry:
+       Send Accept message
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
 
@@ -833,6 +1722,11 @@ policy_state usbpd_policy_drs_ufp_dfp_change_to_dfp(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       Actions on entry:
+       Request Device Policy Manager to change port to DFP
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.set_data_role(pd_data, USBPD_DFP);
@@ -848,21 +1742,45 @@ policy_state usbpd_policy_drs_ufp_dfp_send_dr_swap(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
+       int ret = 0;
+       int ms = 0;
+
+       /**********************************************
+       Actions on entry:
+       Send Swap DR message
+       Initialize and run SenderResponseTimer
+       **********************************************/
 
        dev_info(pd_data->dev, "%s\n", __func__);
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
 
        if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header,
                                USBPD_DR_Swap, USBPD_UFP, power_role)) {
-               unsigned msg;
-               pd_data->policy.state = PE_DRS_UFP_DFP_Send_DR_Swap;
-               msg = usbpd_wait_msg(pd_data, MSG_ACCEPT | MSG_REJECT
-                               | MSG_WAIT, tSenderResponse);
-               if (policy->abnormal_state)
-                       return PE_DRS_UFP_DFP_Send_DR_Swap;
-
-               if (msg & MSG_ACCEPT)
-                       return PE_DRS_UFP_DFP_Change_to_DFP;
+               usbpd_timer1_start(pd_data);
+               while (1) {
+                       if (policy->plug_valid == 0) {
+                               ret = PE_DRS_UFP_DFP_Send_DR_Swap;
+                               break;
+                       }
+                       ms = usbpd_check_time1(pd_data);
+                       if (pd_data->phy_ops.get_status(pd_data, MSG_ACCEPT)) {
+                               dev_info(pd_data->dev, "%s, got Accept\n", __func__);
+                               ret = PE_DRS_UFP_DFP_Change_to_DFP;
+                               break;
+                       }
+                       if (pd_data->phy_ops.get_status(pd_data, MSG_REJECT)) {
+                               dev_info(pd_data->dev, "%s, got Reject\n", __func__);
+                               break;
+                       }
+                       if (pd_data->phy_ops.get_status(pd_data, MSG_WAIT)) {
+                               dev_info(pd_data->dev, "%s, got Wait\n", __func__);
+                               break;
+                       }
+                       if (ms > tSenderResponse)
+                               break;
+               }
+               if (ret > 0)
+                       return ret;
        }
 
        if (power_role == USBPD_SOURCE)
@@ -875,12 +1793,20 @@ policy_state usbpd_policy_drs_ufp_dfp_reject_dr_swap(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
+       int data_role = 0;
+
+       /**********************************************
+       Actions on entry:
+       Send Reject or Wait message as appropriate
+       **********************************************/
 
        dev_info(pd_data->dev, "%s\n", __func__);
+
+       pd_data->phy_ops.get_data_role(pd_data, &data_role);
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
 
        if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header,
-                               USBPD_Reject, USBPD_UFP, USBPD_SINK)) {
+                               USBPD_Reject, data_role, USBPD_SINK)) {
                if (power_role == USBPD_SOURCE)
                        return PE_SRC_Ready;
                else
@@ -893,11 +1819,20 @@ policy_state usbpd_policy_drs_ufp_dfp_reject_dr_swap(struct policy_data *policy)
 policy_state usbpd_policy_prs_src_snk_reject_pr_swap(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int data_role = 0;
 
+       /**********************************************
+       Actions on entry:
+       Send Reject or Wait message as appropriate
+       **********************************************/
+
+       /* 1) PD State Inform for AP */
        dev_info(pd_data->dev, "%s\n", __func__);
 
+       pd_data->phy_ops.get_data_role(pd_data, &data_role);
+
        if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header,
-                               USBPD_Reject, USBPD_DFP, USBPD_SOURCE))
+                               USBPD_Reject, data_role, USBPD_SOURCE))
                return PE_SRC_Ready;
 
        return PE_PRS_SRC_SNK_Reject_PR_Swap;
@@ -908,10 +1843,18 @@ policy_state usbpd_policy_prs_src_snk_evaluate_swap(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        bool prs_ok;
 
+       /**********************************************
+       Actions on entry:
+       Get evaluation of swap request from Device Policy Manager
+       **********************************************/
+
+       /* 1) PD State Inform for AP */
        dev_info(pd_data->dev, "%s\n", __func__);
 
+       /* 2) DPM Check to support roleswap */
        prs_ok = usbpd_manager_power_role_swap(pd_data);
 
+       /* 3) Branch */
        if (prs_ok)
                return PE_PRS_SRC_SNK_Accept_Swap;
        else
@@ -921,54 +1864,152 @@ policy_state usbpd_policy_prs_src_snk_evaluate_swap(struct policy_data *policy)
 policy_state usbpd_policy_prs_src_snk_send_swap(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int data_role = 0;
+       int ret = PE_SRC_Ready;
+       int ms = 0;
 
-       if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header,
-                               USBPD_PR_Swap, USBPD_DFP, USBPD_SOURCE)) {
-               unsigned msg;
+       /**********************************************
+       Actions on entry:
+       Send PR_Swap message
+       Initialize and run SenderResponseTimer
+       **********************************************/
+
+       /* 1) PD State Inform for AP */
+       dev_info(pd_data->dev, "%s\n", __func__);
+
+       /* 2) Read Data Role */
+       pd_data->phy_ops.get_data_role(pd_data, &data_role);
+
+       usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header,
+                                                               USBPD_PR_Swap, data_role, USBPD_SOURCE);
+
+       /* 3) Start Timer */
+       usbpd_timer1_start(pd_data);
+
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_PRS_SRC_SNK_Send_Swap;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               if (pd_data->phy_ops.get_status(pd_data, MSG_ACCEPT)) {
+                       ret = PE_PRS_SRC_SNK_Transition_off;
+                       break;
+               }
+
+               if (pd_data->phy_ops.get_status(pd_data, MSG_REJECT)) {
+                       ret = PE_SRC_Ready;
+                       break;
+               }
 
-               pd_data->policy.state = PE_PRS_SRC_SNK_Send_Swap;
-               msg = usbpd_wait_msg(pd_data, MSG_ACCEPT | MSG_REJECT
-                               | MSG_WAIT, tSenderResponse);
-               if (policy->abnormal_state)
-                       return PE_PRS_SRC_SNK_Send_Swap;
+               if (pd_data->phy_ops.get_status(pd_data, MSG_WAIT)) {
+                       ret = PE_SRC_Ready;
+                       break;
+               }
+
+               /* TimeOver Check */
+               if (ms >= tSenderResponse + 5) {
+                       ret = PE_SRC_Ready;
+                       break;
+               }
 
-               if (msg & MSG_ACCEPT)
-                       return PE_PRS_SRC_SNK_Transition_off;
        }
+
        return PE_SRC_Ready;
 }
 
 policy_state usbpd_policy_prs_src_snk_accept_swap(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int data_role = 0;
 
-       if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header,
-                               USBPD_Accept, USBPD_DFP, USBPD_SOURCE))
-               return PE_PRS_SRC_SNK_Transition_off;
+       /**********************************************
+       Actions on entry:
+       Send Accept message
+       **********************************************/
+
+       /* 1) PD State Inform for AP */
+       dev_info(pd_data->dev, "%s\n", __func__);
+       pd_data->phy_ops.get_data_role(pd_data, &data_role);
+
+       usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header,
+                                       USBPD_Accept, data_role, USBPD_SOURCE);
+
+       return PE_PRS_SRC_SNK_Transition_off;
 
-       return PE_PRS_SRC_SNK_Accept_Swap;
 }
 
 policy_state usbpd_policy_prs_src_snk_transition_to_off(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        struct usbpd_manager_data *manager = &pd_data->manager;
+       int ret = PE_PRS_SRC_SNK_Assert_Rd;
+       int ms = 0;
+
+       /**********************************************
+       Actions on entry:
+       Tell Device Policy Manager to turn off power supply
+       **********************************************/
+
+       /* 1) PD State Inform for AP */
+       dev_info(pd_data->dev, "%s\n", __func__);
 
+       /* 2) Delay */
+       usbpd_timer1_start(pd_data);
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_PRS_SRC_SNK_Transition_off;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               if (ms >= tSrcTransition)
+                       break;
+       }
+
+       if (ret == PE_PRS_SRC_SNK_Transition_off)
+               return ret;
+
+       pd_data->phy_ops.pr_swap(pd_data, USBPD_SOURCE_OFF);
+
+       /* 3) VBUS off */
        pd_data->phy_ops.set_otg_control(pd_data, 0);
 
        pr_info("%s, %d\n", __func__, manager->acc_type);
 
+       usbpd_timer1_start(pd_data);
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_PRS_SRC_SNK_Transition_off;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               if (ms >= 500)
+                       break;
+       }
+#if 0
+       /* TODO: svid_0 == 0 confition check?
+        * based on 004 code 600ms no condition vs here 150ms w/ condition */
        /* skip delay when GEARVR is attached */
        if (manager->acc_type != CCIC_DOCK_HMT || manager->SVID_0 == 0)
-               msleep(150);
+               msleep(600);
+#endif
 
-       return PE_PRS_SRC_SNK_Assert_Rd;
+       return ret;
 }
 
 policy_state usbpd_policy_prs_src_snk_assert_rd(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
 
+       /**********************************************
+       Actions on entry:
+       Request DPM to assert Rd
+       **********************************************/
+
+       /* 1) PD State Inform for AP */
+       dev_info(pd_data->dev, "%s\n", __func__);
+
+       /* 2) Asserted Rd */
        pd_data->phy_ops.set_power_role(pd_data, USBPD_SINK);
 
        return PE_PRS_SRC_SNK_Wait_Source_on;
@@ -977,43 +2018,64 @@ policy_state usbpd_policy_prs_src_snk_assert_rd(struct policy_data *policy)
 policy_state usbpd_policy_prs_src_snk_wait_source_on(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
-       struct usbpd_manager_data *manager = &pd_data->manager;
-       int wait_time = 0;
-
+       int ret = 0;
+       int data_role = 0;
+       int ms = 0;
+       /**********************************************
+       Actions on entry:
+       Send PS_RDY message
+       Initialize and run PSSourceOnTimer
+       **********************************************/
+
+       /* 1) PD State Inform for AP */
        dev_info(pd_data->dev, "%s\n", __func__);
 
-       if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header,
-                               USBPD_PS_RDY, USBPD_DFP, USBPD_SINK)) {
-               pd_data->policy.state = PE_PRS_SRC_SNK_Wait_Source_on;
-               if (manager->acc_type == CCIC_DOCK_HMT)
-                       wait_time = 2000;
-               else
-                       wait_time = tPSSourceOn;
-               if (usbpd_wait_msg(pd_data, MSG_PSRDY, tPSSourceOn)) {
-                       pd_data->counter.swap_hard_reset_counter = 0;
+       pd_data->phy_ops.get_data_role(pd_data, &data_role);
+
+       /* 2) Send Message */
+       usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header,
+                                               USBPD_PS_RDY, data_role, USBPD_SINK);
+       usbpd_timer1_start(pd_data);
+
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_PRS_SRC_SNK_Wait_Source_on;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               if (pd_data->phy_ops.get_status(pd_data, MSG_PSRDY)) {
                        dev_info(pd_data->dev, "got PSRDY.\n");
-                       mdelay(10);
-                       pd_data->phy_ops.set_power_role(pd_data, USBPD_DRP);
-                       return PE_SNK_Startup;
-               } else {
-                       if (policy->abnormal_state)
-                               return PE_PRS_SRC_SNK_Wait_Source_on;
-                       goto hard_reset;
+                       pd_data->counter.swap_hard_reset_counter = 0;
+                       mdelay(15);
+
+                       /* Self SoftReset for Message ID Clear */
+                       pd_data->phy_ops.soft_reset(pd_data);
+
+                       ret = PE_SNK_Startup;
+                       break;
+               }
+               if (ms >= tPSSourceOn) {
+                       ret = PE_SNK_Hard_Reset;
+                       if (pd_data->counter.hard_reset_counter > USBPD_nHardResetCount)
+                               ret = Error_Recovery;
+                       break;
                }
        }
-       return PE_PRS_SRC_SNK_Wait_Source_on;
 
-hard_reset:
-       if (pd_data->counter.swap_hard_reset_counter > USBPD_nHardResetCount)
-               return Error_Recovery;
+       pd_data->phy_ops.set_power_role(pd_data, USBPD_DRP);
 
-       return PE_SNK_Hard_Reset;
+       return ret;
 }
 
 policy_state usbpd_policy_prs_snk_src_reject_swap(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
 
+       /**********************************************
+       Actions on entry:
+       Send Reject or Wait message as appropriate
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header,
@@ -1027,77 +2089,156 @@ policy_state usbpd_policy_prs_snk_src_evaluate_swap(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        bool prs_ok;
+       int ret = PE_PRS_SNK_SRC_Evaluate_Swap;
+
+       /**********************************************
+       Actions on entry:
+       Get evaluation of swap request from Device Policy Manager
+       **********************************************/
+
+       /* 1) PD State Inform to AP */
        dev_info(pd_data->dev, "%s\n", __func__);
 
+       /* 2) Power Role Swap Check */
        prs_ok = usbpd_manager_power_role_swap(pd_data);
 
        if (prs_ok)
-               return PE_PRS_SNK_SRC_Accept_Swap;
+               ret = PE_PRS_SNK_SRC_Accept_Swap;
        else
-               return PE_PRS_SNK_SRC_Reject_Swap;
+               ret = PE_PRS_SNK_SRC_Reject_Swap;
+
+       return ret;
 }
 
 policy_state usbpd_policy_prs_snk_src_send_swap(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int data_role = 0;
+       int ret = PE_SNK_Ready;
+       int ms = 0;
 
+       /**********************************************
+       Actions on entry:
+       Send PR_Swap message
+       Initialize and run SenderResponseTimer
+       **********************************************/
+
+       /* 1) PD State Inform to AP */
        dev_info(pd_data->dev, "%s\n", __func__);
 
-       if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header,
-                               USBPD_PR_Swap, USBPD_UFP, USBPD_SINK)) {
-               unsigned msg;
+       pd_data->phy_ops.get_data_role(pd_data, &data_role);
+
+       usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header,
+                                               USBPD_PR_Swap, data_role, USBPD_SINK);
+
+       usbpd_timer1_start(pd_data);
+
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_PRS_SNK_SRC_Send_Swap;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               if (pd_data->phy_ops.get_status(pd_data, MSG_ACCEPT)) {
+                       ret = PE_PRS_SNK_SRC_Transition_off;
+                       break;
+               }
+
+               if (pd_data->phy_ops.get_status(pd_data, MSG_REJECT)) {
+                       ret = PE_SNK_Ready;
+                       break;
+               }
+
+               if (pd_data->phy_ops.get_status(pd_data, MSG_WAIT)) {
+                       ret = PE_SNK_Ready;
+                       break;
+               }
+
+               /* TimeOver Check */
+               if (ms >= tSenderResponse) {
+                       ret = PE_SNK_Ready;
+                       break;
+               }
 
-               pd_data->policy.state = PE_PRS_SNK_SRC_Send_Swap;
-               msg = usbpd_wait_msg(pd_data, MSG_ACCEPT | MSG_REJECT
-                               | MSG_WAIT, tSenderResponse);
-               if (policy->abnormal_state)
-                       return PE_PRS_SNK_SRC_Send_Swap;
-               if (msg & MSG_ACCEPT)
-                       return PE_PRS_SNK_SRC_Transition_off;
        }
-       return PE_SNK_Ready;
+
+       return ret;
 }
 
 policy_state usbpd_policy_prs_snk_src_accept_swap(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int data_role = 0;
 
+       /**********************************************
+       Actions on entry:
+       Send Accept message
+       **********************************************/
+
+       /* 1) PD State Inform to AP */
        dev_info(pd_data->dev, "%s\n", __func__);
 
-       if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header,
-                               USBPD_Accept, USBPD_DFP, USBPD_SINK))
-               return PE_PRS_SNK_SRC_Transition_off;
+       /* Send Accept Message */
+       pd_data->phy_ops.get_data_role(pd_data, &data_role);
+       usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, USBPD_Accept,
+                                                                                                       data_role, USBPD_SINK);
+       pd_data->phy_ops.set_power_role(pd_data, USBPD_SINK);
 
-       return PE_PRS_SNK_SRC_Accept_Swap;
+       return PE_PRS_SNK_SRC_Transition_off;
 }
 
 policy_state usbpd_policy_prs_snk_src_transition_to_off(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
-
+       int ret = 0;
+       int ms = 0;
+       /**********************************************
+       Actions on entry:
+       Initialize and run PSSourceOffTimer
+       Tell Device Policy Manager to turn off Power Sink.
+       **********************************************/
+
+       /* 1) PD State Inform to AP */
        dev_info(pd_data->dev, "%s\n", __func__);
 
+       pd_data->phy_ops.pr_swap(pd_data, USBPD_SINK_OFF);
        usbpd_manager_turn_off_power_sink(pd_data);
 
-       pd_data->policy.state = PE_PRS_SNK_SRC_Transition_off;
-       if (usbpd_wait_msg(pd_data, MSG_PSRDY, tPSSourceOff)) {
-               pd_data->counter.swap_hard_reset_counter = 0;
-               dev_info(pd_data->dev, "got PSRDY.\n");
-               return PE_PRS_SNK_SRC_Assert_Rp;
-       }
-       if (policy->abnormal_state)
-               return PE_PRS_SNK_SRC_Transition_off;
+       /* Start Timer 750ms */
+       usbpd_timer1_start(pd_data);
 
-       if (pd_data->counter.swap_hard_reset_counter > USBPD_nHardResetCount)
-               return Error_Recovery;
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_PRS_SNK_SRC_Transition_off;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               if (pd_data->phy_ops.get_status(pd_data, MSG_PSRDY)) {
+                       dev_info(pd_data->dev, "got PSRDY.\n");
+                       ret = PE_PRS_SNK_SRC_Assert_Rp;
+                       break;
+               }
+               if (ms >= tPSSourceOff) {
+                       ret = PE_SRC_Hard_Reset;
+                       pd_data->phy_ops.set_power_role(pd_data, USBPD_DRP);
+                       if (pd_data->counter.hard_reset_counter > USBPD_nHardResetCount)
+                               ret = Error_Recovery;
+                       break;
+               }
+       }
 
-       return PE_SRC_Hard_Reset;
+       return ret;
 }
 
 policy_state usbpd_policy_prs_snk_src_assert_rp(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
 
+       /**********************************************
+       Actions on entry:
+       Request DPM to assert Rp
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.set_power_role(pd_data, USBPD_SOURCE);
@@ -1108,19 +2249,67 @@ policy_state usbpd_policy_prs_snk_src_assert_rp(struct policy_data *policy)
 policy_state usbpd_policy_prs_snk_src_source_on(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int data_role = 0;
+       int ret = 0;
+       int ms = 0;
 
+       /**********************************************
+       Actions on entry:
+       Tell Device Policy Manager to turn on Source
+       Initialize and run SourceActivityTimer (see Section 8.3.3.6.1.2)1
+       **********************************************/
+
+       /* 1) PD State Inform to AP */
        dev_info(pd_data->dev, "%s\n", __func__);
 
+       /* 2) Read Data Role */
+       pd_data->phy_ops.get_data_role(pd_data, &data_role);
+
+       pd_data->phy_ops.pr_swap(pd_data, USBPD_SOURCE_ON);
+
+       /* 3) VBUS on */
        pd_data->phy_ops.set_otg_control(pd_data, 1);
 
-       msleep(150);
+       /* 4) Dealy */
+       usbpd_timer1_start(pd_data);
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_PRS_SNK_SRC_Source_on;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               if (ms >= 200)
+                       break;
+       }
 
+       if (ret == PE_PRS_SNK_SRC_Source_on)
+               return ret;
+
+       /* 5) send PS_RDY */
        if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header,
-                               USBPD_PS_RDY, USBPD_DFP, USBPD_SOURCE)) {
-               msleep(tSwapSourceStart); /* 20ms */
+                               USBPD_PS_RDY, data_role, USBPD_SOURCE)) {
                pd_data->phy_ops.set_power_role(pd_data, USBPD_DRP);
+               usbpd_timer1_start(pd_data);
+               while (1) {
+                       if (policy->plug_valid == 0) {
+                               ret = PE_PRS_SNK_SRC_Source_on;
+                               break;
+                       }
+                       ms = usbpd_check_time1(pd_data);
+                       if (ms >= tSwapSourceStart)
+                               break;
+               }
+
+               if (ret == PE_PRS_SNK_SRC_Source_on)
+                       return ret;
+               /*  TODO: 4) check GoodCRC : may need to be added for certification */
+
+               /* Self SoftReset for Message ID Clear */
+               pd_data->phy_ops.soft_reset(pd_data);
+
                return PE_SRC_Startup;
        }
+
        return PE_PRS_SNK_SRC_Source_on;
 }
 
@@ -1129,7 +2318,16 @@ policy_state usbpd_policy_vcs_evaluate_swap(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        bool vcs_ok;
 
+       /**********************************************
+       Actions on entry:
+       Get evaluation of VCONN swap
+       request from Device Policy Manager
+       **********************************************/
+
+       /* 1) PD State Inform to AP */
        dev_info(pd_data->dev, "%s\n", __func__);
+
+       /* 2) Request from DPM */
        vcs_ok = usbpd_manager_vconn_source_swap(pd_data);
 
        if (vcs_ok)
@@ -1145,6 +2343,11 @@ policy_state usbpd_policy_vcs_accept_swap(struct policy_data *policy)
        int power_role = 0;
        int data_role = 0;
 
+       /**********************************************
+       Actions on entry:
+       Send Accept message
+       **********************************************/
+
        pd_data->phy_ops.get_vconn_source(pd_data, &vconn_source);
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
        pd_data->phy_ops.get_data_role(pd_data, &data_role);
@@ -1165,40 +2368,96 @@ policy_state usbpd_policy_vcs_send_swap(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int vconn_source = 0;
        int power_role = 0;
+       int ret = PE_VCS_Send_Swap;
+       int ms = 0;
+
+       /**********************************************
+       Actions on entry:
+       Send VCONN_Swap message
+       Initialize and run SenderResponseTimer
+       **********************************************/
+
 
+       /* 1) PD State Inform for AP */
+       dev_info(pd_data->dev, "%s\n", __func__);
+
+       /* 2) Get Vconn Source */
        pd_data->phy_ops.get_vconn_source(pd_data, &vconn_source);
+
+       /* 3) Get Power Role */
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
 
-       if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header,
-                               USBPD_VCONN_Swap, USBPD_DFP, power_role)) {
-               if (vconn_source)
-                       return PE_VCS_Wait_for_VCONN;
-               else
-                       return PE_VCS_Turn_On_VCONN;
+       /* 4) Send Vconn Swap */
+       usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, USBPD_VCONN_Swap, USBPD_DFP, power_role);
+
+       /* 5) Start Timer */
+       usbpd_timer1_start(pd_data);
+
+       /* 6) Wait Message or State */
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_VCS_Send_Swap;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               if (pd_data->phy_ops.get_status(pd_data, MSG_GOODCRC)) {
+                       if (vconn_source)
+                               ret = PE_VCS_Wait_for_VCONN;
+                       else
+                               ret = PE_VCS_Turn_On_VCONN;
+                       break;
+               }
+               /* TimeOver Check */
+               if (ms >= 5) {
+                       if (power_role == USBPD_SINK)
+                               ret = PE_SNK_Hard_Reset;
+                       else
+                               ret = PE_SRC_Hard_Reset;
+                       break;
+               }
        }
 
-       return PE_VCS_Send_Swap;
+       return ret;
 }
 
 policy_state usbpd_policy_vcs_wait_for_vconn(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int ret = PE_VCS_Wait_for_VCONN;
+       int ms = 0;
+       /**********************************************
+       Actions on entry:
+       Start VCONNOnTimer
+       **********************************************/
 
        dev_info(pd_data->dev, "%s\n", __func__);
 
-       pd_data->policy.state = PE_VCS_Wait_for_VCONN;
-       if (usbpd_wait_msg(pd_data, MSG_PSRDY, tVCONNSourceOn)) {
-               pd_data->counter.swap_hard_reset_counter = 0;
-               dev_info(pd_data->dev, "got PSRDY.\n");
-               return PE_VCS_Turn_Off_VCONN;
-       }
-       if (policy->abnormal_state)
-               return PE_VCS_Wait_for_VCONN;
+       /* 5) Start Timer */
+       usbpd_timer1_start(pd_data);
 
-       if (pd_data->counter.swap_hard_reset_counter > USBPD_nHardResetCount)
-               return Error_Recovery;
+       /* 6) Wait Message or State */
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_VCS_Wait_for_VCONN;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               if (pd_data->phy_ops.get_status(pd_data, MSG_PSRDY)) {
+                       pd_data->counter.swap_hard_reset_counter = 0;
+                       ret = PE_VCS_Turn_Off_VCONN;    
+                       break;
+               }
+               /* TimeOver Check */
+               if (ms >= tVCONNSourceOn) {
+                       if (pd_data->counter.swap_hard_reset_counter > USBPD_nHardResetCount)
+                               ret = Error_Recovery;
+                       else
+                               ret = PE_SNK_Hard_Reset;
+                       break;
+               }
+       }
 
-       return PE_SNK_Hard_Reset;
+       return ret;
 }
 
 policy_state usbpd_policy_vcs_turn_off_vconn(struct policy_data *policy)
@@ -1206,6 +2465,11 @@ policy_state usbpd_policy_vcs_turn_off_vconn(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       Actions on entry:
+       Tell Device Policy Manager to turn off VCONN
+       **********************************************/
+
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
 
        dev_info(pd_data->dev, "%s\n", __func__);
@@ -1222,6 +2486,11 @@ policy_state usbpd_policy_vcs_turn_on_vconn(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
 
+       /**********************************************
+       Actions on entry:
+       Tell Device Policy Manager to turn on VCONN
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.set_vconn_source(pd_data, USBPD_VCONN_ON);
@@ -1235,6 +2504,11 @@ policy_state usbpd_policy_vcs_send_ps_rdy(struct policy_data *policy)
        int power_role = 0;
        int data_role = 0;
 
+       /**********************************************
+       Actions on entry:
+       Send PS_RDY message
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
@@ -1258,6 +2532,11 @@ policy_state usbpd_policy_vcs_reject_vconn_swap(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       Actions on entry:
+       Send Reject or Wait message as appropriate
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
@@ -1275,6 +2554,12 @@ policy_state usbpd_policy_vcs_reject_vconn_swap(struct policy_data *policy)
 
 policy_state usbpd_policy_ufp_vdm_get_identity(struct policy_data *policy)
 {
+
+       /**********************************************
+       Actions on entry:
+       Request Identity information from DPM
+       **********************************************/
+
        return PE_UFP_VDM_Get_Identity_NAK;
 }
 
@@ -1283,6 +2568,11 @@ policy_state usbpd_policy_ufp_vdm_send_identity(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       Actions on entry:
+       Send Discover Identity ACK
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
@@ -1316,6 +2606,12 @@ policy_state usbpd_policy_ufp_vdm_get_identity_nak(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       Actions on entry: NAK
+       Send Discover Identity NAK/BUSY Command
+       response as requested
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
@@ -1346,6 +2642,11 @@ policy_state usbpd_policy_ufp_vdm_get_svids(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
 
+       /**********************************************
+       Actions on entry:
+       Request SVIDs information from DPM
+       **********************************************/
+
        if (usbpd_manager_get_svids(pd_data) == 0)
                return PE_UFP_VDM_Send_SVIDs;
        else
@@ -1358,6 +2659,11 @@ policy_state usbpd_policy_ufp_vdm_send_svids(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       Actions on entry:
+       Send Discover SVIDs ACK
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
@@ -1395,6 +2701,12 @@ policy_state usbpd_policy_ufp_vdm_get_svids_nak(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       Actions on entry:
+       Send Discover SVIDs NAK/BUSY Command
+       response as requested
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
@@ -1425,6 +2737,11 @@ policy_state usbpd_policy_ufp_vdm_get_modes(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
 
+       /**********************************************
+       Actions on entry:
+       Request Modes information from DPM
+       **********************************************/
+
        if (usbpd_manager_get_modes(pd_data) == 0)
                return PE_UFP_VDM_Send_Modes;
        else
@@ -1436,6 +2753,11 @@ policy_state usbpd_policy_ufp_vdm_send_modes(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       Actions on entry:
+       Send Discover Modes ACK
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
@@ -1469,6 +2791,12 @@ policy_state usbpd_policy_ufp_vdm_get_modes_nak(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       Actions on entry:
+       Send Discover Modes NAK/BUSY Command
+       response as requested
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
@@ -1501,8 +2829,19 @@ policy_state usbpd_policy_ufp_vdm_evaluate_mode_entry(struct policy_data *policy
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
 
+       /**********************************************
+       Actions on entry:
+       Request DPM to evaluate request to enter a Mode
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
+       /* Certification: Ellisys: TD.PD.VDMU.E15.Applicability */
+       if (usbpd_manager_get_svids(pd_data) == 0)
+               return PE_UFP_VDM_Mode_Entry_ACK;
+       else
+               return PE_UFP_VDM_Mode_Entry_NAK;
+
        /* Todo
        check DPM evaluate request to enter a mode
        */
@@ -1521,6 +2860,11 @@ policy_state usbpd_policy_ufp_vdm_mode_entry_ack(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       Actions on entry:
+       Send Enter Mode ACK Command
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
@@ -1539,6 +2883,7 @@ policy_state usbpd_policy_ufp_vdm_mode_entry_ack(struct policy_data *policy)
 
        if (usbpd_send_msg(pd_data, &policy->tx_msg_header,
                                policy->tx_data_obj)) {
+               /* TODO: may need to wait a while(5ms) and send status_update */
                if (power_role == USBPD_SINK)
                        return PE_SNK_Ready;
                else
@@ -1552,6 +2897,11 @@ policy_state usbpd_policy_ufp_vdm_mode_entry_nak(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       Actions on entry:
+       Send Enter Mode NAK Command response as requested
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
@@ -1582,6 +2932,11 @@ policy_state usbpd_policy_ufp_vdm_mode_exit(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
 
+       /**********************************************
+       Actions on entry:
+       Request DPM to evaluate request to exit the requested Mode
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        if (pd_data->phy_ops.get_status(pd_data, VDM_EXIT_MODE)) {
@@ -1606,6 +2961,11 @@ policy_state usbpd_policy_ufp_vdm_mode_exit_ack(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       Actions on entry:
+       Send Exit Mode ACK Command
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
@@ -1637,6 +2997,11 @@ policy_state usbpd_policy_ufp_vdm_mode_exit_nak(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       Actions on entry:
+       Send Exit Mode NAK Command
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
@@ -1668,6 +3033,11 @@ policy_state usbpd_policy_ufp_vdm_attention_request(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       Actions on entry:
+       Send Attention Command request
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
@@ -1700,6 +3070,9 @@ policy_state usbpd_policy_ufp_vdm_evaluate_status(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
@@ -1726,6 +3099,9 @@ policy_state usbpd_policy_ufp_vdm_status_ack(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
@@ -1757,6 +3133,9 @@ policy_state usbpd_policy_ufp_vdm_status_nak(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
@@ -1788,6 +3167,9 @@ policy_state usbpd_policy_ufp_vdm_evaluate_configure(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
@@ -1814,6 +3196,9 @@ policy_state usbpd_policy_ufp_vdm_configure_ack(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
@@ -1845,6 +3230,9 @@ policy_state usbpd_policy_ufp_vdm_configure_nak(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
@@ -1878,6 +3266,12 @@ policy_state usbpd_policy_dfp_vdm_identity_request(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       Actions on entry:
+       Send Discover Identity request
+       Start VDMResponseTimer
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
@@ -1905,9 +3299,16 @@ policy_state usbpd_policy_dfp_vdm_identity_request(struct policy_data *policy)
                        if (policy->rx_data_obj[0].structured_vdm.command_type
                                        == Responder_ACK)
                                return PE_DFP_VDM_Identity_ACKed;
+                       else if (policy->rx_data_obj[0].structured_vdm.command_type == Responder_NAK
+                               || policy->rx_data_obj[0].structured_vdm.command_type == Responder_BUSY)
+                               return PE_DFP_VDM_Identity_NAKed;
                }
        }
-       return PE_DFP_VDM_Identity_NAKed;
+
+       if (pd_data->counter.swap_hard_reset_counter > USBPD_nHardResetCount)
+               return Error_Recovery;
+
+       return PE_SRC_Hard_Reset;
 }
 
 static policy_state usbpd_policy_dfp_vdm_response(struct policy_data *policy,
@@ -1916,6 +3317,9 @@ static policy_state usbpd_policy_dfp_vdm_response(struct policy_data *policy,
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       **********************************************/
+
        usbpd_manager_inform_event(pd_data, event);
 
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
@@ -1930,6 +3334,11 @@ policy_state usbpd_policy_dfp_vdm_identity_acked(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
 
+       /**********************************************
+       Actions on entry:
+       Inform DPM of identity
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        return usbpd_policy_dfp_vdm_response(policy,
@@ -1940,6 +3349,11 @@ policy_state usbpd_policy_dfp_vdm_identity_naked(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
 
+       /**********************************************
+       Actions on entry:
+       Inform DPM of result
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        return usbpd_policy_dfp_vdm_response(policy,
@@ -1951,6 +3365,12 @@ policy_state usbpd_policy_dfp_vdm_svids_request(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       Actions on entry:
+       Send Discover SVIDs request
+       Start VDMResponseTimer
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
@@ -1984,6 +3404,11 @@ policy_state usbpd_policy_dfp_vdm_svids_acked(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
 
+       /**********************************************
+       Actions on entry:
+       Inform DPM of SVIDs
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        return usbpd_policy_dfp_vdm_response(policy,
@@ -1994,6 +3419,11 @@ policy_state usbpd_policy_dfp_vdm_svids_naked(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
 
+       /**********************************************
+       Actions on entry:
+       Inform DPM of result
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        return usbpd_policy_dfp_vdm_response(policy,
@@ -2006,6 +3436,12 @@ policy_state usbpd_policy_dfp_vdm_modes_request(struct policy_data *policy)
        struct usbpd_manager_data *manager = &pd_data->manager;
        int power_role = 0;
 
+       /**********************************************
+       Actions on entry:
+       Send Discover Modes request
+       Start VDMResponseTimer
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
@@ -2039,6 +3475,11 @@ policy_state usbpd_policy_dfp_vdm_modes_acked(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
 
+       /**********************************************
+       Actions on entry:
+       Inform DPM of Modes
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        return usbpd_policy_dfp_vdm_response(policy,
@@ -2049,6 +3490,11 @@ policy_state usbpd_policy_dfp_vdm_modes_naked(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
 
+       /**********************************************
+       Actions on entry:
+       Inform DPM of result
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        return usbpd_policy_dfp_vdm_response(policy,
@@ -2061,6 +3507,12 @@ policy_state usbpd_policy_dfp_vdm_entry_request(struct policy_data *policy)
        struct usbpd_manager_data *manager = &pd_data->manager;
        int power_role = 0;
 
+       /**********************************************
+       Actions on entry:
+       Send Mode Entry request
+       Start VDMModeEntryTimer
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
@@ -2097,6 +3549,11 @@ policy_state usbpd_policy_dfp_vdm_entry_acked(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
 
+       /**********************************************
+       Actions on entry:
+       Request DPM to enter the mode
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        return usbpd_policy_dfp_vdm_response(policy, MANAGER_ENTER_MODE_ACKED);
@@ -2106,6 +3563,11 @@ policy_state usbpd_policy_dfp_vdm_entry_naked(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
 
+       /**********************************************
+       Actions on entry:
+       Inform DPM of reason for failure
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        return usbpd_policy_dfp_vdm_response(policy, MANAGER_ENTER_MODE_NAKED);
@@ -2116,6 +3578,12 @@ policy_state usbpd_policy_dfp_vdm_exit_request(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       Actions on entry:
+       Send Exit Mode request
+       Start VDMModeExitTimer
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
@@ -2149,6 +3617,11 @@ policy_state usbpd_policy_dfp_vdm_exit_acked(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
 
+       /**********************************************
+       Actions on entry:
+       Inform DPM of ACK
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        return usbpd_policy_dfp_vdm_response(policy, MANAGER_EXIT_MODE_ACKED);
@@ -2158,6 +3631,11 @@ policy_state usbpd_policy_dfp_vdm_exit_naked(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
 
+       /**********************************************
+       Actions on entry:
+       Inform DPM of NAK
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        return usbpd_policy_dfp_vdm_response(policy, MANAGER_EXIT_MODE_NAKED);
@@ -2167,6 +3645,11 @@ policy_state usbpd_policy_dfp_vdm_attention_request(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
 
+       /**********************************************
+       Actions on entry:
+       Inform Device Policy Manager of Attention Command request
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        return usbpd_policy_dfp_vdm_response(policy, MANAGER_ATTENTION_REQUEST);
@@ -2177,6 +3660,9 @@ policy_state usbpd_policy_dfp_vdm_status_update(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
@@ -2229,6 +3715,9 @@ policy_state usbpd_policy_dfp_vdm_status_update_acked(struct policy_data *policy
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
 
+       /**********************************************
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        return usbpd_policy_dfp_vdm_response(policy, MANAGER_STATUS_UPDATE_ACKED);
@@ -2238,6 +3727,9 @@ policy_state usbpd_policy_dfp_vdm_status_update_naked(struct policy_data *policy
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
 
+       /**********************************************
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        return usbpd_policy_dfp_vdm_response(policy, MANAGER_STATUS_UPDATE_NAKED);
@@ -2246,9 +3738,11 @@ policy_state usbpd_policy_dfp_vdm_status_update_naked(struct policy_data *policy
 policy_state usbpd_policy_dfp_vdm_displayport_configure(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
-       struct usbpd_manager_data *manager = &pd_data->manager;
        int power_role = 0;
 
+       /**********************************************
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.get_power_role(pd_data, &power_role);
@@ -2259,7 +3753,7 @@ policy_state usbpd_policy_dfp_vdm_displayport_configure(struct policy_data *poli
        policy->tx_msg_header.port_power_role = power_role;
        policy->tx_msg_header.num_data_objs = 2;
 
-       policy->tx_data_obj[0].structured_vdm.svid = manager->SVID_0;
+       policy->tx_data_obj[0].structured_vdm.svid = PD_SID_1;
        policy->tx_data_obj[0].structured_vdm.vdm_type = Structured_VDM;
        policy->tx_data_obj[0].structured_vdm.version = 0;
        policy->tx_data_obj[0].structured_vdm.obj_pos = 1;/* Todo select which_mode */
@@ -2268,14 +3762,9 @@ policy_state usbpd_policy_dfp_vdm_displayport_configure(struct policy_data *poli
 
        /* second object for vdo */
        policy->tx_data_obj[1].object = 0;
-       policy->tx_data_obj[1].displayport_configurations.select_configuration =
-                                                                                                                               USB_U_AS_UFP_D;
-       policy->tx_data_obj[1].displayport_configurations.displayport_protocol =
-                                                                                                                               DP_V_1_3;
-//     policy->tx_data_obj[1].displayport_configurations.ufp_u_pin_assignment =
-//                                                                                                     manager->pin_assignment;
-       policy->tx_data_obj[1].displayport_configurations.ufp_u_pin_assignment =
-                                                                                                       4;
+       policy->tx_data_obj[1].displayport_configurations.select_configuration = USB_U_AS_UFP_D;
+       policy->tx_data_obj[1].displayport_configurations.displayport_protocol = DP_V_1_3;
+       policy->tx_data_obj[1].displayport_configurations.ufp_u_pin_assignment = PIN_ASSIGNMENT_D;
 
        /* TODO: obj_pos , vdo should be set by device manager */
        if (usbpd_send_msg(pd_data, &policy->tx_msg_header,
@@ -2298,6 +3787,9 @@ policy_state usbpd_policy_dfp_vdm_displayport_configure_acked(struct policy_data
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
 
+       /**********************************************
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        return usbpd_policy_dfp_vdm_response(policy, MANAGER_DisplayPort_Configure_ACKED);
@@ -2307,6 +3799,9 @@ policy_state usbpd_policy_dfp_vdm_displayport_configure_naked(struct policy_data
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
 
+       /**********************************************
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        return usbpd_policy_dfp_vdm_response(policy, MANAGER_DisplayPort_Configure_NACKED);
@@ -2318,6 +3813,9 @@ policy_state usbpd_policy_dfp_uvdm_send_message(struct policy_data *policy)
        struct usbpd_manager_data *manager = &pd_data->manager;
        int power_role = 0;
 
+       /**********************************************
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        pd_data->phy_ops.set_check_msg_pass(pd_data, CHECK_MSG_PASS);
@@ -2337,6 +3835,9 @@ policy_state usbpd_policy_dfp_uvdm_receive_message(struct policy_data *policy)
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
        int power_role = 0;
 
+       /**********************************************
+       **********************************************/
+
        dev_info(pd_data->dev, "%s\n", __func__);
 
        usbpd_manager_inform_event(pd_data, MANAGER_UVDM_RECEIVE_MESSAGE);
@@ -2349,10 +3850,333 @@ policy_state usbpd_policy_dfp_uvdm_receive_message(struct policy_data *policy)
                return PE_SNK_Ready;
 }
 
+policy_state usbpd_policy_dr_src_get_source_cap(struct policy_data *policy)
+{
+       struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int ret = PE_DR_SRC_Get_Source_Cap;
+       int data_role = 0;
+       int ms = 0;
+
+       /**********************************************
+       get source capabilities request from Device Policy Manager
+
+       Actions on entry:
+       Send Get_Source_Cap message
+       Initialize and run SenderResponseTimer
+       **********************************************/
+
+       /* 1) PD State Inform to AP */
+       dev_info(pd_data->dev, "%s\n", __func__);
+
+       /* 2) Read Data Role */
+       pd_data->phy_ops.get_data_role(pd_data, &data_role);
+
+       /* 3) Send Message */
+       usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, USBPD_Get_Source_Cap, data_role, USBPD_SOURCE);
+
+       /* 4) Start Timer */
+       usbpd_timer1_start(pd_data);
+
+       /* 5) Wait Message or State */
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_DR_SRC_Get_Source_Cap;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               if (pd_data->phy_ops.get_status(pd_data, MSG_ERROR)) {
+                       ret = PE_SRC_Send_Soft_Reset;
+                       break;
+               }
+
+               if (pd_data->phy_ops.get_status(pd_data, MSG_SRC_CAP)) {
+                       ret = PE_SRC_Ready;
+                       break;
+               }
+
+               if (pd_data->phy_ops.get_status(pd_data, MSG_REJECT)) {
+                       ret = PE_SRC_Ready;
+                       break;
+               }
+
+               /* TimeOver Check */
+               if (ms >= tSenderResponse) {
+                       ret = PE_SRC_Ready;
+                       break;
+               }
+       }
+
+       /**********************************************
+       Actions on exit:
+       Pass source capabilities/outcome to Device Policy Manager
+
+       Source capabilities message received
+       | SenderResponseTimer Timeout | Reject message received
+       **********************************************/
+
+       return ret;
+}
+
+policy_state usbpd_policy_dr_src_give_sink_cap(struct policy_data *policy)
+{
+       struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int data_role = 0;
+       int ret = PE_DR_SRC_Give_Sink_Cap;
+       int ms = 0;
+
+       /**********************************************
+       Actions on entry:
+       Get present sink capabilities from Device Policy Manager
+       Send Capabilities message (based on Device Policy Manager response)
+       **********************************************/
+
+       /* 1) PD State Inform to AP */
+       dev_info(pd_data->dev, "%s\n", __func__);
+
+       /* 2) Read Data Role */
+       pd_data->phy_ops.get_data_role(pd_data, &data_role);
+
+       /* 3) Sink Cap Message Setting */
+       policy->tx_msg_header.word = pd_data->sink_msg_header.word;
+       policy->tx_msg_header.port_data_role = data_role;
+       policy->tx_data_obj[0].object = pd_data->sink_data_obj[0].object;
+       policy->tx_data_obj[1].object = pd_data->sink_data_obj[1].object;
+
+       /* 4) Send Message */
+       usbpd_send_msg(pd_data, &policy->tx_msg_header, policy->tx_data_obj);
+
+       /* 5) Start Timer */
+       usbpd_timer1_start(pd_data);
+
+       /* 6) Wait Message or State */
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_DR_SRC_Give_Sink_Cap;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               if (pd_data->phy_ops.get_status(pd_data, MSG_GOODCRC)) {
+                       dev_info(pd_data->dev, "got dr_src_give_sink_cap MSG_GOODCRC.\n");
+                       ret = PE_SRC_Ready;
+                       break;
+               }
+
+               if (ms >= 5) {
+                       ret = PE_SRC_Send_Soft_Reset;
+                       dev_info(pd_data->dev, "got dr_src_give_sink_cap Timer1_overflag.\n");
+                       break;
+               }
+       }
+
+       /* 8) Sink Capabilities message sent */
+       return ret;
+}
+
+policy_state usbpd_policy_dr_snk_get_sink_cap(struct policy_data *policy)
+{
+       struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int ret = PE_DR_SNK_Get_Sink_Cap;
+       int data_role = 0;
+       int ms = 0;
+
+       /**********************************************
+       get sink capabilities request from Device Policy Manager
+
+       Actions on entry:
+       Send Get_Sink_Cap message
+       Initialize and run
+       SenderResponseTimer
+       **********************************************/
+
+       /* 1) PD State Inform to AP */
+       dev_info(pd_data->dev, "%s\n", __func__);
+
+       /* 2) Read Data Role */
+       pd_data->phy_ops.get_data_role(pd_data, &data_role);
+
+       /* 3) Send Message */
+       usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header,
+                                                       USBPD_Get_Sink_Cap, data_role, USBPD_SINK);
+
+       /* 4) Start Timer */
+       usbpd_timer1_start(pd_data);
+
+       /* 5) Wait Message or State */
+       while (1) {
+               if (policy->plug_valid == 0) {
+                       ret = PE_DR_SNK_Get_Sink_Cap;
+                       break;
+               }
+               ms = usbpd_check_time1(pd_data);
+               if (pd_data->phy_ops.get_status(pd_data, MSG_ERROR)) {
+                       ret = PE_SNK_Send_Soft_Reset;
+                       break;
+               }
+
+               if (pd_data->phy_ops.get_status(pd_data, MSG_SNK_CAP)) {
+                       ret = PE_SNK_Ready;
+                       break;
+               }
+
+               if (pd_data->phy_ops.get_status(pd_data, MSG_REJECT)) {
+                       ret = PE_SNK_Ready;
+                       break;
+               }
+
+               /* TimeOver Check */
+               if (ms >= tSenderResponse) {
+                       ret = PE_SNK_Ready;
+                       break;
+               }
+       }
+
+       /**********************************************
+       Actions on exit:
+       Pass sink capabilities/outcome to
+       Device Policy Manager
+
+       Sink capabilities message received
+       | SenderResponseTimer Timeout | Reject message received
+       **********************************************/
+
+       return ret;
+}
+
+policy_state usbpd_policy_dr_snk_give_source_cap(struct policy_data *policy)
+{
+       struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int ret = PE_DR_SNK_Give_Source_Cap;
+       int data_role = 0;
+       int ms = 0;
+       /**********************************************
+       Actions on entry:
+       Request source capabilities from
+       Device Policy Manager
+       Send Capabilities message
+       **********************************************/
+
+       /* 1) PD State Inform to AP */
+       dev_info(pd_data->dev, "%s\n", __func__);
+
+       usbpd_protocol_rx(pd_data);
+
+       if (!pd_data->id_matched)
+               return PE_SNK_Ready;
+
+#if 0
+       /* 2) Message ID Check and Ignored */
+       if (pd_data->phy_ops.compare_message_id(pd_data) != 0) {
+               dev_info(pd_data->dev, "After compare_message_id not Match move to PE_SNK_Ready.\n");
+               return PE_SNK_Ready;
+       } else {
+               dev_info(pd_data->dev, "After compare_message_id Match move to PE_SNK_Ready.\n");
+       }
+#endif
+
+       /* 3) Read Data Role */
+       pd_data->phy_ops.get_data_role(pd_data, &data_role);
+
+       /* 4) Message Setting */
+       policy->tx_msg_header.msg_type = USBPD_Source_Capabilities;
+       policy->tx_msg_header.port_data_role = data_role;
+       policy->tx_msg_header.port_power_role = USBPD_SINK;
+       policy->tx_msg_header.num_data_objs = 1;
+
+       policy->tx_data_obj[0].power_data_obj.max_current = 1500 / 10;
+       policy->tx_data_obj[0].power_data_obj.voltage = 5000 / 50;
+       policy->tx_data_obj[0].power_data_obj.peak_current = 0;
+       policy->tx_data_obj[0].power_data_obj.rsvd = 0;
+       policy->tx_data_obj[0].power_data_obj.data_role_swap = 1;
+       policy->tx_data_obj[0].power_data_obj.usb_comm_capable = 1;
+       policy->tx_data_obj[0].power_data_obj.externally_powered = 0;
+       policy->tx_data_obj[0].power_data_obj.usb_suspend_support = 1;
+       policy->tx_data_obj[0].power_data_obj.dual_role_power = 1;
+       policy->tx_data_obj[0].power_data_obj.supply = 0;
+
+       /* 5) Send Message */
+       usbpd_send_msg(pd_data, &policy->tx_msg_header, policy->tx_data_obj);
+
+       /* 6) Start Timer */
+       usbpd_timer1_start(pd_data);
+
+       /* 7) Wait Message or State */
+       while (1) {
+               if (policy->plug_valid == 0)
+                       break;
+               ms = usbpd_check_time1(pd_data);
+               if (pd_data->phy_ops.get_status(pd_data, MSG_GOODCRC)) {
+                       ret = PE_SNK_Ready;
+                       break;
+               }
+
+               if (ms >= 5) {
+                       ret = PE_SNK_Send_Soft_Reset;
+                       break;
+               }
+       }
+
+       return ret;
+}
+#if 1 //JETSEO
+policy_state usbpd_policy_bist_receive_mode(struct policy_data *policy)
+{
+
+       struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int ret = PE_BIST_Receive_Mode;
+
+       /**********************************************
+       Actions on entry:
+       Tell Protocol Layer to go to BIST
+       Receive Mode
+       **********************************************/
+
+       /* 1) PD State Inform to AP */
+       dev_info(pd_data->dev, "%s\n", __func__);
+
+       /* 2) Interrupt Status All Mask */
+
+       /**********************************************
+       Actions on exit:
+       Goto bist frame received state
+       or Hard Reset signaling received
+       **********************************************/
+       ret = PE_BIST_Frame_Received;
+
+       return ret;
+
+}
+
+policy_state usbpd_policy_bist_frame_received(struct policy_data *policy)
+{
+
+       struct usbpd_data *pd_data = policy_to_usbpd(policy);
+       int ret = PE_BIST_Frame_Received;
+
+       /**********************************************
+       Actions on entry:
+       Consume Frame
+       **********************************************/
+
+       /* 1) PD State Inform to AP */
+       dev_info(pd_data->dev, "%s\n", __func__);
+
+       /**********************************************
+       Actions on exit:
+    Detach
+    or Hard Reset signaling received
+       **********************************************/
+
+       return ret;
+
+}
+#endif
 policy_state usbpd_error_recovery(struct policy_data *policy)
 {
        struct usbpd_data *pd_data = policy_to_usbpd(policy);
 
+       /**********************************************
+       **********************************************/
+
        dev_err(pd_data->dev, "%s\n", __func__);
 
        return Error_Recovery;
@@ -2382,6 +4206,7 @@ void usbpd_policy_work(struct work_struct *work)
                switch (next_state) {
                case PE_SRC_Startup:
                        next_state = usbpd_policy_src_startup(policy);
+                       store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL);
                        break;
                case PE_SRC_Discovery:
                        next_state = usbpd_policy_src_discovery(policy);
@@ -2397,18 +4222,22 @@ void usbpd_policy_work(struct work_struct *work)
                        break;
                case PE_SRC_Ready:
                        next_state = usbpd_policy_src_ready(policy);
+                       store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL);
                        break;
                case PE_SRC_Disabled:
                        next_state = usbpd_policy_src_disabled(policy);
+                       store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL);
                        break;
                case PE_SRC_Capability_Response:
                        next_state = usbpd_policy_src_capability_response(policy);
                        break;
                case PE_SRC_Hard_Reset:
                        next_state = usbpd_policy_src_hard_reset(policy);
+                       store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL);
                        break;
                case PE_SRC_Hard_Reset_Received:
                        next_state = usbpd_policy_src_hard_reset_received(policy);
+                       store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL);
                        break;
                case PE_SRC_Transition_to_default:
                        next_state = usbpd_policy_src_transition_to_default(policy);
@@ -2427,10 +4256,12 @@ void usbpd_policy_work(struct work_struct *work)
                        break;
                case PE_SRC_Soft_Reset:
                        next_state = usbpd_policy_src_soft_reset(policy);
+                       store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL);
                        break;
 
                case PE_SNK_Startup:
                        next_state = usbpd_policy_snk_startup(policy);
+                       store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL);
                        break;
                case PE_SNK_Discovery:
                        next_state = usbpd_policy_snk_discovery(policy);
@@ -2449,12 +4280,15 @@ void usbpd_policy_work(struct work_struct *work)
                        break;
                case PE_SNK_Ready:
                        next_state = usbpd_policy_snk_ready(policy);
+                       store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL);
                        break;
                case PE_SNK_Hard_Reset:
                        next_state = usbpd_policy_snk_hard_reset(policy);
+                       store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL);
                        break;
                case PE_SNK_Transition_to_default:
                        next_state = usbpd_policy_snk_transition_to_default(policy);
+                       store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL);
                        break;
                case PE_SNK_Give_Sink_Cap:
                        next_state = usbpd_policy_snk_give_sink_cap(policy);
@@ -2462,10 +4296,14 @@ void usbpd_policy_work(struct work_struct *work)
                case PE_SNK_Get_Source_Cap:
                        next_state = usbpd_policy_snk_get_source_cap(policy);
                        break;
+               case PE_SNK_Send_Soft_Reset:
+                       next_state = usbpd_policy_snk_send_soft_reset(policy);
+                       store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL);
+                       break;
                case PE_SNK_Soft_Reset:
                        next_state = usbpd_policy_snk_soft_reset(policy);
+                       store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL);
                        break;
-
                case PE_DRS_Evaluate_Port:
                        next_state = usbpd_policy_drs_evaluate_port(policy);
                        break;
@@ -2477,12 +4315,14 @@ void usbpd_policy_work(struct work_struct *work)
                        break;
                case PE_DRS_DFP_UFP_Accept_DR_Swap:
                        next_state = usbpd_policy_drs_dfp_ufp_accept_dr_swap(policy);
+                       store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL);
                        break;
                case PE_DRS_DFP_UFP_Change_to_UFP:
                        next_state = usbpd_policy_drs_dfp_ufp_change_to_ufp(policy);
                        break;
                case PE_DRS_DFP_UFP_Send_DR_Swap:
                        next_state = usbpd_policy_drs_dfp_ufp_send_dr_swap(policy);
+                       store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL);
                        break;
                case PE_DRS_DFP_UFP_Reject_DR_Swap:
                        next_state = usbpd_policy_drs_dfp_ufp_reject_dr_swap(policy);
@@ -2492,12 +4332,14 @@ void usbpd_policy_work(struct work_struct *work)
                        break;
                case PE_DRS_UFP_DFP_Accept_DR_Swap:
                        next_state = usbpd_policy_drs_ufp_dfp_accept_dr_swap(policy);
+                       store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL);
                        break;
                case PE_DRS_UFP_DFP_Change_to_DFP:
                        next_state = usbpd_policy_drs_ufp_dfp_change_to_dfp(policy);
                        break;
                case PE_DRS_UFP_DFP_Send_DR_Swap:
                        next_state = usbpd_policy_drs_ufp_dfp_send_dr_swap(policy);
+                       store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL);
                        break;
                case PE_DRS_UFP_DFP_Reject_DR_Swap:
                        next_state = usbpd_policy_drs_ufp_dfp_reject_dr_swap(policy);
@@ -2511,9 +4353,11 @@ void usbpd_policy_work(struct work_struct *work)
                        break;
                case PE_PRS_SRC_SNK_Send_Swap:
                        next_state = usbpd_policy_prs_src_snk_send_swap(policy);
+                       store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL);
                        break;
                case PE_PRS_SRC_SNK_Accept_Swap:
                        next_state = usbpd_policy_prs_src_snk_accept_swap(policy);
+                       store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL);
                        break;
                case PE_PRS_SRC_SNK_Transition_off:
                        next_state = usbpd_policy_prs_src_snk_transition_to_off(policy);
@@ -2532,9 +4376,11 @@ void usbpd_policy_work(struct work_struct *work)
                        break;
                case PE_PRS_SNK_SRC_Send_Swap:
                        next_state = usbpd_policy_prs_snk_src_send_swap(policy);
+                       store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL);
                        break;
                case PE_PRS_SNK_SRC_Accept_Swap:
                        next_state = usbpd_policy_prs_snk_src_accept_swap(policy);
+                       store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL);
                        break;
                case PE_PRS_SNK_SRC_Transition_off:
                        next_state = usbpd_policy_prs_snk_src_transition_to_off(policy);
@@ -2708,8 +4554,29 @@ void usbpd_policy_work(struct work_struct *work)
                case PE_DFP_UVDM_Receive_Message:
                        next_state = usbpd_policy_dfp_uvdm_receive_message(policy);
                        break;
+               case PE_DR_SRC_Get_Source_Cap:
+                       next_state = usbpd_policy_dr_src_get_source_cap(policy);
+                       break;
+               case PE_DR_SRC_Give_Sink_Cap:
+                       next_state = usbpd_policy_dr_src_give_sink_cap(policy);
+                       break;
+               case PE_DR_SNK_Get_Sink_Cap:
+                       next_state = usbpd_policy_dr_snk_get_sink_cap(policy);
+                       break;
+               case PE_DR_SNK_Give_Source_Cap:
+                       next_state = usbpd_policy_dr_snk_give_source_cap(policy);
+                       break;
+#if 1  //JETSEO
+               case PE_BIST_Receive_Mode:
+                       next_state = usbpd_policy_bist_receive_mode(policy);
+                       break;
+               case PE_BIST_Frame_Received:
+                       next_state = usbpd_policy_bist_frame_received(policy);
+                       break;
+#endif
                case Error_Recovery:
                        next_state = usbpd_error_recovery(policy);
+                       store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL);
                        break;
 
                default:
@@ -2745,6 +4612,7 @@ void usbpd_policy_work(struct work_struct *work)
                                        next_state = PE_SRC_Startup;
                                }
                        }
+
                        break;
                }
        dev_info(pd_data->dev, "%s saved state %x next_state %x \n", __func__, saved_state, next_state);
@@ -2768,6 +4636,8 @@ void usbpd_init_policy(struct usbpd_data *pd_data)
        policy->modal_operation = 0;
        policy->sink_cap_received = 0;
        policy->send_sink_cap = 0;
+       policy->txhardresetflag = 0;
+       policy->pd_support = 0;
        for (i = 0; i < USBPD_MAX_COUNT_MSG_OBJECT; i++) {
                policy->rx_data_obj[i].object = 0;
                policy->tx_data_obj[i].object = 0;
@@ -2778,6 +4648,16 @@ void usbpd_kick_policy_work(struct device *dev)
 {
        struct usbpd_data *pd_data = dev_get_drvdata(dev);
 
-       schedule_work(&pd_data->worker);
+       if (pd_data->policy_wqueue)
+               queue_work(pd_data->policy_wqueue, &pd_data->worker);
+       else
+               schedule_work(&pd_data->worker);
 }
 
+void usbpd_cancel_policy_work(struct device *dev)
+{
+       struct usbpd_data *pd_data = dev_get_drvdata(dev);
+
+       if (pd_data->policy_wqueue)
+               flush_workqueue(pd_data->policy_wqueue);
+}
index 3fdebd5625553bc8eed393da60d65714d1a0338c..6203c50be444b57b4be67f431a9aa58916f5fab6 100644 (file)
@@ -149,24 +149,24 @@ int ifconn_notifier_notify(ifconn_notifier_t src,
                                memcpy(&(pnoti[src].ifconn_template[listener]), template,
                                           sizeof(struct ifconn_notifier_template));
                        }
-                       return -1;
+                       ret = NOTIFY_BAD;
+               } else {
+                       nb = pnoti[src].nb[listener];
+                       ret = nb->notifier_call(nb, (unsigned long)noti_id, template);
                }
-
-               nb = pnoti[src].nb[listener];
-               ret = nb->notifier_call(nb, (unsigned long)noti_id, template);
        }
 
        switch (ret) {
        case NOTIFY_STOP_MASK:
        case NOTIFY_BAD:
-               pr_err("%s: notify error occur(0x%x)\n", __func__, ret);
+               pr_err("%s: src(%d) notify error occur(0x%x)\n", __func__, src, ret);
                break;
        case NOTIFY_DONE:
        case NOTIFY_OK:
-               pr_info("%s: notify done(0x%x)\n", __func__, ret);
+               pr_info("%s: src(%d) notify done(0x%x)\n", __func__, src, ret);
                break;
        default:
-               pr_info("%s: notify status unknown(0x%x)\n", __func__, ret);
+               pr_info("%s: src(%d) notify status unknown(0x%x)\n", __func__, src, ret);
                break;
        }
 
index ace20bdf421dbf2803fc3cc373e8395adc151087..dcbc7e2c4617186881ea6d61eca097f1d82ef8d5 100644 (file)
 #include <linux/mfd/samsung/s2mu106.h>
 #include <linux/of_gpio.h>
 
-#if defined(CONFIG_CHARGER_S2MU106)
-#define CONFIG_PM_S2MU106
-#endif
-
 static struct mfd_cell s2mu106_devs[] = {
 #if defined(CONFIG_CHARGER_S2MU106)
        { .name = "s2mu106-charger", },
index f861f2899fdb9e98748b91f924175262e632d56a..2738159c8a7c3aeeff77b895d4e88d8cf33ca166 100644 (file)
@@ -32,6 +32,9 @@
 #if defined(CONFIG_MUIC_S2MU106)
 #include <linux/muic/s2mu106-muic.h>
 #endif
+#if defined(CONFIG_PM_S2MU106)
+#include <linux/power/s2mu106_pmeter.h>
+#endif
 /* TODO : add IP Header file include*/
 
 static const u8 s2mu106_mask_reg[] = {
@@ -78,7 +81,7 @@ static struct i2c_client *get_i2c(struct s2mu106_dev *s2mu106,
                return s2mu106->muic;
 #endif
 #if defined(CONFIG_PM_S2MU106)
-       case PM_VAL_UP1 ... PM_INT2:
+       case PM_VALUP1 ... PM_INT2:
                return s2mu106->muic;
 #endif
 #if defined(CONFIG_MST_S2MU106)
@@ -334,6 +337,12 @@ static irqreturn_t s2mu106_irq_thread(int irq, void *data)
 #endif
 #if defined(CONFIG_PM_S2MU106)
        if (irq_src & S2MU106_IRQSRC_PM) {
+        s2mu106_read_reg(s2mu106->muic, S2MU106_PM_VALUP1, &irq_reg[PM_VALUP1]);
+        s2mu106_read_reg(s2mu106->muic, S2MU106_PM_VALUP2, &irq_reg[PM_VALUP2]);
+        s2mu106_read_reg(s2mu106->muic, S2MU106_PM_INT1, &irq_reg[PM_INT1]);
+        s2mu106_read_reg(s2mu106->muic, S2MU106_PM_INT2, &irq_reg[PM_INT2]);
+        pr_info("%s: powermeter interrupt(0x%02x, 0x%02x, 0x%02x, 0x%02x)\n", __func__,
+                               irq_reg[PM_VALUP1], irq_reg[PM_VALUP2], irq_reg[PM_INT1], irq_reg[PM_INT2]);
        }
 #endif
 #if defined(CONFIG_MST_S2MU106)
index 1c4d60537137a1593a8a275ae47a2fd96662a54a..bace721691612eea416b46f254e515d19c803358 100644 (file)
@@ -711,6 +711,40 @@ static int muic_manager_handle_ccic_TA(struct muic_interface_t *muic_if, void *d
 #endif
 #endif
 
+static int muic_manager_handle_ccic_role_swap(struct muic_interface_t *muic_if, void *data)
+{
+#ifdef CONFIG_IFCONN_NOTIFIER
+       struct ifconn_notifier_template *pnoti = (struct ifconn_notifier_template *)data;
+#else
+       CC_NOTI_TYPEDEF *pnoti = (CC_NOTI_TYPEDEF *)data;
+#endif
+       struct ccic_desc_t *ccic = muic_if->ccic;
+       
+       pr_info("%s: src:%d dest:%d sub1:%d\n", __func__,
+               pnoti->src, pnoti->dest, pnoti->sub1);
+       
+       if (pnoti->sub1 == true) {
+               /* sink -> src */
+               ccic->ccic_evt_rprd = 1;
+               ccic->ccic_evt_roleswap = 1;
+               ccic->attached_dev = ATTACHED_DEV_OTG_MUIC;
+               if (muic_if->set_cable_state)
+                       muic_if->set_cable_state(muic_if->muic_data, ccic->attached_dev);
+       } else {
+               /* src -> sink */
+               muic_manager_handle_ccic_detach(muic_if);
+
+               ccic->ccic_evt_attached = MUIC_CCIC_NOTI_ATTACH;
+               ccic->ccic_evt_rprd = 1;
+               ccic->ccic_evt_roleswap = 1;
+               ccic->attached_dev = ATTACHED_DEV_TYPE3_CHARGER_MUIC;
+               if (muic_if->set_cable_state)
+                       muic_if->set_cable_state(muic_if->muic_data, ccic->attached_dev);
+       }
+
+       return 0;       
+}
+
 static int muic_manager_handle_otg(struct muic_interface_t *muic_if, void *data)
 {
        int ret = MUIC_NORMAL_OTG;
@@ -767,6 +801,7 @@ static int muic_manager_handle_notification(struct notifier_block *nb,
        int water = IFCONN_NOTIFY_ID_WATER;
        int otg = IFCONN_NOTIFY_ID_OTG;
        int ta = IFCONN_NOTIFY_ID_TA;
+       int role_swap = IFCONN_NOTIFY_ID_ROLE_SWAP;
 #else
        CC_NOTI_TYPEDEF *pnoti = (CC_NOTI_TYPEDEF *) data;
        int attach = CCIC_NOTIFY_ID_ATTACH;
@@ -814,6 +849,9 @@ static int muic_manager_handle_notification(struct notifier_block *nb,
                muic_manager_handle_ccic_TA(muic_if, data);
 #endif
 #endif
+       } else if (pnoti->id == role_swap) {
+               pr_info("%s: NOTIFY_ID_ROLE_SWAP\n", __func__);
+               muic_manager_handle_ccic_role_swap(muic_if, data);
        } else {
                pr_info("%s: Undefined Noti. ID\n", __func__);
        }
index 637f0d530c164433880a6de778bcd38dbc4ddc2f..e694fabc0cb6e9a2567a53f1a352f1ebc7fa20b9 100644 (file)
@@ -49,7 +49,7 @@
 
 /* powermeter */
 #if defined(CONFIG_PM_S2MU106)
-#include "../battery_v2/include/s2mu106_pmeter.h"
+#include <linux/power/s2mu106_pmeter.h>
 #endif
 
 static struct s2mu106_muic_data *static_data;
index c6fdbc12845cacad46b9ac2fc6bf86ab3c0f2079..5dbfed13b48ce432092b61ab0b3a8cecd6ec8294 100644 (file)
@@ -657,6 +657,14 @@ config CHARGER_S2MU106
       S2MU106 incluse pmic, led driver.
       You have to define MFD_S2MU106
 
+config PM_S2MU106
+       tristate "S2MU106 power meter support"
+       depends on (MFD_S2MU106) && I2C
+       help
+        Say Y here to enable support for the S2MU106 power meter.
+        S2MU106 power meter is dependent on MFD_S2MU106
+        so it needs to be defined.
+
 config SMALL_CHARGER
        tristate "Small charger support"
        depends on I2C
index de4e49b81101a85c62e9a351d70767c74e842b4b..c12a30b7d73781d0950a28aeebff7556acec27a8 100644 (file)
@@ -85,7 +85,8 @@ obj-$(CONFIG_AXP288_CHARGER)  += axp288_charger.o
 obj-$(CONFIG_FUELGAUGE_S2MU004) += s2mu004_fuelgauge.o
 obj-$(CONFIG_CHARGER_S2MU004)   += s2mu004_charger.o
 obj-$(CONFIG_FUELGAUGE_S2MU106) += s2mu106_fuelgauge.o
-obj-$(CONFIG_CHARGER_S2MU106)   += s2mu106_charger.o s2mu106_pmeter.o
+obj-$(CONFIG_CHARGER_S2MU106)   += s2mu106_charger.o
 obj-$(CONFIG_BATTERY_S2MU00X)   += s2mu00x_battery.o
 obj-$(CONFIG_BATTERY_S2MU00X_ERD)   += s2mu00x_erd_battery.o
 obj-$(CONFIG_CHARGER_S2MCS02)   += s2mcs02_charger.o
+obj-$(CONFIG_PM_S2MU106)               += s2mu106_pmeter.o
index 8ecc694106a0fcd9e08f2ea976a4f622483fd165..7ea664107294ab918082c6448b2a6668a786a0dc 100644 (file)
@@ -143,6 +143,7 @@ struct s2mu00x_battery_info {
        struct power_supply_desc psy_ac_desc;
 
        struct mutex iolock;
+       struct mutex ifconn_lock;
 
        struct wake_lock monitor_wake_lock;
        struct workqueue_struct *monitor_wqueue;
@@ -159,12 +160,16 @@ struct s2mu00x_battery_info {
        int max_charging_current;
 
 #if defined(CONFIG_USE_CCIC)
+       struct delayed_work select_pdo_work;
        int pdo_max_input_vol;
        int pdo_max_chg_power;
 
        int pdo_sel_num;
        int pdo_sel_vol;
        int pdo_sel_cur;
+
+       int pd_input_current;
+       bool pd_attach;
 #endif
 
        int topoff_current;
@@ -205,6 +210,7 @@ struct s2mu00x_battery_info {
 #if defined(CONFIG_SMALL_CHARGER)
        int small_input;        /* input current limit (mA) */
        int small_chg;  /* charge current limit (mA) */
+       int small_input_flag;
 #endif
 
 #if defined(CONFIG_MUIC_NOTIFIER)
@@ -255,22 +261,37 @@ static int set_charging_current(struct s2mu00x_battery_info *battery)
                topoff_current =
                        battery->pdata->charging_current[battery->cable_type].full_check_current;
        struct power_supply *psy;
-       int ret;
+       int ret = 0;
 
        pr_info("%s: cable_type(%d), current(%d, %d, %d)\n", __func__,
                        battery->cable_type, input_current, charging_current, topoff_current);
        mutex_lock(&battery->iolock);
 
        /*Limit input & charging current according to the max current*/
-       get_charging_current(battery, &input_current, &charging_current);\
+       if (battery->cable_type == POWER_SUPPLY_TYPE_PREPARE_TA ||
+               battery->cable_type == POWER_SUPPLY_TYPE_USB_PD) {
+               pr_info("%s, %d, %d\n", __func__, input_current, battery->pd_input_current);
+               input_current = battery->pd_input_current;
+
+               if (input_current >= 1500)
+                       input_current = input_current - 50;
+
+               if (input_current > 2000) {
+                       battery->small_input_flag = input_current - 2000;
+                       input_current = 2000;
+               }
+       } else
+               get_charging_current(battery, &input_current, &charging_current);
 
        /* set input current limit */
        if (battery->input_current != input_current) {
                value.intval = input_current;
 
                psy = power_supply_get_by_name(battery->pdata->charger_name);
-               if (!psy)
-                       return -EINVAL;
+               if (!psy) {
+                       ret = -EINVAL;
+                       goto out;
+               }
                ret = power_supply_set_property(psy, POWER_SUPPLY_PROP_CURRENT_MAX, &value);
                if (ret < 0)
                        pr_err("%s: Fail to execute property\n", __func__);
@@ -282,8 +303,10 @@ static int set_charging_current(struct s2mu00x_battery_info *battery)
                value.intval = charging_current;
 
                psy = power_supply_get_by_name(battery->pdata->charger_name);
-               if (!psy)
-                       return -EINVAL;
+               if (!psy) {
+                       ret = -EINVAL;
+                       goto out;
+               }
                ret = power_supply_set_property(psy, POWER_SUPPLY_PROP_CURRENT_NOW, &value);
                if (ret < 0)
                        pr_err("%s: Fail to execute property\n", __func__);
@@ -295,8 +318,10 @@ static int set_charging_current(struct s2mu00x_battery_info *battery)
                value.intval = topoff_current;
 
                psy = power_supply_get_by_name(battery->pdata->charger_name);
-               if (!psy)
-                       return -EINVAL;
+               if (!psy) {
+                       ret = -EINVAL;
+                       goto out;
+               }
                ret = power_supply_set_property(psy, POWER_SUPPLY_PROP_CURRENT_FULL, &value);
                if (ret < 0)
                        pr_err("%s: Fail to execute property\n", __func__);
@@ -306,25 +331,36 @@ static int set_charging_current(struct s2mu00x_battery_info *battery)
 #if defined(CONFIG_SMALL_CHARGER)
        if (battery->cable_type == POWER_SUPPLY_TYPE_PREPARE_TA ||
                battery->cable_type == POWER_SUPPLY_TYPE_USB_PD) {
-               value.intval = battery->pdata->small_input_current;
+
+               if (battery->small_input_flag == 0) {
+                       ret = 0;
+                       goto out;
+               }
+
+               value.intval = battery->small_input_flag;
                psy = power_supply_get_by_name(battery->pdata->smallcharger_name);
-               if (!psy)
-                       return -EINVAL;
+               if (!psy) {
+                       ret = -EINVAL;
+                       goto out;
+               }
                ret = power_supply_set_property(psy, POWER_SUPPLY_PROP_CURRENT_MAX, &value);
                if (ret < 0)
                        pr_err("%s: Fail to execute property\n", __func__);
 
                value.intval = battery->pdata->small_charging_current;
                psy = power_supply_get_by_name(battery->pdata->smallcharger_name);
-               if (!psy)
-                       return -EINVAL;
+               if (!psy) {
+                       ret = -EINVAL;
+                       goto out;
+               }
                ret = power_supply_set_property(psy, POWER_SUPPLY_PROP_CURRENT_NOW, &value);
                if (ret < 0)
                        pr_err("%s: Fail to execute property\n", __func__);
        }
 #endif
+out:
        mutex_unlock(&battery->iolock);
-       return 0;
+       return ret;
 }
 
 
@@ -365,6 +401,10 @@ static int set_charger_mode(
        if (charger_mode == S2MU00X_BAT_CHG_MODE_CHARGING &&
                        (battery->cable_type == POWER_SUPPLY_TYPE_PREPARE_TA ||
                         battery->cable_type == POWER_SUPPLY_TYPE_USB_PD)) {
+
+               if (battery->small_input_flag == 0)
+                       return 0;
+
                psy = power_supply_get_by_name(battery->pdata->smallcharger_name);
                if (!psy)
                        return -EINVAL;
@@ -372,6 +412,7 @@ static int set_charger_mode(
                if (ret < 0)
                        pr_err("%s: Fail to execute property\n", __func__);
        } else if (charger_mode != S2MU00X_BAT_CHG_MODE_CHARGING) {
+               battery->small_input_flag = 0;
                psy = power_supply_get_by_name(battery->pdata->smallcharger_name);
                if (!psy)
                        return -EINVAL;
@@ -464,6 +505,7 @@ static int set_battery_status(struct s2mu00x_battery_info *battery,
                battery->input_current = 0;
                battery->charging_current = 0;
                battery->topoff_current = 0;
+               battery->small_input_flag = 0;
                break;
 
        case POWER_SUPPLY_STATUS_FULL:
@@ -910,19 +952,16 @@ static int s2mu00x_battery_handle_notification(struct notifier_block *nb,
        return 0;
 }
 #endif
+
 #if defined(CONFIG_IFCONN_NOTIFIER)
 #if defined(CONFIG_USE_CCIC)
-static int s2mu00x_bat_set_pdo(struct s2mu00x_battery_info *battery,
-               ifconn_pd_sink_status_t *pdo_data)
+static void usbpd_select_pdo_work(struct work_struct *work)
 {
-       int ret = -1;
-       int pdo_num = battery->pdo_sel_num;
+       struct s2mu00x_battery_info *battery =
+               container_of(work, struct s2mu00x_battery_info, select_pdo_work.work);
 
-       if (pdo_num > pdo_data->available_pdo_num + 1 || pdo_num < 1) {
-               dev_info(battery->dev, "%s: wrong pdo number. Stop pdo select.\n",
-                               __func__);
-               return ret;
-       }
+       int pdo_num = battery->pdo_sel_num;
+       int ret = -1;
 
        ret = ifconn_notifier_notify(IFCONN_NOTIFY_BATTERY,
                        IFCONN_NOTIFY_MANAGER,
@@ -930,13 +969,26 @@ static int s2mu00x_bat_set_pdo(struct s2mu00x_battery_info *battery,
                        pdo_num,
                        IFCONN_NOTIFY_PARAM_DATA,
                        NULL);
-       if (ret < 0) {
+       if (ret < 0)
                pr_err("%s: Fail to send noti\n", __func__);
+
+}
+
+static int s2mu00x_bat_set_pdo(struct s2mu00x_battery_info *battery,
+               ifconn_pd_sink_status_t *pdo_data)
+{
+       int ret = -1;
+       int pdo_num = battery->pdo_sel_num;
+
+       if (pdo_num > pdo_data->available_pdo_num + 1 || pdo_num < 1) {
+               dev_info(battery->dev, "%s: wrong pdo number. Stop pdo select.\n",
+                               __func__);
                return ret;
        }
 
        ret = POWER_SUPPLY_TYPE_PREPARE_TA;
 
+       schedule_delayed_work(&battery->select_pdo_work, msecs_to_jiffies(50));
        return ret;
 }
 
@@ -969,7 +1021,7 @@ static int s2mu00x_bat_pdo_check(struct s2mu00x_battery_info *battery,
                goto end_pdo_check;
        }
 
-       for (i = 1; i <= pdo_data->available_pdo_num + 1; i++) {
+       for (i = 1; i <= pdo_data->available_pdo_num; i++) {
                dev_info(battery->dev, "%s: pdo_num:%d, max_voltage:%d, max_current:%d\n",
                                __func__, i, pdo_data->power_list[i].max_voltage,
                                pdo_data->power_list[i].max_current);
@@ -990,6 +1042,8 @@ static int s2mu00x_bat_pdo_check(struct s2mu00x_battery_info *battery,
                }
        }
 
+       battery->pd_input_current = pd_input_current_limit;
+
        if (battery->pdo_sel_num == 0) {
                dev_info(battery->dev, "%s: There is no proper pdo. Do normal TA setting\n", __func__);
                current_cable = POWER_SUPPLY_TYPE_MAINS;
@@ -1013,24 +1067,39 @@ static int s2mu00x_ifconn_handle_notification(struct notifier_block *nb,
        struct power_supply *psy;
        int ret;
 
-       dev_info(battery->dev, "%s: action (%ld) dump(0x%01x, 0x%01x, 0x%02x, 0x%04x, 0x%04x, 0x%04x, 0x%04x)\n",
+       dev_info(battery->dev, "%s: action(%ld) dump(0x%01x, 0x%01x, 0x%02x, 0x%04x, 0x%04x, 0x%04x, 0x%04x)\n",
                __func__, action, ifconn_info->src, ifconn_info->dest, ifconn_info->id,
                ifconn_info->attach, ifconn_info->rprd, ifconn_info->cable_type, ifconn_info->event);
-       ifconn_info->cable_type = (muic_attached_dev_t)ifconn_info->event;
 
+       ifconn_info->cable_type = (muic_attached_dev_t)ifconn_info->event;
+#if defined(CONFIG_USE_CCIC)
+       dev_info(battery->dev, "%s: pd_attach(%d)\n", __func__, battery->pd_attach);
+#endif
        action = ifconn_info->id;
+       mutex_lock(&battery->ifconn_lock);
 
-       if (attached_dev == ATTACHED_DEV_MHL_MUIC)
+       if (attached_dev == ATTACHED_DEV_MHL_MUIC) {
+               mutex_unlock(&battery->ifconn_lock);
                return 0;
+       }
 
        switch (action) {
        case IFCONN_NOTIFY_ID_DETACH:
+#if defined(CONFIG_USE_CCIC)
+               if ((ifconn_info->src == IFCONN_NOTIFY_MANAGER) && battery->pd_attach) {
+                       pr_info("%s, Skip cable check when PD TA attaching\n", __func__);
+                       mutex_unlock(&battery->ifconn_lock);
+                       return 0;
+               }
+
+               battery->pd_attach = false;
+#endif
                cmd = "DETACH";
                cable_type = POWER_SUPPLY_TYPE_BATTERY;
                break;
        case IFCONN_NOTIFY_ID_ATTACH:
 #if defined(CONFIG_USE_CCIC)
-               if (battery->cable_type == POWER_SUPPLY_TYPE_USB_PD) {
+               if ((ifconn_info->src == IFCONN_NOTIFY_MANAGER) && battery->pd_attach) {
                        pr_info("%s: PD TA is attached. Skip cable check\n", __func__);
                        cable_type =  POWER_SUPPLY_TYPE_USB_PD;
                        cmd = "PD ATTACH";
@@ -1043,6 +1112,7 @@ static int s2mu00x_ifconn_handle_notification(struct notifier_block *nb,
 #if defined(CONFIG_USE_CCIC)
        case IFCONN_NOTIFY_ID_POWER_STATUS:
                cable_type = s2mu00x_bat_pdo_check(battery, ifconn_info);
+               battery->pd_attach = true;
                switch (cable_type) {
                        case POWER_SUPPLY_TYPE_USB_PD:
                                cmd = "PD ATTACH";
@@ -1083,8 +1153,10 @@ static int s2mu00x_ifconn_handle_notification(struct notifier_block *nb,
                        value.intval = true;
 
                        psy = power_supply_get_by_name(battery->pdata->charger_name);
-                       if (!psy)
+                       if (!psy) {
+                               mutex_unlock(&battery->ifconn_lock);
                                return -EINVAL;
+                       }
                        ret = power_supply_set_property(psy, POWER_SUPPLY_PROP_CHARGE_OTG_CONTROL, &value);
                        if (ret < 0)
                                pr_err("%s: Fail to execute property\n", __func__);
@@ -1094,8 +1166,10 @@ static int s2mu00x_ifconn_handle_notification(struct notifier_block *nb,
                        value.intval = false;
 
                        psy = power_supply_get_by_name(battery->pdata->charger_name);
-                       if (!psy)
+                       if (!psy) {
+                               mutex_unlock(&battery->ifconn_lock);
                                return -EINVAL;
+                       }
                        ret = power_supply_set_property(psy, POWER_SUPPLY_PROP_CHARGE_OTG_CONTROL, &value);
                        if (ret < 0)
                                pr_err("%s: Fail to execute property\n", __func__);
@@ -1116,6 +1190,7 @@ end_ifconn_handle:
        alarm_cancel(&battery->monitor_alarm);
        wake_lock(&battery->monitor_wake_lock);
        queue_delayed_work(battery->monitor_wqueue, &battery->monitor_work, 0);
+       mutex_unlock(&battery->ifconn_lock);
        return 0;
 }
 #endif
@@ -1238,10 +1313,14 @@ static int get_battery_info(struct s2mu00x_battery_info *battery)
                pr_err("%s: battery status = %d, charger status = %d\n",
                                __func__, battery->status, value.intval);
 #endif
+       psy = power_supply_get_by_name("s2mu106_pmeter");
+       ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_VCHGIN, &value);
 
        /* Get input voltage & current from powermeter */
-       battery->vchg_voltage = s2mu106_powermeter_get_vchg_voltage();
-       battery->vchg_current = s2mu106_powermeter_get_vchg_current();
+       battery->vchg_voltage = value.intval;
+
+       ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_ICHGIN, &value);
+       battery->vchg_current = value.intval;
 
        dev_info(battery->dev,
                        "%s:Vnow(%dmV),Inow(%dmA),Imax(%dmA),Ichg(%dmA),SOC(%d%%),Tbat(%d),SOH(%d%%)"
@@ -1778,6 +1857,7 @@ static int s2mu00x_battery_probe(struct platform_device *pdev)
        battery->dev = &pdev->dev;
 
        mutex_init(&battery->iolock);
+       mutex_init(&battery->ifconn_lock);
 
        wake_lock_init(&battery->monitor_wake_lock, WAKE_LOCK_SUSPEND,
                        "sec-battery-monitor");
@@ -1791,12 +1871,15 @@ static int s2mu00x_battery_probe(struct platform_device *pdev)
        battery->input_current = 0;
        battery->charging_current = 0;
        battery->topoff_current = 0;
+       battery->small_input_flag = 0;
 
        battery->max_input_current = battery->pdata->max_input_current;
        battery->max_charging_current = battery->pdata->max_charging_current;
 #if defined(CONFIG_USE_CCIC)
        battery->pdo_max_input_vol = battery->pdata->pdo_max_input_vol;
        battery->pdo_max_chg_power = battery->pdata->pdo_max_chg_power;
+       battery->pd_input_current = 2000;
+       battery->pd_attach = false;
 #endif
        battery->temp_high = battery->pdata->temp_high;
        battery->temp_high_recovery = battery->pdata->temp_high_recovery;
@@ -1809,6 +1892,8 @@ static int s2mu00x_battery_probe(struct platform_device *pdev)
 
        battery->is_recharging = false;
        battery->cable_type = POWER_SUPPLY_TYPE_BATTERY;
+       battery->pd_attach = false;
+
 #if defined(CONFIG_CHARGER_S2MU106)
        psy = power_supply_get_by_name(battery->pdata->charger_name);
        if (!psy)
@@ -1859,6 +1944,9 @@ static int s2mu00x_battery_probe(struct platform_device *pdev)
        alarm_init(&battery->monitor_alarm, ALARM_BOOTTIME, bat_monitor_alarm);
        battery->monitor_alarm_interval = DEFAULT_ALARM_INTERVAL;
 
+#if defined(CONFIG_USE_CCIC)
+       INIT_DELAYED_WORK(&battery->select_pdo_work, usbpd_select_pdo_work);
+#endif
        /* Register power supply to framework */
        psy_cfg.drv_data = battery;
        psy_cfg.supplied_to = s2mu00x_supplied_to;
@@ -1915,6 +2003,10 @@ static int s2mu00x_battery_probe(struct platform_device *pdev)
                        s2mu00x_ifconn_handle_notification,
                        IFCONN_NOTIFY_BATTERY,
                        IFCONN_NOTIFY_MANAGER);
+       ifconn_notifier_register(&battery->ifconn_nb,
+                       s2mu00x_ifconn_handle_notification,
+                       IFCONN_NOTIFY_BATTERY,
+                       IFCONN_NOTIFY_CCIC);
 #elif defined(CONFIG_MUIC_NOTIFIER)
        pr_info("%s: Register MUIC notifier\n", __func__);
        muic_notifier_register(&battery->batt_nb, s2mu00x_battery_handle_notification,
@@ -1950,6 +2042,7 @@ err_irr:
        wake_lock_destroy(&battery->monitor_wake_lock);
        wake_lock_destroy(&battery->vbus_wake_lock);
        mutex_destroy(&battery->iolock);
+       mutex_destroy(&battery->ifconn_lock);
 err_parse_dt_nomem:
        kfree(battery->pdata);
 err_bat_free:
index 175eedcee6e2a02c9baf35f43211e361a1b57162..79799e4063e6a06c715d87d36792629af2b6f2c9 100755 (executable)
@@ -68,7 +68,7 @@ static void s2mu106_test_read(struct i2c_client *i2c)
 static int s2mu106_charger_otg_control(
                struct s2mu106_charger_data *charger, bool enable)
 {
-       u8 chg_sts2, chg_ctrl0, temp;
+       u8 chg_sts2, chg_ctrl0;
        pr_info("%s: called charger otg control : %s\n", __func__,
                        enable ? "ON" : "OFF");
 
@@ -87,14 +87,12 @@ static int s2mu106_charger_otg_control(
        if (!enable) {
                s2mu106_update_reg(charger->i2c,
                                S2MU106_CHG_CTRL0, CHG_MODE, REG_MODE_MASK);
-               s2mu106_update_reg(charger->i2c, 0xAE, 0x80, 0xF0);
        } else {
                s2mu106_update_reg(charger->i2c,
                                S2MU106_CHG_CTRL3,
                                S2MU106_SET_OTG_OCP_1500mA << SET_OTG_OCP_SHIFT,
                                SET_OTG_OCP_MASK);
-               msleep(30);
-               s2mu106_update_reg(charger->i2c, 0xAE, 0x00, 0xF0);
+//             msleep(30);
                s2mu106_update_reg(charger->i2c,
                                S2MU106_CHG_CTRL0, OTG_BST_MODE, REG_MODE_MASK);
                charger->cable_type = POWER_SUPPLY_TYPE_OTG;
@@ -104,10 +102,8 @@ static int s2mu106_charger_otg_control(
 
        s2mu106_read_reg(charger->i2c, S2MU106_CHG_STATUS2, &chg_sts2);
        s2mu106_read_reg(charger->i2c, S2MU106_CHG_CTRL0, &chg_ctrl0);
-       s2mu106_read_reg(charger->i2c, 0xAE, &temp);
        pr_info("%s S2MU106_CHG_STATUS2: 0x%x\n", __func__, chg_sts2);
        pr_info("%s S2MU106_CHG_CTRL0: 0x%x\n", __func__, chg_ctrl0);
-       pr_info("%s 0xAE: 0x%x\n", __func__, temp);
 
        power_supply_changed(charger->psy_otg);
        return enable;
@@ -119,6 +115,7 @@ static void s2mu106_enable_charger_switch(
 
        if (charger->otg_on) {
                pr_info("[DEBUG] %s: skipped set(%d) : OTG is on\n", __func__, onoff);
+               charger->is_charging = false;
                return;
        }
 
@@ -624,6 +621,12 @@ static int s2mu106_chg_set_property(struct power_supply *psy,
                                charger->is_charging = true;
                                break;
                        }
+
+                       if (buck_state)
+                               s2mu106_enable_charger_switch(charger, charger->is_charging);
+                       else
+                               s2mu106_set_buck(charger, buck_state);
+
                        value.intval = charger->is_charging;
 
                        psy = power_supply_get_by_name(charger->pdata->fuelgauge_name);
@@ -633,10 +636,6 @@ static int s2mu106_chg_set_property(struct power_supply *psy,
                        if (ret < 0)
                                pr_err("%s: Fail to execute property\n", __func__);
 
-                       if (buck_state)
-                               s2mu106_enable_charger_switch(charger, charger->is_charging);
-                       else
-                               s2mu106_set_buck(charger, buck_state);
                } else {
                        pr_info("[DEBUG]%s: SKIP CHARGING CONTROL while OTG(%d)\n",
                                        __func__, value.intval);
index 8fd6ccb163e7b2fb1176a8475fce4fdbc5c06ded..7701e34162490922e3787635a2fcb096866e7129 100755 (executable)
 #include <linux/mfd/samsung/s2mu106.h>
 #include <linux/power/s2mu106_pmeter.h>
 #include <linux/version.h>
+#include <linux/module.h>
+#include <linux/slab.h>
 
+#define EN_IRQ         0
+#define VOLTAGE_9V     8000
+#define VOLTAGE_5V     6000
 
-struct s2mu106_pmeter_data *g_pmeter;
-int s2mu106_powermeter_get_vchg_voltage(void)
+static enum power_supply_property s2mu106_pmeter_props[] = {
+};
+
+static const unsigned char enable_bit_data[PM_TYPE_MAX] =
+{0x80, 0x40, 0x20, 0x01, 0x08, 0x04, 0x02, 0x80,
+0x40, 0x01, 0x10, 0x80};
+
+static int s2mu106_pm_enable(struct s2mu106_pmeter_data *pmeter,
+                                       int mode, enum pm_type type)
 {
-       struct s2mu106_pmeter_data *pmeter;
-       u8 ret;
-       u8 v_12 = 0, v_13 = 0;
-       int chg_voltage = 0;
+       u8 addr1 = S2MU106_PM_REQ_BOX_CO1;
+       u8 addr2 = S2MU106_PM_REQ_BOX_CO2;
+       u8 data1, data2;
+       
+       /* Default PM mode = continuous */
+       if (mode == REQUEST_RESPONSE_MODE) {
+               pr_info ("%s PM mode : Request Response mode (RR)\n", __func__);
+               addr1 = S2MU106_PM_REQ_BOX_RR1;
+               addr2 = S2MU106_PM_REQ_BOX_RR2;
+       }
+
+       s2mu106_read_reg(pmeter->i2c, addr1, &data1);
+       s2mu106_read_reg(pmeter->i2c, addr2, &data2);
+
+       switch (type) {
+       case PM_TYPE_VCHGIN ... PM_TYPE_VGPADC:
+       case PM_TYPE_VCC2:
+               data1 |= enable_bit_data[type];
+               break;
+       case PM_TYPE_ICHGIN:
+       case PM_TYPE_IWCIN:
+       case PM_TYPE_IOTG:
+       case PM_TYPE_ITX:
+               data2 |= enable_bit_data[type];
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       s2mu106_write_reg(pmeter->i2c, addr1, data1);
+       s2mu106_write_reg(pmeter->i2c, addr2, data2);
+
+       pr_info ("%s data1 : 0x%2x, data2 0x%2x\n", __func__, data1, data2);
+       return 0;
+}
 
-       pmeter = g_pmeter;
+static int s2mu106_pm_get_vchgin(struct s2mu106_pmeter_data *pmeter)
+{
+       u8 data1, data2;
+       int charge_voltage = 0;
+
+       s2mu106_read_reg(pmeter->i2c, S2MU106_PM_VAL1_VCHGIN, &data1);
+       s2mu106_read_reg(pmeter->i2c, S2MU106_PM_VAL2_VCHGIN, &data2);
+
+       if (data1 < 0 || data2 < 0)
+               return -EINVAL;
+       
+       charge_voltage = ((data1 << 4) | (data2 >> 4)) * 5;
+       pr_info ("%s, data1 : 0x%2x, data2 : 0x%2x, voltage = %d\n",
+                       __func__, data1, data2, charge_voltage);
+       return charge_voltage;
+}
 
-       s2mu106_read_reg(pmeter->i2c, 0x12, &v_12);
-       s2mu106_read_reg(pmeter->i2c, 0x13, &v_13);
+static int s2mu106_pm_get_vwcin(struct s2mu106_pmeter_data *pmeter)
+{
+       u8 data1, data2;
+       int charge_voltage = 0;
+
+       s2mu106_read_reg(pmeter->i2c, S2MU106_PM_VAL1_VWCIN, &data1);
+       s2mu106_read_reg(pmeter->i2c, S2MU106_PM_VAL2_VWCIN, &data2);
+       
+       if (data1 < 0 || data2 < 0)
+               return -EINVAL;
+
+       charge_voltage = ((data1 << 4) | (data2 >> 4)) * 5;
+       pr_info ("%s, data1 : 0x%2x, data2 : 0x%2x, voltage = %d\n",
+                       __func__, data1, data2, charge_voltage);
+       return charge_voltage;
+}
 
-       pr_info("%s: S2MU106_POWERMETER 0x57: 0x%x 0x12:0x%x 0x13:0x%x\n", __func__, ret, v_12, v_13);
-       chg_voltage = ((v_12 << 4) + (v_13 >> 4)) * 5;  //mV
+static int s2mu106_pm_get_vbyp(struct s2mu106_pmeter_data *pmeter)
+{
+       u8 data1, data2;
+       int charge_voltage = 0;
+
+       s2mu106_read_reg(pmeter->i2c, S2MU106_PM_VAL1_VBYP, &data1);
+       s2mu106_read_reg(pmeter->i2c, S2MU106_PM_VAL2_VBYP, &data2);
+       
+       if (data1 < 0 || data2 < 0)
+               return -EINVAL;
+
+       charge_voltage = ((data1 << 4) | (data2 >> 4)) * 5;
+       pr_info ("%s, data1 : 0x%2x, data2 : 0x%2x, voltage = %d\n",
+                       __func__, data1, data2, charge_voltage);
+       return charge_voltage;
+}
+
+static int s2mu106_pm_get_vsysa(struct s2mu106_pmeter_data *pmeter)
+{
+       u8 data1, data2;
+       int charge_voltage = 0;
+
+       s2mu106_read_reg(pmeter->i2c, S2MU106_PM_VAL1_VSYS, &data1);
+       s2mu106_read_reg(pmeter->i2c, S2MU106_PM_VAL2_VSYS, &data2);
+       
+       if (data1 < 0 || data2 < 0)
+               return -EINVAL;
 
-       pr_info("%s: S2MU106_POWERMETER  chg_voltage: %d mV\n", __func__, chg_voltage);
-       return chg_voltage;
+       charge_voltage = ((data1 << 4) | (data2 >> 4)) * 25;
+       charge_voltage = charge_voltage / 10;
 
+       pr_info ("%s, data1 : 0x%2x, data2 : 0x%2x, voltage = %d\n",
+                       __func__, data1, data2, charge_voltage);
+       return charge_voltage;
 }
 
-int s2mu106_powermeter_get_vchg_current(void)
+static int s2mu106_pm_get_vbata(struct s2mu106_pmeter_data *pmeter)
 {
-       struct s2mu106_pmeter_data *pmeter;
-       u8 v_20 = 0, v_21 = 0;
-       int chg_current = 0;
+       u8 data1, data2;
+       int charge_voltage = 0;
+
+       s2mu106_read_reg(pmeter->i2c, S2MU106_PM_VAL1_VBAT, &data1);
+       s2mu106_read_reg(pmeter->i2c, S2MU106_PM_VAL2_VBAT, &data2);
+       
+       if (data1 < 0 || data2 < 0)
+               return -EINVAL;
+
+       charge_voltage = ((data1 << 4) | (data2 >> 4)) * 25;
+       charge_voltage = charge_voltage / 10;
+
+       pr_info ("%s, data1 : 0x%2x, data2 : 0x%2x, voltage = %d\n",
+                       __func__, data1, data2, charge_voltage);
+       return charge_voltage;
+}
+
+static int s2mu106_pm_get_vgpadc(struct s2mu106_pmeter_data *pmeter)
+{
+       u8 data1, data2;
+       int charge_voltage = 0;
+
+       s2mu106_read_reg(pmeter->i2c, S2MU106_PM_VAL1_VGPADC, &data1);
+       s2mu106_read_reg(pmeter->i2c, S2MU106_PM_VAL2_VGPADC, &data2);
+       
+       if (data1 < 0 || data2 < 0)
+               return -EINVAL;
+
+       charge_voltage = ((data1 << 4) | (data2 >> 4)) * 25;
+       charge_voltage = charge_voltage / 10;
+
+       pr_info ("%s, data1 : 0x%2x, data2 : 0x%2x, voltage = %d\n",
+                       __func__, data1, data2, charge_voltage);
+       return charge_voltage;
+}
+
+static int s2mu106_pm_get_vcc1(struct s2mu106_pmeter_data *pmeter)
+{
+       u8 data1, data2;
+       int charge_voltage = 0;
+
+       s2mu106_read_reg(pmeter->i2c, S2MU106_PM_VAL1_VCC1, &data1);
+       s2mu106_read_reg(pmeter->i2c, S2MU106_PM_VAL2_VCC1, &data2);
+       
+       if (data1 < 0 || data2 < 0)
+               return -EINVAL;
 
-       pmeter = g_pmeter;
+       charge_voltage = ((data1 << 4) | (data2 >> 4)) * 625;
+       charge_voltage = charge_voltage / 1000;
 
-       s2mu106_read_reg(pmeter->i2c, 0x20, &v_20);
-       s2mu106_read_reg(pmeter->i2c, 0x21, &v_21);
+       pr_info ("%s2, data1 : 0x%2x, data2 : 0x%2x, voltage = %d\n",
+                       __func__, data1, data2, charge_voltage);
+       return charge_voltage;
+}
+
+static int s2mu106_pm_get_vcc2(struct s2mu106_pmeter_data *pmeter)
+{
+       u8 data1, data2;
+       int charge_voltage = 0;
+
+       s2mu106_read_reg(pmeter->i2c, S2MU106_PM_VAL1_VCC2, &data1);
+       s2mu106_read_reg(pmeter->i2c, S2MU106_PM_VAL2_VCC2, &data2);
+       
+       if (data1 < 0 || data2 < 0)
+               return -EINVAL;
+
+       charge_voltage = ((data1 << 4) | (data2 >> 4)) * 625;
+       charge_voltage = charge_voltage / 1000;
+
+       pr_info ("%s, data1 : 0x%2x, data2 : 0x%2x, voltage = %d\n",
+                       __func__, data1, data2, charge_voltage);
+       return charge_voltage;
+}
+
+static int s2mu106_pm_get_ichgin(struct s2mu106_pmeter_data *pmeter)
+{
+       u8 data1, data2;
+       int charge_current = 0;
 
-       chg_current = ((v_20 << 4) + (v_21 >> 4));      //mA
+       s2mu106_read_reg(pmeter->i2c, S2MU106_PM_VAL1_ICHGIN, &data1);
+       s2mu106_read_reg(pmeter->i2c, S2MU106_PM_VAL2_ICHGIN, &data2);
+       
+       if (data1 < 0 || data2 < 0)
+               return -EINVAL;
 
-       pr_info("%s: S2MU106_POWERMETER  chg_current: %d mA\n", __func__, chg_current);
-       return chg_current;
+       charge_current = (int)((data1 << 4) | (data2 >> 4));
 
+       pr_info ("%s, data1 : 0x%2x, data2 : 0x%2x, current = %d\n",
+                       __func__, data1, data2, charge_current);
+       return charge_current;
 }
 
+static int s2mu106_pm_get_iwcin(struct s2mu106_pmeter_data *pmeter)
+{
+       u8 data1, data2;
+       int charge_current = 0;
+
+       s2mu106_read_reg(pmeter->i2c, S2MU106_PM_VAL1_IWCIN, &data1);
+       s2mu106_read_reg(pmeter->i2c, S2MU106_PM_VAL2_IWCIN, &data2);
+       
+       if (data1 < 0 || data2 < 0)
+               return -EINVAL;
+
+       charge_current = (int)((data1 << 4) | (data2 >> 4));
+
+       pr_info ("%s, data1 : 0x%2x, data2 : 0x%2x, current = %d\n",
+                       __func__, data1, data2, charge_current);
+       return charge_current;
+}
+
+static int s2mu106_pm_get_iotg(struct s2mu106_pmeter_data *pmeter)
+{
+       u8 data1, data2;
+       int charge_current = 0;
+
+       s2mu106_read_reg(pmeter->i2c, S2MU106_PM_VAL1_IOTG, &data1);
+       s2mu106_read_reg(pmeter->i2c, S2MU106_PM_VAL2_IOTG, &data2);
+       
+       if (data1 < 0 || data2 < 0)
+               return -EINVAL;
+
+       charge_current = (int)((data1 << 4) | (data2 >> 4));
+
+       pr_info ("%s, data1 : 0x%2x, data2 : 0x%2x, current = %d\n",
+                       __func__, data1, data2, charge_current);
+       return charge_current;
+}
+
+static int s2mu106_pm_get_itx(struct s2mu106_pmeter_data *pmeter)
+{
+       u8 data1, data2;
+       int charge_current = 0;
+
+       s2mu106_read_reg(pmeter->i2c, S2MU106_PM_VAL1_ITX, &data1);
+       s2mu106_read_reg(pmeter->i2c, S2MU106_PM_VAL2_ITX, &data2);
+       
+       if (data1 < 0 || data2 < 0)
+               return -EINVAL;
+
+       charge_current = (int)((data1 << 4) | (data2 >> 4));
+
+       pr_info ("%s, data1 : 0x%2x, data2 : 0x%2x, current = %d\n",
+                       __func__, data1, data2, charge_current);
+       return charge_current;
+}
+
+static int s2mu106_pm_get_property(struct power_supply *psy,
+               enum power_supply_property psp,
+               union power_supply_propval *val)
+{
+       struct s2mu106_pmeter_data *pmeter = power_supply_get_drvdata(psy);
+
+       switch (psp) {
+       case POWER_SUPPLY_PROP_VCHGIN:
+               val->intval = s2mu106_pm_get_vchgin(pmeter);
+               break;
+       case POWER_SUPPLY_PROP_VWCIN:
+               val->intval = s2mu106_pm_get_vwcin(pmeter);
+               break;
+       case POWER_SUPPLY_PROP_VBYP:
+               val->intval = s2mu106_pm_get_vbyp(pmeter);
+               break;
+       case POWER_SUPPLY_PROP_VSYS:
+               val->intval = s2mu106_pm_get_vsysa(pmeter);
+               break;
+       case POWER_SUPPLY_PROP_VBAT:
+               val->intval = s2mu106_pm_get_vbata(pmeter);
+               break;
+       case POWER_SUPPLY_PROP_VGPADC:
+               val->intval = s2mu106_pm_get_vgpadc(pmeter);
+               break;
+       case POWER_SUPPLY_PROP_VCC1:
+               val->intval = s2mu106_pm_get_vcc1(pmeter);
+               break;
+       case POWER_SUPPLY_PROP_VCC2:
+               val->intval = s2mu106_pm_get_vcc2(pmeter);
+               break;
+       case POWER_SUPPLY_PROP_ICHGIN:
+               val->intval = s2mu106_pm_get_ichgin(pmeter);
+               break;
+       case POWER_SUPPLY_PROP_IWCIN:
+               val->intval = s2mu106_pm_get_iwcin(pmeter);
+               break;
+       case POWER_SUPPLY_PROP_IOTG:
+               val->intval = s2mu106_pm_get_iotg(pmeter);
+               break;
+       case POWER_SUPPLY_PROP_ITX:
+               val->intval = s2mu106_pm_get_itx(pmeter);
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int s2mu106_pm_set_property(struct power_supply *psy,
+               enum power_supply_property psp,
+               const union power_supply_propval *val)
+{
+       struct s2mu106_pmeter_data *pmeter = power_supply_get_drvdata(psy);
+
+       switch (psp) {
+       case POWER_SUPPLY_PROP_CO_ENABLE:
+               s2mu106_pm_enable(pmeter, CONTINUOUS_MODE, val->intval);
+               break;
+       case POWER_SUPPLY_PROP_RR_ENABLE:
+               s2mu106_pm_enable(pmeter, REQUEST_RESPONSE_MODE, val->intval);
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+#if EN_IRQ
+static irqreturn_t s2mu106_vchgin_isr(int irq, void *data)
+{
+       struct s2mu106_pmeter_data *pmeter = data;
+       int voltage;
+
+       voltage = s2mu106_pm_get_vchgin(pmeter);
+       pr_info("%s voltage : %d", __func__, voltage);
+
+       return IRQ_HANDLED;
+}
+#endif 
 static const struct of_device_id s2mu106_pmeter_match_table[] = {
        { .compatible = "samsung,s2mu106-pmeter",},
        {},
 };
 
-static int s2mu106_pm_enable(struct s2mu106_pmeter_data *pmeter)
+static void s2mu106_powermeter_initial(struct s2mu106_pmeter_data *pmeter)
 {
-       u8 data1;
-
-       s2mu106_read_reg(pmeter->i2c, 0x5F, &data1);
-       data1 |= 0x80;
-       s2mu106_write_reg(pmeter->i2c, 0x5F, data1);
-       return 0;
+       s2mu106_pm_enable(pmeter, CONTINUOUS_MODE, PM_TYPE_VCHGIN);
+       s2mu106_pm_enable(pmeter, CONTINUOUS_MODE, PM_TYPE_VCC1);
+       s2mu106_pm_enable(pmeter, CONTINUOUS_MODE, PM_TYPE_VCC2);
 }
 
 static int s2mu106_pmeter_probe(struct platform_device *pdev)
 {
        struct s2mu106_dev *s2mu106 = dev_get_drvdata(pdev->dev.parent);
        struct s2mu106_pmeter_data *pmeter;
+       struct power_supply_config psy_cfg = {};
        int ret = 0;
 
        pr_info("%s:[BATT] S2MU106 Power meter driver probe\n", __func__);
-       pmeter = kzalloc(sizeof(*pmeter), GFP_KERNEL);
+       pmeter = kzalloc(sizeof(struct s2mu106_pmeter_data), GFP_KERNEL);
        if (!pmeter)
                return -ENOMEM;
 
@@ -92,10 +399,40 @@ static int s2mu106_pmeter_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, pmeter);
 
-       g_pmeter = pmeter;
+       pmeter->psy_pm_desc.name           = "s2mu106_pmeter"; //pmeter->pdata->powermeter_name;
+       pmeter->psy_pm_desc.type           = POWER_SUPPLY_TYPE_UNKNOWN;
+       pmeter->psy_pm_desc.get_property   = s2mu106_pm_get_property;
+       pmeter->psy_pm_desc.set_property   = s2mu106_pm_set_property;
+       pmeter->psy_pm_desc.properties     = s2mu106_pmeter_props;
+       pmeter->psy_pm_desc.num_properties = ARRAY_SIZE(s2mu106_pmeter_props);
+
+       psy_cfg.drv_data = pmeter;
+
+       pmeter->psy_pm = power_supply_register(&pdev->dev, &pmeter->psy_pm_desc, &psy_cfg);
+       if (IS_ERR(pmeter->psy_pm)) {
+               pr_err("%s: Failed to Register psy_chg\n", __func__);
+               ret = PTR_ERR(pmeter->psy_pm);
+               goto err_power_supply_register;
+       }
+
+#if EN_IRQ
+       pmeter->irq_vchgin = s2mu106->pdata->irq_base + S2MU106_PM_IRQ1_VCHGINUP;
+       ret = request_threaded_irq(pmeter->irq_vchgin, NULL,
+                       s2mu106_vchgin_isr, 0, "vchgin-irq", pmeter);
+       if (ret < 0) {
+               pr_err("%s: Fail to request SYS in IRQ: %d: %d\n",
+                               __func__, pmeter->irq_vchgin, ret);
+       }
+#endif
+       s2mu106_powermeter_initial(pmeter);
+
        pr_info("%s:[BATT] S2MU106 pmeter driver loaded OK\n", __func__);
 
-       s2mu106_pm_enable(pmeter);
+       return ret;
+
+err_power_supply_register:
+       mutex_destroy(&pmeter->pmeter_mutex);
+       kfree(pmeter);
 
        return ret;
 }
@@ -147,7 +484,7 @@ static struct platform_driver s2mu106_pmeter_driver = {
 static int __init s2mu106_pmeter_init(void)
 {
        int ret = 0;
-
+       pr_info("%s\n", __func__);
        ret = platform_driver_register(&s2mu106_pmeter_driver);
 
        return ret;
index 8131dbc6290e134f285728fa9951c183a09cf892..f67051328dcb084fc88816186991aa6e4eb5377f 100644 (file)
@@ -548,7 +548,7 @@ static int vbus_handle_notification(struct notifier_block *nb,
 
 static int otg_accessory_power(bool enable)
 {
-#if !defined(CONFIG_CCIC_S2MM005)
+#if 0
        u8 on = (u8)!!enable;
        union power_supply_propval val;
 
index 13d1b37d4df2d74a68622069a2a6fb7d8a69d848..e44c5cb92b923551101788a7decc88d40e107a2f 100644 (file)
 /*****************************************/
 /***********DEFINITION REGISTER***********/
 /*****************************************/
-#define S2MU106_RESET_REG_00           (0x00)
+#define S2MU106_RESET_REG_00        (0x00)
 
 /* reg 0x00 VBUS WAKEUP CONTROL */
 #define S2MU106_REG_VBUS_WAKEUP_DIS_SHIFT (1)
 #define S2MU106_REG_VBUS_WAKEUP_DIS \
-                       (0x1 << S2MU106_REG_VBUS_WAKEUP_DIS_SHIFT) /* 0x02 */
+               (0x1 << S2MU106_REG_VBUS_WAKEUP_DIS_SHIFT) /* 0x02 */
 
 /* reg 0x01 LPM MODE ENABLE */
 #define S2MU106_REG_LP_LDO_D_SHIFT (0)
 #define S2MU106_REG_IFG_SHIFT (4)
 #define S2MU106_REG_IFG_MASK (0xf << S2MU106_REG_IFG_SHIFT) /* 0xf0 */
 
+/* reg 0x04 */
+#define S2MU106_REG_OTP_CC_PUB_SHIFT    (7)
+#define S2MU106_REG_CC_PU_LPM_CTRL_DIS_SHIFT    (2)
+#define S2MU106_REG_CC2_RS_SW_ON_SHIFT    (1)
+#define S2MU106_REG_CC1_RS_SW_ON_SHIFT    (0)
+
+#define S2MU106_REG_OTP_CC_PUB_MASK \
+               (0x1 << S2MU106_REG_OTP_CC_PUB_SHIFT)
+#define S2MU106_REG_CC_PU_LPM_CTRL_DIS_MASK \
+               (0x1 << S2MU106_REG_CC_PU_LPM_CTRL_DIS_SHIFT)
+#define S2MU106_REG_CC2_RS_SW_ON_MASK    (0x1 << S2MU106_REG_CC2_RS_SW_ON_SHIFT)
+#define S2MU106_REG_CC1_RS_SW_ON_MASK    (0x1 << S2MU106_REG_CC1_RS_SW_ON_SHIFT)
+
+/* reg 0x08 */
+#define S2MU106_REG_LPMPUI_SEL_SHIFT        (2)
+#define S2MU106_REG_LPMPUI_SEL_MASK            (0x3 << S2MU106_REG_LPMPUI_SEL_SHIFT)
+#define S2MU106_REG_LPMPUI_SEL_250NA_MASK    (0x0 << S2MU106_REG_LPMPUI_SEL_SHIFT)
+#define S2MU106_REG_LPMPUI_SEL_500NA_MASK    (0x1 << S2MU106_REG_LPMPUI_SEL_SHIFT)
+#define S2MU106_REG_LPMPUI_SEL_1UA_MASK        (0x2 << S2MU106_REG_LPMPUI_SEL_SHIFT)
+#define S2MU106_REG_LPMPUI_SEL_2UA_MASK        (0x3 << S2MU106_REG_LPMPUI_SEL_SHIFT)
+
+/* reg 0x0A */
+#define S2MU106_REG_OVP_ON_SHIFT        (7)
+#define S2MU106_REG_OVP_ON            (0x1 << S2MU106_REG_OVP_ON_SHIFT)
+
 /* reg 0x18 */
-#define S2MU106_REG_PLUG_CTRL_MODE_SHIFT       (0)
-#define S2MU106_REG_PLUG_CTRL_RP_SEL_SHIFT     (4)
-#define S2MU106_REG_PLUG_CTRL_DETECT_BAT_DISABLE_SHIFT (6)
-#define S2MU106_REG_PLUG_CTRL_DETECT_OCP_DISABLE_SHIFT (7)
+#define S2MU106_REG_PLUG_CTRL_MODE_SHIFT    (0)
+#define S2MU106_REG_PLUG_CTRL_RP_SEL_SHIFT    (4)
+#define S2MU106_REG_PLUG_CTRL_DETECT_BAT_DISABLE_SHIFT    (6)
+#define S2MU106_REG_PLUG_CTRL_DETECT_OCP_DISABLE_SHIFT    (7)
 #define S2MU106_REG_PLUG_CTRL_DFP \
                (0x1 << S2MU106_REG_PLUG_CTRL_MODE_SHIFT) /* 0x01 */
 #define S2MU106_REG_PLUG_CTRL_UFP \
                (0x1 << S2MU106_REG_PLUG_CTRL_RP_SEL_SHIFT) /* 0x10 */
 #define S2MU106_REG_PLUG_CTRL_RP180 \
                (0x2 << S2MU106_REG_PLUG_CTRL_RP_SEL_SHIFT) /* 0x20 */
-#define S2MU106_REG_PLUG_CTRL_MODE_MASK        \
+#define S2MU106_REG_PLUG_CTRL_MODE_MASK    \
                (0x3 << S2MU106_REG_PLUG_CTRL_MODE_SHIFT) /* 0x03 */
 #define S2MU106_REG_PLUG_CTRL_RP_SEL_MASK \
                (0x3 << S2MU106_REG_PLUG_CTRL_RP_SEL_SHIFT)/* 0x30 */
                (0x1 << S2MU106_REG_PLUG_CTRL_DETECT_OCP_DISABLE_SHIFT)/* 0x80 */
 
 /* reg 0x19 */
-#define S2MU106_REG_MSG_DATA_ROLE_SHIFT                (5)
-#define S2MU106_REG_MSG_POWER_ROLE_SHIFT       (6)
+#define S2MU106_REG_MSG_DATA_ROLE_SHIFT        (5)
+#define S2MU106_REG_MSG_POWER_ROLE_SHIFT    (6)
 #define S2MU106_REG_MSG_DATA_ROLE_UFP \
                (0x0 << S2MU106_REG_MSG_DATA_ROLE_SHIFT) /* 0x00 */
 #define S2MU106_REG_MSG_DATA_ROLE_DFP \
                (0x1 << S2MU106_REG_MSG_POWER_ROLE_SHIFT) /* 0x40 */
 
 #define S2MU106_REG_RD_OR_VBUS_MUX_SEL_SHIFT    (4)
-#define S2MU106_REG_RD_OR_VBUS_MUX_SEL \
+#define S2MU106_REG_RD_OR_VBUS_MUX_SEL    \
                (0x1 << S2MU106_REG_RD_OR_VBUS_MUX_SEL_SHIFT)
 
-/* reg 0x1B */
-#define S2MU106_REG_DET_RD_OR_VBUS_SHIFT       (4)
-#define S2MU106_REG_DET_RD_OR_VBUS \
-               (0x1 << S2MU106_REG_DET_RD_OR_VBUS_SHIFT) /* 0x10 */
-
-/* reg 0x1E */
-#define S2MU106_REG_USB31_EN_SHIFT             (6)
-#define S2MU106_REG_USB31_EN \
-               (0x1 << S2MU106_REG_USB31_EN_SHIFT) /* 0x40 */
+/* reg 0x22 */
+#define S2MU106_REG_PLUG_CTRL_SET_MON_RD     (0x1 << 3)
 
 /* reg 0x26 */
 #define S2MU106_REG_PLUG_CTRL_CC_HOLD_BIT     (0x1)
+#define S2MU106_REG_PLUG_CTRL_SUPPORT_ACC     (0x1 << 7)
 
 /* reg 0x27 */
-#define S2MU106_REG_PLUG_CTRL_FSM_MANUAL_EN_SHIFT      (2)
-#define S2MU106_REG_PLUG_CTRL_RpRd_PLUG_SEL_SHIFT      (3)
-#define S2MU106_REG_PLUG_CTRL_VCONN_MANUAL_EN_SHIFT    (4)
-#define S2MU106_REG_PLUG_CTRL_RpRd_CC1_VCONN_SHIFT     (5)
-#define S2MU106_REG_PLUG_CTRL_RpRd_CC2_VCONN_SHIFT     (6)
-#define S2MU106_REG_PLUG_CTRL_RpRd_MANUAL_EN_SHIFT     (7)
+#define S2MU106_REG_PLUG_CTRL_FSM_MANUAL_EN_SHIFT    (2)
+#define S2MU106_REG_PLUG_CTRL_RpRd_PLUG_SEL_SHIFT    (3)
+#define S2MU106_REG_PLUG_CTRL_VCONN_MANUAL_EN_SHIFT    (4)
+#define S2MU106_REG_PLUG_CTRL_RpRd_CC1_VCONN_SHIFT    (5)
+#define S2MU106_REG_PLUG_CTRL_RpRd_CC2_VCONN_SHIFT    (6)
+#define S2MU106_REG_PLUG_CTRL_RpRd_MANUAL_EN_SHIFT    (7)
 
 #define S2MU106_REG_PLUG_CTRL_FSM_MANUAL_EN \
                (0x1 << S2MU106_REG_PLUG_CTRL_FSM_MANUAL_EN_SHIFT) /* 0x04 */
                0x1 << S2MU106_REG_PLUG_CTRL_RpRd_CC2_VCONN_SHIFT) /* 0x70 */
 
 /* reg 0x28 */
-#define S2MU106_REG_PLUG_CTRL_CC_MANUAL_EN_SHIFT       (4)
-#define S2MU106_REG_PLUG_CTRL_CC1_MANUAL_EN_SHIFT      (5)
-#define S2MU106_REG_PLUG_CTRL_CC2_MANUAL_EN_SHIFT      (6)
-
-#define S2MU106_REG_PLUG_CTRL_FSM_MANUAL_INPUT_MASK    (0xf)
-#define S2MU106_REG_PLUG_CTRL_FSM_ATTACHED_SNK         (2)
-#define S2MU106_REG_PLUG_CTRL_FSM_ATTACHED_SRC         (6)
-#define S2MU106_REG_PLUG_CTRL_FSM_ATTACH_WAIT_SRC      (5)
+#define S2MU106_REG_PLUG_CTRL_CC_MANUAL_EN_SHIFT    (4)
+#define S2MU106_REG_PLUG_CTRL_CC1_MANUAL_EN_SHIFT    (5)
+#define S2MU106_REG_PLUG_CTRL_CC2_MANUAL_EN_SHIFT    (6)
+
+#define S2MU106_REG_PLUG_CTRL_FSM_MANUAL_INPUT_MASK    (0xf)
+#define S2MU106_REG_PLUG_CTRL_FSM_ATTACHED_SNK        (2)
+#define S2MU106_REG_PLUG_CTRL_FSM_ATTACHED_SRC        (6)
 #define S2MU106_REG_PLUG_CTRL_CC_MANUAL_EN \
                (0x1 << S2MU106_REG_PLUG_CTRL_CC_MANUAL_EN_SHIFT) /* 0x10 */
 #define S2MU106_REG_PLUG_CTRL_CC1_MANUAL_ON \
                0x1 << S2MU106_REG_PLUG_CTRL_CC2_MANUAL_EN_SHIFT) /* 0x70 */
 
 /* reg 0x2E */
-#define S2MU106_REG_PLUG_CTRL_VDM_DISABLE_SHIFT                        (1)
-#define S2MU106_REG_PLUG_CTRL_UFP_ATTACH_OPT_SHIFT             (5)
-#define S2MU106_REG_PLUG_CTRL_ECO_SRC_CAP_RDY_SHIFT            (6)
-#define S2MU106_REG_PLUG_CTRL_UFP_ATTACH_OPT \
-               (0x1 << S2MU106_REG_PLUG_CTRL_UFP_ATTACH_OPT_SHIFT) /* 0x20 */
-
+#define S2MU106_REG_PLUG_CTRL_SSM_DISABLE_SHIFT        (0)
+#define S2MU106_REG_PLUG_CTRL_VDM_DISABLE_SHIFT        (1)
+#define S2MU106_REG_PLUG_CTRL_ATTACH_OPT_EN_SHIFT         (5)
+#define S2MU106_REG_PLUG_CTRL_ECO_SRC_CAP_RDY_SHIFT    (6)
+#define S2MU106_REG_PLUG_CTRL_SSM_DISABLE \
+               (0x1 << S2MU106_REG_PLUG_CTRL_SSM_DISABLE_SHIFT) /* 0x01 */
 #define S2MU106_REG_PLUG_CTRL_VDM_DISABLE \
                (0x1 << S2MU106_REG_PLUG_CTRL_VDM_DISABLE_SHIFT) /* 0x02 */
 #define S2MU106_REG_PLUG_CTRL_ECO_SRC_CAP_RDY \
-               (0x1 << S2MU106_REG_PLUG_CTRL_ECO_SRC_CAP_RDY_SHIFT) /* 0x80 */
+               (0x1 << S2MU106_REG_PLUG_CTRL_ECO_SRC_CAP_RDY_SHIFT) /* 0x40 */
+#define S2MU106_REG_PLUG_CTRL_ATTACH_OPT_EN \
+               (0x1 << S2MU106_REG_PLUG_CTRL_ATTACH_OPT_EN_SHIFT) /* 0x20 */
 
 /* reg 0x90 (For S2MU106_REG_MSG_SEND_CON) */
-#define S2MU106_REG_MSG_SEND_CON_SEND_MSG_EN_SHIFT     (0)
-#define S2MU106_REG_MSG_SEND_CON_OP_MODE_SHIFT         (1)
-#define S2MU106_REG_MSG_SEND_CON_SOP_SHIFT             (2)
+#define S2MU106_REG_MSG_SEND_CON_SEND_MSG_EN_SHIFT    (0)
+#define S2MU106_REG_MSG_SEND_CON_OP_MODE_SHIFT        (1)
+#define S2MU106_REG_MSG_SEND_CON_SOP_SHIFT            (2)
+#define S2MU106_REG_MSG_SEND_CON_HARD_EN_SHIFT        (6)
 
 #define S2MU106_REG_MSG_SEND_CON_SEND_MSG_EN \
                (0x1 << S2MU106_REG_MSG_SEND_CON_SEND_MSG_EN_SHIFT) /* 0x01 */
                (0x5 << S2MU106_REG_MSG_SEND_CON_SOP_SHIFT) /* 0x14 */
 #define S2MU106_REG_MSG_SEND_CON_SOP_CableRST \
                (0x6 << S2MU106_REG_MSG_SEND_CON_SOP_SHIFT) /* 0x18 */
+#define S2MU106_REG_MSG_SEND_CON_HARD_EN \
+               (0x1 << S2MU106_REG_MSG_SEND_CON_HARD_EN_SHIFT) /* 0x40 */
 
 /* reg 0xB2 */
-#define S2MU106_PDIC_RID_SHIFT         (5)
-#define S2MU106_PDIC_RID_MASK          (0x7 << S2MU106_PDIC_RID_SHIFT) /* 0xE0 */
+#define S2MU106_PDIC_RID_SHIFT        (5)
+#define S2MU106_PDIC_RID_MASK        (0x7 << S2MU106_PDIC_RID_SHIFT) /* 0xE0 */
 
 /* reg 0xB3 */
-#define S2MU106_REG_CTRL_MON_CC1_SHIFT         (0)
-#define S2MU106_REG_CTRL_MON_CC2_SHIFT         (3)
+#define S2MU106_REG_CTRL_MON_CC1_SHIFT        (0)
+#define S2MU106_REG_CTRL_MON_CC2_SHIFT        (3)
 #define S2MU106_REG_CTRL_MON_CC1_MASK \
                (0x7 << S2MU106_REG_CTRL_MON_CC1_SHIFT) /* 0x07 */
 #define S2MU106_REG_CTRL_MON_CC2_MASK \
                (0x7 << S2MU106_REG_CTRL_MON_CC2_SHIFT) /* 0x38 */
 
 /* reg 0xB4 */
-#define S2MU106_PDIC_PLUG_ATTACH_DONE_SHIFT    (1)
-#define S2MU106_PDIC_SINK_SEL_MONITOR_SHIFT    (2)
-#define S2MU106_PDIC_SOURCE_SEL_MONITOR_SHIFT  (3)
+#define S2MU106_PDIC_PLUG_ATTACH_DONE_SHIFT    (1)
+#define S2MU106_PDIC_SINK_SEL_MONITOR_SHIFT    (2)
+#define S2MU106_PDIC_SOURCE_SEL_MONITOR_SHIFT    (3)
 
 #define S2MU106_PDIC_SINK (1 << S2MU106_PDIC_SINK_SEL_MONITOR_SHIFT \
                | 1 << S2MU106_PDIC_PLUG_ATTACH_DONE_SHIFT) /* 0x06 */
 #define S2MU106_PR_MASK (S2MU106_PDIC_SINK | S2MU106_PDIC_SOURCE) /* 0x0E */
 
 /* reg 0xF7 */
-#define S2MU106_REG_ETC_SOFT_RESET_EN_SHIFT    (1)
+#define S2MU106_REG_ETC_SOFT_RESET_EN_SHIFT    (1)
 #define S2MU106_REG_ETC_SOFT_RESET_EN \
                (0x1 << S2MU106_REG_ETC_SOFT_RESET_EN_SHIFT) /* 0x02 */
 #define S2MU106_REG_ETC_SOFT_RESET_DIS \
                (0x0 << S2MU106_REG_ETC_SOFT_RESET_EN_SHIFT) /* 0x00 */
 
 /* reg 0xF8 */
-#define S2MU106_REG_ID_MONITOR_MSG_ID_MASK     (0x07)
+#define S2MU106_REG_ID_MONITOR_MSG_ID_MASK    (0x07)
 
 
 /*****************************************/
 #define S2MU106_REG_INT_STATUS5_HARD_RESET     (1<<2)
 
 /* interrupt for checking message */
-#define ENABLED_INT_0  (S2MU106_REG_INT_STATUS0_MSG_ACCEPT |\
-                       S2MU106_REG_INT_STATUS0_VDM_DISCOVER_ID |\
-                       S2MU106_REG_INT_STATUS0_VDM_DISCOVER_SVID |\
-                       S2MU106_REG_INT_STATUS0_VDM_DISCOVER_MODE)
-#define ENABLED_INT_1  (S2MU106_REG_INT_STATUS1_MSG_DR_SWAP |\
+#define ENABLED_INT_0    (S2MU106_REG_INT_STATUS0_MSG_ACCEPT |\
+                                               S2MU106_REG_INT_STATUS0_VDM_DISCOVER_ID |\
+                                               S2MU106_REG_INT_STATUS0_VDM_DISCOVER_SVID |\
+                                               S2MU106_REG_INT_STATUS0_VDM_DISCOVER_MODE |\
+                                               S2MU106_REG_INT_STATUS0_VDM_ENTER |\
+                                               S2MU106_REG_INT_STATUS0_MSG_GOODCRC)
+#define ENABLED_INT_1    (S2MU106_REG_INT_STATUS1_MSG_DR_SWAP |\
                        S2MU106_REG_INT_STATUS1_MSG_PR_SWAP |\
                        S2MU106_REG_INT_STATUS1_MSG_GETSRCCAP |\
                        S2MU106_REG_INT_STATUS1_MSG_GETSNKCAP |\
                        S2MU106_REG_INT_STATUS1_MSG_REJECT |\
-                       S2MU106_REG_INT_STATUS1_MSG_PSRDY)
-#define ENABLED_INT_2  (S2MU106_REG_INT_STATUS2_MSG_SRC_CAP |\
+                       S2MU106_REG_INT_STATUS1_MSG_PSRDY |\
+                       S2MU106_REG_INT_STATUS1_MSG_GOTOMIN)
+#define ENABLED_INT_2    (S2MU106_REG_INT_STATUS2_MSG_SRC_CAP |\
                        S2MU106_REG_INT_STATUS2_MSG_SNK_CAP |\
                        S2MU106_REG_INT_STATUS2_MSG_REQUEST |\
                        S2MU106_REG_INT_STATUS2_MSG_SOFTRESET |\
-                       S2MU106_REG_INT_STATUS2_MSG_VCONN_SWAP)
+                       S2MU106_REG_INT_STATUS2_MSG_VCONN_SWAP |\
+                       S2MU106_REG_INT_STATUS2_MSG_WAIT)
 #define ENABLED_INT_2_WAKEUP    (S2MU106_REG_INT_STATUS2_MSG_SRC_CAP |\
                        S2MU106_REG_INT_STATUS2_MSG_SNK_CAP |\
                        S2MU106_REG_INT_STATUS2_MSG_REQUEST |\
                        S2MU106_REG_INT_STATUS2_MSG_SOFTRESET |\
                        S2MU106_REG_INT_STATUS2_MSG_VCONN_SWAP |\
-                       S2MU106_REG_INT_STATUS2_WAKEUP)
-#define ENABLED_INT_3  S2MU106_REG_INT_STATUS3_UNS_CMD_DATA
-#define ENABLED_INT_4  (S2MU106_REG_INT_STATUS4_USB_DETACH |\
+                       S2MU106_REG_INT_STATUS2_WAKEUP |\
+                       S2MU106_REG_INT_STATUS2_MSG_WAIT)
+#define ENABLED_INT_3    S2MU106_REG_INT_STATUS3_UNS_CMD_DATA
+#define ENABLED_INT_4    (S2MU106_REG_INT_STATUS4_USB_DETACH |\
                                S2MU106_REG_INT_STATUS4_PLUG_IRQ |\
-                               S2MU106_REG_INT_STATUS4_MSG_PASS)
-#define ENABLED_INT_5  (S2MU106_REG_INT_STATUS5_HARD_RESET)
+                               S2MU106_REG_INT_STATUS4_MSG_PASS |\
+                               S2MU106_REG_INT_STATUS4_MSG_ERROR)
+#define ENABLED_INT_5    (S2MU106_REG_INT_STATUS5_HARD_RESET)
 
 /* S2MU106 I2C registers */
 enum s2mu106_usbpd_reg {
-       S2MU106_REG_PD_TRIM         = 0x00,
-       S2MU106_REG_PD_CTRL                 = 0x01,
-       S2MU106_REG_PD_CTRL_2               = 0x02,
-       S2MU106_REG_ANALOG_OTP_04           = 0x04,
-       S2MU106_REG_ANALOG_OTP_08           = 0x08,
-       S2MU106_REG_ANALOG_OTP_0A       = 0x0A,
-       S2MU106_REG_PHY_CTRL_IFG            = 0x13,
-       S2MU106_REG_PLUG_CTRL_PORT          = 0x18,
-       S2MU106_REG_PLUG_CTRL_MSG           = 0x19,
-       S2MU106_REG_PLUG_CTRL_VBUS_MUX      = 0x1B,
-       S2MU106_REG_PLUG_CTRL_SET_RD_2      = 0x1C,
-       S2MU106_REG_PLUG_CTRL_SET_RP_2      = 0x1D,
-       S2MU106_REG_PLUG_CTRL_SET_RD        = 0x1E,
-       S2MU106_REG_PLUG_CTRL_SET_RP        = 0x1F,
-       S2MU106_REG_PLUG_CTRL_CC_HOLD       = 0x26,
-       S2MU106_REG_PLUG_CTRL_RpRd          = 0x27,
-       S2MU106_REG_PLUG_CTRL_CC12          = 0x28,
-       S2MU106_REG_PLUG_CTRL               = 0x2E,
-       S2MU106_REG_CTRL                    = 0x2F,
-
-       S2MU106_REG_INT_MASK0               = 0x3E,
-       S2MU106_REG_INT_MASK1               = 0x3F,
-       S2MU106_REG_INT_MASK2               = 0x40,
-       S2MU106_REG_INT_MASK3               = 0x41,
-       S2MU106_REG_INT_MASK4               = 0x42,
-       S2MU106_REG_INT_STATUS0             = 0xE0,
-       S2MU106_REG_INT_STATUS1             = 0xE1,
-       S2MU106_REG_INT_STATUS2             = 0xE2,
-       S2MU106_REG_INT_STATUS3             = 0xE3,
-       S2MU106_REG_INT_STATUS4             = 0xE4,
-       S2MU106_REG_ADC_STATUS              = 0xB2,
-       S2MU106_REG_PLUG_MON1               = 0xB3,
-       S2MU106_REG_PLUG_MON2               = 0xB4,
-       S2MU106_REG_PLUG_FSM_MON            = 0xB7,
-
-       S2MU106_REG_MSG_SEND_CON            = 0x90,
-       S2MU106_REG_MSG_TX_HEADER_L            = 0x91,
-       S2MU106_REG_MSG_TX_HEADER_H            = 0x92,
-       S2MU106_REG_MSG_TX_OBJECT0_0_L         = 0x93,
-       S2MU106_REG_MSG_TX_OBJECT0_0_H         = 0x94,
-       S2MU106_REG_MSG_TX_OBJECT0_1_L         = 0x95,
-       S2MU106_REG_MSG_TX_OBJECT0_1_H         = 0x96,
-       S2MU106_REG_MSG_TX_OBJECT1_0_L         = 0x97,
-       S2MU106_REG_MSG_TX_OBJECT1_0_H         = 0x98,
-       S2MU106_REG_MSG_TX_OBJECT1_1_L         = 0x99,
-       S2MU106_REG_MSG_TX_OBJECT1_1_H         = 0x9A,
-       S2MU106_REG_MSG_TX_OBJECT2_0_L         = 0x9B,
-       S2MU106_REG_MSG_TX_OBJECT2_0_H         = 0x9C,
-       S2MU106_REG_MSG_TX_OBJECT2_1_L         = 0x9D,
-       S2MU106_REG_MSG_TX_OBJECT2_1_H         = 0x9E,
-       S2MU106_REG_MSG_TX_OBJECT3_0_L         = 0x9F,
-       S2MU106_REG_MSG_TX_OBJECT3_0_H         = 0xA0,
-       S2MU106_REG_MSG_TX_OBJECT3_1_L         = 0xA1,
-       S2MU106_REG_MSG_TX_OBJECT3_1_H         = 0xA2,
-       S2MU106_REG_MSG_TX_OBJECT4_0_L         = 0xA3,
-       S2MU106_REG_MSG_TX_OBJECT4_0_H         = 0xA4,
-       S2MU106_REG_MSG_TX_OBJECT4_1_L         = 0xA5,
-       S2MU106_REG_MSG_TX_OBJECT4_1_H         = 0xA6,
-       S2MU106_REG_MSG_TX_OBJECT5_0_L         = 0xA7,
-       S2MU106_REG_MSG_TX_OBJECT5_0_H         = 0xA8,
-       S2MU106_REG_MSG_TX_OBJECT5_1_L         = 0xA9,
-       S2MU106_REG_MSG_TX_OBJECT5_1_H         = 0xAA,
-       S2MU106_REG_MSG_TX_OBJECT6_0_L         = 0xAB,
-       S2MU106_REG_MSG_TX_OBJECT6_0_H         = 0xAC,
-       S2MU106_REG_MSG_TX_OBJECT6_1_L         = 0xAD,
-       S2MU106_REG_MSG_TX_OBJECT6_1_H         = 0xAE,
-
-       S2MU106_REG_MSG_RX_HEADER_L            = 0xC1,
-       S2MU106_REG_MSG_RX_HEADER_H            = 0xC2,
-       S2MU106_REG_MSG_RX_OBJECT0_0_L         = 0xC3,
-       S2MU106_REG_MSG_RX_OBJECT0_0_H         = 0xC4,
-       S2MU106_REG_MSG_RX_OBJECT0_1_L         = 0xC5,
-       S2MU106_REG_MSG_RX_OBJECT0_1_H         = 0xC6,
-       S2MU106_REG_MSG_RX_OBJECT1_0_L         = 0xC7,
-       S2MU106_REG_MSG_RX_OBJECT1_0_H         = 0xC8,
-       S2MU106_REG_MSG_RX_OBJECT1_1_L         = 0xC9,
-       S2MU106_REG_MSG_RX_OBJECT1_1_H         = 0xCA,
-       S2MU106_REG_MSG_RX_OBJECT2_0_L         = 0xCB,
-       S2MU106_REG_MSG_RX_OBJECT2_0_H         = 0xCC,
-       S2MU106_REG_MSG_RX_OBJECT2_1_L         = 0xCD,
-       S2MU106_REG_MSG_RX_OBJECT2_1_H         = 0xCE,
-       S2MU106_REG_MSG_RX_OBJECT3_0_L         = 0xCF,
-       S2MU106_REG_MSG_RX_OBJECT3_0_H         = 0xD0,
-       S2MU106_REG_MSG_RX_OBJECT3_1_L         = 0xD1,
-       S2MU106_REG_MSG_RX_OBJECT3_1_H         = 0xD2,
-       S2MU106_REG_MSG_RX_OBJECT4_0_L         = 0xD3,
-       S2MU106_REG_MSG_RX_OBJECT4_0_H         = 0xD4,
-       S2MU106_REG_MSG_RX_OBJECT4_1_L         = 0xD5,
-       S2MU106_REG_MSG_RX_OBJECT4_1_H         = 0xD6,
-       S2MU106_REG_MSG_RX_OBJECT5_0_L         = 0xD7,
-       S2MU106_REG_MSG_RX_OBJECT5_0_H         = 0xD8,
-       S2MU106_REG_MSG_RX_OBJECT5_1_L         = 0xD9,
-       S2MU106_REG_MSG_RX_OBJECT5_1_H         = 0xDA,
-       S2MU106_REG_MSG_RX_OBJECT6_0_L         = 0xDB,
-       S2MU106_REG_MSG_RX_OBJECT6_0_H         = 0xDC,
-       S2MU106_REG_MSG_RX_OBJECT6_1_L         = 0xDD,
-       S2MU106_REG_MSG_RX_OBJECT6_1_H         = 0xDE,
-
-       S2MU106_REG_ETC                     = 0xF7,
-       S2MU106_REG_ID_MONITOR              = 0xF8
+    S2MU106_REG_PD_TRIM            = 0x00,
+    S2MU106_REG_PD_CTRL            = 0x01,
+    S2MU106_REG_PD_CTRL_2          = 0x02,
+    S2MU106_REG_ANALOG_OTP_04      = 0x04,
+    S2MU106_REG_ANALOG_OTP_08      = 0x08,
+    S2MU106_REG_ANALOG_OTP_0A      = 0x0A,
+    S2MU106_REG_PHY_CTRL_00        = 0x10,
+    S2MU106_REG_PHY_CTRL_IFG       = 0x13,
+    S2MU106_REG_BMC_CTRL              = 0x14,
+    S2MU106_REG_PLUG_CTRL_PORT     = 0x18,
+    S2MU106_REG_PLUG_CTRL_MSG      = 0x19,
+    S2MU106_REG_PLUG_CTRL_VBUS_MUX = 0x1B,
+    S2MU106_REG_PLUG_CTRL_SET_RD_2 = 0x1C,
+    S2MU106_REG_PLUG_CTRL_SET_RP_2 = 0x1D,
+    S2MU106_REG_PLUG_CTRL_SET_RD   = 0x1E,
+    S2MU106_REG_PLUG_CTRL_SET_RP   = 0x1F,
+    S2MU106_REG_PLUG_CTRL_CC_TIMER1 = 0x20,
+    S2MU106_REG_PLUG_CTRL_CC_TIMER2 = 0x21,
+    S2MU106_REG_PLUG_CTRL_SET_MON  = 0x22,
+    S2MU106_REG_PLUG_CTRL_CC_HOLD  = 0x26,
+    S2MU106_REG_PLUG_CTRL_RpRd     = 0x27,
+    S2MU106_REG_PLUG_CTRL_CC12     = 0x28,
+    S2MU106_REG_PLUG_CTRL          = 0x2E,
+    S2MU106_REG_CTRL               = 0x2F,
+
+    S2MU106_REG_INT_MASK0          = 0x3E,
+    S2MU106_REG_INT_MASK1          = 0x3F,
+    S2MU106_REG_INT_MASK2          = 0x40,
+    S2MU106_REG_INT_MASK3          = 0x41,
+    S2MU106_REG_INT_MASK4          = 0x42,
+    S2MU106_REG_INT_STATUS0        = 0xE0,
+    S2MU106_REG_INT_STATUS1        = 0xE1,
+    S2MU106_REG_INT_STATUS2        = 0xE2,
+    S2MU106_REG_INT_STATUS3        = 0xE3,
+    S2MU106_REG_INT_STATUS4        = 0xE4,
+    S2MU106_REG_ADC_STATUS         = 0xB2,
+    S2MU106_REG_PLUG_MON1          = 0xB3,
+    S2MU106_REG_PLUG_MON2          = 0xB4,
+    S2MU106_REG_PLUG_FSM_MON       = 0xB5,
+
+    S2MU106_REG_MSG_SEND_CON       = 0x90,
+    S2MU106_REG_MSG_TX_HEADER_L    = 0x91,
+    S2MU106_REG_MSG_TX_HEADER_H    = 0x92,
+    S2MU106_REG_MSG_TX_OBJECT0_0_L = 0x93,
+    S2MU106_REG_MSG_TX_OBJECT0_0_H = 0x94,
+    S2MU106_REG_MSG_TX_OBJECT0_1_L = 0x95,
+    S2MU106_REG_MSG_TX_OBJECT0_1_H = 0x96,
+    S2MU106_REG_MSG_TX_OBJECT1_0_L = 0x97,
+    S2MU106_REG_MSG_TX_OBJECT1_0_H = 0x98,
+    S2MU106_REG_MSG_TX_OBJECT1_1_L = 0x99,
+    S2MU106_REG_MSG_TX_OBJECT1_1_H = 0x9A,
+    S2MU106_REG_MSG_TX_OBJECT2_0_L = 0x9B,
+    S2MU106_REG_MSG_TX_OBJECT2_0_H = 0x9C,
+    S2MU106_REG_MSG_TX_OBJECT2_1_L = 0x9D,
+    S2MU106_REG_MSG_TX_OBJECT2_1_H = 0x9E,
+    S2MU106_REG_MSG_TX_OBJECT3_0_L = 0x9F,
+    S2MU106_REG_MSG_TX_OBJECT3_0_H = 0xA0,
+    S2MU106_REG_MSG_TX_OBJECT3_1_L = 0xA1,
+    S2MU106_REG_MSG_TX_OBJECT3_1_H = 0xA2,
+    S2MU106_REG_MSG_TX_OBJECT4_0_L = 0xA3,
+    S2MU106_REG_MSG_TX_OBJECT4_0_H = 0xA4,
+    S2MU106_REG_MSG_TX_OBJECT4_1_L = 0xA5,
+    S2MU106_REG_MSG_TX_OBJECT4_1_H = 0xA6,
+    S2MU106_REG_MSG_TX_OBJECT5_0_L = 0xA7,
+    S2MU106_REG_MSG_TX_OBJECT5_0_H = 0xA8,
+    S2MU106_REG_MSG_TX_OBJECT5_1_L = 0xA9,
+    S2MU106_REG_MSG_TX_OBJECT5_1_H = 0xAA,
+    S2MU106_REG_MSG_TX_OBJECT6_0_L = 0xAB,
+    S2MU106_REG_MSG_TX_OBJECT6_0_H = 0xAC,
+    S2MU106_REG_MSG_TX_OBJECT6_1_L = 0xAD,
+    S2MU106_REG_MSG_TX_OBJECT6_1_H = 0xAE,
+
+    S2MU106_REG_MSG_RX_HEADER_L    = 0xC1,
+    S2MU106_REG_MSG_RX_HEADER_H    = 0xC2,
+    S2MU106_REG_MSG_RX_OBJECT0_0_L = 0xC3,
+    S2MU106_REG_MSG_RX_OBJECT0_0_H = 0xC4,
+    S2MU106_REG_MSG_RX_OBJECT0_1_L = 0xC5,
+    S2MU106_REG_MSG_RX_OBJECT0_1_H = 0xC6,
+    S2MU106_REG_MSG_RX_OBJECT1_0_L = 0xC7,
+    S2MU106_REG_MSG_RX_OBJECT1_0_H = 0xC8,
+    S2MU106_REG_MSG_RX_OBJECT1_1_L = 0xC9,
+    S2MU106_REG_MSG_RX_OBJECT1_1_H = 0xCA,
+    S2MU106_REG_MSG_RX_OBJECT2_0_L = 0xCB,
+    S2MU106_REG_MSG_RX_OBJECT2_0_H = 0xCC,
+    S2MU106_REG_MSG_RX_OBJECT2_1_L = 0xCD,
+    S2MU106_REG_MSG_RX_OBJECT2_1_H = 0xCE,
+    S2MU106_REG_MSG_RX_OBJECT3_0_L = 0xCF,
+    S2MU106_REG_MSG_RX_OBJECT3_0_H = 0xD0,
+    S2MU106_REG_MSG_RX_OBJECT3_1_L = 0xD1,
+    S2MU106_REG_MSG_RX_OBJECT3_1_H = 0xD2,
+    S2MU106_REG_MSG_RX_OBJECT4_0_L = 0xD3,
+    S2MU106_REG_MSG_RX_OBJECT4_0_H = 0xD4,
+    S2MU106_REG_MSG_RX_OBJECT4_1_L = 0xD5,
+    S2MU106_REG_MSG_RX_OBJECT4_1_H = 0xD6,
+    S2MU106_REG_MSG_RX_OBJECT5_0_L = 0xD7,
+    S2MU106_REG_MSG_RX_OBJECT5_0_H = 0xD8,
+    S2MU106_REG_MSG_RX_OBJECT5_1_L = 0xD9,
+    S2MU106_REG_MSG_RX_OBJECT5_1_H = 0xDA,
+    S2MU106_REG_MSG_RX_OBJECT6_0_L = 0xDB,
+    S2MU106_REG_MSG_RX_OBJECT6_0_H = 0xDC,
+    S2MU106_REG_MSG_RX_OBJECT6_1_L = 0xDD,
+    S2MU106_REG_MSG_RX_OBJECT6_1_H = 0xDE,
+
+    S2MU106_REG_ETC                = 0xF7,
+    S2MU106_REG_ID_MONITOR         = 0xF8,
+    S2MU106_REG_ID_MONITOR2        = 0xF9
 };
 
 typedef enum {
-       S2MU106_THRESHOLD_128MV = 2,
-       S2MU106_THRESHOLD_171MV = 3,
-       S2MU106_THRESHOLD_214MV = 4,
-       S2MU106_THRESHOLD_257MV = 5,
-       S2MU106_THRESHOLD_300MV = 6,
-       S2MU106_THRESHOLD_342MV = 7,
-       S2MU106_THRESHOLD_385MV = 8,
-       S2MU106_THRESHOLD_428MV = 9,
-       S2MU106_THRESHOLD_450MV = 10,
-       S2MU106_THRESHOLD_471MV = 11,
-       S2MU106_THRESHOLD_492MV = 12,
-       S2MU106_THRESHOLD_514MV = 13,
-       S2MU106_THRESHOLD_535MV = 14,
-       S2MU106_THRESHOLD_557MV = 15,
-       S2MU106_THRESHOLD_578MV = 16,
-       S2MU106_THRESHOLD_600MV = 17,
-       S2MU106_THRESHOLD_621MV = 18,
-       S2MU106_THRESHOLD_642MV = 19,
-       S2MU106_THRESHOLD_685MV = 20,
-       S2MU106_THRESHOLD_1000MV = 27,
-
-       S2MU106_THRESHOLD_1200MV = 32,
-       S2MU106_THRESHOLD_1242MV = 33,
-       S2MU106_THRESHOLD_1285MV = 34,
-       S2MU106_THRESHOLD_1328MV = 35,
-       S2MU106_THRESHOLD_1371MV = 36,
-       S2MU106_THRESHOLD_1414MV = 37,
-       S2MU106_THRESHOLD_1457MV = 38,
-       S2MU106_THRESHOLD_1500MV = 39,
-       S2MU106_THRESHOLD_1542MV = 40,
-       S2MU106_THRESHOLD_1587MV = 41,
-       S2MU106_THRESHOLD_1628MV = 42,
-       S2MU106_THRESHOLD_1671MV = 43,
-       S2MU106_THRESHOLD_1714MV = 44,
-       S2MU106_THRESHOLD_1757MV = 45,
-       S2MU106_THRESHOLD_1799MV = 46,
-       S2MU106_THRESHOLD_1842MV = 47,
-       S2MU106_THRESHOLD_1885MV = 48,
-       S2MU106_THRESHOLD_1928MV = 49,
-       S2MU106_THRESHOLD_1971MV = 50,
-       S2MU106_THRESHOLD_2014MV = 51,
-       S2MU106_THRESHOLD_2057MV = 52,
-       S2MU106_THRESHOLD_2099MV = 53,
-       S2MU106_THRESHOLD_2142MV = 54,
-       S2MU106_THRESHOLD_2185MV = 55,
-       S2MU106_THRESHOLD_2228MV = 56,
-       S2MU106_THRESHOLD_2271MV = 57,
-
-       S2MU106_THRESHOLD_MAX    = 63
+    S2MU106_THRESHOLD_128MV = 2,
+    S2MU106_THRESHOLD_171MV = 3,
+    S2MU106_THRESHOLD_214MV = 4,
+    S2MU106_THRESHOLD_257MV = 5,
+    S2MU106_THRESHOLD_300MV = 6,
+    S2MU106_THRESHOLD_342MV = 7,
+    S2MU106_THRESHOLD_385MV = 8,
+    S2MU106_THRESHOLD_428MV = 9,
+    S2MU106_THRESHOLD_450MV = 10,
+    S2MU106_THRESHOLD_471MV = 11,
+    S2MU106_THRESHOLD_492MV = 12,
+    S2MU106_THRESHOLD_514MV = 13,
+    S2MU106_THRESHOLD_535MV = 14,
+    S2MU106_THRESHOLD_557MV = 15,
+    S2MU106_THRESHOLD_578MV = 16,
+    S2MU106_THRESHOLD_600MV = 17,
+    S2MU106_THRESHOLD_621MV = 18,
+    S2MU106_THRESHOLD_642MV = 19,
+    S2MU106_THRESHOLD_685MV = 20,
+    S2MU106_THRESHOLD_1000MV = 27,
+
+    S2MU106_THRESHOLD_1200MV = 32,
+    S2MU106_THRESHOLD_1242MV = 33,
+    S2MU106_THRESHOLD_1285MV = 34,
+    S2MU106_THRESHOLD_1328MV = 35,
+    S2MU106_THRESHOLD_1371MV = 36,
+    S2MU106_THRESHOLD_1414MV = 37,
+    S2MU106_THRESHOLD_1457MV = 38,
+    S2MU106_THRESHOLD_1500MV = 39,
+    S2MU106_THRESHOLD_1542MV = 40,
+    S2MU106_THRESHOLD_1587MV = 41,
+    S2MU106_THRESHOLD_1628MV = 42,
+    S2MU106_THRESHOLD_1671MV = 43,
+    S2MU106_THRESHOLD_1714MV = 44,
+    S2MU106_THRESHOLD_1757MV = 45,
+    S2MU106_THRESHOLD_1799MV = 46,
+    S2MU106_THRESHOLD_1842MV = 47,
+    S2MU106_THRESHOLD_1885MV = 48,
+    S2MU106_THRESHOLD_1928MV = 49,
+    S2MU106_THRESHOLD_1971MV = 50,
+    S2MU106_THRESHOLD_2014MV = 51,
+    S2MU106_THRESHOLD_2057MV = 52,
+    S2MU106_THRESHOLD_2099MV = 53,
+    S2MU106_THRESHOLD_2142MV = 54,
+    S2MU106_THRESHOLD_2185MV = 55,
+    S2MU106_THRESHOLD_2228MV = 56,
+    S2MU106_THRESHOLD_2271MV = 57,
+
+    S2MU106_THRESHOLD_MAX     = 63
 } CCIC_THRESHOLD_SEL;
 
 typedef enum {
-       S2MU106_CC_OCP_255MV = 0,
-       S2MU106_CC_OCP_262MV = 1,
-       S2MU106_CC_OCP_273MV = 2,
-       S2MU106_CC_OCP_282MV = 3,
-       S2MU106_CC_OCP_301MV = 4,
-       S2MU106_CC_OCP_311MV = 5,
-       S2MU106_CC_OCP_327MV = 6,
-       S2MU106_CC_OCP_339MV = 7,
-       S2MU106_CC_OCP_375MV = 8,
-       S2MU106_CC_OCP_390MV = 9,
-       S2MU106_CC_OCP_415MV = 10,
-       S2MU106_CC_OCP_433MV = 11,
-       S2MU106_CC_OCP_478MV = 12,
-       S2MU106_CC_OCP_502MV = 13,
-       S2MU106_CC_OCP_542MV = 14,
-       S2MU106_CC_OCP_575MV = 15,
-
-       S2MU106_CC_OCP_MAX   = 16
+    S2MU106_CC_OCP_255MV = 0,
+    S2MU106_CC_OCP_262MV = 1,
+    S2MU106_CC_OCP_273MV = 2,
+    S2MU106_CC_OCP_282MV = 3,
+    S2MU106_CC_OCP_301MV = 4,
+    S2MU106_CC_OCP_311MV = 5,
+    S2MU106_CC_OCP_327MV = 6,
+    S2MU106_CC_OCP_339MV = 7,
+    S2MU106_CC_OCP_375MV = 8,
+    S2MU106_CC_OCP_390MV = 9,
+    S2MU106_CC_OCP_415MV = 10,
+    S2MU106_CC_OCP_433MV = 11,
+    S2MU106_CC_OCP_478MV = 12,
+    S2MU106_CC_OCP_502MV = 13,
+    S2MU106_CC_OCP_542MV = 14,
+    S2MU106_CC_OCP_575MV = 15,
+
+    S2MU106_CC_OCP_MAX   = 16
 } CCIC_CC_OCP_SEL;
 
 typedef enum {
-       S2MU106_PHY_IFG_25US = 0,
-       S2MU106_PHY_IFG_30US = 1,
-       S2MU106_PHY_IFG_35US = 2,
+    S2MU106_PHY_IFG_25US = 0,
+    S2MU106_PHY_IFG_30US = 1,
+    S2MU106_PHY_IFG_35US = 2,
 } CCIC_PHY_IFG_SEL;
 
 enum s2mu106_power_role {
-       PDIC_SINK,
-       PDIC_SOURCE
+    PDIC_SINK,
+    PDIC_SOURCE
 };
 
 enum s2mu106_pdic_rid {
@@ -612,6 +647,7 @@ struct s2mu106_usbpd_data {
        struct mutex poll_mutex;
        struct mutex lpm_mutex;
        struct mutex cc_mutex;
+       struct mutex vbus_mutex;
        int vconn_en;
        int regulator_en;
        int irq_gpio;
@@ -633,6 +669,7 @@ struct s2mu106_usbpd_data {
        bool is_muic_attached;
        bool vbus_short_check;
        bool vbus_short;
+       bool vbus_access;
 #ifndef CONFIG_SEC_FACTORY
        bool lpcharge_water;
 #endif
@@ -664,8 +701,11 @@ struct s2mu106_usbpd_data {
        struct delayed_work water_detect_handler;
        struct delayed_work ta_water_detect_handler;
        struct delayed_work water_dry_handler;
-
+    int pm_cc1;
+    int pm_cc2;
+    int pm_chgin;
        struct power_supply_desc ccic_desc;
+       struct power_supply *psy_pm;
        struct power_supply *psy_ccic;
 
        struct regulator *regulator;
index 50cb6467530cbbc497a2598ee5980a28101de846..ff9ab9c16d51e88a656ff4f4d1c858fb566de7ea 100644 (file)
@@ -3,10 +3,16 @@
 
 #include <linux/ccic/usbpd_msg.h>
 #include <linux/muic/muic.h>
+
 #ifdef CONFIG_IFCONN_NOTIFIER
 #include <linux/ifconn/ifconn_notifier.h>
 #endif
 
+#include <linux/time.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/ktime.h>
+
 #define MAX_CHARGING_VOLT              12000 /* 12V */
 #define USBPD_VOLT_UNIT                        50 /* 50mV */
 #define USBPD_CURRENT_UNIT             10 /* 10mA */
 #define USBPD_nDiscoverIdentityCount   (20)
 
 /* Timer */
-#define tSrcTransition         (35)    /* 25~35 ms */
-#define tPSSourceOn            (480)   /* 390~480 ms */
+#define tSrcTransition         (25)    /* 25~35 ms */
+#define tPSSourceOn            (420)   /* 390~480 ms */
 #define tPSSourceOff           (750)   /* 750~960 ms */
-#define tSenderResponse                (1000)  /* 1000 ms */
+#define tSenderResponse                (25)    /* 24~30ms */
 #define tSenderResponseSRC     (300)   /* 1000 ms */
 #define tSendSourceCap         (10)    /* 1~2 s */
 #define tPSHardReset           (25)    /* 25~35 ms */
 #define tSinkWaitCap           (2500)  /* 2.1~2.5 s  */
-#define tPSTransition          (5500)  /* 450~550 ms */
+#define tPSTransition          (450)   /* 450~550 ms */
 #define tVCONNSourceOn         (100)   /* 24~30 ms */
 #define tVDMSenderResponse     (50)    /* 24~30 ms */
 #define tVDMWaitModeEntry      (50)    /* 40~50  ms */
@@ -37,6 +43,9 @@
 #define tDiscoverIdentity      (50)    /* 40~50  ms */
 #define tSwapSourceStart        (20)   /* 20  ms */
 #define tTypeCSinkWaitCap       (310)  /* 310~620 ms */
+#define tTypeCSendSourceCap (100) /* 100~200ms */
+#define tSrcRecover (880) /* 660~1000ms */
+#define tNoResponse (5500) /* 660~1000ms */
 
 /* Protocol States */
 typedef enum {
@@ -191,6 +200,16 @@ typedef enum {
        PE_DFP_UVDM_Send_Message        = 0xD0,
        PE_DFP_UVDM_Receive_Message     = 0xD1,
 
+       /* Dual Role */
+       PE_DR_SRC_Get_Source_Cap = 0xE0,
+       PE_DR_SRC_Give_Sink_Cap = 0xE1,
+       PE_DR_SNK_Get_Sink_Cap  = 0xE2,
+       PE_DR_SNK_Give_Source_Cap = 0xE3,
+
+       /* Bist Mode */
+       PE_BIST_Receive_Mode = 0xE4,
+       PE_BIST_Frame_Received = 0xE5,
+
        Error_Recovery                  = 0xFF
 } policy_state;
 
@@ -234,6 +253,7 @@ typedef enum usbpd_manager_event {
        MANAGER_UVDM_SEND_MESSAGE               = 16,
        MANAGER_UVDM_RECEIVE_MESSAGE            = 17,
        MANAGER_START_DISCOVER_IDENTITY = 18,
+       MANAGER_SEND_PR_SWAP    = 19,
 } usbpd_manager_event_type;
 
 enum usbpd_msg_status {
@@ -315,6 +335,7 @@ typedef struct usbpd_phy_ops {
        int    (*tx_msg)(void *, msg_header_type *, data_obj_type *);
        int    (*rx_msg)(void *, msg_header_type *, data_obj_type *);
        int    (*hard_reset)(void *);
+       void    (*soft_reset)(void *);
        int    (*set_power_role)(void *, int);
        int    (*get_power_role)(void *, int *);
        int    (*set_data_role)(void *, int);
@@ -326,9 +347,11 @@ typedef struct usbpd_phy_ops {
        bool   (*poll_status)(void *);
        void   (*driver_reset)(void *);
        int    (*set_otg_control)(void *, int);
-       void    (*get_vbus_short_check)(void *, bool *);
        int    (*set_cc_control)(void *, int);
-       int    (*get_side_check)(void *);
+       void    (*pr_swap)(void *, int);
+       int    (*vbus_on_check)(void *);
+       int    (*check_bist_message)(void *);
+       int             (*get_side_check)(void *_data);
 } usbpd_phy_ops_type;
 
 struct policy_data {
@@ -345,6 +368,8 @@ struct policy_data {
        bool                    abnormal_state;
        bool                    sink_cap_received;
        bool                    send_sink_cap;
+       bool                    txhardresetflag;
+       bool                    pd_support;
 };
 
 struct protocol_data {
@@ -367,12 +392,13 @@ struct usbpd_counter {
 struct usbpd_manager_data {
        usbpd_manager_command_type cmd;  /* request to policy engine */
        usbpd_manager_event_type   event;    /* policy engine infromed */
-
-       msg_header_type         uvdm_msg_header;
-       data_obj_type           uvdm_data_obj[USBPD_MAX_COUNT_MSG_OBJECT];
 #if defined(CONFIG_IFCONN_NOTIFIER)
        struct ifconn_notifier_template template;
 #endif
+
+       msg_header_type         uvdm_msg_header;
+       data_obj_type           uvdm_data_obj[USBPD_MAX_COUNT_MSG_OBJECT];
+
        int alt_sended;
        int vdm_en;
        /* request */
@@ -435,6 +461,8 @@ struct usbpd_manager_data {
        struct delayed_work select_pdo_handler;
        struct delayed_work start_discover_msg_handler;
        muic_attached_dev_t     attached_dev;
+
+       int pd_attached;
 };
 
 struct usbpd_data {
@@ -454,9 +482,15 @@ struct usbpd_data {
        data_obj_type           sink_data_obj[2];
        data_obj_type           source_request_obj;
        struct usbpd_manager_data       manager;
+       struct workqueue_struct *policy_wqueue;
        struct work_struct      worker;
        struct completion       msg_arrived;
        unsigned                wait_for_msg_arrived;
+       int                                     lc_test;
+       int                                     id_matched;
+
+       struct timeval          time1;
+       struct timeval          time2;
 };
 
 static inline struct usbpd_data *protocol_rx_to_usbpd(struct protocol_data *rx)
@@ -504,7 +538,6 @@ extern int usbpd_manager_get_status(struct usbpd_data *pd_data);
 extern int usbpd_manager_get_configure(struct usbpd_data *pd_data);
 extern int usbpd_manager_get_attention(struct usbpd_data *pd_data);
 extern void usbpd_dp_detach(struct usbpd_data *pd_data);
-
 extern void usbpd_manager_inform_event(struct usbpd_data *,
                usbpd_manager_event_type);
 extern int usbpd_manager_evaluate_capability(struct usbpd_data *);
@@ -512,10 +545,12 @@ extern data_obj_type usbpd_manager_select_capability(struct usbpd_data *);
 extern bool usbpd_manager_vdm_request_enabled(struct usbpd_data *);
 extern void usbpd_manager_acc_handler_cancel(struct device *);
 extern void usbpd_manager_acc_detach_handler(struct work_struct *);
+extern void usbpd_manager_send_pr_swap(struct device *);
 extern void usbpd_policy_work(struct work_struct *);
 extern void usbpd_protocol_tx(struct usbpd_data *);
 extern void usbpd_protocol_rx(struct usbpd_data *);
 extern void usbpd_kick_policy_work(struct device *);
+extern void usbpd_cancel_policy_work(struct device *);
 extern void usbpd_rx_hard_reset(struct device *);
 extern void usbpd_rx_soft_reset(struct usbpd_data *);
 extern void usbpd_policy_reset(struct usbpd_data *, unsigned flag);
@@ -530,4 +565,11 @@ extern unsigned usbpd_wait_msg(struct usbpd_data *pd_data, unsigned msg_status,
                unsigned ms);
 extern void usbpd_reinit(struct device *);
 extern void usbpd_init_protocol(struct usbpd_data *);
+
+/* for usbpd certification polling */
+void usbpd_timer1_start(struct usbpd_data *pd_data);
+int usbpd_check_time1(struct usbpd_data *pd_data);
+void usbpd_timer2_start(struct usbpd_data *pd_data);
+int usbpd_check_time2(struct usbpd_data *pd_data);
+
 #endif
index ef0e5a2ab44261667f003aaa702c18dcb7490c36..b7c0cacf4d6608aa25a9cfc9bff617236b3eed93 100644 (file)
@@ -5,7 +5,6 @@
 #include <linux/usb/class-dual-role.h>
 #endif
 
-
 #ifndef __USBPD_EXT_H__
 #define __USBPD_EXT_H__
 
@@ -34,6 +33,7 @@ enum {
 /* Samsung Acc VID */
 #define SAMSUNG_VENDOR_ID              0x04E8
 #define SAMSUNG_MPA_VENDOR_ID          0x04B4
+#define TypeC_DP_SUPPORT       (0xFF01)
 /* Samsung Acc PID */
 #define GEARVR_PRODUCT_ID              0xA500
 #define GEARVR_PRODUCT_ID_1            0xA501
index 3c2f3c4b6aa8695560d75890be54e31d09e73afa..bc1c0a0a9fd218da9090b34c09d369dab93352ef 100644 (file)
@@ -6,13 +6,33 @@
 #define PD_SID         (0xFF00)
 #define PD_SID_1       (0xFF01)
 
+#define MAX_INPUT_DATA (255)
+#define SEC_UVDM_ALIGN (4)
+#define SEC_UVDM_WAIT_MS (5000)
+#define SEC_UVDM_MAXDATA_FIRST (12)
+#define SEC_UVDM_MAXDATA_NORMAL (16)
+#define SEC_UVDM_CHECKSUM_COUNT (20)
+
+enum uvdm_res_type {
+       RES_INIT = 0,
+       RES_ACK,
+       RES_NAK,
+       RES_BUSY,
+};
+
+enum uvdm_rx_type {
+       RX_ACK = 0,
+       RX_NAK,
+       RX_BUSY,
+};
+
 typedef union {
        u16 word;
        u8  byte[2];
 
        struct {
                unsigned msg_type:4;
-               unsigned:1;
+               unsigned rsvd:1;
                unsigned port_data_role:1;
                unsigned spec_revision:2;
                unsigned port_power_role:1;
@@ -36,7 +56,7 @@ typedef union {
                unsigned max_current:10;        /* 10mA units */
                unsigned voltage:10;            /* 50mV units */
                unsigned peak_current:2;
-               unsigned:3;
+               unsigned rsvd:3;
                unsigned data_role_swap:1;
                unsigned usb_comm_capable:1;
                unsigned externally_powered:1;
@@ -48,7 +68,7 @@ typedef union {
        struct {
                unsigned op_current:10; /* 10mA units */
                unsigned voltage:10;    /* 50mV units */
-               unsigned:5;
+               unsigned rsvd:5;
                unsigned data_role_swap:1;
                unsigned usb_comm_capable:1;
                unsigned externally_powered:1;
@@ -74,7 +94,7 @@ typedef union {
        struct {
                unsigned min_current:10;        /* 10mA units */
                unsigned op_current:10;         /* 10mA units */
-               unsigned:4;
+               unsigned rsvd:4;
                unsigned no_usb_suspend:1;
                unsigned usb_comm_capable:1;
                unsigned capability_mismatch:1;
@@ -86,7 +106,7 @@ typedef union {
        struct {
                unsigned max_power:10;          /* 250mW units */
                unsigned op_power:10;           /* 250mW units */
-               unsigned:4;
+               unsigned rsvd:4;
                unsigned no_usb_suspend:1;
                unsigned usb_comm_capable:1;
                unsigned capability_mismatch:1;
@@ -112,10 +132,10 @@ typedef union {
 
        struct {
                unsigned command:5;
-               unsigned:1;
+               unsigned reserved:1;
                unsigned command_type:2;
                unsigned obj_pos:3;
-               unsigned:2;
+               unsigned rsvd:2;
                unsigned version:2;
                unsigned vdm_type:1;
                unsigned svid:16;
@@ -195,7 +215,7 @@ typedef union {
                unsigned pid:16;
        };
 } s_uvdm_header;
-       
+
 typedef union {
        u32 object;
        u16 word[2];
@@ -285,6 +305,13 @@ enum usbpd_port_vconn_role {
        USBPD_VCONN_ON,
 };
 
+enum usbpd_power_role_swap {
+       USBPD_SINK_OFF,
+       USBPD_SINK_ON,
+       USBPD_SOURCE_OFF,
+       USBPD_SOURCE_ON,
+};
+
 enum usbpd_port_role {
        USBPD_Rp        = 0x01,
        USBPD_Rd        = 0x01 << 1,
@@ -292,9 +319,9 @@ enum usbpd_port_role {
 };
 
 enum usbpd_port_rp_level {
-       USBPD_56k       = 1,
-       USBPD_22k       = 3,
-       USBPD_10k       = 7,
+    USBPD_56k   = 1,
+    USBPD_22k   = 3,
+    USBPD_10k   = 7,
 };
 
 enum {
@@ -302,12 +329,6 @@ enum {
        USBPD_CC_ON,
 };
 
-enum usbpd_connect_type {
-       USBPD_UP_SIDE   = 1,
-       USBPD_DOWN_SIDE = 2,
-       USBPD_UNDEFFINED_SIDE   = 3,
-};
-
 enum vdm_command_type{
        Initiator       = 0,
        Responder_ACK   = 1,
@@ -358,6 +379,13 @@ enum vdm_command_msg {
        DisplayPort_Configure           = 0x11,
 };
 
+enum usbpd_connect_type {
+       USBPD_UP_SIDE   = 1,
+       USBPD_DOWN_SIDE = 2,
+       USBPD_UNDEFFINED_SIDE   = 3,
+};
+
+
 enum usbpd_data_msg_type {
        USBPD_Source_Capabilities       = 0x1,
        USBPD_Request                   = 0x2,
index a2d8bdcfccd058ef1cdaa683c0a950888d87a9ac..38dba2de5747f3349bb419209e9fde43cc8b7768 100755 (executable)
 #ifndef S2MU106_PMETER_H
 #define S2MU106_PMETER_H
 #include <linux/mfd/samsung/s2mu106.h>
-#include <linux/power/s2mu00x_battery.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/power_supply.h>
+
+#define S2MU106_PM_VALUP1      0x03
+#define S2MU106_PM_VALUP2      0x04
+#define S2MU106_PM_INT1                0x05
+#define S2MU106_PM_INT2                0x06
+#define S2MU106_PM_VALUP1_MASK 0x0B
+#define S2MU106_PM_VALUP2_MASK 0x0C
+#define S2MU106_PM_INT1_MASK   0x0D
+#define S2MU106_PM_INT2_MASK   0x0E
+
+#define S2MU106_PM_CO_MASK1    0x59
+#define S2MU106_PM_CO_MASK2    0x5A
+#define S2MU106_PM_CAL_DIS1    0x5B
+#define S2MU106_PM_CAL_DIS2    0x5C
+#define S2MU106_PM_REQ_BOX_RR1 0x5D
+#define S2MU106_PM_REQ_BOX_RR2 0x5E
+#define S2MU106_PM_REQ_BOX_CO1 0x5F
+#define S2MU106_PM_REQ_BOX_CO2 0x60
+#define S2MU106_PM_CTRL1       0x61
+#define S2MU106_PM_CTRL2       0x62
+#define S2MU106_PM_CTRL3       0x63
+#define S2MU106_PM_CTRL4       0x64
+
+#define S2MU106_PM_VAL1_VCHGIN 0x12
+#define S2MU106_PM_VAL2_VCHGIN 0x13
+#define S2MU106_PM_VAL1_VWCIN  0x14
+#define S2MU106_PM_VAL2_VWCIN  0x15
+#define S2MU106_PM_VAL1_VBYP   0x16
+#define S2MU106_PM_VAL2_VBYP   0x17
+#define S2MU106_PM_VAL1_VSYS   0x18
+#define S2MU106_PM_VAL2_VSYS   0x19
+#define S2MU106_PM_VAL1_VBAT   0x1A
+#define S2MU106_PM_VAL2_VBAT   0x1B
+#define S2MU106_PM_VAL1_VCC1   0x1C
+#define S2MU106_PM_VAL2_VCC1   0x1D
+#define S2MU106_PM_VAL1_VGPADC 0x1E
+#define S2MU106_PM_VAL2_VGPADC 0x1F
+#define S2MU106_PM_VAL1_ICHGIN 0x20
+#define S2MU106_PM_VAL2_ICHGIN 0x21
+#define S2MU106_PM_VAL1_IWCIN  0x22
+#define S2MU106_PM_VAL2_IWCIN  0x23
+#define S2MU106_PM_VAL1_VCC2   0x24
+#define S2MU106_PM_VAL2_VCC2   0x25
+#define S2MU106_PM_VAL1_IOTG   0x26
+#define S2MU106_PM_VAL2_IOTG   0x27
+#define S2MU106_PM_VAL1_ITX    0x28
+#define S2MU106_PM_VAL2_ITX    0x29
+#define S2MU106_PM_HYST_LEVEL1 0xA3
+#define S2MU106_PM_HYST_CONTI1 0xA9
+
+enum pm_type {
+       PM_TYPE_VCHGIN = 0,
+       PM_TYPE_VWCIN,
+       PM_TYPE_VBYP,
+       PM_TYPE_VSYS,
+       PM_TYPE_VBAT,
+       PM_TYPE_VCC1,
+       PM_TYPE_VGPADC,
+       PM_TYPE_ICHGIN,
+       PM_TYPE_IWCIN,
+       PM_TYPE_VCC2,
+       PM_TYPE_IOTG,
+       PM_TYPE_ITX,
+       PM_TYPE_MAX,
+};
+
+enum { 
+       CONTINUOUS_MODE = 0,
+       REQUEST_RESPONSE_MODE,
+};
+#if 0
+enum power_supply_pm_property {
+       POWER_SUPPLY_PROP_VWCIN,
+       POWER_SUPPLY_PROP_VBYP,
+       POWER_SUPPLY_PROP_VSYS,
+       POWER_SUPPLY_PROP_VBAT,
+       POWER_SUPPLY_PROP_VGPADC,
+       POWER_SUPPLY_PROP_VCC1,
+       POWER_SUPPLY_PROP_VCC2,
+       POWER_SUPPLY_PROP_ICHGIN,
+       POWER_SUPPLY_PROP_IWCIN,
+       POWER_SUPPLY_PROP_IOTG,
+       POWER_SUPPLY_PROP_ITX,
+       POWER_SUPPLY_PROP_CO_ENABLE,
+       POWER_SUPPLY_PROP_RR_ENABLE,
+};
+#endif
+
+#define HYST_LEV_VCHGIN_SHIFT  4
+#define HYST_LEV_VCHGIN_MASK   0x70
+
+enum {
+       HYST_LEV_VCHGIN_80mV    =       0x1,
+       HYST_LEV_VCHGIN_160mV   =       0x2,
+       HYST_LEV_VCHGIN_320mV   =       0x3,
+       HYST_LEV_VCHGIN_640mV   =       0x4,
+       HYST_LEV_VCHGIN_1280mV  =       0x5,
+       HYST_LEV_VCHGIN_2560mV  =       0x6,
+       HYST_LEV_VCHGIN_5120mV  =       0x7,
+};
+
+#define HYST_CON_VCHGIN_SHIFT  6
+#define HYST_CON_VCHGIN_MASK   0xC0
+enum {
+       HYST_CON_VCHGIN_1       =       0x1,
+       HYST_CON_VCHGIN_4       =       0x2,
+       HYST_CON_VCHGIN_16      =       0x3,
+       HYST_CON_VCHGIN_32      =       0x4,
+};
 
 struct s2mu106_pmeter_data {
        struct i2c_client       *i2c;
        struct device *dev;
        struct s2mu106_platform_data *s2mu106_pdata;
-};
 
-int s2mu106_powermeter_get_vchg_voltage(void);
-int s2mu106_powermeter_get_vchg_current(void);
+       int irq_vchgin;
+
+       struct power_supply     *psy_pm;
+       struct power_supply_desc psy_pm_desc;
+
+       struct mutex    pmeter_mutex;
+};
 
 #endif /*S2MU106_PMETER_H*/
index ac5d4a4a3820f3faed445a927005cd61c72dd6b9..e6d70fcff400d1252e572eaef760eefcb6398456 100644 (file)
@@ -169,6 +169,21 @@ enum power_supply_property {
        POWER_SUPPLY_PROP_MODEL_NAME,
        POWER_SUPPLY_PROP_MANUFACTURER,
        POWER_SUPPLY_PROP_SERIAL_NUMBER,
+
+       POWER_SUPPLY_PROP_VCHGIN,
+       POWER_SUPPLY_PROP_VWCIN,
+       POWER_SUPPLY_PROP_VBYP,
+       POWER_SUPPLY_PROP_VSYS,
+       POWER_SUPPLY_PROP_VBAT,
+       POWER_SUPPLY_PROP_VGPADC,
+       POWER_SUPPLY_PROP_VCC1,
+       POWER_SUPPLY_PROP_VCC2,
+       POWER_SUPPLY_PROP_ICHGIN,
+       POWER_SUPPLY_PROP_IWCIN,
+       POWER_SUPPLY_PROP_IOTG,
+       POWER_SUPPLY_PROP_ITX,
+       POWER_SUPPLY_PROP_CO_ENABLE,
+       POWER_SUPPLY_PROP_RR_ENABLE,
        POWER_SUPPLY_PROP_USBPD_RESET,
 };