mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
mfd/fusb302: support data role swap (UFP -> DFP)
This patch set a frame for DR_SWAP, and it only support UFP to DFP, because there are many works to coordinate USB part and PD part when change DFP to UFP. Change-Id: Iebcccdcd9115c5be4704e6e8e0dc0b568a4ac48d Signed-off-by: zain wang <wzz@rock-chips.com>
This commit is contained in:
@@ -1806,12 +1806,18 @@ static void fusb_state_swap_msg_process(struct fusb30x_chip *chip, int evt)
|
||||
set_state(chip, policy_vcs_ufp_evaluate_swap);
|
||||
} else if (PACKET_IS_CONTROL_MSG(chip->rec_head,
|
||||
CMT_DR_SWAP)) {
|
||||
/* TODO */
|
||||
set_state(chip, chip->conn_state);
|
||||
if (chip->notify.data_role)
|
||||
set_state(chip, policy_drs_dfp_evaluate);
|
||||
else
|
||||
set_state(chip, policy_drs_ufp_evaluate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define VDM_IS_ACTIVE(chip) \
|
||||
(chip->notify.data_role && chip->vdm_state != 5 && \
|
||||
chip->vdm_state != 0xff)
|
||||
|
||||
static void fusb_state_src_ready(struct fusb30x_chip *chip, int evt)
|
||||
{
|
||||
if (evt & EVENT_RX) {
|
||||
@@ -1819,15 +1825,14 @@ static void fusb_state_src_ready(struct fusb30x_chip *chip, int evt)
|
||||
process_vdm_msg(chip);
|
||||
chip->work_continue = 1;
|
||||
chip->timer_state = T_DISABLED;
|
||||
} else if ((chip->vdm_state == 5) ||
|
||||
(chip->vdm_state == 0xff)) {
|
||||
} else if (!VDM_IS_ACTIVE(chip)) {
|
||||
fusb_state_swap_msg_process(chip, evt);
|
||||
}
|
||||
}
|
||||
|
||||
if (!chip->partner_cap[0])
|
||||
set_state(chip, policy_src_get_sink_caps);
|
||||
else if ((chip->vdm_state != 5) && (chip->vdm_state != 0xff))
|
||||
else if (VDM_IS_ACTIVE(chip))
|
||||
auto_vdm_machine(chip, evt);
|
||||
}
|
||||
|
||||
@@ -1841,7 +1846,8 @@ static void fusb_state_prs_evaluate(struct fusb30x_chip *chip, int evt)
|
||||
|
||||
static void fusb_state_send_simple_msg(struct fusb30x_chip *chip, int evt,
|
||||
int cmd, int is_DMT,
|
||||
enum connection_state state)
|
||||
enum connection_state state_success,
|
||||
enum connection_state state_failed)
|
||||
{
|
||||
u32 tmp;
|
||||
|
||||
@@ -1853,14 +1859,10 @@ static void fusb_state_send_simple_msg(struct fusb30x_chip *chip, int evt,
|
||||
/* fallthrough */
|
||||
case 1:
|
||||
tmp = policy_send_data(chip);
|
||||
if (tmp == tx_success) {
|
||||
set_state(chip, state);
|
||||
} else if (tmp == tx_failed) {
|
||||
if (chip->notify.power_role)
|
||||
set_state(chip, policy_src_send_softrst);
|
||||
else
|
||||
set_state(chip, policy_snk_send_softrst);
|
||||
}
|
||||
if (tmp == tx_success)
|
||||
set_state(chip, state_success);
|
||||
else if (tmp == tx_failed)
|
||||
set_state(chip, state_failed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1868,7 +1870,10 @@ static void fusb_state_prs_reject(struct fusb30x_chip *chip, int evt)
|
||||
{
|
||||
fusb_state_send_simple_msg(chip, evt, CMT_REJECT, CONTROLMESSAGE,
|
||||
(chip->notify.power_role) ?
|
||||
policy_src_ready : policy_snk_ready);
|
||||
policy_src_ready : policy_snk_ready,
|
||||
(chip->notify.power_role) ?
|
||||
policy_src_send_softrst :
|
||||
policy_snk_send_softrst);
|
||||
}
|
||||
|
||||
static void fusb_state_prs_accept(struct fusb30x_chip *chip, int evt)
|
||||
@@ -1876,7 +1881,10 @@ static void fusb_state_prs_accept(struct fusb30x_chip *chip, int evt)
|
||||
fusb_state_send_simple_msg(chip, evt, CMT_ACCEPT, CONTROLMESSAGE,
|
||||
(chip->notify.power_role) ?
|
||||
policy_src_prs_transition_to_off :
|
||||
policy_snk_prs_transition_to_off);
|
||||
policy_snk_prs_transition_to_off,
|
||||
(chip->notify.power_role) ?
|
||||
policy_src_send_softrst :
|
||||
policy_snk_send_softrst);
|
||||
}
|
||||
|
||||
static void fusb_state_vcs_ufp_accept(struct fusb30x_chip *chip, int evt)
|
||||
@@ -1884,7 +1892,10 @@ static void fusb_state_vcs_ufp_accept(struct fusb30x_chip *chip, int evt)
|
||||
fusb_state_send_simple_msg(chip, evt, CMT_ACCEPT, CONTROLMESSAGE,
|
||||
(chip->vconn_enabled) ?
|
||||
policy_vcs_ufp_wait_for_dfp_vconn :
|
||||
policy_vcs_ufp_turn_on_vconn);
|
||||
policy_vcs_ufp_turn_on_vconn,
|
||||
(chip->notify.power_role) ?
|
||||
policy_src_send_softrst :
|
||||
policy_snk_send_softrst);
|
||||
}
|
||||
|
||||
static void fusb_state_vcs_set_vconn(struct fusb30x_chip *chip,
|
||||
@@ -1908,7 +1919,10 @@ static void fusb_state_vcs_send_ps_rdy(struct fusb30x_chip *chip, int evt)
|
||||
{
|
||||
fusb_state_send_simple_msg(chip, evt, CMT_PS_RDY, CONTROLMESSAGE,
|
||||
(chip->notify.power_role) ?
|
||||
policy_src_ready : policy_snk_ready);
|
||||
policy_src_ready : policy_snk_ready,
|
||||
(chip->notify.power_role) ?
|
||||
policy_src_send_softrst :
|
||||
policy_snk_send_softrst);
|
||||
}
|
||||
|
||||
static void fusb_state_vcs_wait_for_vconn(struct fusb30x_chip *chip,
|
||||
@@ -2013,6 +2027,38 @@ static void fusb_state_src_prs_source_off(struct fusb30x_chip *chip, int evt)
|
||||
}
|
||||
}
|
||||
|
||||
static void fusb_state_drs_evaluate(struct fusb30x_chip *chip, int evt)
|
||||
{
|
||||
if (chip->pd_cap_info.data_role_swap)
|
||||
/*
|
||||
* TODO:
|
||||
* NOW REJECT swap when the port is DFP
|
||||
* since we should work together with USB part
|
||||
*/
|
||||
set_state(chip, chip->notify.data_role ?
|
||||
policy_drs_dfp_reject : policy_drs_ufp_accept);
|
||||
else
|
||||
set_state(chip, chip->notify.data_role ?
|
||||
policy_drs_dfp_reject : policy_drs_ufp_reject);
|
||||
}
|
||||
|
||||
static void fusb_state_drs_send_accept(struct fusb30x_chip *chip, int evt)
|
||||
{
|
||||
fusb_state_send_simple_msg(chip, evt, CMT_ACCEPT, CONTROLMESSAGE,
|
||||
chip->notify.power_role ?
|
||||
policy_drs_dfp_change :
|
||||
policy_drs_ufp_change,
|
||||
error_recovery);
|
||||
}
|
||||
|
||||
static void fusb_state_drs_role_change(struct fusb30x_chip *chip, int evt)
|
||||
{
|
||||
chip->notify.data_role = chip->notify.data_role ? false : true;
|
||||
tcpm_set_msg_header(chip);
|
||||
set_state(chip, chip->notify.power_role ? policy_src_ready :
|
||||
policy_snk_ready);
|
||||
}
|
||||
|
||||
static void fusb_state_src_get_sink_cap(struct fusb30x_chip *chip, int evt)
|
||||
{
|
||||
u32 tmp;
|
||||
@@ -2349,8 +2395,20 @@ static void fusb_state_snk_transition_default(struct fusb30x_chip *chip,
|
||||
|
||||
static void fusb_state_snk_ready(struct fusb30x_chip *chip, int evt)
|
||||
{
|
||||
fusb_state_swap_msg_process(chip, evt);
|
||||
if (evt & EVENT_RX) {
|
||||
if (PACKET_IS_DATA_MSG(chip->rec_head, DMT_VENDERDEFINED)) {
|
||||
process_vdm_msg(chip);
|
||||
chip->work_continue = 1;
|
||||
chip->timer_state = T_DISABLED;
|
||||
} else if (!VDM_IS_ACTIVE(chip)) {
|
||||
fusb_state_swap_msg_process(chip, evt);
|
||||
}
|
||||
}
|
||||
|
||||
if (VDM_IS_ACTIVE(chip))
|
||||
auto_vdm_machine(chip, evt);
|
||||
|
||||
fusb_state_swap_msg_process(chip, evt);
|
||||
platform_fusb_notify(chip);
|
||||
}
|
||||
|
||||
@@ -2393,6 +2451,11 @@ static void fusb_state_send_swap(struct fusb30x_chip *chip, int evt, int cmd)
|
||||
chip->timer_state);
|
||||
chip->sub_state++;
|
||||
} else if (tmp == tx_failed) {
|
||||
if (cmd == CMT_DR_SWAP) {
|
||||
set_state(chip, error_recovery);
|
||||
return;
|
||||
}
|
||||
|
||||
if (chip->notify.power_role)
|
||||
set_state(chip, policy_src_send_softrst);
|
||||
else
|
||||
@@ -2415,6 +2478,10 @@ static void fusb_state_send_swap(struct fusb30x_chip *chip, int evt, int cmd)
|
||||
set_state(chip, policy_snk_prs_transition_to_off);
|
||||
chip->notify.power_role = 1;
|
||||
tcpm_set_msg_header(chip);
|
||||
} else if (cmd == CMT_DR_SWAP) {
|
||||
set_state(chip, chip->notify.data_role ?
|
||||
policy_drs_dfp_change :
|
||||
policy_drs_ufp_change);
|
||||
}
|
||||
} else if (PACKET_IS_CONTROL_MSG(chip->rec_head,
|
||||
CMT_REJECT) ||
|
||||
@@ -2748,6 +2815,8 @@ static void state_machine_typec(struct fusb30x_chip *chip)
|
||||
case policy_snk_prs_reject:
|
||||
case policy_src_prs_reject:
|
||||
case policy_vcs_ufp_reject:
|
||||
case policy_drs_dfp_reject:
|
||||
case policy_drs_ufp_reject:
|
||||
fusb_state_prs_reject(chip, evt);
|
||||
break;
|
||||
case policy_src_prs_transition_to_off:
|
||||
@@ -2797,6 +2866,22 @@ static void state_machine_typec(struct fusb30x_chip *chip)
|
||||
case policy_vcs_dfp_send_swap:
|
||||
fusb_state_send_swap(chip, evt, CMT_VCONN_SWAP);
|
||||
break;
|
||||
case policy_drs_ufp_evaluate:
|
||||
case policy_drs_dfp_evaluate:
|
||||
fusb_state_drs_evaluate(chip, evt);
|
||||
break;
|
||||
case policy_drs_dfp_accept:
|
||||
case policy_drs_ufp_accept:
|
||||
fusb_state_drs_send_accept(chip, evt);
|
||||
break;
|
||||
case policy_drs_dfp_change:
|
||||
case policy_drs_ufp_change:
|
||||
fusb_state_drs_role_change(chip, evt);
|
||||
break;
|
||||
case policy_drs_ufp_send_swap:
|
||||
case policy_drs_dfp_send_swap:
|
||||
fusb_state_send_swap(chip, evt, CMT_DR_SWAP);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -2968,8 +3053,7 @@ static int fusb30x_probe(struct i2c_client *client,
|
||||
|
||||
pd_cap_info = &chip->pd_cap_info;
|
||||
pd_cap_info->dual_role_power = 1;
|
||||
/* TODO: add date role swap */
|
||||
pd_cap_info->data_role_swap = 0;
|
||||
pd_cap_info->data_role_swap = 1;
|
||||
|
||||
pd_cap_info->externally_powered = 1;
|
||||
pd_cap_info->usb_suspend_support = 0;
|
||||
|
||||
@@ -118,6 +118,18 @@ enum connection_state {
|
||||
policy_vcs_ufp_turn_off_vconn,
|
||||
policy_vcs_ufp_turn_on_vconn,
|
||||
policy_vcs_ufp_send_ps_rdy,
|
||||
|
||||
policy_drs_ufp_evaluate,
|
||||
policy_drs_ufp_accept,
|
||||
policy_drs_ufp_reject,
|
||||
policy_drs_ufp_change,
|
||||
policy_drs_ufp_send_swap,
|
||||
|
||||
policy_drs_dfp_evaluate,
|
||||
policy_drs_dfp_accept,
|
||||
policy_drs_dfp_reject,
|
||||
policy_drs_dfp_change,
|
||||
policy_drs_dfp_send_swap,
|
||||
};
|
||||
|
||||
enum tcpm_rp_value {
|
||||
|
||||
Reference in New Issue
Block a user