1/*	$OpenBSD: dwc2.h,v 1.16 2022/09/04 08:42:39 mglocker Exp $	*/
2/*	$NetBSD: dwc2.h,v 1.4 2014/12/23 16:20:06 macallan Exp $	*/
3
4/*-
5 * Copyright (c) 2013 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Nick Hudson
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#ifndef _EXTERNAL_BSD_DWC2_DWC2_H_
34#define _EXTERNAL_BSD_DWC2_DWC2_H_
35
36#include <sys/param.h>
37#include <sys/kernel.h>
38
39#include <sys/task.h>
40
41#include <lib/libkern/libkern.h>
42
43#define STATIC
44
45// #define DWC2_DEBUG
46// #define VERBOSE_DEBUG
47// #define CONFIG_USB_DWC2_TRACK_MISSED_SOFS
48
49#define CONFIG_USB_DWC2_HOST		1
50#define CONFIG_USB_DWC2_DUAL_ROLE	0
51#define CONFIG_USB_DWC2_PERIPHERAL	0
52
53typedef int irqreturn_t;
54#define	IRQ_NONE 0
55#define IRQ_HANDLED 1
56
57#define	u8	uint8_t
58#define	u16	uint16_t
59#define	s16	int16_t
60#define	u32	uint32_t
61#define	u64	uint64_t
62
63#define	dma_addr_t	bus_addr_t
64
65#ifdef DWC2_DEBUG
66extern int dwc2debug;
67#define	dev_info(d,fmt,...) do {			\
68	printf("%s: " fmt, device_xname(d), 		\
69	    ## __VA_ARGS__);				\
70} while (0)
71#define	dev_warn(d,fmt,...) do {			\
72	printf("%s: " fmt, device_xname(d), 		\
73	    ## __VA_ARGS__);				\
74} while (0)
75#define	dev_err(d,fmt,...) do {				\
76	printf("%s: " fmt, device_xname(d), 		\
77	    ## __VA_ARGS__);				\
78} while (0)
79#define	dev_dbg(d,fmt,...) do {				\
80	if (dwc2debug >= 1) {				\
81	    printf("%s: " fmt, device_xname(d), 	\
82		    ## __VA_ARGS__);			\
83	}						\
84} while (0)
85#define	dev_vdbg(d,fmt,...) do {			\
86	if (dwc2debug >= 2) {				\
87	    printf("%s: " fmt, device_xname(d), 	\
88		    ## __VA_ARGS__);			\
89	}						\
90} while (0)
91#else
92#define	dev_info(...) do { } while (0)
93#define	dev_warn(...) do { } while (0)
94#define	dev_err(...) do { } while (0)
95#define	dev_dbg(...) do { } while (0)
96#define	dev_vdbg(...) do { } while (0)
97#endif
98
99enum usb_otg_state {
100	OTG_STATE_RESERVED = 0,
101
102	OTG_STATE_A_HOST,
103	OTG_STATE_A_PERIPHERAL,
104	OTG_STATE_A_SUSPEND,
105	OTG_STATE_B_HOST,
106	OTG_STATE_B_PERIPHERAL,
107};
108
109#define spinlock_t		struct mutex
110#define spin_lock_init(lock)	mtx_init(lock, IPL_VM)
111#define spin_lock(l)		do { mtx_enter(l); } while (0)
112#define spin_unlock(l)		do { mtx_leave(l); } while (0)
113
114#define	spin_lock_irqsave(l, f)		\
115	do { mtx_enter(l); (void)(f); } while (0)
116
117#define	spin_trylock_irqsave(l, f)	mtx_enter_try(l)
118
119#define	spin_unlock_irqrestore(l, f)	\
120	do { mtx_leave(l); (void)(f); } while (0)
121
122#define	IRQ_RETVAL(r)	(r)
123
124#define	USB_ENDPOINT_XFER_CONTROL	UE_CONTROL		/* 0 */
125#define	USB_ENDPOINT_XFER_ISOC		UE_ISOCHRONOUS		/* 1 */
126#define	USB_ENDPOINT_XFER_BULK		UE_BULK			/* 2 */
127#define	USB_ENDPOINT_XFER_INT		UE_INTERRUPT		/* 3 */
128
129#define USB_DIR_IN			UE_DIR_IN
130#define USB_DIR_OUT			UE_DIR_OUT
131
132#define	USB_PORT_FEAT_CONNECTION	UHF_PORT_CONNECTION
133#define	USB_PORT_FEAT_ENABLE		UHF_PORT_ENABLE
134#define	USB_PORT_FEAT_SUSPEND		UHF_PORT_SUSPEND
135#define	USB_PORT_FEAT_OVER_CURRENT	UHF_PORT_OVER_CURRENT
136#define	USB_PORT_FEAT_RESET		UHF_PORT_RESET
137// #define	USB_PORT_FEAT_L1		5	/* L1 suspend */
138#define	USB_PORT_FEAT_POWER		UHF_PORT_POWER
139#define	USB_PORT_FEAT_LOWSPEED		UHF_PORT_LOW_SPEED
140#define	USB_PORT_FEAT_C_CONNECTION	UHF_C_PORT_CONNECTION
141#define	USB_PORT_FEAT_C_ENABLE		UHF_C_PORT_ENABLE
142#define	USB_PORT_FEAT_C_SUSPEND		UHF_C_PORT_SUSPEND
143#define	USB_PORT_FEAT_C_OVER_CURRENT	UHF_C_PORT_OVER_CURRENT
144#define	USB_PORT_FEAT_C_RESET		UHF_C_PORT_RESET
145#define	USB_PORT_FEAT_TEST              UHF_PORT_TEST
146#define	USB_PORT_FEAT_INDICATOR         UHF_PORT_INDICATOR
147#define	USB_PORT_FEAT_C_PORT_L1         UHF_C_PORT_L1
148
149#define	C_HUB_LOCAL_POWER		UHF_C_HUB_LOCAL_POWER
150#define	C_HUB_OVER_CURRENT		UHF_C_HUB_OVER_CURRENT
151
152#define USB_REQ_GET_STATUS		UR_GET_STATUS
153#define USB_REQ_CLEAR_FEATURE		UR_CLEAR_FEATURE
154#define USB_REQ_SET_FEATURE		UR_SET_FEATURE
155#define USB_REQ_GET_DESCRIPTOR		UR_GET_DESCRIPTOR
156
157#define	ClearHubFeature		((UT_WRITE_CLASS_DEVICE << 8) | USB_REQ_CLEAR_FEATURE)
158#define	ClearPortFeature	((UT_WRITE_CLASS_OTHER << 8) | USB_REQ_CLEAR_FEATURE)
159#define	GetHubDescriptor	((UT_READ_CLASS_DEVICE << 8) | USB_REQ_GET_DESCRIPTOR)
160#define	GetHubStatus		((UT_READ_CLASS_DEVICE << 8) | USB_REQ_GET_STATUS)
161#define	GetPortStatus		((UT_READ_CLASS_OTHER << 8) | USB_REQ_GET_STATUS)
162#define	SetHubFeature		((UT_WRITE_CLASS_DEVICE << 8) | USB_REQ_SET_FEATURE)
163#define	SetPortFeature		((UT_WRITE_CLASS_OTHER << 8) | USB_REQ_SET_FEATURE)
164
165#define	USB_PORT_STAT_CONNECTION	UPS_CURRENT_CONNECT_STATUS
166#define	USB_PORT_STAT_ENABLE		UPS_PORT_ENABLED
167#define	USB_PORT_STAT_SUSPEND		UPS_SUSPEND
168#define	USB_PORT_STAT_OVERCURRENT	UPS_OVERCURRENT_INDICATOR
169#define	USB_PORT_STAT_RESET		UPS_RESET
170#define	USB_PORT_STAT_L1		UPS_PORT_L1
171#define	USB_PORT_STAT_POWER		UPS_PORT_POWER
172#define	USB_PORT_STAT_LOW_SPEED		UPS_LOW_SPEED
173#define	USB_PORT_STAT_HIGH_SPEED        UPS_HIGH_SPEED
174#define	USB_PORT_STAT_TEST              UPS_PORT_TEST
175#define	USB_PORT_STAT_INDICATOR         UPS_PORT_INDICATOR
176
177#define	USB_PORT_STAT_C_CONNECTION	UPS_C_CONNECT_STATUS
178#define	USB_PORT_STAT_C_ENABLE		UPS_C_PORT_ENABLED
179#define	USB_PORT_STAT_C_SUSPEND		UPS_C_SUSPEND
180#define	USB_PORT_STAT_C_OVERCURRENT	UPS_C_OVERCURRENT_INDICATOR
181#define	USB_PORT_STAT_C_RESET		UPS_C_PORT_RESET
182#define	USB_PORT_STAT_C_L1		UPS_C_PORT_L1
183
184#define	USB_DT_HUB			UDESC_HUB
185
186/* See USB 2.0 spec Table 11-13, offset 3 */
187#define HUB_CHAR_LPSM		UHD_PWR
188#define HUB_CHAR_COMMON_LPSM	UHD_PWR_GANGED
189#define HUB_CHAR_INDV_PORT_LPSM	UHD_PWR_INDIVIDUAL
190#define HUB_CHAR_NO_LPSM	UHD_PWR_NO_SWITCH
191
192#define HUB_CHAR_COMPOUND	UHD_COMPOUND
193
194#define HUB_CHAR_OCPM		UHD_OC
195#define HUB_CHAR_COMMON_OCPM	UHD_OC_GLOBAL
196#define HUB_CHAR_INDV_PORT_OCPM	UHD_OC_INDIVIDUAL
197#define HUB_CHAR_NO_OCPM	UHD_OC_NONE
198
199#define HUB_CHAR_TTTT		UHD_TT_THINK
200#define HUB_CHAR_PORTIND	UHD_PORT_IND
201
202enum usb_dr_mode {
203	USB_DR_MODE_UNKNOWN,
204	USB_DR_MODE_HOST,
205	USB_DR_MODE_PERIPHERAL,
206	USB_DR_MODE_OTG,
207};
208
209struct usb_phy;
210struct usb_hcd;
211
212static inline int
213usb_phy_set_suspend(struct usb_phy *x, int suspend)
214{
215
216	return 0;
217}
218
219static inline void
220usb_hcd_resume_root_hub(struct usb_hcd *hcd)
221{
222
223	return;
224}
225
226static inline int
227usb_disabled(void)
228{
229
230	return 0;
231}
232
233static inline void
234udelay(unsigned long usecs)
235{
236	DELAY(usecs);
237}
238
239static inline void
240mdelay(unsigned long msecs)
241{
242	int loops = msecs;
243	while (loops--)
244		DELAY(1000);
245}
246
247static inline void
248usleep_range(unsigned long min, unsigned long max)
249{
250	DELAY((min + max) / 2);
251}
252
253#define dwc2_msleep(x)	mdelay(x)
254
255#define	EREMOTEIO	EIO
256#define	ECOMM		EIO
257#define	ENOTSUPP	ENOTSUP
258
259void dw_timeout(void *);
260
261struct delayed_work {
262	struct task work;
263	struct timeout dw_timer;
264
265	struct taskq *dw_wq;
266	void (*dw_fn)(void *);
267	void *dw_arg;
268};
269
270static inline void
271INIT_DELAYED_WORK(struct delayed_work *dw, void (*fn)(void *), void *arg)
272{
273	dw->dw_fn = fn;
274	dw->dw_arg = arg;
275	timeout_set(&dw->dw_timer, dw_timeout, dw);
276}
277
278static inline void
279queue_delayed_work(struct taskq *wq, struct delayed_work *dw, int j)
280{
281	dw->dw_wq = wq;
282	timeout_add(&dw->dw_timer, j);
283}
284
285#define USB_RESUME_TIMEOUT	40 /* ms */
286
287#endif
288