aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/phy
diff options
context:
space:
mode:
authorAnton Tikhomirov <av.tikhomirov@samsung.com>2013-10-02 23:42:04 -0400
committerFelipe Balbi <balbi@ti.com>2013-10-04 10:44:49 -0400
commitec04996a080d825f8acdf0f8fbb2f3ebd5963cf3 (patch)
treedcd9889f256659ce68434ca764beb657c04687a1 /drivers/usb/phy
parent68041785d0c69884c4adb3bcab48f92ac3e75629 (diff)
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: Anton Tikhomirov <av.tikhomirov@samsung.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/phy')
-rw-r--r--drivers/usb/phy/phy-fsm-usb.c18
-rw-r--r--drivers/usb/phy/phy-fsm-usb.h36
2 files changed, 50 insertions, 4 deletions
diff --git a/drivers/usb/phy/phy-fsm-usb.c b/drivers/usb/phy/phy-fsm-usb.c
index d5c6db004531..329c2d2f8595 100644
--- a/drivers/usb/phy/phy-fsm-usb.c
+++ b/drivers/usb/phy/phy-fsm-usb.c
@@ -71,8 +71,11 @@ void otg_leave_state(struct otg_fsm *fsm, enum usb_otg_state old_state)
71 case OTG_STATE_B_IDLE: 71 case OTG_STATE_B_IDLE:
72 otg_del_timer(fsm, B_SE0_SRP); 72 otg_del_timer(fsm, B_SE0_SRP);
73 fsm->b_se0_srp = 0; 73 fsm->b_se0_srp = 0;
74 fsm->adp_sns = 0;
75 fsm->adp_prb = 0;
74 break; 76 break;
75 case OTG_STATE_B_SRP_INIT: 77 case OTG_STATE_B_SRP_INIT:
78 fsm->data_pulse = 0;
76 fsm->b_srp_done = 0; 79 fsm->b_srp_done = 0;
77 break; 80 break;
78 case OTG_STATE_B_PERIPHERAL: 81 case OTG_STATE_B_PERIPHERAL:
@@ -84,6 +87,7 @@ void otg_leave_state(struct otg_fsm *fsm, enum usb_otg_state old_state)
84 case OTG_STATE_B_HOST: 87 case OTG_STATE_B_HOST:
85 break; 88 break;
86 case OTG_STATE_A_IDLE: 89 case OTG_STATE_A_IDLE:
90 fsm->adp_prb = 0;
87 break; 91 break;
88 case OTG_STATE_A_WAIT_VRISE: 92 case OTG_STATE_A_WAIT_VRISE:
89 otg_del_timer(fsm, A_WAIT_VRISE); 93 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 otg_chrg_vbus(fsm, 0); 135 otg_chrg_vbus(fsm, 0);
132 otg_loc_conn(fsm, 0); 136 otg_loc_conn(fsm, 0);
133 otg_loc_sof(fsm, 0); 137 otg_loc_sof(fsm, 0);
138 /*
139 * Driver is responsible for starting ADP probing
140 * if ADP sensing times out.
141 */
142 otg_start_adp_sns(fsm);
134 otg_set_protocol(fsm, PROTO_UNDEF); 143 otg_set_protocol(fsm, PROTO_UNDEF);
135 otg_add_timer(fsm, B_SE0_SRP); 144 otg_add_timer(fsm, B_SE0_SRP);
136 break; 145 break;
@@ -167,6 +176,7 @@ int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state)
167 otg_chrg_vbus(fsm, 0); 176 otg_chrg_vbus(fsm, 0);
168 otg_loc_conn(fsm, 0); 177 otg_loc_conn(fsm, 0);
169 otg_loc_sof(fsm, 0); 178 otg_loc_sof(fsm, 0);
179 otg_start_adp_prb(fsm);
170 otg_set_protocol(fsm, PROTO_HOST); 180 otg_set_protocol(fsm, PROTO_HOST);
171 break; 181 break;
172 case OTG_STATE_A_WAIT_VRISE: 182 case OTG_STATE_A_WAIT_VRISE:
@@ -256,7 +266,8 @@ int otg_statemachine(struct otg_fsm *fsm)
256 otg_set_state(fsm, OTG_STATE_A_IDLE); 266 otg_set_state(fsm, OTG_STATE_A_IDLE);
257 else if (fsm->b_sess_vld && fsm->otg->gadget) 267 else if (fsm->b_sess_vld && fsm->otg->gadget)
258 otg_set_state(fsm, OTG_STATE_B_PERIPHERAL); 268 otg_set_state(fsm, OTG_STATE_B_PERIPHERAL);
259 else if (fsm->b_bus_req && fsm->b_ssend_srp && fsm->b_se0_srp) 269 else if ((fsm->b_bus_req || fsm->adp_change || fsm->power_up) &&
270 fsm->b_ssend_srp && fsm->b_se0_srp)
260 otg_set_state(fsm, OTG_STATE_B_SRP_INIT); 271 otg_set_state(fsm, OTG_STATE_B_SRP_INIT);
261 break; 272 break;
262 case OTG_STATE_B_SRP_INIT: 273 case OTG_STATE_B_SRP_INIT:
@@ -283,13 +294,14 @@ int otg_statemachine(struct otg_fsm *fsm)
283 case OTG_STATE_B_HOST: 294 case OTG_STATE_B_HOST:
284 if (!fsm->id || !fsm->b_sess_vld) 295 if (!fsm->id || !fsm->b_sess_vld)
285 otg_set_state(fsm, OTG_STATE_B_IDLE); 296 otg_set_state(fsm, OTG_STATE_B_IDLE);
286 else if (!fsm->b_bus_req || !fsm->a_conn) 297 else if (!fsm->b_bus_req || !fsm->a_conn || fsm->test_device)
287 otg_set_state(fsm, OTG_STATE_B_PERIPHERAL); 298 otg_set_state(fsm, OTG_STATE_B_PERIPHERAL);
288 break; 299 break;
289 case OTG_STATE_A_IDLE: 300 case OTG_STATE_A_IDLE:
290 if (fsm->id) 301 if (fsm->id)
291 otg_set_state(fsm, OTG_STATE_B_IDLE); 302 otg_set_state(fsm, OTG_STATE_B_IDLE);
292 else if (!fsm->a_bus_drop && (fsm->a_bus_req || fsm->a_srp_det)) 303 else if (!fsm->a_bus_drop && (fsm->a_bus_req ||
304 fsm->a_srp_det || fsm->adp_change || fsm->power_up))
293 otg_set_state(fsm, OTG_STATE_A_WAIT_VRISE); 305 otg_set_state(fsm, OTG_STATE_A_WAIT_VRISE);
294 break; 306 break;
295 case OTG_STATE_A_WAIT_VRISE: 307 case OTG_STATE_A_WAIT_VRISE:
diff --git a/drivers/usb/phy/phy-fsm-usb.h b/drivers/usb/phy/phy-fsm-usb.h
index 2f185ed0f54f..6ce3b3cfd7b5 100644
--- a/drivers/usb/phy/phy-fsm-usb.h
+++ b/drivers/usb/phy/phy-fsm-usb.h
@@ -54,6 +54,9 @@ enum otg_fsm_timer {
54/* OTG state machine according to the OTG spec */ 54/* OTG state machine according to the OTG spec */
55struct otg_fsm { 55struct otg_fsm {
56 /* Input */ 56 /* Input */
57 int adp_change;
58 int power_up;
59 int test_device;
57 int a_bus_drop; 60 int a_bus_drop;
58 int a_bus_req; 61 int a_bus_req;
59 int a_bus_resume; 62 int a_bus_resume;
@@ -93,9 +96,12 @@ struct otg_fsm {
93 int b_bus_req_inf; 96 int b_bus_req_inf;
94 97
95 /* Output */ 98 /* Output */
99 int data_pulse;
96 int drv_vbus; 100 int drv_vbus;
97 int loc_conn; 101 int loc_conn;
98 int loc_sof; 102 int loc_sof;
103 int adp_prb;
104 int adp_sns;
99 105
100 struct otg_fsm_ops *ops; 106 struct otg_fsm_ops *ops;
101 struct usb_otg *otg; 107 struct usb_otg *otg;
@@ -111,6 +117,8 @@ struct otg_fsm_ops {
111 void (*loc_conn)(struct otg_fsm *fsm, int on); 117 void (*loc_conn)(struct otg_fsm *fsm, int on);
112 void (*loc_sof)(struct otg_fsm *fsm, int on); 118 void (*loc_sof)(struct otg_fsm *fsm, int on);
113 void (*start_pulse)(struct otg_fsm *fsm); 119 void (*start_pulse)(struct otg_fsm *fsm);
120 void (*start_adp_prb)(struct otg_fsm *fsm);
121 void (*start_adp_sns)(struct otg_fsm *fsm);
114 void (*add_timer)(struct otg_fsm *fsm, enum otg_fsm_timer timer); 122 void (*add_timer)(struct otg_fsm *fsm, enum otg_fsm_timer timer);
115 void (*del_timer)(struct otg_fsm *fsm, enum otg_fsm_timer timer); 123 void (*del_timer)(struct otg_fsm *fsm, enum otg_fsm_timer timer);
116 int (*start_host)(struct otg_fsm *fsm, int on); 124 int (*start_host)(struct otg_fsm *fsm, int on);
@@ -163,7 +171,33 @@ static inline int otg_start_pulse(struct otg_fsm *fsm)
163{ 171{
164 if (!fsm->ops->start_pulse) 172 if (!fsm->ops->start_pulse)
165 return -EOPNOTSUPP; 173 return -EOPNOTSUPP;
166 fsm->ops->start_pulse(fsm); 174 if (!fsm->data_pulse) {
175 fsm->data_pulse = 1;
176 fsm->ops->start_pulse(fsm);
177 }
178 return 0;
179}
180
181static inline int otg_start_adp_prb(struct otg_fsm *fsm)
182{
183 if (!fsm->ops->start_adp_prb)
184 return -EOPNOTSUPP;
185 if (!fsm->adp_prb) {
186 fsm->adp_sns = 0;
187 fsm->adp_prb = 1;
188 fsm->ops->start_adp_prb(fsm);
189 }
190 return 0;
191}
192
193static inline int otg_start_adp_sns(struct otg_fsm *fsm)
194{
195 if (!fsm->ops->start_adp_sns)
196 return -EOPNOTSUPP;
197 if (!fsm->adp_sns) {
198 fsm->adp_sns = 1;
199 fsm->ops->start_adp_sns(fsm);
200 }
167 return 0; 201 return 0;
168} 202}
169 203