static int s2mu106_usbpd_reg_init(struct s2mu106_usbpd_data *_data);
static void s2mu106_dfp(struct i2c_client *i2c);
static void s2mu106_ufp(struct i2c_client *i2c);
-#ifdef CONFIG_CCIC_VDM
-static int s2mu106_usbpd_check_vdm_msg(void *_data, u64 *val);
-#endif
+static int s2mu106_usbpd_check_msg(void *_data, u64 *val);
static void s2mu106_src(struct i2c_client *i2c);
static void s2mu106_snk(struct i2c_client *i2c);
static void s2mu106_assert_rd(void *_data);
return ret;
}
+static int s2mu106_write_msg_all(struct i2c_client *i2c, int count, u8 *buf)
+{
+ int ret;
+
+ ret = s2mu106_usbpd_bulk_write(i2c, S2MU106_REG_MSG_TX_HEADER_L,
+ 2 + (count * 4), buf);
+
+ return ret;
+}
+#if 0
static int s2mu106_write_msg_header(struct i2c_client *i2c, u8 *buf)
{
int ret;
return ret;
}
-
+#endif
static int s2mu106_send_msg(struct i2c_client *i2c)
{
int ret;
s2mu106_usbpd_write_reg(i2c, reg, val);
- ret = s2mu106_usbpd_write_reg(i2c, reg, S2MU106_REG_MSG_SEND_CON_OP_MODE);
+ ret = s2mu106_usbpd_write_reg(i2c, reg, S2MU106_REG_MSG_SEND_CON_OP_MODE |
+ S2MU106_REG_MSG_SEND_CON_HARD_EN);
return ret;
}
static bool s2mu106_poll_status(void *_data)
{
struct usbpd_data *data = (struct usbpd_data *) _data;
- struct policy_data *policy = &data->policy;
struct s2mu106_usbpd_data *pdic_data = data->phy_driver_data;
struct i2c_client *i2c = pdic_data->i2c;
struct device *dev = &i2c->dev;
u8 intr[S2MU106_MAX_NUM_INT_STATUS] = {0};
int ret = 0, retry = 0;
u64 status_reg_val = 0;
+ msg_header_type header;
+ int data_obj_num = 0;
+ int msg_id = 0;
ret = s2mu106_usbpd_bulk_read(i2c, S2MU106_REG_INT_STATUS0,
S2MU106_MAX_NUM_INT_STATUS, intr);
dev_info(dev, "%s status[0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x]\n",
__func__, intr[0], intr[1], intr[2], intr[3], intr[4], intr[5], intr[6]);
- if ((intr[0] | intr[1] | intr[2] | intr[3] | intr[4] | intr[5]) == 0) {
- status_reg_val |= MSG_NONE;
+ if ((intr[0] | intr[1] | intr[2] | intr[3] | intr[4] | intr[5]) == 0)
goto out;
- }
if ((intr[2] & S2MU106_REG_INT_STATUS2_WAKEUP) ||
(intr[4] & S2MU106_REG_INT_STATUS4_CC12_DET_IRQ))
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)
- status_reg_val |= MSG_HARDRESET;
-
/* when occur detach & attach atomic */
if (intr[4] & S2MU106_REG_INT_STATUS4_USB_DETACH) {
status_reg_val |= PLUG_DETACH;
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) {
- if (intr[4] & S2MU106_REG_INT_STATUS4_MSG_PASS)
- status_reg_val |= MSG_PASS;
- }
-#endif
-/* #if defined(CONFIG_CCIC_FACTORY) */
- if ((intr[4] & S2MU106_REG_INT_STATUS4_MSG_PASS) &&
- (intr[3] & S2MU106_REG_INT_STATUS3_UNS_CMD_DATA)) {
- status_reg_val |= MSG_RID;
- }
-/* #endif */
+ if (intr[5] & S2MU106_REG_INT_STATUS5_HARD_RESET)
+ status_reg_val |= MSG_HARDRESET;
- if (intr[0] & S2MU106_REG_INT_STATUS0_MSG_GOODCRC
- || intr[4] & S2MU106_REG_INT_STATUS4_MSG_SENT)
+ if (intr[0] & S2MU106_REG_INT_STATUS0_MSG_GOODCRC)
status_reg_val |= MSG_GOODCRC;
- if (intr[0] & S2MU106_REG_INT_STATUS0_MSG_ACCEPT)
- status_reg_val |= MSG_ACCEPT;
-
- if (intr[1] & S2MU106_REG_INT_STATUS1_MSG_PSRDY)
- status_reg_val |= MSG_PSRDY;
-
- if (intr[2] & S2MU106_REG_INT_STATUS2_MSG_REQUEST)
- status_reg_val |= MSG_REQUEST;
-
- if (intr[1] & S2MU106_REG_INT_STATUS1_MSG_REJECT)
- status_reg_val |= MSG_REJECT;
-
- if (intr[2] & S2MU106_REG_INT_STATUS2_MSG_WAIT)
- status_reg_val |= MSG_WAIT;
-
- if (intr[4] & S2MU106_REG_INT_STATUS4_MSG_ERROR)
- status_reg_val |= MSG_ERROR;
-
- if (intr[1] & S2MU106_REG_INT_STATUS1_MSG_PING)
- status_reg_val |= MSG_PING;
+ if (intr[1] & S2MU106_REG_INT_STATUS1_MSG_PR_SWAP)
+ status_reg_val |= MSG_PR_SWAP;
- if (intr[1] & S2MU106_REG_INT_STATUS1_MSG_GETSNKCAP)
- status_reg_val |= MSG_GET_SNK_CAP;
+ if (intr[2] & S2MU106_REG_INT_STATUS2_MSG_SOFTRESET)
+ status_reg_val |= MSG_SOFTRESET;
- if (intr[1] & S2MU106_REG_INT_STATUS1_MSG_GETSRCCAP)
- status_reg_val |= MSG_GET_SRC_CAP;
+ if (intr[1] & S2MU106_REG_INT_STATUS1_MSG_DR_SWAP)
+ status_reg_val |= MSG_DR_SWAP;
- if (intr[2] & S2MU106_REG_INT_STATUS2_MSG_SRC_CAP) {
- if (!policy->plug_valid)
- pdic_data->status_reg |= PLUG_ATTACH;
- status_reg_val |= MSG_SRC_CAP;
- }
+ /* function that support dp control */
+ if (intr[4] & S2MU106_REG_INT_STATUS4_MSG_PASS) {
+ if (intr[3] & S2MU106_REG_INT_STATUS3_UNS_CMD_DATA)
+ status_reg_val |= MSG_RID;
+ else {
+ usbpd_protocol_rx(data);
+ header = data->protocol_rx.msg_header;
+ data_obj_num = header.num_data_objs;
+ msg_id = header.msg_id;
+ pr_info("%s, prev msg_id =(%d), received msg_id =(%d)\n", __func__,
+ data->msg_id, msg_id);
+
+ if (msg_id == data->msg_id)
+ goto out;
+ else
+ data->msg_id = msg_id;
- if (intr[2] & S2MU106_REG_INT_STATUS2_MSG_SNK_CAP)
- status_reg_val |= MSG_SNK_CAP;
+ if (data_obj_num > 0)
+ s2mu106_usbpd_check_msg(data, &status_reg_val);
- if (intr[2] & S2MU106_REG_INT_STATUS2_MSG_SOFTRESET)
- status_reg_val |= MSG_SOFTRESET;
+ if (intr[0] & S2MU106_REG_INT_STATUS0_MSG_ACCEPT)
+ status_reg_val |= MSG_ACCEPT;
- if (intr[1] & S2MU106_REG_INT_STATUS1_MSG_PR_SWAP)
- status_reg_val |= MSG_PR_SWAP;
+ if (intr[1] & S2MU106_REG_INT_STATUS1_MSG_PSRDY)
+ status_reg_val |= MSG_PSRDY;
- if (intr[2] & S2MU106_REG_INT_STATUS2_MSG_VCONN_SWAP)
- status_reg_val |= MSG_VCONN_SWAP;
+ if (intr[2] & S2MU106_REG_INT_STATUS2_MSG_REQUEST)
+ status_reg_val |= MSG_REQUEST;
- if (intr[1] & S2MU106_REG_INT_STATUS1_MSG_DR_SWAP)
- status_reg_val |= MSG_DR_SWAP;
+ if (intr[1] & S2MU106_REG_INT_STATUS1_MSG_REJECT)
+ status_reg_val |= MSG_REJECT;
- if (intr[0] & S2MU106_REG_INT_STATUS0_VDM_DISCOVER_ID)
- status_reg_val |= VDM_DISCOVER_IDENTITY;
+ if (intr[2] & S2MU106_REG_INT_STATUS2_MSG_WAIT)
+ status_reg_val |= MSG_WAIT;
- if (intr[0] & S2MU106_REG_INT_STATUS0_VDM_DISCOVER_SVID)
- status_reg_val |= VDM_DISCOVER_SVID;
+ if (intr[4] & S2MU106_REG_INT_STATUS4_MSG_ERROR)
+ status_reg_val |= MSG_ERROR;
- if (intr[0] & S2MU106_REG_INT_STATUS0_VDM_DISCOVER_MODE)
- status_reg_val |= VDM_DISCOVER_MODE;
+ if (intr[1] & S2MU106_REG_INT_STATUS1_MSG_PING)
+ status_reg_val |= MSG_PING;
- if (intr[0] & S2MU106_REG_INT_STATUS0_VDM_ENTER)
- status_reg_val |= VDM_ENTER_MODE;
+ if (intr[1] & S2MU106_REG_INT_STATUS1_MSG_GETSNKCAP)
+ status_reg_val |= MSG_GET_SNK_CAP;
- if (intr[0] & S2MU106_REG_INT_STATUS0_VDM_EXIT)
- status_reg_val |= VDM_EXIT_MODE;
+ if (intr[1] & S2MU106_REG_INT_STATUS1_MSG_GETSRCCAP)
+ status_reg_val |= MSG_GET_SRC_CAP;
- if (intr[0] & S2MU106_REG_INT_STATUS0_VDM_ATTENTION)
- status_reg_val |= VDM_ATTENTION;
-/* disable function that support dp control */
-#ifdef CONFIG_CCIC_VDM
- /* read message if data object message */
- if (status_reg_val &
- (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)) {
- usbpd_protocol_rx(data);
- if (status_reg_val & MSG_PASS)
- s2mu106_usbpd_check_vdm_msg(data, &status_reg_val);
- }
-#else
- /* read message if data object message */
- if (status_reg_val &
- (MSG_PSRDY | MSG_REQUEST | MSG_SNK_CAP
- | VDM_DISCOVER_IDENTITY | VDM_DISCOVER_SVID
- | VDM_DISCOVER_MODE | VDM_ENTER_MODE | VDM_EXIT_MODE
- | VDM_ATTENTION)) {
- usbpd_protocol_rx(data);
+ if (intr[2] & S2MU106_REG_INT_STATUS2_MSG_VCONN_SWAP)
+ status_reg_val |= MSG_VCONN_SWAP;
+ }
}
-#endif
out:
pdic_data->status_reg |= status_reg_val;
struct s2mu106_usbpd_data *pdic_data = data->phy_driver_data;
struct i2c_client *i2c = pdic_data->i2c;
int ret = 0;
+ int i = 0;
int count = 0;
- u8 reg_data = 0;
- u8 msg_id = 0;
+ u8 send_msg[30];
+
+ pr_info("%s, \n", __func__);
- mutex_lock(&pdic_data->cc_mutex);
/* if there is no attach, skip tx msg */
if (pdic_data->detach_valid)
goto done;
+#if 0
/* using msg id counter at s2mu106 */
s2mu106_usbpd_read_reg(pdic_data->i2c, S2MU106_REG_ID_MONITOR, ®_data);
msg_id = reg_data & S2MU106_REG_ID_MONITOR_MSG_ID_MASK;
header->msg_id = msg_id;
-
- ret = s2mu106_write_msg_header(i2c, header->byte);
- if (ret < 0)
- goto done;
+#endif
+ send_msg[0] = header->byte[0];
+ send_msg[1] = header->byte[1];
count = header->num_data_objs;
- if (count > 0) {
- ret = s2mu106_write_msg_obj(i2c, count, obj);
- if (ret < 0)
- goto done;
+ for (i = 0; i < count; i++) {
+ send_msg[2 + (i * 4)] = obj[i].byte[0];
+ send_msg[3 + (i * 4)] = obj[i].byte[1];
+ send_msg[4 + (i * 4)] = obj[i].byte[2];
+ send_msg[5 + (i * 4)] = obj[i].byte[3];
}
+ ret = s2mu106_write_msg_all(i2c, count, send_msg);
+ if (ret < 0)
+ goto done;
+
s2mu106_send_msg(i2c);
done:
- mutex_unlock(&pdic_data->cc_mutex);
return ret;
}
return s2mu106_usbpd_check_vbus(pdic_data, 4500, 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, ®_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, ®_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)
static int s2mu106_get_side_check(void *_data)
{
}
#endif
-#ifdef CONFIG_CCIC_VDM
-int s2mu106_usbpd_check_vdm_msg(void *_data, u64 *val)
+int s2mu106_usbpd_check_msg(void *_data, u64 *val)
{
struct usbpd_data *data = (struct usbpd_data *) _data;
- int vdm_command = 0, vdm_type = 0;
+ int data_type = 0;
+ int msg_type = 0;
+ int vdm_type = 0;
+ int vdm_command = 0;
- dev_info(data->dev, "%s ++\n", __func__);
- if (data->protocol_rx.msg_header.num_data_objs == 0) {
- dev_info(data->dev, "%s data_obj null\n", __func__);
- return 0;
- }
+ dev_info(data->dev, "%s\n", __func__);
- if (data->protocol_rx.msg_header.msg_type == USBPD_Source_Capabilities) {
- *val |= MSG_SRC_CAP;
- return 0;
- }
+ if (data->protocol_rx.msg_header.num_data_objs == 0)
+ data_type = USBPD_CTRL_MSG;
+ else
+ data_type = USBPD_DATA_MSG;
- if (data->protocol_rx.msg_header.msg_type != USBPD_Vendor_Defined) {
- dev_info(data->dev, "%s msg type is wrong\n", __func__);
+ msg_type = data->protocol_rx.msg_header.msg_type;
+
+ if (data_type == USBPD_CTRL_MSG)
return 0;
- }
- vdm_command = data->protocol_rx.data_obj[0].structured_vdm.command;
- vdm_type = data->protocol_rx.data_obj[0].structured_vdm.vdm_type;
+ if (data_type == USBPD_DATA_MSG) {
+ switch (msg_type) {
+ case USBPD_Source_Capabilities:
+ *val |= MSG_SRC_CAP;
+ break;
+ case USBPD_Request:
+ *val |= MSG_REQUEST;
+ break;
+ case USBPD_Sink_Capabilities:
+ *val |= MSG_SNK_CAP;
+ break;
+ case USBPD_BIST:
+ *val |= MSG_BIST;
+ break;
+ case USBPD_Vendor_Defined:
+ vdm_command = data->protocol_rx.data_obj[0].structured_vdm.command;
+ vdm_type = data->protocol_rx.data_obj[0].structured_vdm.vdm_type;
- if (vdm_type == Unstructured_VDM) {
- dev_info(data->dev, "%s : uvdm msg received!\n", __func__);
- *val |= UVDM_MSG;
- return 0;
- }
+ if (vdm_type == Unstructured_VDM) {
+ dev_info(data->dev, "%s : uvdm msg received!\n", __func__);
+ *val |= UVDM_MSG;
+ break;
+ }
-#if 0
- switch (vdm_command) {
- case DisplayPort_Status_Update:
- *val |= VDM_DP_STATUS_UPDATE;
- break;
- case DisplayPort_Configure:
- *val |= VDM_DP_CONFIGURE;
- break;
- default:
- return 0;
+ switch (vdm_command) {
+ case DisplayPort_Status_Update:
+ *val |= VDM_DP_STATUS_UPDATE;
+ break;
+ case DisplayPort_Configure:
+ *val |= VDM_DP_CONFIGURE;
+ break;
+ case Attention:
+ *val |= VDM_ATTENTION;
+ break;
+ case Exit_Mode:
+ *val |= VDM_EXIT_MODE;
+ break;
+ case Enter_Mode:
+ *val |= VDM_ENTER_MODE;
+ break;
+ case Discover_Modes:
+ *val |= VDM_ENTER_MODE;
+ break;
+ case Discover_SVIDs:
+ *val |= VDM_DISCOVER_SVID;
+ break;
+ case Discover_Identity:
+ *val |= VDM_DISCOVER_IDENTITY;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
}
-#endif
- dev_info(data->dev, "%s: check vdm mag val(%d)\n", __func__, vdm_command);
+
+ dev_info(data->dev, "%s: msg status(%lld)\n", __func__, *val);
return 0;
}
-#endif
static int s2mu106_usbpd_set_cc_control(struct s2mu106_usbpd_data *pdic_data, int val)
{
pdic_data->lpm_mode = false;
- s2mu106_set_irq_enable(pdic_data, 0, 0,
- S2MU106_REG_INT_STATUS2_MSG_SRC_CAP, ENABLED_INT_3,
- ENABLED_INT_4, 0);
+ s2mu106_set_irq_enable(pdic_data, ENABLED_INT_0, ENABLED_INT_1,
+ ENABLED_INT_2, ENABLED_INT_3, ENABLED_INT_4, ENABLED_INT_5);
dev_info(dev, "%s s2mu106 exit lpm mode\n", __func__);
dev_info(dev, "%s\n", __func__);
+ mutex_lock(&pd_data->accept_mutex);
+ mutex_unlock(&pd_data->accept_mutex);
+
mutex_lock(&pdic_data->_mutex);
s2mu106_poll_status(pd_data);
goto out;
#endif
- if (s2mu106_get_status(pd_data, MSG_NONE))
+ if (pdic_data->status_reg == 0)
goto out;
if (s2mu106_get_status(pd_data, MSG_SOFTRESET))
mutex_unlock(&pdic_data->cc_mutex);
s2mu106_self_soft_reset(i2c);
pdic_data->status_reg = 0;
+ if (pdic_data->power_role == PDIC_SOURCE)
+ s2mu106_dfp(i2c);
+ else
+ s2mu106_ufp(i2c);
usbpd_rx_hard_reset(dev);
usbpd_kick_policy_work(dev);
goto out;
if (_data->lpm_mode)
s2mu106_set_irq_enable(_data, 0, 0, 0, 0, 0, 0);
else
- s2mu106_set_irq_enable(_data, 0, 0, 0, 0, ENABLED_INT_4, 0);
+ s2mu106_set_irq_enable(_data, ENABLED_INT_0, ENABLED_INT_1,
+ ENABLED_INT_2, ENABLED_INT_3, ENABLED_INT_4, ENABLED_INT_5);
return ret;
}
.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
rx_layer_init(&pd_data->protocol_rx);
tx_layer_init(&pd_data->protocol_tx);
pd_data->id_matched = 0;
+ pd_data->msg_id = USBPD_nMessageIDCount + 1;
}
void usbpd_init_counters(struct usbpd_data *pd_data)
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)
struct usbpd_data *pd_data = protocol_rx_to_usbpd(rx);
protocol_state state = PRL_Rx_Wait_for_PHY_Message;
+ pd_data->msg_received = 0;
+
if (pd_data->phy_ops.rx_msg(pd_data, &rx->msg_header, rx->data_obj)) {
dev_err(pd_data->dev, "%s IO Error\n", __func__);
return state;
}
pd_data->id_matched = 1;
+ pd_data->msg_received = 1;
dev_err(pd_data->dev, "[Rx] [0x%x] [0x%x]\n",
rx->msg_header.word, rx->data_obj[0].object);
rx->stored_message_id = rx->msg_header.msg_id;
usbpd_read_msg(pd_data);
+
/*
return PRL_Rx_Wait_for_PHY_Message;
*/
usbpd_init_policy(pd_data);
usbpd_init_manager(pd_data);
+ mutex_init(&pd_data->accept_mutex);
+
pd_data->policy_wqueue =
create_singlethread_workqueue(dev_name(dev));
if (!pd_data->policy_wqueue)
data_obj->power_data_obj.data_role_swap = 1;
data_obj->power_data_obj.dual_role_power = 1;
data_obj->power_data_obj.usb_suspend_support = 1;
- data_obj->power_data_obj.usb_comm_capable = 1;
+ data_obj->power_data_obj.usb_comm_capable = 0;
}
msg_header->port_data_role = USBPD_UFP;
msg_header->spec_revision = 1;
msg_header->port_power_role = USBPD_SINK;
- msg_header->num_data_objs = 2;
+ msg_header->num_data_objs = 1;
data_obj->power_data_obj_sink.supply_type = POWER_TYPE_FIXED;
data_obj->power_data_obj_sink.dual_role_power = 1;
data_obj->power_data_obj_sink.higher_capability = 1;
data_obj->power_data_obj_sink.externally_powered = 0;
- data_obj->power_data_obj_sink.usb_comm_capable = 1;
+ data_obj->power_data_obj_sink.usb_comm_capable = 0;
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 = 3000/10;
-
+#if 0
(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 = 3000 / 10;
+#endif
}
void usbpd_manager_receive_samsung_uvdm_message(struct usbpd_data *pd_data)
int pdo_num = pd_noti.sink_status.selected_pdo_num;
#endif
obj.request_data_object.no_usb_suspend = 1;
- obj.request_data_object.usb_comm_capable = 1;
+ obj.request_data_object.usb_comm_capable = 0;
obj.request_data_object.capability_mismatch = 0;
obj.request_data_object.give_back = 0;
#ifdef CONFIG_IFCONN_NOTIFIER
= pd_data->source_request_obj.power_data_obj_supply_type.supply_type;
unsigned src_max_current, mismatch, max_min, op, pos;
- if (supply_type == POWER_TYPE_FIXED) {
+ if (supply_type == POWER_TYPE_FIXED)
pr_info("REQUEST: FIXED\n");
- goto log_fixed_variable;
- } else if (supply_type == POWER_TYPE_VARIABLE) {
+ else if (supply_type == POWER_TYPE_VARIABLE)
pr_info("REQUEST: VARIABLE\n");
- goto log_fixed_variable;
- } else if (supply_type == POWER_TYPE_BATTERY) {
+ else if (supply_type == POWER_TYPE_BATTERY) {
pr_info("REQUEST: BATTERY\n");
goto log_battery;
} else {
return -1;
}
-log_fixed_variable:
/* Tx Source PDO */
src_max_current = pd_data->source_data_obj.power_data_obj.max_current;
op = pd_data->source_request_obj.request_data_object.op_current;
pos = pd_data->source_request_obj.request_data_object.object_position;
+#if 0
pr_info("%s %x\n", __func__, pd_data->source_request_obj.object);
-
+#endif
/*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);
if (pd_data->phy_ops.get_status(pd_data, MSG_REQUEST)) {
pd_data->counter.hard_reset_counter = 0;
pd_data->counter.caps_counter = 0;
- 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");
{
struct usbpd_data *pd_data = policy_to_usbpd(policy);
int ret = PE_SRC_Negotiate_Capability;
+ int data_role = 0;
/**********************************************
Actions on entry:
/* 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);
+
+ mutex_lock(&pd_data->accept_mutex);
/* 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);
+ usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, USBPD_Accept,
+ data_role, USBPD_SOURCE);
+ dev_info(pd_data->dev, "%s sended accept\n", __func__);
ret = PE_SRC_Transition_Supply; /* Accept */
} else {
ret = PE_SRC_Capability_Response; /* Reject */
}
+ mutex_unlock(&pd_data->accept_mutex);
return ret;
}
break;
}
- if (ms1 >= 5) {
+ if (ms1 >= 8) {
ret = PE_SRC_Hard_Reset;
break;
}
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);
+ CHECK_MSG(pd_data, MSG_BIST, PE_BIST_Receive_Mode);
#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_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)) {
/* 1) PD State Inform to AP */
dev_info(pd_data->dev, "%s\n", __func__);
- /* 3) Get Rx Buffer */
- usbpd_protocol_rx(pd_data);
-
/* 4) Select PDO */
#if defined(CONFIG_IFCONN_NOTIFIER)
if (pd_noti.sink_status.selected_pdo_num == 0) {
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);
+ CHECK_MSG(pd_data, MSG_BIST, PE_BIST_Receive_Mode);
#if 0
CHECK_MSG(pd_data, VDM_DISCOVER_IDENTITY, PE_UFP_VDM_Get_Identity);
/* 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);
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;
+#if 0
policy->tx_data_obj[1].object = pd_data->sink_data_obj[1].object;
-
+#endif
policy->sink_cap_received = 1;
/* 4) Send Message */
pd_data->phy_ops.get_power_role(pd_data, &power_role);
- if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header,
- USBPD_Accept, USBPD_DFP, power_role)) {
- return PE_DRS_DFP_UFP_Change_to_UFP;
- }
+ mutex_lock(&pd_data->accept_mutex);
+ usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header,
+ USBPD_Accept, USBPD_DFP, power_role);
+
+ pd_data->phy_ops.set_data_role(pd_data, USBPD_UFP);
+ mutex_unlock(&pd_data->accept_mutex);
- return PE_DRS_DFP_UFP_Accept_DR_Swap;
+ return PE_DRS_DFP_UFP_Change_to_UFP;
}
policy_state usbpd_policy_drs_dfp_ufp_change_to_ufp(struct policy_data *policy)
dev_info(pd_data->dev, "%s\n", __func__);
- pd_data->phy_ops.set_data_role(pd_data, USBPD_UFP);
pd_data->phy_ops.get_power_role(pd_data, &power_role);
if (power_role == USBPD_SOURCE)
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_Accept, USBPD_UFP, power_role)) {
- return PE_DRS_UFP_DFP_Change_to_DFP;
- }
- return PE_DRS_UFP_DFP_Accept_DR_Swap;
+ mutex_lock(&pd_data->accept_mutex);
+ usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header,
+ USBPD_Accept, USBPD_UFP, power_role);
+ pd_data->phy_ops.set_data_role(pd_data, USBPD_DFP);
+ mutex_unlock(&pd_data->accept_mutex);
+ return PE_DRS_UFP_DFP_Change_to_DFP;
}
policy_state usbpd_policy_drs_ufp_dfp_change_to_dfp(struct policy_data *policy)
dev_info(pd_data->dev, "%s\n", __func__);
- pd_data->phy_ops.set_data_role(pd_data, USBPD_DFP);
pd_data->phy_ops.get_power_role(pd_data, &power_role);
if (power_role == USBPD_SOURCE)
if (pd_data->phy_ops.get_status(pd_data, MSG_PSRDY)) {
dev_info(pd_data->dev, "got PSRDY.\n");
pd_data->counter.swap_hard_reset_counter = 0;
- mdelay(15);
-
/* Self SoftReset for Message ID Clear */
pd_data->phy_ops.soft_reset(pd_data);
-
+ mdelay(15);
ret = PE_SNK_Startup;
break;
}
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);
/* Start Timer 750ms */
usbpd_timer1_start(pd_data);
/* 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;
pr_info("%s: called charger otg control : %s\n", __func__,
enable ? "ON" : "OFF");
+ mutex_lock(&charger->charger_mutex);
if (charger->is_charging) {
pr_info("%s: Charger is enabled and OTG noti received!!!\n", __func__);
pr_info("%s: is_charging: %d, otg_on: %d",
__func__, charger->is_charging, charger->otg_on);
s2mu106_test_read(charger->i2c);
- return 0;
+ goto out;
}
if (charger->otg_on == enable)
- return 0;
+ goto out;
- mutex_lock(&charger->charger_mutex);
if (!enable) {
s2mu106_update_reg(charger->i2c,
S2MU106_CHG_CTRL0, CHG_MODE, REG_MODE_MASK);
S2MU106_CHG_CTRL3,
S2MU106_SET_OTG_OCP_1500mA << SET_OTG_OCP_SHIFT,
SET_OTG_OCP_MASK);
-// msleep(30);
s2mu106_update_reg(charger->i2c,
S2MU106_CHG_CTRL0, OTG_BST_MODE, REG_MODE_MASK);
charger->cable_type = POWER_SUPPLY_TYPE_OTG;
}
charger->otg_on = enable;
+
+out:
mutex_unlock(&charger->charger_mutex);
s2mu106_read_reg(charger->i2c, S2MU106_CHG_STATUS2, &chg_sts2);
struct s2mu106_charger_data *charger, int onoff)
{
+ mutex_lock(&charger->charger_mutex);
if (charger->otg_on) {
pr_info("[DEBUG] %s: skipped set(%d) : OTG is on\n", __func__, onoff);
charger->is_charging = false;
- return;
+ goto out;
}
if (onoff > 0) {
s2mu106_update_reg(charger->i2c, S2MU106_CHG_CTRL0, BUCK_MODE, REG_MODE_MASK);
}
+out:
+ mutex_unlock(&charger->charger_mutex);
}
static void s2mu106_set_buck(
pr_info("[DEBUG]%s: current %d, 0x%x\n", __func__, charging_current, data);
-#if EN_TEST_READ
+#if 0
s2mu106_test_read(charger->i2c);
#endif
}
pr_info("[DEBUG]%s: current %d, 0x%02x\n", __func__, charging_current, data);
-#if EN_TEST_READ
+#if 0
s2mu106_test_read(charger->i2c);
#endif
}
#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 |\
- 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 |\
- 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_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 |\
- S2MU106_REG_INT_STATUS2_MSG_WAIT)
+#define ENABLED_INT_0 (S2MU106_REG_INT_STATUS0_MSG_GOODCRC |\
+ S2MU106_REG_INT_STATUS0_MSG_ACCEPT)
+#define ENABLED_INT_1 (S2MU106_REG_INT_STATUS1_MSG_PING |\
+ S2MU106_REG_INT_STATUS1_MSG_REJECT |\
+ S2MU106_REG_INT_STATUS1_MSG_PSRDY |\
+ S2MU106_REG_INT_STATUS1_MSG_GETSRCCAP |\
+ S2MU106_REG_INT_STATUS1_MSG_GETSNKCAP |\
+ S2MU106_REG_INT_STATUS1_MSG_DR_SWAP |\
+ S2MU106_REG_INT_STATUS1_MSG_PR_SWAP)
+#define ENABLED_INT_2 (S2MU106_REG_INT_STATUS2_MSG_VCONN_SWAP |\
+ S2MU106_REG_INT_STATUS2_MSG_WAIT |\
+ S2MU106_REG_INT_STATUS2_MSG_SOFTRESET)
+#define ENABLED_INT_2_WAKEUP (S2MU106_REG_INT_STATUS2_MSG_VCONN_SWAP |\
+ S2MU106_REG_INT_STATUS2_MSG_WAIT |\
+ S2MU106_REG_INT_STATUS2_MSG_SOFTRESET |\
+ 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_STATUS4_PLUG_IRQ |\
#define tSenderResponse (25) /* 24~30ms */
#define tSenderResponseSRC (300) /* 1000 ms */
#define tSendSourceCap (10) /* 1~2 s */
-#define tPSHardReset (25) /* 25~35 ms */
+#define tPSHardReset (17) /* 25~35 ms */
#define tSinkWaitCap (2500) /* 2.1~2.5 s */
#define tPSTransition (450) /* 450~550 ms */
#define tVCONNSourceOn (100) /* 24~30 ms */
UVDM_MSG = 1<<28,
MSG_PASS = 1<<29,
MSG_RID = 1<<30,
- MSG_NONE = 1<<31,
+ MSG_BIST = 1<<31,
};
/* Timer */
int (*set_cc_control)(void *, int);
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;
unsigned wait_for_msg_arrived;
int lc_test;
int id_matched;
+ bool msg_received;
+ int msg_id;
+ struct mutex accept_mutex;
struct timeval time1;
struct timeval time2;
USBPD_Vendor_Defined = 0xF,
};
+enum usbpd_msg_type {
+ USBPD_CTRL_MSG = 0,
+ USBPD_DATA_MSG = 1,
+};
+
#endif