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
53 typedef 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
66 extern 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
99 enum 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
202 enum 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
209 struct usb_phy;
210 struct usb_hcd;
211
212 static inline int
usb_phy_set_suspend(struct usb_phy * x,int suspend)213 usb_phy_set_suspend(struct usb_phy *x, int suspend)
214 {
215
216 return 0;
217 }
218
219 static inline void
usb_hcd_resume_root_hub(struct usb_hcd * hcd)220 usb_hcd_resume_root_hub(struct usb_hcd *hcd)
221 {
222
223 return;
224 }
225
226 static inline int
usb_disabled(void)227 usb_disabled(void)
228 {
229
230 return 0;
231 }
232
233 static inline void
udelay(unsigned long usecs)234 udelay(unsigned long usecs)
235 {
236 DELAY(usecs);
237 }
238
239 static inline void
mdelay(unsigned long msecs)240 mdelay(unsigned long msecs)
241 {
242 int loops = msecs;
243 while (loops--)
244 DELAY(1000);
245 }
246
247 static inline void
usleep_range(unsigned long min,unsigned long max)248 usleep_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
259 void dw_timeout(void *);
260
261 struct 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
270 static inline void
INIT_DELAYED_WORK(struct delayed_work * dw,void (* fn)(void *),void * arg)271 INIT_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
278 static inline void
queue_delayed_work(struct taskq * wq,struct delayed_work * dw,int j)279 queue_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