-
Notifications
You must be signed in to change notification settings - Fork 0
/
dwc_otgvar.h
224 lines (191 loc) · 6.25 KB
/
dwc_otgvar.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
/* $NetBSD: $ */
/* $FreeBSD: src/sys/dev/usb/controller/dwc_otg.h,v 1.12 2012/09/27 15:23:38 hselasky Exp $ */
/*-
* Copyright (c) 2012 Hans Petter Selasky. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _DWC_OTGVAR_H_
#define _DWC_OTGVAR_H_
#define DWC_OTG_MAX_DEVICES MIN(USB_MAX_DEVICES, 32)
#define DWC_OTG_FRAME_MASK 0x7FF
#define DWC_OTG_MAX_TXP 4
#define DWC_OTG_MAX_TXN (0x200 * DWC_OTG_MAX_TXP)
#define DWC_OTG_MAX_CHANNELS 16
#define DWC_OTG_MAX_ENDPOINTS 16
#define DWC_OTG_HOST_TIMER_RATE 10 /* ms */
struct dwc_otg_td;
typedef uint8_t (dwc_otg_cmd_t)(struct dwc_otg_td *td);
typedef struct dwc_otg_td {
struct dwc_otg_td *obj_next;
dwc_otg_cmd_t *func;
usbd_xfer_handle xfer;
void *buf;
// usb_dma_t *dmap;
uint32_t tx_bytes;
uint32_t offset;
uint32_t remainder;
uint32_t hcchar; /* HOST CFG */
uint32_t hcsplt; /* HOST CFG */
uint16_t max_packet_size; /* packet_size */
uint16_t npkt;
uint8_t errcnt;
uint8_t tmr_res;
uint8_t tmr_val;
uint8_t curr_frame;
uint8_t ep_no;
uint8_t channel;
uint8_t state;
#define DWC_CHAN_ST_START 0
#define DWC_CHAN_ST_WAIT_ANE 1
#define DWC_CHAN_ST_WAIT_S_ANE 2
#define DWC_CHAN_ST_WAIT_C_ANE 3
#define DWC_CHAN_ST_RX_PKT 4
#define DWC_CHAN_ST_RX_SPKT 5
#define DWC_CHAN_ST_RX_SPKT_SYNC 6
#define DWC_CHAN_ST_TX_PKT 4
#define DWC_CHAN_ST_TX_CPKT 5
#define DWC_CHAN_ST_TX_PKT_SYNC 6
uint8_t error:1;
uint8_t error_any:1;
uint8_t error_stall:1;
uint8_t alt_next:1;
uint8_t short_pkt:1;
uint8_t did_stall:1;
uint8_t toggle:1;
uint8_t set_toggle:1;
uint8_t got_short:1;
uint8_t did_nak:1;
} dwc_otg_td_t;
struct dwc_otg_std_temp {
dwc_otg_cmd_t *func;
usbd_xfer_handle xfer;
void *buf;
// usb_dma_t *dmap;
struct dwc_otg_td *td;
struct dwc_otg_td *td_next;
uint32_t len;
uint32_t offset;
uint16_t max_frame_size;
uint8_t short_pkt;
/*
* short_pkt = 0: transfer should be short terminated
* short_pkt = 1: transfer should not be short terminated
*/
uint8_t setup_alt_next;
uint8_t did_stall;
uint8_t bulk_or_control;
};
struct dwc_otg_flags {
uint8_t change_connect:1;
uint8_t change_suspend:1;
uint8_t change_reset:1;
uint8_t change_enabled:1;
uint8_t change_over_current:1;
uint8_t status_suspend:1; /* set if suspended */
uint8_t status_vbus:1; /* set if present */
uint8_t status_bus_reset:1; /* set if reset complete */
uint8_t status_high_speed:1; /* set if High Speed is selected */
uint8_t status_low_speed:1; /* set if Low Speed is selected */
uint8_t status_device_mode:1; /* set if device mode */
uint8_t self_powered:1;
uint8_t clocks_off:1;
uint8_t port_powered:1;
uint8_t port_enabled:1;
uint8_t port_over_current:1;
uint8_t d_pulled_up:1;
};
typedef struct dwc_otg_soft_ed {
} dwc_otg_soft_ed_t;
typedef struct dwc_otg_soft_td {
dwc_otg_td_t *td;
usb_dma_t dma;
int offs;
} dwc_otg_soft_td_t;
struct dwc_otg_xfer {
struct usbd_xfer xfer; /* Needs to be first */
struct usb_task abort_task;
TAILQ_ENTRY(dwc_otg_xfer) xnext; /* list of active/complete xfers */
void *td_start[1];
dwc_otg_td_t *td_transfer_first;
dwc_otg_td_t *td_transfer_last;
dwc_otg_td_t *td_transfer_cache;
};
struct dwc_otg_chan_state {
uint32_t hcint;
uint8_t wait_sof;
uint8_t allocated;
uint8_t suspended;
};
typedef struct dwc_otg_softc {
device_t sc_dev;
struct usbd_bus sc_bus;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
bus_size_t sc_size;
kmutex_t sc_lock;
kmutex_t sc_intr_lock;
void *sc_rhc_si;
void *sc_dvd_si;
int sc_noport;
usbd_xfer_handle sc_intrxfer;
device_t sc_child; /* /dev/usb# device */
char sc_dying;
struct usb_dma_reserve sc_dma_reserve;
char sc_vendor[32]; /* vendor string for root hub */
int sc_id_vendor; /* vendor ID for root hub */
TAILQ_HEAD(, dwc_otg_xfer) sc_active; /* active transfers */
TAILQ_HEAD(, dwc_otg_xfer) sc_complete; /* complete transfers */
/* From FreeBSD softc */
struct callout sc_timer;
uint32_t sc_rx_bounce_buffer[1024 / 4];
uint32_t sc_tx_bounce_buffer[(512 * DWC_OTG_MAX_TXP) / 4];
uint32_t sc_fifo_size;
uint32_t sc_irq_mask;
uint32_t sc_last_rx_status;
uint32_t sc_out_ctl[DWC_OTG_MAX_ENDPOINTS];
uint32_t sc_in_ctl[DWC_OTG_MAX_ENDPOINTS];
struct dwc_otg_chan_state sc_chan_state[DWC_OTG_MAX_CHANNELS];
uint32_t sc_hprt_val;
uint32_t sc_tmr_val; /* timer value */
uint16_t sc_active_rx_ep;
uint8_t sc_timer_active;
uint8_t sc_dev_ep_max;
uint8_t sc_dev_in_ep_max;
uint8_t sc_host_ch_max;
uint8_t sc_addr; /* device address */
uint8_t sc_conf; /* device configuration */
uint8_t sc_mode; /* mode of operation */
#define DWC_MODE_OTG 0 /* both modes */
#define DWC_MODE_DEVICE 1 /* device only */
#define DWC_MODE_HOST 2 /* host only */
struct dwc_otg_flags sc_flags;
} dwc_otg_softc_t;
usbd_status dwc_otg_init(dwc_otg_softc_t *);
int dwc_otg_intr(void *);
int dwc_otg_detach(dwc_otg_softc_t *, int);
bool dwc_otg_shutdown(device_t, int);
void dwc_otg_childdet(device_t, device_t);
int dwc_otg_activate(device_t, enum devact);
bool dwc_otg_resume(device_t, const pmf_qual_t *);
bool dwc_otg_suspend(device_t, const pmf_qual_t *);
#endif /* _DWC_OTGVAR_H_ */