File Index
Files and directories
Sign in
FILE

otg-fsm.h

File preview with syntax highlighting.

linux-6.19.14/include/linux/usb/otg-fsm.h C
  1// SPDX-License-Identifier: GPL-2.0+
  2/*
  3 * Copyright (C) 2007,2008 Freescale Semiconductor, Inc.
  4 */
  5
  6#ifndef __LINUX_USB_OTG_FSM_H
  7#define __LINUX_USB_OTG_FSM_H
  8
  9#include <linux/mutex.h>
 10#include <linux/errno.h>
 11
 12#define PROTO_UNDEF	(0)
 13#define PROTO_HOST	(1)
 14#define PROTO_GADGET	(2)
 15
 16#define OTG_STS_SELECTOR	0xF000	/* OTG status selector, according to
 17					 * OTG and EH 2.0 Chapter 6.2.3
 18					 * Table:6-4
 19					 */
 20
 21#define HOST_REQUEST_FLAG	1	/* Host request flag, according to
 22					 * OTG and EH 2.0 Charpter 6.2.3
 23					 * Table:6-5
 24					 */
 25
 26#define T_HOST_REQ_POLL		(1500)	/* 1500ms, HNP polling interval */
 27
 28enum otg_fsm_timer {
 29	/* Standard OTG timers */
 30	A_WAIT_VRISE,
 31	A_WAIT_VFALL,
 32	A_WAIT_BCON,
 33	A_AIDL_BDIS,
 34	B_ASE0_BRST,
 35	A_BIDL_ADIS,
 36	B_AIDL_BDIS,
 37
 38	/* Auxiliary timers */
 39	B_SE0_SRP,
 40	B_SRP_FAIL,
 41	A_WAIT_ENUM,
 42	B_DATA_PLS,
 43	B_SSEND_SRP,
 44
 45	NUM_OTG_FSM_TIMERS,
 46};
 47
 48/**
 49 * struct otg_fsm - OTG state machine according to the OTG spec
 50 *
 51 * OTG hardware Inputs
 52 *
 53 *	Common inputs for A and B device
 54 * @id:		TRUE for B-device, FALSE for A-device.
 55 * @adp_change: TRUE when current ADP measurement (n) value, compared to the
 56 *		ADP measurement taken at n-2, differs by more than CADP_THR
 57 * @power_up:	TRUE when the OTG device first powers up its USB system and
 58 *		ADP measurement taken if ADP capable
 59 *
 60 *	A-Device state inputs
 61 * @a_srp_det:	TRUE if the A-device detects SRP
 62 * @a_vbus_vld:	TRUE when VBUS voltage is in regulation
 63 * @b_conn:	TRUE if the A-device detects connection from the B-device
 64 * @a_bus_resume: TRUE when the B-device detects that the A-device is signaling
 65 *		  a resume (K state)
 66 *	B-Device state inputs
 67 * @a_bus_suspend: TRUE when the B-device detects that the A-device has put the
 68 *		bus into suspend
 69 * @a_conn:	TRUE if the B-device detects a connection from the A-device
 70 * @b_se0_srp:	TRUE when the line has been at SE0 for more than the minimum
 71 *		time before generating SRP
 72 * @b_ssend_srp: TRUE when the VBUS has been below VOTG_SESS_VLD for more than
 73 *		 the minimum time before generating SRP
 74 * @b_sess_vld:	TRUE when the B-device detects that the voltage on VBUS is
 75 *		above VOTG_SESS_VLD
 76 * @test_device: TRUE when the B-device switches to B-Host and detects an OTG
 77 *		test device. This must be set by host/hub driver
 78 *
 79 *	Application inputs (A-Device)
 80 * @a_bus_drop:	TRUE when A-device application needs to power down the bus
 81 * @a_bus_req:	TRUE when A-device application wants to use the bus.
 82 *		FALSE to suspend the bus
 83 *
 84 *	Application inputs (B-Device)
 85 * @b_bus_req:	TRUE during the time that the Application running on the
 86 *		B-device wants to use the bus
 87 *
 88 *	Auxiliary inputs (OTG v1.3 only. Obsolete now.)
 89 * @a_sess_vld:	TRUE if the A-device detects that VBUS is above VA_SESS_VLD
 90 * @b_bus_suspend: TRUE when the A-device detects that the B-device has put
 91 *		the bus into suspend
 92 * @b_bus_resume: TRUE when the A-device detects that the B-device is signaling
 93 *		 resume on the bus
 94 *
 95 * OTG Output status. Read only for users. Updated by OTG FSM helpers defined
 96 * in this file
 97 *
 98 *	Outputs for Both A and B device
 99 * @drv_vbus:	TRUE when A-device is driving VBUS
100 * @loc_conn:	TRUE when the local device has signaled that it is connected
101 *		to the bus
102 * @loc_sof:	TRUE when the local device is generating activity on the bus
103 * @adp_prb:	TRUE when the local device is in the process of doing
104 *		ADP probing
105 *
106 *	Outputs for B-device state
107 * @adp_sns:	TRUE when the B-device is in the process of carrying out
108 *		ADP sensing
109 * @data_pulse: TRUE when the B-device is performing data line pulsing
110 *
111 * Internal Variables
112 *
113 * a_set_b_hnp_en: TRUE when the A-device has successfully set the
114 *		b_hnp_enable bit in the B-device.
115 *		   Unused as OTG fsm uses otg->host->b_hnp_enable instead
116 * b_srp_done:	TRUE when the B-device has completed initiating SRP
117 * b_hnp_enable: TRUE when the B-device has accepted the
118 *		SetFeature(b_hnp_enable) B-device.
119 *		Unused as OTG fsm uses otg->gadget->b_hnp_enable instead
120 * a_clr_err:	Asserted (by application ?) to clear a_vbus_err due to an
121 *		overcurrent condition and causes the A-device to transition
122 *		to a_wait_vfall
123 */
124struct otg_fsm {
125	/* Input */
126	int id;
127	int adp_change;
128	int power_up;
129	int a_srp_det;
130	int a_vbus_vld;
131	int b_conn;
132	int a_bus_resume;
133	int a_bus_suspend;
134	int a_conn;
135	int b_se0_srp;
136	int b_ssend_srp;
137	int b_sess_vld;
138	int test_device;
139	int a_bus_drop;
140	int a_bus_req;
141	int b_bus_req;
142
143	/* Auxiliary inputs */
144	int a_sess_vld;
145	int b_bus_resume;
146	int b_bus_suspend;
147
148	/* Output */
149	int drv_vbus;
150	int loc_conn;
151	int loc_sof;
152	int adp_prb;
153	int adp_sns;
154	int data_pulse;
155
156	/* Internal variables */
157	int a_set_b_hnp_en;
158	int b_srp_done;
159	int b_hnp_enable;
160	int a_clr_err;
161
162	/* Informative variables. All unused as of now */
163	int a_bus_drop_inf;
164	int a_bus_req_inf;
165	int a_clr_err_inf;
166	int b_bus_req_inf;
167	/* Auxiliary informative variables */
168	int a_suspend_req_inf;
169
170	/* Timeout indicator for timers */
171	int a_wait_vrise_tmout;
172	int a_wait_vfall_tmout;
173	int a_wait_bcon_tmout;
174	int a_aidl_bdis_tmout;
175	int b_ase0_brst_tmout;
176	int a_bidl_adis_tmout;
177
178	struct otg_fsm_ops *ops;
179	struct usb_otg *otg;
180
181	/* Current usb protocol used: 0:undefine; 1:host; 2:client */
182	int protocol;
183	struct mutex lock;
184	u8 *host_req_flag;
185	struct delayed_work hnp_polling_work;
186	bool hnp_work_inited;
187	bool state_changed;
188};
189
190struct otg_fsm_ops {
191	void	(*chrg_vbus)(struct otg_fsm *fsm, int on);
192	void	(*drv_vbus)(struct otg_fsm *fsm, int on);
193	void	(*loc_conn)(struct otg_fsm *fsm, int on);
194	void	(*loc_sof)(struct otg_fsm *fsm, int on);
195	void	(*start_pulse)(struct otg_fsm *fsm);
196	void	(*start_adp_prb)(struct otg_fsm *fsm);
197	void	(*start_adp_sns)(struct otg_fsm *fsm);
198	void	(*add_timer)(struct otg_fsm *fsm, enum otg_fsm_timer timer);
199	void	(*del_timer)(struct otg_fsm *fsm, enum otg_fsm_timer timer);
200	int	(*start_host)(struct otg_fsm *fsm, int on);
201	int	(*start_gadget)(struct otg_fsm *fsm, int on);
202};
203
204
205static inline int otg_chrg_vbus(struct otg_fsm *fsm, int on)
206{
207	if (!fsm->ops->chrg_vbus)
208		return -EOPNOTSUPP;
209	fsm->ops->chrg_vbus(fsm, on);
210	return 0;
211}
212
213static inline int otg_drv_vbus(struct otg_fsm *fsm, int on)
214{
215	if (!fsm->ops->drv_vbus)
216		return -EOPNOTSUPP;
217	if (fsm->drv_vbus != on) {
218		fsm->drv_vbus = on;
219		fsm->ops->drv_vbus(fsm, on);
220	}
221	return 0;
222}
223
224static inline int otg_loc_conn(struct otg_fsm *fsm, int on)
225{
226	if (!fsm->ops->loc_conn)
227		return -EOPNOTSUPP;
228	if (fsm->loc_conn != on) {
229		fsm->loc_conn = on;
230		fsm->ops->loc_conn(fsm, on);
231	}
232	return 0;
233}
234
235static inline int otg_loc_sof(struct otg_fsm *fsm, int on)
236{
237	if (!fsm->ops->loc_sof)
238		return -EOPNOTSUPP;
239	if (fsm->loc_sof != on) {
240		fsm->loc_sof = on;
241		fsm->ops->loc_sof(fsm, on);
242	}
243	return 0;
244}
245
246static inline int otg_start_pulse(struct otg_fsm *fsm)
247{
248	if (!fsm->ops->start_pulse)
249		return -EOPNOTSUPP;
250	if (!fsm->data_pulse) {
251		fsm->data_pulse = 1;
252		fsm->ops->start_pulse(fsm);
253	}
254	return 0;
255}
256
257static inline int otg_start_adp_prb(struct otg_fsm *fsm)
258{
259	if (!fsm->ops->start_adp_prb)
260		return -EOPNOTSUPP;
261	if (!fsm->adp_prb) {
262		fsm->adp_sns = 0;
263		fsm->adp_prb = 1;
264		fsm->ops->start_adp_prb(fsm);
265	}
266	return 0;
267}
268
269static inline int otg_start_adp_sns(struct otg_fsm *fsm)
270{
271	if (!fsm->ops->start_adp_sns)
272		return -EOPNOTSUPP;
273	if (!fsm->adp_sns) {
274		fsm->adp_sns = 1;
275		fsm->ops->start_adp_sns(fsm);
276	}
277	return 0;
278}
279
280static inline int otg_add_timer(struct otg_fsm *fsm, enum otg_fsm_timer timer)
281{
282	if (!fsm->ops->add_timer)
283		return -EOPNOTSUPP;
284	fsm->ops->add_timer(fsm, timer);
285	return 0;
286}
287
288static inline int otg_del_timer(struct otg_fsm *fsm, enum otg_fsm_timer timer)
289{
290	if (!fsm->ops->del_timer)
291		return -EOPNOTSUPP;
292	fsm->ops->del_timer(fsm, timer);
293	return 0;
294}
295
296static inline int otg_start_host(struct otg_fsm *fsm, int on)
297{
298	if (!fsm->ops->start_host)
299		return -EOPNOTSUPP;
300	return fsm->ops->start_host(fsm, on);
301}
302
303static inline int otg_start_gadget(struct otg_fsm *fsm, int on)
304{
305	if (!fsm->ops->start_gadget)
306		return -EOPNOTSUPP;
307	return fsm->ops->start_gadget(fsm, on);
308}
309
310int otg_statemachine(struct otg_fsm *fsm);
311
312#endif /* __LINUX_USB_OTG_FSM_H */
~/ Read-only file preview.