2 * Copyright (C) 2009 Samsung Electronics
3 * Minkyu Kang <mk7.kang@samsung.com>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24 #include <asm/errno.h>
25 #include "usb-hs-otg.h"
31 int s5p_usb_connected;
33 USB_OPMODE op_mode = USB_CPU;
34 USB_SPEED speed = USB_HIGH;
36 USB_OPMODE op_mode = USB_DMA;
37 USB_SPEED speed = USB_FULL;
41 get_status_t get_status;
45 EP0, EP1, EP2, EP3, EP4
48 /*------------------------------------------------*/
52 EP0_STATE_GD_DEV_0 = 11,
53 EP0_STATE_GD_DEV_1 = 12,
54 EP0_STATE_GD_DEV_2 = 13,
55 EP0_STATE_GD_CFG_0 = 21,
56 EP0_STATE_GD_CFG_1 = 22,
57 EP0_STATE_GD_CFG_2 = 23,
58 EP0_STATE_GD_CFG_3 = 24,
59 EP0_STATE_GD_CFG_4 = 25,
60 EP0_STATE_GD_STR_I0 = 30,
61 EP0_STATE_GD_STR_I1 = 31,
62 EP0_STATE_GD_STR_I2 = 32,
63 EP0_STATE_GD_DEV_QUALIFIER = 33,
64 EP0_STATE_INTERFACE_GET = 34,
65 EP0_STATE_GET_STATUS0 = 35,
66 EP0_STATE_GET_STATUS1 = 36,
67 EP0_STATE_GET_STATUS2 = 37,
68 EP0_STATE_GET_STATUS3 = 38,
69 EP0_STATE_GET_STATUS4 = 39,
70 EP0_STATE_GD_OTHER_SPEED = 40,
71 EP0_STATE_GD_CFG_ONLY_0 = 41,
72 EP0_STATE_GD_CFG_ONLY_1 = 42,
73 EP0_STATE_GD_IF_ONLY_0 = 44,
74 EP0_STATE_GD_IF_ONLY_1 = 45,
75 EP0_STATE_GD_EP0_ONLY_0 = 46,
76 EP0_STATE_GD_EP1_ONLY_0 = 47,
77 EP0_STATE_GD_EP2_ONLY_0 = 48,
78 EP0_STATE_GD_EP3_ONLY_0 = 49,
79 EP0_STATE_GD_OTHER_SPEED_HIGH_1 = 51,
80 EP0_STATE_GD_OTHER_SPEED_HIGH_2 = 52,
81 EP0_STATE_GD_OTHER_SPEED_HIGH_3 = 53
84 /*definitions related to CSR setting */
87 #define B_SESSION_VALID (0x1 << 19)
88 #define A_SESSION_VALID (0x1 << 18)
91 #define PTXFE_HALF (0<<8)
92 #define PTXFE_ZERO (1<<8)
93 #define NPTXFE_HALF (0<<7)
94 #define NPTXFE_ZERO (1<<7)
95 #define MODE_SLAVE (0<<5)
96 #define MODE_DMA (1<<5)
97 #define BURST_SINGLE (0<<1)
98 #define BURST_INCR (1<<1)
99 #define BURST_INCR4 (3<<1)
100 #define BURST_INCR8 (5<<1)
101 #define BURST_INCR16 (7<<1)
102 #define GBL_INT_UNMASK (1<<0)
103 #define GBL_INT_MASK (0<<0)
106 #define AHB_MASTER_IDLE (1u<<31)
107 #define CORE_SOFT_RESET (0x1<<0)
109 /* OTG_GINTSTS/OTG_GINTMSK core interrupt register */
110 #define INT_RESUME (1u<<31)
111 #define INT_DISCONN (0x1<<29)
112 #define INT_CONN_ID_STS_CNG (0x1<<28)
113 #define INT_OUT_EP (0x1<<19)
114 #define INT_IN_EP (0x1<<18)
115 #define INT_ENUMDONE (0x1<<13)
116 #define INT_RESET (0x1<<12)
117 #define INT_SUSPEND (0x1<<11)
118 #define INT_TX_FIFO_EMPTY (0x1<<5)
119 #define INT_RX_FIFO_NOT_EMPTY (0x1<<4)
120 #define INT_SOF (0x1<<3)
121 #define INT_DEV_MODE (0x0<<0)
122 #define INT_HOST_MODE (0x1<<1)
123 #define INT_OTG (0x1<<2)
125 /* OTG_GRXSTSP STATUS*/
126 #define GLOBAL_OUT_NAK (0x1<<17)
127 #define OUT_PKT_RECEIVED (0x2<<17)
128 #define OUT_TRNASFER_COMPLETED (0x3<<17)
129 #define SETUP_TRANSACTION_COMPLETED (0x4<<17)
130 #define SETUP_PKT_RECEIVED (0x6<<17)
132 /* OTG_DCTL device control register */
133 #define NORMAL_OPERATION (0x1<<0)
134 #define SOFT_DISCONNECT (0x1<<1)
135 #define TEST_J_MODE (TEST_J<<4)
136 #define TEST_K_MODE (TEST_K<<4)
137 #define TEST_SE0_NAK_MODE (TEST_SE0_NAK<<4)
138 #define TEST_PACKET_MODE (TEST_PACKET<<4)
139 #define TEST_FORCE_ENABLE_MODE (TEST_FORCE_ENABLE<<4)
140 #define TEST_CONTROL_FIELD (0x7<<4)
142 /* OTG_DAINT device all endpoint interrupt register */
143 #define INT_IN_EP0 (0x1<<0)
144 #define INT_IN_EP1 (0x1<<1)
145 #define INT_IN_EP3 (0x1<<3)
146 #define INT_OUT_EP0 (0x1<<16)
147 #define INT_OUT_EP2 (0x1<<18)
148 #define INT_OUT_EP4 (0x1<<20)
150 /* OTG_DIEPCTL0/OTG_DOEPCTL0 */
151 #define DEPCTL_EPENA (0x1<<31)
152 #define DEPCTL_EPDIS (0x1<<30)
153 #define DEPCTL_SNAK (0x1<<27)
154 #define DEPCTL_CNAK (0x1<<26)
155 #define DEPCTL_CTRL_TYPE (EP_TYPE_CONTROL<<18)
156 #define DEPCTL_ISO_TYPE (EP_TYPE_ISOCHRONOUS<<18)
157 #define DEPCTL_BULK_TYPE (EP_TYPE_BULK<<18)
158 #define DEPCTL_INTR_TYPE (EP_TYPE_INTERRUPT<<18)
159 #define DEPCTL_USBACTEP (0x1<<15)
161 /*ep0 enable, clear nak, next ep0, max 64byte */
162 #define EPEN_CNAK_EP0_64 (DEPCTL_EPENA|DEPCTL_CNAK|(CONTROL_EP<<11)|(0<<0))
164 /*ep0 enable, clear nak, next ep0, 8byte */
165 #define EPEN_CNAK_EP0_8 (DEPCTL_EPENA|DEPCTL_CNAK|(CONTROL_EP<<11)|(3<<0))
167 /* DIEPCTLn/DOEPCTLn */
168 #define BACK2BACK_SETUP_RECEIVED (0x1<<6)
169 #define INTKN_TXFEMP (0x1<<4)
170 #define NON_ISO_IN_EP_TIMEOUT (0x1<<3)
171 #define CTRL_OUT_EP_SETUP_PHASE_DONE (0x1<<3)
172 #define AHB_ERROR (0x1<<2)
173 #define TRANSFER_DONE (0x1<<0)
175 /* codes representing languages */
176 const u8 string_desc0[] = {
177 4, STRING_DESCRIPTOR, LANGID_US_L, LANGID_US_H,
180 #ifdef CONFIG_SAMSUNG_USB
181 const u8 string_desc1[] = /* Manufacturer */
183 (0x14 + 2), STRING_DESCRIPTOR,
184 'S', 0x0, '/', 0x0, 'W', 0x0, ' ', 0x0, 'C', 0x0,
185 'e', 0x0, 'n', 0x0, 't', 0x0, 'e', 0x0, 'r', 0x0,
188 const u8 string_desc1[] = /* Manufacturer */
190 (0x14 + 2), STRING_DESCRIPTOR,
191 'S', 0x0, 'y', 0x0, 's', 0x0, 't', 0x0, 'e', 0x0,
192 'm', 0x0, ' ', 0x0, 'M', 0x0, 'C', 0x0, 'U', 0x0,
196 #ifdef CONFIG_SAMSUNG_USB
197 const u8 string_desc2[] = /* Product */
199 (0x24 + 2), STRING_DESCRIPTOR,
200 'S', 0x0, 'A', 0x0, 'M', 0x0, 'S', 0x0, 'U', 0x0,
201 'N', 0x0, 'G', 0x0, ' ', 0x0, 'S', 0x0, 'L', 0x0,
202 'P', 0x0, ' ', 0x0, 'D', 0x0, 'R', 0x0, 'I', 0x0,
203 'V', 0x0, 'E', 0x0, 'R', 0x0
206 const u8 string_desc2[] = /* Product */
208 (0x2a + 2), STRING_DESCRIPTOR,
209 'S', 0x0, 'E', 0x0, 'C', 0x0, ' ', 0x0, 'S', 0x0,
210 '3', 0x0, 'C', 0x0, '6', 0x0, '4', 0x0, '0', 0x0,
211 '0', 0x0, 'X', 0x0, ' ', 0x0, 'T', 0x0, 'e', 0x0,
212 's', 0x0, 't', 0x0, ' ', 0x0, 'B', 0x0, '/', 0x0,
217 /* setting the device qualifier descriptor and a string descriptor */
218 const u8 qualifier_desc[] = {
219 0x0a, /* 0 desc size */
220 0x06, /* 1 desc type (DEVICE_QUALIFIER) */
221 0x00, /* 2 USB release */
222 0x02, /* 3 => 2.00 */
224 0x00, /* 5 subclass */
225 0x00, /* 6 protocol */
226 64, /* 7 max pack size */
227 0x01, /* 8 number of other-speed configuration */
228 0x00, /* 9 reserved */
231 const u8 config_full[] = {
232 0x09, /* 0 desc size */
233 0x07, /* 1 desc type (other speed) */
234 0x20, /* 2 Total length of data returned */
236 0x01, /* 4 Number of interfaces */
237 0x01, /* 5 value to use to select configuration */
238 0x00, /* 6 index of string desc */
239 /* 7 same as configuration desc */
240 CONF_ATTR_DEFAULT | CONF_ATTR_SELFPOWERED,
241 0x19, /* 8 same as configuration desc */
245 const u8 config_full_total[] = {
246 0x09, 0x07, 0x20, 0x00, 0x01, 0x01, 0x00, 0xC0, 0x19,
247 0x09, 0x04, 0x00, 0x00, 0x02, 0xff, 0x00, 0x00, 0x00,
248 0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x00,
249 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00
252 const u8 config_high[] = {
253 0x09, /* 0 desc size */
254 0x07, /* 1 desc type (other speed) */
255 0x20, /* 2 Total length of data returned */
257 0x01, /* 4 Number of interfaces */
258 0x01, /* 5 value to use to select configuration */
259 0x00, /* 6 index of string desc */
260 /* 7 same as configuration desc */
261 CONF_ATTR_DEFAULT | CONF_ATTR_SELFPOWERED,
262 0x19, /* 8 same as configuration desc */
266 const u8 config_high_total[] = {
267 0x09, 0x07, 0x20, 0x00, 0x01, 0x01, 0x00, 0xC0, 0x19,
268 0x09, 0x04, 0x00, 0x00, 0x02, 0xff, 0x00, 0x00, 0x00,
269 0x07, 0x05, 0x81, 0x02, 0x00, 0x02, 0x00,
270 0x07, 0x05, 0x02, 0x02, 0x00, 0x02, 0x00
273 /* Descriptor size */
274 enum DESCRIPTOR_SIZE {
275 DEVICE_DESC_SIZE = sizeof(device_desc_t),
276 STRING_DESC0_SIZE = sizeof(string_desc0),
277 STRING_DESC1_SIZE = sizeof(string_desc1),
278 STRING_DESC2_SIZE = sizeof(string_desc2),
279 CONFIG_DESC_SIZE = sizeof(config_desc_t),
280 INTERFACE_DESC_SIZE = sizeof(intf_desc_t),
281 ENDPOINT_DESC_SIZE = sizeof(ep_desc_t),
282 DEVICE_QUALIFIER_SIZE = sizeof(qualifier_desc),
283 OTHER_SPEED_CFG_SIZE = 9
286 /*32 <cfg desc>+<if desc>+<endp0 desc>+<endp1 desc>*/
287 #define CONFIG_DESC_TOTAL_SIZE \
288 (CONFIG_DESC_SIZE+INTERFACE_DESC_SIZE+ENDPOINT_DESC_SIZE*2)
290 static unsigned int phy_base;
291 static unsigned int otg_base;
293 static inline void s5p_usb_init_base(void)
295 phy_base = samsung_get_base_usb_phy();
296 otg_base = samsung_get_base_usb_otg();
299 static inline int s5p_phy_read_reg(int offset)
301 return readl(phy_base + offset);
304 static inline void s5p_phy_write_reg(int value, int offset)
306 writel(value, phy_base + offset);
309 static inline int s5p_otg_read_reg(int offset)
311 return readl(otg_base + offset);
314 static inline void s5p_otg_write_reg(int value, int offset)
316 writel(value, otg_base + offset);
319 static void s5p_usb_init_phy(void)
322 if (s5p_cpu_id == 0xc100) {
323 s5p_phy_write_reg(0x0, OTG_PHYPWR);
324 #ifdef CONFIG_OTG_CLK_OSCC
325 s5p_phy_write_reg(0x22, OTG_PHYCTRL);
327 s5p_phy_write_reg(0x2, OTG_PHYCTRL);
329 } else if (s5p_cpu_id == 0xc110) {
330 s5p_phy_write_reg(0xA0, OTG_PHYPWR);
331 s5p_phy_write_reg(0x3, OTG_PHYCTRL);
332 } else if (s5p_cpu_id == 0x4321) {
333 s5p_phy_write_reg(0x1f80, OTG_PHYPWR);
334 s5p_phy_write_reg(0x3, OTG_PHYCTRL);
335 } else if (s5p_cpu_id == 0x4322) {
336 s5p_phy_write_reg(0x7f80, OTG_PHYPWR);
337 s5p_phy_write_reg(0x5, OTG_PHYCTRL);
338 } else if (s5p_cpu_id == 0xe441) {
339 s5p_phy_write_reg(0x7f80, OTG_PHYPWR);
340 s5p_phy_write_reg(0x5, OTG_PHYCTRL);
343 s5p_phy_write_reg(0x1, OTG_RSTCON);
345 s5p_phy_write_reg(0x0, OTG_RSTCON);
349 int s5p_usb_detect_irq(void)
352 status = s5p_otg_read_reg(OTG_GINTSTS);
353 return (status & 0x800c3810);
356 void s5p_usb_clear_irq(void)
358 s5p_otg_write_reg(0xffffffff, OTG_GINTSTS);
361 static void s5p_usb_core_soft_reset(void)
365 s5p_otg_write_reg(CORE_SOFT_RESET, OTG_GRSTCTL);
368 tmp = s5p_otg_read_reg(OTG_GRSTCTL);
369 } while (!(tmp & AHB_MASTER_IDLE));
373 static void s5p_usb_wait_cable_insert(void)
381 tmp = s5p_otg_read_reg(OTG_GOTGCTL);
383 if (tmp & (B_SESSION_VALID | A_SESSION_VALID)) {
385 } else if (ucFirst == 1) {
386 puts("Insert a OTG cable into the connector!\n");
393 static void s5p_usb_init_core(void)
395 s5p_otg_write_reg(PTXFE_HALF | NPTXFE_HALF | MODE_SLAVE |
396 BURST_SINGLE | GBL_INT_UNMASK, OTG_GAHBCFG);
399 0x0 << 15 /* PHY Low Power Clock sel */
400 | 0x1 << 14 /* Non-Periodic TxFIFO Rewind Enable */
401 | 0x5 << 10 /* Turnaround time */
402 | 0x0 << 9 /* 0:HNP disable, 1:HNP enable */
403 | 0x0 << 8 /* 0:SRP disable, 1:SRP enable */
404 | 0x0 << 7 /* ULPI DDR sel */
405 | 0x0 << 6 /* 0: high speed utmi+, 1: full speed serial */
406 | 0x0 << 4 /* 0: utmi+, 1:ulpi */
407 | 0x1 << 3 /* phy i/f 0:8bit, 1:16bit */
408 | 0x7 << 0, /* HS/FS Timeout* */
412 static void s5p_usb_check_current_mode(u8 *pucMode)
416 tmp = s5p_otg_read_reg(OTG_GINTSTS);
417 *pucMode = tmp & 0x1;
420 static void s5p_usb_soft_disconnect(int set)
424 tmp = s5p_otg_read_reg(OTG_DCTL);
426 tmp |= SOFT_DISCONNECT;
428 tmp &= ~SOFT_DISCONNECT;
429 s5p_otg_write_reg(tmp, OTG_DCTL);
432 static void s5p_usb_init_device(void)
434 s5p_otg_write_reg(1 << 18 | otg.speed << 0, OTG_DCFG);
436 s5p_otg_write_reg(INT_RESUME | INT_OUT_EP | INT_IN_EP |
437 INT_ENUMDONE | INT_RESET | INT_SUSPEND |
438 INT_RX_FIFO_NOT_EMPTY, OTG_GINTMSK);
441 int s5p_usbctl_init(void)
448 reg = readl(s5p_get_usb_power_reg());
450 if (s5p_cpu_id == 0xc100)
451 reg |= (1 << 16); /* unmask usb signal */
453 reg |= (1 << 0); /* USB PHY0 enable */
455 writel(reg, s5p_get_usb_power_reg());
459 otg.ep0_state = EP0_STATE_INIT;
460 otg.ep0_substate = 0;
463 s5p_usb_core_soft_reset();
465 s5p_usb_check_current_mode(&ucMode);
467 if (ucMode == INT_DEV_MODE) {
468 s5p_usb_soft_disconnect(1);
470 s5p_usb_soft_disconnect(0);
471 s5p_usb_init_device();
474 puts("Error : Current Mode is Host\n");
479 static void s5p_usb_set_inep_xfersize(EP_TYPE type, u32 pktcnt, u32 xfersize)
481 if (type == EP_TYPE_CONTROL) {
482 s5p_otg_write_reg((pktcnt << 19) | (xfersize << 0),
484 } else if (type == EP_TYPE_BULK) {
485 s5p_otg_write_reg((1 << 29) | (pktcnt << 19) |
486 (xfersize << 0), OTG_DIEPTSIZ_IN);
490 static void s5p_usb_set_outep_xfersize(EP_TYPE type, u32 pktcnt, u32 xfersize)
492 if (type == EP_TYPE_CONTROL) {
493 s5p_otg_write_reg((1 << 29) | (pktcnt << 19) |
494 (xfersize << 0), OTG_DOEPTSIZ0);
495 } else if (type == EP_TYPE_BULK) {
496 s5p_otg_write_reg((pktcnt << 19) | (xfersize << 0),
501 /* works on both aligned and unaligned buffers */
502 static void s5p_usb_write_ep0_fifo(u8 *buf, int num)
507 for (i = 0; i < num; i += 4) {
508 Wr_Data = ((*(buf + 3)) << 24) |
509 ((*(buf + 2)) << 16) |
510 ((*(buf + 1)) << 8) |
512 s5p_otg_write_reg(Wr_Data, OTG_EP0_FIFO);
517 /* optimized fifo access routines, warning: only aligned buffers are supported */
518 static inline void s5p_usb_write_in_fifo(u8 *buf, int num)
520 u32 fifo = otg_base + OTG_IN_FIFO;
524 for (i = 0; i < num; i += 4)
528 static inline void s5p_usb_read_out_fifo(u8 *buf, int num)
530 u32 fifo = otg_base + OTG_OUT_FIFO;
534 for (i = 0; i < num; i += 4)
538 static void s5p_usb_get_desc(void)
540 switch (otg.dev_req.wValue_H) {
541 case DEVICE_DESCRIPTOR:
542 otg.req_length = (u32)((otg.dev_req.wLength_H << 8) |
543 otg.dev_req.wLength_L);
544 otg.ep0_state = EP0_STATE_GD_DEV_0;
547 case CONFIGURATION_DESCRIPTOR:
548 otg.req_length = (u32)((otg.dev_req.wLength_H << 8) |
549 otg.dev_req.wLength_L);
551 if (otg.req_length > CONFIG_DESC_SIZE)
552 otg.ep0_state = EP0_STATE_GD_CFG_0;
554 otg.ep0_state = EP0_STATE_GD_CFG_ONLY_0;
557 case STRING_DESCRIPTOR:
558 switch (otg.dev_req.wValue_L) {
560 otg.ep0_state = EP0_STATE_GD_STR_I0;
563 otg.ep0_state = EP0_STATE_GD_STR_I1;
566 otg.ep0_state = EP0_STATE_GD_STR_I2;
573 case ENDPOINT_DESCRIPTOR:
574 switch (otg.dev_req.wValue_L & 0xf) {
576 otg.ep0_state = EP0_STATE_GD_EP0_ONLY_0;
579 otg.ep0_state = EP0_STATE_GD_EP1_ONLY_0;
586 case DEVICE_QUALIFIER:
587 otg.req_length = (u32)((otg.dev_req.wLength_H << 8) |
588 otg.dev_req.wLength_L);
589 otg.ep0_state = EP0_STATE_GD_DEV_QUALIFIER;
592 case OTHER_SPEED_CONFIGURATION:
593 otg.req_length = (u32)((otg.dev_req.wLength_H << 8) |
594 otg.dev_req.wLength_L);
595 otg.ep0_state = EP0_STATE_GD_OTHER_SPEED;
600 static void s5p_usb_clear_feature(void)
602 switch (otg.dev_req.bmRequestType) {
603 case DEVICE_RECIPIENT:
604 if (otg.dev_req.wValue_L == 1)
608 case ENDPOINT_RECIPIENT:
609 if (otg.dev_req.wValue_L == 0) {
610 if ((otg.dev_req.wIndex_L & 0x7f) == CONTROL_EP)
611 get_status.ep_ctrl = 0;
614 if ((otg.dev_req.wIndex_L & 0x7f) == BULK_IN_EP)
615 get_status.ep_in = 0;
618 if ((otg.dev_req.wIndex_L & 0x7f) == BULK_OUT_EP)
619 get_status.ep_out = 0;
626 otg.ep0_state = EP0_STATE_INIT;
629 static void s5p_usb_set_feature(void)
631 switch (otg.dev_req.bmRequestType) {
632 case DEVICE_RECIPIENT:
633 if (otg.dev_req.wValue_L == 1)
637 case ENDPOINT_RECIPIENT:
638 if (otg.dev_req.wValue_L == 0) {
639 if ((otg.dev_req.wIndex_L & 0x7f) == CONTROL_EP)
640 get_status.ep_ctrl = 1;
642 if ((otg.dev_req.wIndex_L & 0x7f) == BULK_IN_EP)
643 get_status.ep_in = 1;
645 if ((otg.dev_req.wIndex_L & 0x7f) == BULK_OUT_EP)
646 get_status.ep_out = 1;
654 otg.ep0_state = EP0_STATE_INIT;
657 static void s5p_usb_get_status(void)
659 switch (otg.dev_req.bmRequestType) {
660 case (0x80): /*device */
661 get_status.Device = ((u8) remode_wakeup << 1) | 0x1;
662 otg.ep0_state = EP0_STATE_GET_STATUS0;
665 case (0x81): /*interface */
666 get_status.Interface = 0;
667 otg.ep0_state = EP0_STATE_GET_STATUS1;
670 case (0x82): /*endpoint */
671 if ((otg.dev_req.wIndex_L & 0x7f) == CONTROL_EP)
672 otg.ep0_state = EP0_STATE_GET_STATUS2;
674 if ((otg.dev_req.wIndex_L & 0x7f) == BULK_IN_EP)
675 otg.ep0_state = EP0_STATE_GET_STATUS3;
677 if ((otg.dev_req.wIndex_L & 0x7f) == BULK_OUT_EP)
678 otg.ep0_state = EP0_STATE_GET_STATUS4;
686 static void s5p_usb_ep0_int_hndlr(void)
689 u32 buf[2] = {0x0000, };
692 if (otg.ep0_state == EP0_STATE_INIT) {
693 for (i = 0; i < 2; i++)
694 buf[i] = s5p_otg_read_reg(OTG_EP0_FIFO);
696 otg.dev_req.bmRequestType = buf[0];
697 otg.dev_req.bRequest = buf[0] >> 8;
698 otg.dev_req.wValue_L = buf[0] >> 16;
699 otg.dev_req.wValue_H = buf[0] >> 24;
700 otg.dev_req.wIndex_L = buf[1];
701 otg.dev_req.wIndex_H = buf[1] >> 8;
702 otg.dev_req.wLength_L = buf[1] >> 16;
703 otg.dev_req.wLength_H = buf[1] >> 24;
705 switch (otg.dev_req.bRequest) {
706 case STANDARD_SET_ADDRESS:
707 /* Set Address Update bit */
708 addr = (otg.dev_req.wValue_L);
709 s5p_otg_write_reg(1 << 18 | addr << 4 | otg.speed << 0,
711 otg.ep0_state = EP0_STATE_INIT;
714 case STANDARD_SET_DESCRIPTOR:
717 case STANDARD_SET_CONFIGURATION:
718 /* Configuration value in configuration descriptor */
719 config_value = otg.dev_req.wValue_L;
721 otg.ep0_state = EP0_STATE_INIT;
723 s5p_usb_connected = 1;
726 case STANDARD_GET_CONFIGURATION:
727 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
729 /*ep0 enable, clear nak, next ep0, 8byte */
730 s5p_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
731 s5p_otg_write_reg(config_value, OTG_EP0_FIFO);
732 otg.ep0_state = EP0_STATE_INIT;
735 case STANDARD_GET_DESCRIPTOR:
739 case STANDARD_CLEAR_FEATURE:
740 s5p_usb_clear_feature();
743 case STANDARD_SET_FEATURE:
744 s5p_usb_set_feature();
747 case STANDARD_GET_STATUS:
748 s5p_usb_get_status();
751 case STANDARD_GET_INTERFACE:
752 otg.ep0_state = EP0_STATE_INTERFACE_GET;
755 case STANDARD_SET_INTERFACE:
756 get_intf.AlternateSetting = otg.dev_req.wValue_L;
757 otg.ep0_state = EP0_STATE_INIT;
760 case STANDARD_SYNCH_FRAME:
761 otg.ep0_state = EP0_STATE_INIT;
769 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, otg.ctrl_max_pktsize);
771 /*clear nak, next ep0, 64byte */
772 s5p_otg_write_reg(((1 << 26) | (CONTROL_EP << 11) | (0 << 0)),
776 static void s5p_usb_set_otherspeed_conf_desc(u32 length)
778 /* Standard device descriptor */
780 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 9);
781 s5p_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
782 s5p_usb_write_ep0_fifo((u8 *) &config_full, 9);
783 } else if (length == 32) {
784 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 32);
785 s5p_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
786 s5p_usb_write_ep0_fifo((u8 *) &config_full_total, 32);
788 otg.ep0_state = EP0_STATE_INIT;
791 static void s5p_usb_transfer_ep0(void)
793 switch (otg.ep0_state) {
795 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 0);
797 /*ep0 enable, clear nak, next ep0, 8byte */
798 s5p_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
801 case EP0_STATE_GD_DEV_0:
802 /*ep0 enable, clear nak, next ep0, max 64byte */
803 s5p_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
804 if (otg.req_length < DEVICE_DESC_SIZE) {
805 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
807 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.dev)),
810 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
812 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.dev)),
815 otg.ep0_state = EP0_STATE_INIT;
818 case EP0_STATE_GD_DEV_1:
819 s5p_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
820 if (otg.req_length < (2 * FS_CTRL_PKT_SIZE)) {
821 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.dev)) +
823 otg.req_length - FS_CTRL_PKT_SIZE);
824 otg.ep0_state = EP0_STATE_INIT;
826 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.dev)) +
827 FS_CTRL_PKT_SIZE, FS_CTRL_PKT_SIZE);
828 otg.ep0_state = EP0_STATE_GD_DEV_2;
832 case EP0_STATE_GD_DEV_2:
833 s5p_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
834 if (otg.req_length < DEVICE_DESC_SIZE) {
835 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.dev)) +
836 (2 * FS_CTRL_PKT_SIZE),
837 otg.req_length - 2 * FS_CTRL_PKT_SIZE);
839 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.dev)) +
840 (2 * FS_CTRL_PKT_SIZE),
841 DEVICE_DESC_SIZE - 2 * FS_CTRL_PKT_SIZE);
843 otg.ep0_state = EP0_STATE_INIT;
846 case EP0_STATE_GD_CFG_0:
847 s5p_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
848 if (otg.req_length < CONFIG_DESC_TOTAL_SIZE) {
849 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
851 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)),
854 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
855 CONFIG_DESC_TOTAL_SIZE);
856 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)),
857 CONFIG_DESC_TOTAL_SIZE);
859 otg.ep0_state = EP0_STATE_INIT;
862 case EP0_STATE_GD_CFG_1:
863 s5p_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
864 if (otg.req_length < (2 * FS_CTRL_PKT_SIZE)) {
865 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)) +
867 (otg.req_length - FS_CTRL_PKT_SIZE));
868 otg.ep0_state = EP0_STATE_INIT;
870 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)) +
871 FS_CTRL_PKT_SIZE, FS_CTRL_PKT_SIZE);
872 otg.ep0_state = EP0_STATE_GD_CFG_2;
876 case EP0_STATE_GD_CFG_2:
877 s5p_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
878 if (otg.req_length < (3 * FS_CTRL_PKT_SIZE)) {
879 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)) +
880 (2 * FS_CTRL_PKT_SIZE),
881 otg.req_length - 2 * FS_CTRL_PKT_SIZE);
882 otg.ep0_state = EP0_STATE_INIT;
884 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)) +
885 (2 * FS_CTRL_PKT_SIZE), FS_CTRL_PKT_SIZE);
886 otg.ep0_state = EP0_STATE_GD_CFG_3;
890 case EP0_STATE_GD_CFG_3:
891 s5p_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
892 if (otg.req_length < (4 * FS_CTRL_PKT_SIZE)) {
893 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)) +
894 (3 * FS_CTRL_PKT_SIZE),
895 otg.req_length - 3 * FS_CTRL_PKT_SIZE);
896 otg.ep0_state = EP0_STATE_INIT;
898 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)) +
899 (3 * FS_CTRL_PKT_SIZE), FS_CTRL_PKT_SIZE);
900 otg.ep0_state = EP0_STATE_GD_CFG_4;
904 case EP0_STATE_GD_CFG_4:
905 otg.ep0_state = EP0_STATE_INIT;
908 case EP0_STATE_GD_DEV_QUALIFIER:
909 s5p_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
910 if (otg.req_length < 10) {
911 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
913 s5p_usb_write_ep0_fifo((u8 *)qualifier_desc,
916 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 10);
917 s5p_usb_write_ep0_fifo((u8 *)qualifier_desc, 10);
919 otg.ep0_state = EP0_STATE_INIT;
922 case EP0_STATE_GD_OTHER_SPEED:
923 s5p_usb_set_otherspeed_conf_desc(otg.req_length);
926 case EP0_STATE_GD_OTHER_SPEED_HIGH_1:
927 if (otg.req_length == 9) {
928 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
929 s5p_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
930 s5p_usb_write_ep0_fifo(((u8 *) &config_high) + 8, 1);
931 otg.ep0_state = EP0_STATE_INIT;
933 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 8);
934 s5p_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
935 s5p_usb_write_ep0_fifo(((u8 *) &config_high) + 8, 8);
936 otg.ep0_state = EP0_STATE_GD_OTHER_SPEED_HIGH_2;
940 case EP0_STATE_GD_OTHER_SPEED_HIGH_2:
941 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 8);
942 s5p_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
943 s5p_usb_write_ep0_fifo(((u8 *) &config_high) + 16, 8);
944 otg.ep0_state = EP0_STATE_GD_OTHER_SPEED_HIGH_3;
947 case EP0_STATE_GD_OTHER_SPEED_HIGH_3:
948 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 8);
949 s5p_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
950 s5p_usb_write_ep0_fifo(((u8 *) &config_high) + 24, 8);
951 otg.ep0_state = EP0_STATE_INIT;
954 case EP0_STATE_GD_CFG_ONLY_0:
955 if (otg.req_length < CONFIG_DESC_SIZE) {
956 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
958 s5p_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
959 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)),
962 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
964 s5p_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
965 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)),
968 otg.ep0_state = EP0_STATE_INIT;
971 case EP0_STATE_GD_CFG_ONLY_1:
972 s5p_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
973 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)) +
975 CONFIG_DESC_SIZE - FS_CTRL_PKT_SIZE);
976 otg.ep0_state = EP0_STATE_INIT;
979 case EP0_STATE_GD_IF_ONLY_0:
980 if (otg.req_length < INTERFACE_DESC_SIZE) {
981 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
983 s5p_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
984 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.intf)),
987 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
988 INTERFACE_DESC_SIZE);
989 s5p_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
990 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.intf)),
991 INTERFACE_DESC_SIZE);
993 otg.ep0_state = EP0_STATE_INIT;
996 case EP0_STATE_GD_IF_ONLY_1:
997 s5p_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
998 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.intf)) +
1000 INTERFACE_DESC_SIZE - FS_CTRL_PKT_SIZE);
1001 otg.ep0_state = EP0_STATE_INIT;
1004 case EP0_STATE_GD_EP0_ONLY_0:
1005 s5p_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
1006 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, ENDPOINT_DESC_SIZE);
1007 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.ep1)),
1008 ENDPOINT_DESC_SIZE);
1009 otg.ep0_state = EP0_STATE_INIT;
1012 case EP0_STATE_GD_EP1_ONLY_0:
1013 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, ENDPOINT_DESC_SIZE);
1014 s5p_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
1015 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.ep2)),
1016 ENDPOINT_DESC_SIZE);
1017 otg.ep0_state = EP0_STATE_INIT;
1020 case EP0_STATE_GD_STR_I0:
1021 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, STRING_DESC0_SIZE);
1022 s5p_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
1023 s5p_usb_write_ep0_fifo((u8 *)string_desc0, STRING_DESC0_SIZE);
1024 otg.ep0_state = EP0_STATE_INIT;
1027 case EP0_STATE_GD_STR_I1:
1028 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, sizeof(string_desc1));
1029 if ((otg.ep0_substate * otg.ctrl_max_pktsize +
1030 otg.ctrl_max_pktsize) < sizeof(string_desc1)) {
1031 s5p_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
1033 s5p_usb_write_ep0_fifo((u8 *)string_desc1 +
1034 (otg.ep0_substate * otg.ctrl_max_pktsize),
1035 otg.ctrl_max_pktsize);
1036 otg.ep0_state = EP0_STATE_GD_STR_I1;
1039 s5p_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
1041 s5p_usb_write_ep0_fifo((u8 *)string_desc1 +
1042 (otg.ep0_substate * otg.ctrl_max_pktsize),
1043 sizeof(string_desc1) - (otg.ep0_substate *
1044 otg.ctrl_max_pktsize));
1045 otg.ep0_state = EP0_STATE_INIT;
1046 otg.ep0_substate = 0;
1050 case EP0_STATE_GD_STR_I2:
1051 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, sizeof(string_desc2));
1052 if ((otg.ep0_substate * otg.ctrl_max_pktsize +
1053 otg.ctrl_max_pktsize) < sizeof(string_desc2)) {
1054 s5p_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
1056 s5p_usb_write_ep0_fifo((u8 *) string_desc2 +
1057 (otg.ep0_substate * otg.ctrl_max_pktsize),
1058 otg.ctrl_max_pktsize);
1059 otg.ep0_state = EP0_STATE_GD_STR_I2;
1062 s5p_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
1063 s5p_usb_write_ep0_fifo((u8 *) string_desc2 +
1064 (otg.ep0_substate * otg.ctrl_max_pktsize),
1065 sizeof(string_desc2) - (otg.ep0_substate *
1066 otg.ctrl_max_pktsize));
1067 otg.ep0_state = EP0_STATE_INIT;
1068 otg.ep0_substate = 0;
1072 case EP0_STATE_INTERFACE_GET:
1073 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
1074 s5p_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
1075 s5p_usb_write_ep0_fifo((u8 *) &get_intf, 1);
1076 otg.ep0_state = EP0_STATE_INIT;
1079 case EP0_STATE_GET_STATUS0:
1080 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
1081 s5p_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
1082 s5p_usb_write_ep0_fifo((u8 *) &get_status, 1);
1083 otg.ep0_state = EP0_STATE_INIT;
1086 case EP0_STATE_GET_STATUS1:
1087 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
1088 s5p_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
1089 s5p_usb_write_ep0_fifo((u8 *) &get_status + 1, 1);
1090 otg.ep0_state = EP0_STATE_INIT;
1093 case EP0_STATE_GET_STATUS2:
1094 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
1095 s5p_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
1096 s5p_usb_write_ep0_fifo((u8 *) &get_status + 2, 1);
1097 otg.ep0_state = EP0_STATE_INIT;
1100 case EP0_STATE_GET_STATUS3:
1101 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
1102 s5p_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
1103 s5p_usb_write_ep0_fifo((u8 *) &get_status + 3, 1);
1104 otg.ep0_state = EP0_STATE_INIT;
1107 case EP0_STATE_GET_STATUS4:
1108 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
1109 s5p_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
1110 s5p_usb_write_ep0_fifo((u8 *) &get_status + 4, 1);
1111 otg.ep0_state = EP0_STATE_INIT;
1119 void s5p_usb_tx(char *tx_data, int tx_size)
1121 otg.up_ptr = (u8 *) tx_data;
1122 otg.up_addr = (u32) tx_data;
1123 otg.up_size = tx_size;
1125 if (otg.op_mode == USB_CPU) {
1126 if (otg.up_size > otg.bulkin_max_pktsize) {
1127 s5p_usb_set_inep_xfersize(EP_TYPE_BULK, 1,
1128 otg.bulkin_max_pktsize);
1130 s5p_usb_set_inep_xfersize(EP_TYPE_BULK, 1, otg.up_size);
1133 /*ep1 enable, clear nak, bulk, usb active, max pkt */
1134 s5p_otg_write_reg(1u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
1135 otg.bulkin_max_pktsize << 0, OTG_DIEPCTL_IN);
1137 s5p_usb_write_in_fifo(otg.up_ptr, otg.up_size);
1138 } else if ((otg.op_mode == USB_DMA) && (otg.up_size > 0)) {
1139 u32 pktcnt, remainder;
1141 s5p_otg_write_reg(MODE_DMA | BURST_INCR4 | GBL_INT_UNMASK,
1143 s5p_otg_write_reg(INT_RESUME | INT_OUT_EP | INT_IN_EP |
1144 INT_ENUMDONE | INT_RESET | INT_SUSPEND,
1147 s5p_otg_write_reg((u32) otg.up_ptr, OTG_DIEPDMA_IN);
1149 pktcnt = (u32) (otg.up_size / otg.bulkin_max_pktsize);
1150 remainder = (u32) (otg.up_size % otg.bulkin_max_pktsize);
1154 if (pktcnt > 1023) {
1155 s5p_usb_set_inep_xfersize(EP_TYPE_BULK, 1023,
1156 otg.bulkin_max_pktsize * 1023);
1158 s5p_usb_set_inep_xfersize(EP_TYPE_BULK, pktcnt,
1162 /*ep1 enable, clear nak, bulk, usb active, next ep1, max pkt */
1163 s5p_otg_write_reg(1u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
1164 BULK_IN_EP << 11 | otg.bulkin_max_pktsize << 0,
1169 static void s5p_usb_int_bulkout(u32 fifo_cnt_byte)
1171 s5p_usb_read_out_fifo((u8 *)otg.dn_ptr, fifo_cnt_byte);
1172 otg.dn_ptr += fifo_cnt_byte;
1174 s5p_usb_set_outep_xfersize(EP_TYPE_BULK, 1,
1175 otg.bulkout_max_pktsize);
1177 /*ep3 enable, clear nak, bulk, usb active, next ep3, max pkt */
1178 s5p_otg_write_reg(1u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
1179 otg.bulkout_max_pktsize << 0, OTG_DOEPCTL_OUT);
1181 if (((u32)otg.dn_ptr - otg.dn_addr) >= (otg.dn_filesize))
1182 s5p_receive_done = 1;
1185 static void s5p_usb_dma_in_done(void)
1189 otg.up_ptr = (u8 *)s5p_otg_read_reg(OTG_DIEPDMA_IN);
1190 remain_cnt = otg.up_size - ((u32) otg.up_ptr - otg.up_addr);
1192 if (remain_cnt > 0) {
1193 u32 pktcnt, remainder;
1194 pktcnt = (u32)(remain_cnt / otg.bulkin_max_pktsize);
1195 remainder = (u32)(remain_cnt % otg.bulkin_max_pktsize);
1200 if (pktcnt > 1023) {
1201 s5p_usb_set_inep_xfersize(EP_TYPE_BULK, 1023,
1202 otg.bulkin_max_pktsize * 1023);
1204 s5p_usb_set_inep_xfersize(EP_TYPE_BULK, pktcnt,
1208 /*ep1 enable, clear nak, bulk, usb active, next ep1, max pkt */
1209 s5p_otg_write_reg(1u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
1210 BULK_IN_EP << 11 | otg.bulkin_max_pktsize << 0,
1213 s5p_receive_done = 1;
1217 static void s5p_usb_dma_out_done(void)
1221 otg.dn_ptr = (u8 *)s5p_otg_read_reg(OTG_DOEPDMA_OUT);
1223 remain_cnt = otg.dn_filesize - ((u32) otg.dn_ptr - otg.dn_addr + 8);
1225 if (remain_cnt > 0) {
1226 u32 pktcnt, remainder;
1227 pktcnt = (u32)(remain_cnt / otg.bulkout_max_pktsize);
1228 remainder = (u32)(remain_cnt % otg.bulkout_max_pktsize);
1233 if (pktcnt > 1023) {
1234 s5p_usb_set_outep_xfersize(EP_TYPE_BULK, 1023,
1235 otg.bulkout_max_pktsize * 1023);
1237 s5p_usb_set_outep_xfersize(EP_TYPE_BULK, pktcnt,
1241 /*ep3 enable, clear nak, bulk, usb active, next ep3, max pkt 64 */
1242 s5p_otg_write_reg(1u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
1243 otg.bulkout_max_pktsize << 0, OTG_DOEPCTL_OUT);
1245 udelay(500); /*for FPGA ??? */
1249 static void s5p_usb_set_all_outep_nak(int set)
1254 for (i = 0; i < 16; i++) {
1255 tmp = s5p_otg_read_reg(OTG_DOEPCTL0 + 0x20 * i);
1259 tmp |= (DEPCTL_EPENA | DEPCTL_CNAK);
1260 s5p_otg_write_reg(tmp, OTG_DOEPCTL0 + 0x20 * i);
1264 static void s5p_usb_set_max_pktsize(USB_SPEED speed)
1266 otg.speed = USB_HIGH;
1267 otg.ctrl_max_pktsize = HS_CTRL_PKT_SIZE;
1268 otg.bulkin_max_pktsize = HS_BULK_PKT_SIZE;
1269 otg.bulkout_max_pktsize = HS_BULK_PKT_SIZE;
1272 static void s5p_usb_set_endpoint(void)
1274 /* Unmask OTG_DAINT source */
1275 s5p_otg_write_reg(0xff, OTG_DIEPINT0);
1276 s5p_otg_write_reg(0xff, OTG_DOEPINT0);
1277 s5p_otg_write_reg(0xff, OTG_DIEPINT_IN);
1278 s5p_otg_write_reg(0xff, OTG_DOEPINT_OUT);
1282 s5p_otg_write_reg(((1 << 26) | (CONTROL_EP << 11) | (0 << 0)),
1284 /*ep0 enable, clear nak */
1285 s5p_otg_write_reg((1u << 31) | (1 << 26) | (0 << 0),
1289 static void s5p_usb_set_descriptors(void)
1291 #if defined (CONFIG_SAMSUNG_USB)
1292 otg.desc.dev.bLength = DEVICE_DESC_SIZE;
1293 otg.desc.dev.bDescriptorType = DEVICE_DESCRIPTOR;
1294 otg.desc.dev.bDeviceClass = 0xFF;
1295 otg.desc.dev.bDeviceSubClass = 0x0;
1296 otg.desc.dev.bDeviceProtocol = 0x0;
1297 otg.desc.dev.bMaxPacketSize0 = otg.ctrl_max_pktsize;
1298 otg.desc.dev.idVendorL = 0xE8;
1299 otg.desc.dev.idVendorH = 0x04;
1300 otg.desc.dev.idProductL = 0x04;
1301 otg.desc.dev.idProductH = 0x12;
1302 otg.desc.dev.iManufacturer = 0x0;
1303 otg.desc.dev.iProduct = 0x2;
1304 otg.desc.dev.iSerialNumber = 0x0;
1305 otg.desc.dev.bNumConfigurations = 0x1;
1306 otg.desc.dev.bcdUSBL = 0x00;
1307 otg.desc.dev.bcdUSBH = 0x02;
1309 otg.desc.config.bLength = CONFIG_DESC_SIZE;
1310 otg.desc.config.bDescriptorType = CONFIGURATION_DESCRIPTOR;
1311 otg.desc.config.wTotalLengthL = CONFIG_DESC_TOTAL_SIZE;
1312 otg.desc.config.wTotalLengthH = 0;
1313 otg.desc.config.bNumInterfaces = 1;
1314 otg.desc.config.bConfigurationValue = 1;
1315 otg.desc.config.iConfiguration = 0;
1316 otg.desc.config.bmAttributes = CONF_ATTR_DEFAULT | CONF_ATTR_SELFPOWERED;
1317 otg.desc.config.maxPower = 50;
1319 otg.desc.dev.bLength = DEVICE_DESC_SIZE;
1320 otg.desc.dev.bDescriptorType = DEVICE_DESCRIPTOR;
1321 otg.desc.dev.bDeviceClass = 0xFF;
1322 otg.desc.dev.bDeviceSubClass = 0x0;
1323 otg.desc.dev.bDeviceProtocol = 0x0;
1324 otg.desc.dev.bMaxPacketSize0 = otg.ctrl_max_pktsize;
1325 otg.desc.dev.idVendorL = 0xE8;
1326 otg.desc.dev.idVendorH = 0x04;
1327 otg.desc.dev.idProductL = 0x34;
1328 otg.desc.dev.idProductH = 0x12;
1329 otg.desc.dev.bcdDeviceL = 0x00;
1330 otg.desc.dev.bcdDeviceH = 0x01;
1331 otg.desc.dev.iManufacturer = 0x1;
1332 otg.desc.dev.iProduct = 0x2;
1333 otg.desc.dev.iSerialNumber = 0x0;
1334 otg.desc.dev.bNumConfigurations = 0x1;
1335 otg.desc.dev.bcdUSBL = 0x00;
1336 otg.desc.dev.bcdUSBH = 0x02;
1338 otg.desc.config.bLength = CONFIG_DESC_SIZE;
1339 otg.desc.config.bDescriptorType = CONFIGURATION_DESCRIPTOR;
1340 otg.desc.config.wTotalLengthL = CONFIG_DESC_TOTAL_SIZE;
1341 otg.desc.config.wTotalLengthH = 0;
1342 otg.desc.config.bNumInterfaces = 1;
1343 otg.desc.config.bConfigurationValue = 1;
1344 otg.desc.config.iConfiguration = 0;
1345 otg.desc.config.bmAttributes = CONF_ATTR_DEFAULT | CONF_ATTR_SELFPOWERED;
1346 otg.desc.config.maxPower = 25;
1348 otg.desc.intf.bLength = INTERFACE_DESC_SIZE;
1349 otg.desc.intf.bDescriptorType = INTERFACE_DESCRIPTOR;
1350 otg.desc.intf.bInterfaceNumber = 0x0;
1351 otg.desc.intf.bAlternateSetting = 0x0;
1352 otg.desc.intf.bNumEndpoints = 2;
1353 otg.desc.intf.bInterfaceClass = 0xff;
1354 otg.desc.intf.bInterfaceSubClass = 0xff;
1355 otg.desc.intf.bInterfaceProtocol = 0xff;
1356 otg.desc.intf.iInterface = 0x0;
1358 otg.desc.ep1.bLength = ENDPOINT_DESC_SIZE;
1359 otg.desc.ep1.bDescriptorType = ENDPOINT_DESCRIPTOR;
1360 otg.desc.ep1.bEndpointAddress = BULK_IN_EP | EP_ADDR_IN;
1361 otg.desc.ep1.bmAttributes = EP_ATTR_BULK;
1362 otg.desc.ep1.wMaxPacketSizeL = (u8)otg.bulkin_max_pktsize;
1363 otg.desc.ep1.wMaxPacketSizeH = (u8)(otg.bulkin_max_pktsize >> 8);
1364 otg.desc.ep1.bInterval = 0x0;
1366 otg.desc.ep2.bLength = ENDPOINT_DESC_SIZE;
1367 otg.desc.ep2.bDescriptorType = ENDPOINT_DESCRIPTOR;
1368 otg.desc.ep2.bEndpointAddress = BULK_OUT_EP | EP_ADDR_OUT;
1369 otg.desc.ep2.bmAttributes = EP_ATTR_BULK;
1370 otg.desc.ep2.wMaxPacketSizeL = (u8)otg.bulkout_max_pktsize;
1371 otg.desc.ep2.wMaxPacketSizeH = (u8)(otg.bulkout_max_pktsize >> 8);
1372 otg.desc.ep2.bInterval = 0x0;
1375 static void s5p_usb_set_opmode(USB_OPMODE mode)
1379 s5p_otg_write_reg(INT_RESUME | INT_OUT_EP | INT_IN_EP | INT_ENUMDONE |
1380 INT_RESET | INT_SUSPEND | INT_RX_FIFO_NOT_EMPTY,
1383 s5p_otg_write_reg(MODE_SLAVE | BURST_SINGLE | GBL_INT_UNMASK,
1386 s5p_usb_set_outep_xfersize(EP_TYPE_BULK, 1, otg.bulkout_max_pktsize);
1387 s5p_usb_set_inep_xfersize(EP_TYPE_BULK, 1, 0);
1389 /*bulk out ep enable, clear nak, bulk, usb active, next ep3, max pkt */
1390 s5p_otg_write_reg(1u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
1391 otg.bulkout_max_pktsize << 0, OTG_DOEPCTL_OUT);
1393 /*bulk in ep enable, clear nak, bulk, usb active, next ep1, max pkt */
1394 s5p_otg_write_reg(0u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
1395 otg.bulkin_max_pktsize << 0, OTG_DIEPCTL_IN);
1398 static void s5p_usb_reset(void)
1400 s5p_usb_set_all_outep_nak(1);
1402 otg.ep0_state = EP0_STATE_INIT;
1403 s5p_otg_write_reg(((1 << BULK_OUT_EP) | (1 << CONTROL_EP)) << 16 |
1404 ((1 << BULK_IN_EP) | (1 << CONTROL_EP)), OTG_DAINTMSK);
1405 s5p_otg_write_reg(CTRL_OUT_EP_SETUP_PHASE_DONE | AHB_ERROR |
1406 TRANSFER_DONE, OTG_DOEPMSK);
1407 s5p_otg_write_reg(INTKN_TXFEMP | NON_ISO_IN_EP_TIMEOUT | AHB_ERROR |
1408 TRANSFER_DONE, OTG_DIEPMSK);
1411 s5p_otg_write_reg(RX_FIFO_SIZE, OTG_GRXFSIZ);
1413 /* Non Periodic Tx FIFO Size */
1414 s5p_otg_write_reg(NPTX_FIFO_SIZE << 16 | NPTX_FIFO_START_ADDR << 0,
1417 s5p_usb_set_all_outep_nak(0);
1419 /*clear device address */
1420 s5p_otg_write_reg(s5p_otg_read_reg(OTG_DCFG) & ~(0x7f << 4),
1423 s5p_usb_connected = 0;
1426 static int s5p_usb_set_init(void)
1430 status = s5p_otg_read_reg(OTG_DSTS);
1432 /* Set if Device is High speed or Full speed */
1433 if (((status & 0x6) >> 1) == USB_HIGH) {
1434 s5p_usb_set_max_pktsize(USB_HIGH);
1435 } else if (((status & 0x6) >> 1) == USB_FULL) {
1436 s5p_usb_set_max_pktsize(USB_FULL);
1438 puts("Error: Neither High_Speed nor Full_Speed\n");
1442 s5p_usb_set_endpoint();
1443 s5p_usb_set_descriptors();
1444 s5p_usb_set_opmode(op_mode);
1449 static void s5p_usb_pkt_receive(void)
1454 rx_status = s5p_otg_read_reg(OTG_GRXSTSP);
1456 if ((rx_status & (0xf << 17)) == SETUP_PKT_RECEIVED) {
1457 s5p_usb_ep0_int_hndlr();
1458 } else if ((rx_status & (0xf << 17)) == OUT_PKT_RECEIVED) {
1459 fifo_cnt_byte = (rx_status & 0x7ff0) >> 4;
1461 if ((rx_status & BULK_OUT_EP) && (fifo_cnt_byte)) {
1462 s5p_usb_int_bulkout(fifo_cnt_byte);
1463 if (otg.op_mode == USB_CPU) {
1464 s5p_otg_write_reg(INT_RESUME | INT_OUT_EP |
1465 INT_IN_EP | INT_ENUMDONE | INT_RESET |
1466 INT_SUSPEND | INT_RX_FIFO_NOT_EMPTY,
1475 static void s5p_usb_transfer(void)
1481 ep_int = s5p_otg_read_reg(OTG_DAINT);
1483 if (ep_int & (1 << CONTROL_EP)) {
1484 ep_int_status = s5p_otg_read_reg(OTG_DIEPINT0);
1486 if (ep_int_status & INTKN_TXFEMP) {
1489 uNTxFifoSpace = s5p_otg_read_reg(OTG_GNPTXSTS)
1491 } while (uNTxFifoSpace < otg.ctrl_max_pktsize);
1493 s5p_usb_transfer_ep0();
1496 s5p_otg_write_reg(ep_int_status, OTG_DIEPINT0);
1499 if (ep_int & ((1 << CONTROL_EP) << 16)) {
1500 ep_int_status = s5p_otg_read_reg(OTG_DOEPINT0);
1502 s5p_usb_set_outep_xfersize(EP_TYPE_CONTROL, 1, 8);
1503 s5p_otg_write_reg(1u << 31 | 1 << 26, OTG_DOEPCTL0);
1505 s5p_otg_write_reg(ep_int_status, OTG_DOEPINT0);
1508 if (ep_int & (1 << BULK_IN_EP)) {
1509 ep_int_status = s5p_otg_read_reg(OTG_DIEPINT_IN);
1511 s5p_otg_write_reg(ep_int_status, OTG_DIEPINT_IN);
1512 check_dma = s5p_otg_read_reg(OTG_GAHBCFG);
1514 if ((check_dma & MODE_DMA) && (ep_int_status & TRANSFER_DONE))
1515 s5p_usb_dma_in_done();
1518 if (ep_int & ((1 << BULK_OUT_EP) << 16)) {
1519 ep_int_status = s5p_otg_read_reg(OTG_DOEPINT_OUT);
1521 s5p_otg_write_reg(ep_int_status, OTG_DOEPINT_OUT);
1522 check_dma = s5p_otg_read_reg(OTG_GAHBCFG);
1524 if ((check_dma & MODE_DMA) && (ep_int_status & TRANSFER_DONE))
1525 s5p_usb_dma_out_done();
1529 void s5p_udc_int_hndlr(void)
1534 int_status = s5p_otg_read_reg(OTG_GINTSTS);
1535 s5p_otg_write_reg(int_status, OTG_GINTSTS);
1537 if (int_status & INT_RESET) {
1538 s5p_otg_write_reg(INT_RESET, OTG_GINTSTS);
1542 if (int_status & INT_ENUMDONE) {
1543 s5p_otg_write_reg(INT_ENUMDONE, OTG_GINTSTS);
1545 tmp = s5p_usb_set_init();
1550 if (int_status & INT_RESUME)
1551 s5p_otg_write_reg(INT_RESUME, OTG_GINTSTS);
1553 if (int_status & INT_SUSPEND)
1554 s5p_otg_write_reg(INT_SUSPEND, OTG_GINTSTS);
1556 if (int_status & INT_RX_FIFO_NOT_EMPTY) {
1557 s5p_otg_write_reg(INT_RESUME | INT_OUT_EP | INT_IN_EP |
1558 INT_ENUMDONE | INT_RESET | INT_SUSPEND,
1561 s5p_usb_pkt_receive();
1563 s5p_otg_write_reg(INT_RESUME | INT_OUT_EP | INT_IN_EP |
1564 INT_ENUMDONE | INT_RESET | INT_SUSPEND |
1565 INT_RX_FIFO_NOT_EMPTY, OTG_GINTMSK);
1568 if ((int_status & INT_IN_EP) || (int_status & INT_OUT_EP))
1572 void s5p_usb_set_dn_addr(unsigned long addr, unsigned long size)