]>
Commit | Line | Data |
---|---|---|
5be19a9d XS |
1 | /* |
2 | * Intel Langwell USB Device Controller driver | |
3 | * Copyright (C) 2008-2009, Intel Corporation. | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify it | |
6 | * under the terms and conditions of the GNU General Public License, | |
7 | * version 2, as published by the Free Software Foundation. | |
5be19a9d XS |
8 | */ |
9 | ||
10 | #include <linux/usb/langwell_udc.h> | |
5be19a9d | 11 | #include <linux/usb/langwell_otg.h> |
5be19a9d XS |
12 | |
13 | /*-------------------------------------------------------------------------*/ | |
14 | ||
15 | /* driver data structures and utilities */ | |
16 | ||
17 | /* | |
18 | * dTD: Device Endpoint Transfer Descriptor | |
19 | * describe to the device controller the location and quantity of | |
20 | * data to be send/received for given transfer | |
21 | */ | |
22 | struct langwell_dtd { | |
23 | u32 dtd_next; | |
24 | /* bits 31:5, next transfer element pointer */ | |
25 | #define DTD_NEXT(d) (((d)>>5)&0x7ffffff) | |
26 | #define DTD_NEXT_MASK (0x7ffffff << 5) | |
27 | /* terminate */ | |
28 | #define DTD_TERM BIT(0) | |
29 | /* bits 7:0, execution back states */ | |
30 | u32 dtd_status:8; | |
31 | #define DTD_STATUS(d) (((d)>>0)&0xff) | |
32 | #define DTD_STS_ACTIVE BIT(7) /* active */ | |
33 | #define DTD_STS_HALTED BIT(6) /* halted */ | |
34 | #define DTD_STS_DBE BIT(5) /* data buffer error */ | |
35 | #define DTD_STS_TRE BIT(3) /* transaction error */ | |
36 | /* bits 9:8 */ | |
37 | u32 dtd_res0:2; | |
38 | /* bits 11:10, multipier override */ | |
39 | u32 dtd_multo:2; | |
40 | #define DTD_MULTO (BIT(11) | BIT(10)) | |
41 | /* bits 14:12 */ | |
42 | u32 dtd_res1:3; | |
43 | /* bit 15, interrupt on complete */ | |
44 | u32 dtd_ioc:1; | |
45 | #define DTD_IOC BIT(15) | |
46 | /* bits 30:16, total bytes */ | |
47 | u32 dtd_total:15; | |
48 | #define DTD_TOTAL(d) (((d)>>16)&0x7fff) | |
49 | #define DTD_MAX_TRANSFER_LENGTH 0x4000 | |
50 | /* bit 31 */ | |
51 | u32 dtd_res2:1; | |
52 | /* dTD buffer pointer page 0 to 4 */ | |
53 | u32 dtd_buf[5]; | |
54 | #define DTD_OFFSET_MASK 0xfff | |
55 | /* bits 31:12, buffer pointer */ | |
56 | #define DTD_BUFFER(d) (((d)>>12)&0x3ff) | |
57 | /* bits 11:0, current offset */ | |
58 | #define DTD_C_OFFSET(d) (((d)>>0)&0xfff) | |
59 | /* bits 10:0, frame number */ | |
60 | #define DTD_FRAME(d) (((d)>>0)&0x7ff) | |
61 | ||
62 | /* driver-private parts */ | |
63 | ||
64 | /* dtd dma address */ | |
65 | dma_addr_t dtd_dma; | |
66 | /* next dtd virtual address */ | |
67 | struct langwell_dtd *next_dtd_virt; | |
68 | }; | |
69 | ||
70 | ||
71 | /* | |
72 | * dQH: Device Endpoint Queue Head | |
73 | * describe where all transfers are managed | |
74 | * 48-byte data structure, aligned on 64-byte boundary | |
75 | * | |
76 | * These are associated with dTD structure | |
77 | */ | |
78 | struct langwell_dqh { | |
79 | /* endpoint capabilities and characteristics */ | |
80 | u32 dqh_res0:15; /* bits 14:0 */ | |
81 | u32 dqh_ios:1; /* bit 15, interrupt on setup */ | |
82 | #define DQH_IOS BIT(15) | |
83 | u32 dqh_mpl:11; /* bits 26:16, maximum packet length */ | |
84 | #define DQH_MPL (0x7ff << 16) | |
85 | u32 dqh_res1:2; /* bits 28:27 */ | |
86 | u32 dqh_zlt:1; /* bit 29, zero length termination */ | |
87 | #define DQH_ZLT BIT(29) | |
88 | u32 dqh_mult:2; /* bits 31:30 */ | |
89 | #define DQH_MULT (BIT(30) | BIT(31)) | |
90 | ||
91 | /* current dTD pointer */ | |
92 | u32 dqh_current; /* locate the transfer in progress */ | |
93 | #define DQH_C_DTD(e) \ | |
94 | (((e)>>5)&0x7ffffff) /* bits 31:5, current dTD pointer */ | |
95 | ||
96 | /* transfer overlay, hardware parts of a struct langwell_dtd */ | |
97 | u32 dtd_next; | |
98 | u32 dtd_status:8; /* bits 7:0, execution back states */ | |
99 | u32 dtd_res0:2; /* bits 9:8 */ | |
100 | u32 dtd_multo:2; /* bits 11:10, multipier override */ | |
101 | u32 dtd_res1:3; /* bits 14:12 */ | |
102 | u32 dtd_ioc:1; /* bit 15, interrupt on complete */ | |
103 | u32 dtd_total:15; /* bits 30:16, total bytes */ | |
104 | u32 dtd_res2:1; /* bit 31 */ | |
105 | u32 dtd_buf[5]; /* dTD buffer pointer page 0 to 4 */ | |
106 | ||
107 | u32 dqh_res2; | |
108 | struct usb_ctrlrequest dqh_setup; /* setup packet buffer */ | |
109 | } __attribute__ ((aligned(64))); | |
110 | ||
111 | ||
112 | /* endpoint data structure */ | |
113 | struct langwell_ep { | |
114 | struct usb_ep ep; | |
115 | dma_addr_t dma; | |
116 | struct langwell_udc *dev; | |
117 | unsigned long irqs; | |
118 | struct list_head queue; | |
119 | struct langwell_dqh *dqh; | |
120 | const struct usb_endpoint_descriptor *desc; | |
121 | char name[14]; | |
122 | unsigned stopped:1, | |
123 | ep_type:2, | |
124 | ep_num:8; | |
125 | }; | |
126 | ||
127 | ||
128 | /* request data structure */ | |
129 | struct langwell_request { | |
130 | struct usb_request req; | |
131 | struct langwell_dtd *dtd, *head, *tail; | |
132 | struct langwell_ep *ep; | |
133 | dma_addr_t dtd_dma; | |
134 | struct list_head queue; | |
135 | unsigned dtd_count; | |
136 | unsigned mapped:1; | |
137 | }; | |
138 | ||
139 | ||
140 | /* ep0 transfer state */ | |
141 | enum ep0_state { | |
142 | WAIT_FOR_SETUP, | |
143 | DATA_STATE_XMIT, | |
144 | DATA_STATE_NEED_ZLP, | |
145 | WAIT_FOR_OUT_STATUS, | |
146 | DATA_STATE_RECV, | |
147 | }; | |
148 | ||
149 | ||
150 | /* device suspend state */ | |
151 | enum lpm_state { | |
152 | LPM_L0, /* on */ | |
153 | LPM_L1, /* LPM L1 sleep */ | |
154 | LPM_L2, /* suspend */ | |
155 | LPM_L3, /* off */ | |
156 | }; | |
157 | ||
158 | ||
159 | /* device data structure */ | |
160 | struct langwell_udc { | |
161 | /* each pci device provides one gadget, several endpoints */ | |
162 | struct usb_gadget gadget; | |
163 | spinlock_t lock; /* device lock */ | |
164 | struct langwell_ep *ep; | |
165 | struct usb_gadget_driver *driver; | |
166 | struct otg_transceiver *transceiver; | |
167 | u8 dev_addr; | |
168 | u32 usb_state; | |
169 | u32 resume_state; | |
170 | u32 bus_reset; | |
171 | enum lpm_state lpm_state; | |
172 | enum ep0_state ep0_state; | |
173 | u32 ep0_dir; | |
174 | u16 dciversion; | |
175 | unsigned ep_max; | |
176 | unsigned devcap:1, | |
177 | enabled:1, | |
178 | region:1, | |
179 | got_irq:1, | |
180 | powered:1, | |
181 | remote_wakeup:1, | |
182 | rate:1, | |
183 | is_reset:1, | |
184 | softconnected:1, | |
185 | vbus_active:1, | |
186 | suspended:1, | |
187 | stopped:1, | |
912c93d1 J |
188 | lpm:1, /* LPM capability */ |
189 | has_sram:1, /* SRAM caching */ | |
190 | got_sram:1; | |
5be19a9d XS |
191 | |
192 | /* pci state used to access those endpoints */ | |
193 | struct pci_dev *pdev; | |
194 | ||
195 | /* Langwell otg transceiver */ | |
196 | struct langwell_otg *lotg; | |
197 | ||
198 | /* control registers */ | |
199 | struct langwell_cap_regs __iomem *cap_regs; | |
200 | struct langwell_op_regs __iomem *op_regs; | |
201 | ||
202 | struct usb_ctrlrequest local_setup_buff; | |
203 | struct langwell_dqh *ep_dqh; | |
204 | size_t ep_dqh_size; | |
205 | dma_addr_t ep_dqh_dma; | |
206 | ||
207 | /* ep0 status request */ | |
208 | struct langwell_request *status_req; | |
209 | ||
210 | /* dma pool */ | |
211 | struct dma_pool *dtd_pool; | |
212 | ||
213 | /* make sure release() is done */ | |
214 | struct completion *done; | |
3211cbc2 | 215 | |
912c93d1 J |
216 | /* for private SRAM caching */ |
217 | unsigned int sram_addr; | |
218 | unsigned int sram_size; | |
219 | ||
3211cbc2 J |
220 | /* device status data for get_status request */ |
221 | u16 dev_status; | |
5be19a9d XS |
222 | }; |
223 | ||
2c7f0989 FB |
224 | #define gadget_to_langwell(g) container_of((g), struct langwell_udc, gadget) |
225 |