diff options
author | Anton Tikhomirov <av.tikhomirov@samsung.com> | 2013-10-02 23:42:04 -0400 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2013-10-04 10:44:49 -0400 |
commit | ec04996a080d825f8acdf0f8fbb2f3ebd5963cf3 (patch) | |
tree | dcd9889f256659ce68434ca764beb657c04687a1 /drivers/usb/phy | |
parent | 68041785d0c69884c4adb3bcab48f92ac3e75629 (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.c | 18 | ||||
-rw-r--r-- | drivers/usb/phy/phy-fsm-usb.h | 36 |
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 */ |
55 | struct otg_fsm { | 55 | struct 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 | |||
181 | static 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 | |||
193 | static 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 | ||