• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * drivers/usb/sunxi_usb/include/sunxi_udc.h
3  * (C) Copyright 2010-2015
4  * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
5  * javen, 2010-3-3, create this file
6  *
7  * usb udc head file.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of
12  * the License, or (at your option) any later version.
13  *
14  */
15 
16 #ifndef __SUNXI_UDC_H__
17 #define __SUNXI_UDC_H__
18 
19 #include <linux/usb.h>
20 #include <linux/usb/gadget.h>
21 #include <linux/dma-mapping.h>
22 #include <linux/regulator/consumer.h>
23 
24 #if 1
25 typedef struct sunxi_udc_dma {
26 	char name[32];
27 	int is_start;
28 #ifdef SW_UDC_DMA_INNER
29 	int *dma_hdle; /* dma channel handle */
30 #else
31 	struct dma_chan *chan;
32 #endif
33 } sunxi_udc_dma_t;
34 
35 typedef struct sunxi_udc_ep {
36 	struct list_head	queue;
37 	unsigned long		last_io; /* jiffies timestamp */
38 	struct usb_gadget	*gadget;
39 	struct sunxi_udc	*dev;
40 	const struct usb_endpoint_descriptor *desc;
41 	struct usb_ep		ep;
42 	u8			num;
43 
44 	unsigned short		fifo_size;
45 	u8			bEndpointAddress;
46 	u8			bmAttributes;
47 
48 	unsigned		halted : 1;
49 	unsigned		already_seen : 1;
50 	unsigned		setup_stage : 1;
51 
52 #ifdef SW_UDC_DMA_INNER
53 	int				*dma_hdle;
54 #else
55 	sunxi_udc_dma_t			sunxi_udc_dma[6];
56 #endif
57 	__u32			dma_working; /* flag. is dma busy? */
58 	__u32			dma_transfer_len; /* dma want transfer length */
59 } sunxi_udc_ep_t;
60 
61 /**
62  * Warning : ep0 has a fifo of 16 bytes.
63  * Don't try to set 32 or 64.
64  * Also testusb 14 fails  wit 16 but is fine with 8.
65  */
66 #define EP0_FIFO_SIZE			64
67 
68 #define SW_UDC_EP_FIFO_SIZE		512
69 #define SW_UDC_EP_ISO_FIFO_SIZE		1024
70 
71 #define	SW_UDC_EP_CTRL_INDEX		0x00
72 #define SW_UDC_EP_BULK_IN_INDEX	0x01
73 #define SW_UDC_EP_BULK_OUT_INDEX	0x02
74 
75 #ifdef SW_UDC_DOUBLE_FIFO
76 #define SW_UDC_FIFO_NUM		1
77 #else
78 #define SW_UDC_FIFO_NUM		0
79 #endif
80 
81 #define	SUNXI_UDC_TEST_J		0x0100
82 #define	SUNXI_UDC_TEST_K		0x0200
83 #define	SUNXI_UDC_TEST_SE0_NAK		0x0300
84 #define	SUNXI_UDC_TEST_PACKET		0x0400
85 
86 /*
87  * BSP linux5.10 copy from linux5.4 -> net2272.h;
88  * Because linux5.10 modified the net2272.h file.
89  */
90 #define 	TEST_J			1
91 #define 	TEST_K			2
92 #define 	TEST_SE0_NAK		3
93 #define		TEST_PACKET		4
94 
95 
96 static const char ep0name[] = "ep0";
97 static const char ep1in_bulk_name[]  = "ep1in-bulk";
98 static const char ep1out_bulk_name[] = "ep1out-bulk";
99 static const char ep2in_bulk_name[]  = "ep2in-bulk";
100 static const char ep2out_bulk_name[] = "ep2out-bulk";
101 static const char ep3_iso_name[]     = "ep3-iso";
102 static const char ep4_int_name[]     = "ep4-int";
103 static const char ep5in_bulk_name[]  = "ep5in-bulk";
104 static const char ep5out_bulk_name[] = "ep5out-bulk";
105 
106 struct sw_udc_fifo {
107 	const char *name;
108 	u32 fifo_addr;
109 	u32 fifo_size;
110 	u8  double_fifo;
111 };
112 
113 #if defined(CONFIG_ARCH_SUN50IW1) || defined(CONFIG_ARCH_SUN50IW3) \
114 	|| defined(CONFIG_ARCH_SUN8IW6) || defined(CONFIG_ARCH_SUN8IW15) \
115 	|| defined(CONFIG_ARCH_SUN50IW10) || defined(CONFIG_ARCH_SUN50IW9) \
116 	|| defined(CONFIG_ARCH_SUN8IW20) || defined(CONFIG_ARCH_SUN20IW1)
117 /**
118  * fifo 8k
119  *
120  * ep				fifo_addr	fifo_size
121  * "ep0",			0,		0.5k
122  * "ep1in-bulk",		0.5k,		1k
123  * "ep1out-bulk",		1.5k,		1k
124  * "ep2in-bulk",		2.5k,		1k
125  * "ep2out-bulk",		3.5k,		1k
126  * "ep3-iso",			4.5k,		2k
127  * "ep4-int",			6.5k,		0.5k
128  * "ep5in-bulk",		7k,		0.5k
129  * "ep5out-bulk",		7.5k,		0.5k
130  */
131 #define SW_UDC_EPNUMS	5
132 static const struct sw_udc_fifo ep_fifo[] = {
133 	{ep0name,          0,    512,  0},
134 	{ep1in_bulk_name,  512,  1024, 1},
135 	{ep1out_bulk_name, 1536, 1024, 1},
136 	{ep2in_bulk_name,  2560, 1024, 1},
137 	{ep2out_bulk_name, 3584, 1024, 1},
138 	{ep3_iso_name,     4608, 1024, 0},
139 	{ep4_int_name,     5632, 512,  0},
140 	{ep5in_bulk_name,  6144, 1024, 1},
141 	{ep5out_bulk_name, 7168, 1024, 1},
142 };
143 
144 #else
145 
146 /**
147  * fifo 4k
148  *
149  * ep				fifo_addr	fifo_size
150  * "ep0",			0,		0.5k
151  * "ep1in-bulk",		0.5k,		0.5k
152  * "ep1out-bulk",		1k,		0.5k
153  * "ep2in-bulk",		1.5k,		0.5k
154  * "ep2out-bulk",		2k,		0.5k
155  * "ep3-iso",			2.5k,		1k
156  * "ep4-int",			3.5k,		0.5k
157  */
158 #define SW_UDC_EPNUMS	4
159 
160 static const struct sw_udc_fifo ep_fifo[] = {
161 	{ep0name,          0,    512,  0},
162 	{ep1in_bulk_name,  512,  512,  0},
163 	{ep1out_bulk_name, 1024, 512,  0},
164 	{ep2in_bulk_name,  1536, 512,  0},
165 	{ep2out_bulk_name, 2048, 512,  0},
166 	{ep3_iso_name,     2560, 1024, 0},
167 	{ep4_int_name,     3584, 512,  0},
168 };
169 #endif
170 
171 /**
172  * ep_fifo_in[i] = {n} i: the physic ep index, n: ep_fifo's index for the ep
173  *
174  * eg: ep_fifo_in[2] = {3} ===> ep2_in is in ep_fifo[3]
175  *
176  * ep3_iso_name and ep4_int_name cannot be tx or rx simultaneously.
177  *
178  */
179 static const int ep_fifo_in[] = {0, 1, 3, 5, 6, 7};
180 static const int ep_fifo_out[] = {0, 2, 4, 5, 6, 8};
181 
182 #define SW_UDC_ENDPOINTS	ARRAY_SIZE(ep_fifo)
183 
184 #define  is_tx_ep(ep)		((ep->bEndpointAddress) & USB_DIR_IN)
185 
186 enum sunxi_buffer_map_state {
187 	UN_MAPPED = 0,
188 	PRE_MAPPED,
189 	SW_UDC_USB_MAPPED
190 };
191 
192 struct sunxi_udc_request {
193 	struct list_head	queue;	/* ep's requests */
194 	struct usb_request	req;
195 
196 	__u32 is_queue;			/* flag... */
197 	enum sunxi_buffer_map_state map_state;
198 	void *saved_req_buf;
199 };
200 
201 enum ep0_state {
202 	EP0_IDLE,
203 	EP0_IN_DATA_PHASE,
204 	EP0_OUT_DATA_PHASE,
205 	EP0_END_XFER,
206 	EP0_STALL,
207 };
208 
209 typedef struct sunxi_udc_dma_parg {
210 	struct sunxi_udc *dev;
211 	struct sunxi_udc_ep *ep[6];
212 	struct sunxi_udc_request *req;
213 } sunxi_udc_dma_parg_t;
214 #endif
215 
216 typedef struct sunxi_udc_io {
217 	struct resource	*usb_base_res;		/* USB  resources */
218 	struct resource	*usb_base_req;		/* USB  resources */
219 	void __iomem	*usb_vbase;		/* USB  base address */
220 
221 	struct resource	*sram_base_res;		/* SRAM resources */
222 	struct resource	*sram_base_req;		/* SRAM resources */
223 	void __iomem	*sram_vbase;		/* SRAM base address */
224 
225 	struct resource	*clock_base_res;	/* clock resources */
226 	struct resource	*clock_base_req;	/* clock resources */
227 	void __iomem	*clock_vbase;		/* clock base address */
228 
229 	bsp_usbc_t usbc;			/* usb bsp config */
230 	__hdle usb_bsp_hdle;			/* usb bsp handle */
231 
232 	__u32 clk_is_open;			/* is usb clock open? */
233 	struct clk	*clk_bus_otg;
234 	struct clk	*clk_phy;
235 
236 	struct reset_control	*reset_otg;
237 	struct reset_control	*reset_phy;
238 
239 #if defined(CONFIG_ARCH_SUN50IW10)
240 /* for keep common circuit configuration */
241 	void __iomem	*usb_common_phy_config;
242 
243 #define SUNXI_HCI_PHY_CTRL		0x810
244 #define SUNXI_HCI_PHY_CTRL_SIDDQ	3
245 #endif
246 } sunxi_udc_io_t;
247 
248 typedef struct sunxi_udc {
249 	spinlock_t			lock;
250 	struct platform_device		*pdev;
251 	struct device		        *controller;
252 
253 	struct sunxi_udc_ep		ep[SW_UDC_ENDPOINTS];
254 	int				address;
255 	struct usb_gadget		gadget;
256 	struct usb_gadget_driver	*driver;
257 	struct sunxi_udc_request	fifo_req;
258 	u8				fifo_buf[SW_UDC_EP_FIFO_SIZE];
259 	u16				devstatus;
260 
261 	u32				port_status;
262 	int				ep0state;
263 
264 	unsigned			got_irq : 1;
265 
266 	unsigned			req_std : 1;
267 	unsigned			req_config : 1;
268 	unsigned			req_pending : 1;
269 	u8				vbus;
270 	struct dentry			*regs_info;
271 
272 	sunxi_udc_io_t			*sunxi_udc_io;
273 	char				driver_name[32];
274 	__u32				usbc_no; /* controller port index */
275 
276 	u32				stopped; /* controller stop work */
277 	u32				irq_no;	/* usb irq no */
278 
279 	struct work_struct		vbus_det_work;
280 	struct work_struct		set_cur_vol_work;
281 
282 	struct wakeup_source		*ws;
283 	struct regulator		*udc_regulator; /* usbc regulator:vcc-USB */
284 } sunxi_udc_t;
285 
286 enum sunxi_udc_cmd_e {
287 	SW_UDC_P_ENABLE	= 1,		/* Pull-up enable        */
288 	SW_UDC_P_DISABLE = 2,		/* Pull-up disable       */
289 	SW_UDC_P_RESET	= 3,		/* UDC reset, in case of */
290 };
291 
292 typedef struct sunxi_udc_mach_info {
293 	struct usb_port_info *port_info;
294 	unsigned int usbc_base;
295 } sunxi_udc_mach_info_t;
296 
297 extern atomic_t thread_suspend_flag;
298 extern int device_insmod_delay;
299 
300 extern atomic_t vfs_read_flag;
301 extern atomic_t vfs_write_flag;
302 extern unsigned int vfs_amount;
303 extern loff_t vfs_file_offset;
304 
305 int sunxi_usb_device_enable(void);
306 int sunxi_usb_device_disable(void);
307 int get_dp_dm_status_normal(void);
308 
309 #endif   /* __SUNXI_UDC_H__ */
310