Commit ec04996a authored by Anton Tikhomirov's avatar Anton Tikhomirov Committed by Felipe Balbi

usb: phy: Add and use missed OTG FSM inputs/outputs

Several input/output variables missed in current FSM implementation.
This patch adds and makes use of them as specified in OTG and EH
supplement to USB2.0.
Signed-off-by: default avatarAnton Tikhomirov <av.tikhomirov@samsung.com>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent 68041785
...@@ -71,8 +71,11 @@ void otg_leave_state(struct otg_fsm *fsm, enum usb_otg_state old_state) ...@@ -71,8 +71,11 @@ void otg_leave_state(struct otg_fsm *fsm, enum usb_otg_state old_state)
case OTG_STATE_B_IDLE: case OTG_STATE_B_IDLE:
otg_del_timer(fsm, B_SE0_SRP); otg_del_timer(fsm, B_SE0_SRP);
fsm->b_se0_srp = 0; fsm->b_se0_srp = 0;
fsm->adp_sns = 0;
fsm->adp_prb = 0;
break; break;
case OTG_STATE_B_SRP_INIT: case OTG_STATE_B_SRP_INIT:
fsm->data_pulse = 0;
fsm->b_srp_done = 0; fsm->b_srp_done = 0;
break; break;
case OTG_STATE_B_PERIPHERAL: case OTG_STATE_B_PERIPHERAL:
...@@ -84,6 +87,7 @@ void otg_leave_state(struct otg_fsm *fsm, enum usb_otg_state old_state) ...@@ -84,6 +87,7 @@ void otg_leave_state(struct otg_fsm *fsm, enum usb_otg_state old_state)
case OTG_STATE_B_HOST: case OTG_STATE_B_HOST:
break; break;
case OTG_STATE_A_IDLE: case OTG_STATE_A_IDLE:
fsm->adp_prb = 0;
break; break;
case OTG_STATE_A_WAIT_VRISE: case OTG_STATE_A_WAIT_VRISE:
otg_del_timer(fsm, A_WAIT_VRISE); otg_del_timer(fsm, A_WAIT_VRISE);
...@@ -131,6 +135,11 @@ int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state) ...@@ -131,6 +135,11 @@ int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state)
otg_chrg_vbus(fsm, 0); otg_chrg_vbus(fsm, 0);
otg_loc_conn(fsm, 0); otg_loc_conn(fsm, 0);
otg_loc_sof(fsm, 0); otg_loc_sof(fsm, 0);
/*
* Driver is responsible for starting ADP probing
* if ADP sensing times out.
*/
otg_start_adp_sns(fsm);
otg_set_protocol(fsm, PROTO_UNDEF); otg_set_protocol(fsm, PROTO_UNDEF);
otg_add_timer(fsm, B_SE0_SRP); otg_add_timer(fsm, B_SE0_SRP);
break; break;
...@@ -167,6 +176,7 @@ int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state) ...@@ -167,6 +176,7 @@ int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state)
otg_chrg_vbus(fsm, 0); otg_chrg_vbus(fsm, 0);
otg_loc_conn(fsm, 0); otg_loc_conn(fsm, 0);
otg_loc_sof(fsm, 0); otg_loc_sof(fsm, 0);
otg_start_adp_prb(fsm);
otg_set_protocol(fsm, PROTO_HOST); otg_set_protocol(fsm, PROTO_HOST);
break; break;
case OTG_STATE_A_WAIT_VRISE: case OTG_STATE_A_WAIT_VRISE:
...@@ -256,7 +266,8 @@ int otg_statemachine(struct otg_fsm *fsm) ...@@ -256,7 +266,8 @@ int otg_statemachine(struct otg_fsm *fsm)
otg_set_state(fsm, OTG_STATE_A_IDLE); otg_set_state(fsm, OTG_STATE_A_IDLE);
else if (fsm->b_sess_vld && fsm->otg->gadget) else if (fsm->b_sess_vld && fsm->otg->gadget)
otg_set_state(fsm, OTG_STATE_B_PERIPHERAL); otg_set_state(fsm, OTG_STATE_B_PERIPHERAL);
else if (fsm->b_bus_req && fsm->b_ssend_srp && fsm->b_se0_srp) else if ((fsm->b_bus_req || fsm->adp_change || fsm->power_up) &&
fsm->b_ssend_srp && fsm->b_se0_srp)
otg_set_state(fsm, OTG_STATE_B_SRP_INIT); otg_set_state(fsm, OTG_STATE_B_SRP_INIT);
break; break;
case OTG_STATE_B_SRP_INIT: case OTG_STATE_B_SRP_INIT:
...@@ -283,13 +294,14 @@ int otg_statemachine(struct otg_fsm *fsm) ...@@ -283,13 +294,14 @@ int otg_statemachine(struct otg_fsm *fsm)
case OTG_STATE_B_HOST: case OTG_STATE_B_HOST:
if (!fsm->id || !fsm->b_sess_vld) if (!fsm->id || !fsm->b_sess_vld)
otg_set_state(fsm, OTG_STATE_B_IDLE); otg_set_state(fsm, OTG_STATE_B_IDLE);
else if (!fsm->b_bus_req || !fsm->a_conn) else if (!fsm->b_bus_req || !fsm->a_conn || fsm->test_device)
otg_set_state(fsm, OTG_STATE_B_PERIPHERAL); otg_set_state(fsm, OTG_STATE_B_PERIPHERAL);
break; break;
case OTG_STATE_A_IDLE: case OTG_STATE_A_IDLE:
if (fsm->id) if (fsm->id)
otg_set_state(fsm, OTG_STATE_B_IDLE); otg_set_state(fsm, OTG_STATE_B_IDLE);
else if (!fsm->a_bus_drop && (fsm->a_bus_req || fsm->a_srp_det)) else if (!fsm->a_bus_drop && (fsm->a_bus_req ||
fsm->a_srp_det || fsm->adp_change || fsm->power_up))
otg_set_state(fsm, OTG_STATE_A_WAIT_VRISE); otg_set_state(fsm, OTG_STATE_A_WAIT_VRISE);
break; break;
case OTG_STATE_A_WAIT_VRISE: case OTG_STATE_A_WAIT_VRISE:
......
...@@ -54,6 +54,9 @@ enum otg_fsm_timer { ...@@ -54,6 +54,9 @@ enum otg_fsm_timer {
/* OTG state machine according to the OTG spec */ /* OTG state machine according to the OTG spec */
struct otg_fsm { struct otg_fsm {
/* Input */ /* Input */
int adp_change;
int power_up;
int test_device;
int a_bus_drop; int a_bus_drop;
int a_bus_req; int a_bus_req;
int a_bus_resume; int a_bus_resume;
...@@ -93,9 +96,12 @@ struct otg_fsm { ...@@ -93,9 +96,12 @@ struct otg_fsm {
int b_bus_req_inf; int b_bus_req_inf;
/* Output */ /* Output */
int data_pulse;
int drv_vbus; int drv_vbus;
int loc_conn; int loc_conn;
int loc_sof; int loc_sof;
int adp_prb;
int adp_sns;
struct otg_fsm_ops *ops; struct otg_fsm_ops *ops;
struct usb_otg *otg; struct usb_otg *otg;
...@@ -111,6 +117,8 @@ struct otg_fsm_ops { ...@@ -111,6 +117,8 @@ struct otg_fsm_ops {
void (*loc_conn)(struct otg_fsm *fsm, int on); void (*loc_conn)(struct otg_fsm *fsm, int on);
void (*loc_sof)(struct otg_fsm *fsm, int on); void (*loc_sof)(struct otg_fsm *fsm, int on);
void (*start_pulse)(struct otg_fsm *fsm); void (*start_pulse)(struct otg_fsm *fsm);
void (*start_adp_prb)(struct otg_fsm *fsm);
void (*start_adp_sns)(struct otg_fsm *fsm);
void (*add_timer)(struct otg_fsm *fsm, enum otg_fsm_timer timer); void (*add_timer)(struct otg_fsm *fsm, enum otg_fsm_timer timer);
void (*del_timer)(struct otg_fsm *fsm, enum otg_fsm_timer timer); void (*del_timer)(struct otg_fsm *fsm, enum otg_fsm_timer timer);
int (*start_host)(struct otg_fsm *fsm, int on); int (*start_host)(struct otg_fsm *fsm, int on);
...@@ -163,7 +171,33 @@ static inline int otg_start_pulse(struct otg_fsm *fsm) ...@@ -163,7 +171,33 @@ static inline int otg_start_pulse(struct otg_fsm *fsm)
{ {
if (!fsm->ops->start_pulse) if (!fsm->ops->start_pulse)
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (!fsm->data_pulse) {
fsm->data_pulse = 1;
fsm->ops->start_pulse(fsm); fsm->ops->start_pulse(fsm);
}
return 0;
}
static inline int otg_start_adp_prb(struct otg_fsm *fsm)
{
if (!fsm->ops->start_adp_prb)
return -EOPNOTSUPP;
if (!fsm->adp_prb) {
fsm->adp_sns = 0;
fsm->adp_prb = 1;
fsm->ops->start_adp_prb(fsm);
}
return 0;
}
static inline int otg_start_adp_sns(struct otg_fsm *fsm)
{
if (!fsm->ops->start_adp_sns)
return -EOPNOTSUPP;
if (!fsm->adp_sns) {
fsm->adp_sns = 1;
fsm->ops->start_adp_sns(fsm);
}
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment