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