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 <asm/arch/power.h>
26 #include "usb-hs-otg.h"
32 int s5p_usb_connected;
34 USB_OPMODE op_mode = USB_CPU;
35 USB_SPEED speed = USB_HIGH;
37 USB_OPMODE op_mode = USB_DMA;
38 USB_SPEED speed = USB_FULL;
42 get_status_t get_status;
46 EP0, EP1, EP2, EP3, EP4
49 /*------------------------------------------------*/
53 EP0_STATE_GD_DEV_0 = 11,
54 EP0_STATE_GD_DEV_1 = 12,
55 EP0_STATE_GD_DEV_2 = 13,
56 EP0_STATE_GD_CFG_0 = 21,
57 EP0_STATE_GD_CFG_1 = 22,
58 EP0_STATE_GD_CFG_2 = 23,
59 EP0_STATE_GD_CFG_3 = 24,
60 EP0_STATE_GD_CFG_4 = 25,
61 EP0_STATE_GD_STR_I0 = 30,
62 EP0_STATE_GD_STR_I1 = 31,
63 EP0_STATE_GD_STR_I2 = 32,
64 EP0_STATE_GD_DEV_QUALIFIER = 33,
65 EP0_STATE_INTERFACE_GET = 34,
66 EP0_STATE_GET_STATUS0 = 35,
67 EP0_STATE_GET_STATUS1 = 36,
68 EP0_STATE_GET_STATUS2 = 37,
69 EP0_STATE_GET_STATUS3 = 38,
70 EP0_STATE_GET_STATUS4 = 39,
71 EP0_STATE_GD_OTHER_SPEED = 40,
72 EP0_STATE_GD_CFG_ONLY_0 = 41,
73 EP0_STATE_GD_CFG_ONLY_1 = 42,
74 EP0_STATE_GD_IF_ONLY_0 = 44,
75 EP0_STATE_GD_IF_ONLY_1 = 45,
76 EP0_STATE_GD_EP0_ONLY_0 = 46,
77 EP0_STATE_GD_EP1_ONLY_0 = 47,
78 EP0_STATE_GD_EP2_ONLY_0 = 48,
79 EP0_STATE_GD_EP3_ONLY_0 = 49,
80 EP0_STATE_GD_OTHER_SPEED_HIGH_1 = 51,
81 EP0_STATE_GD_OTHER_SPEED_HIGH_2 = 52,
82 EP0_STATE_GD_OTHER_SPEED_HIGH_3 = 53
85 /*definitions related to CSR setting */
88 #define B_SESSION_VALID (0x1 << 19)
89 #define A_SESSION_VALID (0x1 << 18)
92 #define PTXFE_HALF (0<<8)
93 #define PTXFE_ZERO (1<<8)
94 #define NPTXFE_HALF (0<<7)
95 #define NPTXFE_ZERO (1<<7)
96 #define MODE_SLAVE (0<<5)
97 #define MODE_DMA (1<<5)
98 #define BURST_SINGLE (0<<1)
99 #define BURST_INCR (1<<1)
100 #define BURST_INCR4 (3<<1)
101 #define BURST_INCR8 (5<<1)
102 #define BURST_INCR16 (7<<1)
103 #define GBL_INT_UNMASK (1<<0)
104 #define GBL_INT_MASK (0<<0)
107 #define AHB_MASTER_IDLE (1u<<31)
108 #define CORE_SOFT_RESET (0x1<<0)
110 /* OTG_GINTSTS/OTG_GINTMSK core interrupt register */
111 #define INT_RESUME (1u<<31)
112 #define INT_DISCONN (0x1<<29)
113 #define INT_CONN_ID_STS_CNG (0x1<<28)
114 #define INT_OUT_EP (0x1<<19)
115 #define INT_IN_EP (0x1<<18)
116 #define INT_ENUMDONE (0x1<<13)
117 #define INT_RESET (0x1<<12)
118 #define INT_SUSPEND (0x1<<11)
119 #define INT_TX_FIFO_EMPTY (0x1<<5)
120 #define INT_RX_FIFO_NOT_EMPTY (0x1<<4)
121 #define INT_SOF (0x1<<3)
122 #define INT_DEV_MODE (0x0<<0)
123 #define INT_HOST_MODE (0x1<<1)
124 #define INT_OTG (0x1<<2)
126 /* OTG_GRXSTSP STATUS*/
127 #define GLOBAL_OUT_NAK (0x1<<17)
128 #define OUT_PKT_RECEIVED (0x2<<17)
129 #define OUT_TRNASFER_COMPLETED (0x3<<17)
130 #define SETUP_TRANSACTION_COMPLETED (0x4<<17)
131 #define SETUP_PKT_RECEIVED (0x6<<17)
133 /* OTG_DCTL device control register */
134 #define NORMAL_OPERATION (0x1<<0)
135 #define SOFT_DISCONNECT (0x1<<1)
136 #define TEST_J_MODE (TEST_J<<4)
137 #define TEST_K_MODE (TEST_K<<4)
138 #define TEST_SE0_NAK_MODE (TEST_SE0_NAK<<4)
139 #define TEST_PACKET_MODE (TEST_PACKET<<4)
140 #define TEST_FORCE_ENABLE_MODE (TEST_FORCE_ENABLE<<4)
141 #define TEST_CONTROL_FIELD (0x7<<4)
143 /* OTG_DAINT device all endpoint interrupt register */
144 #define INT_IN_EP0 (0x1<<0)
145 #define INT_IN_EP1 (0x1<<1)
146 #define INT_IN_EP3 (0x1<<3)
147 #define INT_OUT_EP0 (0x1<<16)
148 #define INT_OUT_EP2 (0x1<<18)
149 #define INT_OUT_EP4 (0x1<<20)
151 /* OTG_DIEPCTL0/OTG_DOEPCTL0 */
152 #define DEPCTL_EPENA (0x1<<31)
153 #define DEPCTL_EPDIS (0x1<<30)
154 #define DEPCTL_SNAK (0x1<<27)
155 #define DEPCTL_CNAK (0x1<<26)
156 #define DEPCTL_CTRL_TYPE (EP_TYPE_CONTROL<<18)
157 #define DEPCTL_ISO_TYPE (EP_TYPE_ISOCHRONOUS<<18)
158 #define DEPCTL_BULK_TYPE (EP_TYPE_BULK<<18)
159 #define DEPCTL_INTR_TYPE (EP_TYPE_INTERRUPT<<18)
160 #define DEPCTL_USBACTEP (0x1<<15)
162 /*ep0 enable, clear nak, next ep0, max 64byte */
163 #define EPEN_CNAK_EP0_64 (DEPCTL_EPENA|DEPCTL_CNAK|(CONTROL_EP<<11)|(0<<0))
165 /*ep0 enable, clear nak, next ep0, 8byte */
166 #define EPEN_CNAK_EP0_8 (DEPCTL_EPENA|DEPCTL_CNAK|(CONTROL_EP<<11)|(3<<0))
168 /* DIEPCTLn/DOEPCTLn */
169 #define BACK2BACK_SETUP_RECEIVED (0x1<<6)
170 #define INTKN_TXFEMP (0x1<<4)
171 #define NON_ISO_IN_EP_TIMEOUT (0x1<<3)
172 #define CTRL_OUT_EP_SETUP_PHASE_DONE (0x1<<3)
173 #define AHB_ERROR (0x1<<2)
174 #define TRANSFER_DONE (0x1<<0)
176 /* codes representing languages */
177 const u8 string_desc0[] = {
178 4, STRING_DESCRIPTOR, LANGID_US_L, LANGID_US_H,
181 #ifdef CONFIG_SAMSUNG_USB
182 const u8 string_desc1[] = /* Manufacturer */
184 (0x14 + 2), STRING_DESCRIPTOR,
185 'S', 0x0, '/', 0x0, 'W', 0x0, ' ', 0x0, 'C', 0x0,
186 'e', 0x0, 'n', 0x0, 't', 0x0, 'e', 0x0, 'r', 0x0,
189 const u8 string_desc1[] = /* Manufacturer */
191 (0x14 + 2), STRING_DESCRIPTOR,
192 'S', 0x0, 'y', 0x0, 's', 0x0, 't', 0x0, 'e', 0x0,
193 'm', 0x0, ' ', 0x0, 'M', 0x0, 'C', 0x0, 'U', 0x0,
197 #ifdef CONFIG_SAMSUNG_USB
198 const u8 string_desc2[] = /* Product */
200 (0x22 + 2), STRING_DESCRIPTOR,
201 'S', 0x0, 'A', 0x0, 'M', 0x0, 'S', 0x0, 'U', 0x0,
202 'N', 0x0, 'G', 0x0, ' ', 0x0, 'X', 0x0, 'O', 0x0,
203 ' ', 0x0, 'D', 0x0, 'R', 0x0, 'I', 0x0, 'V', 0x0,
207 const u8 string_desc2[] = /* Product */
209 (0x2a + 2), STRING_DESCRIPTOR,
210 'S', 0x0, 'E', 0x0, 'C', 0x0, ' ', 0x0, 'S', 0x0,
211 '3', 0x0, 'C', 0x0, '6', 0x0, '4', 0x0, '0', 0x0,
212 '0', 0x0, 'X', 0x0, ' ', 0x0, 'T', 0x0, 'e', 0x0,
213 's', 0x0, 't', 0x0, ' ', 0x0, 'B', 0x0, '/', 0x0,
218 /* setting the device qualifier descriptor and a string descriptor */
219 const u8 qualifier_desc[] = {
220 0x0a, /* 0 desc size */
221 0x06, /* 1 desc type (DEVICE_QUALIFIER) */
222 0x00, /* 2 USB release */
223 0x02, /* 3 => 2.00 */
225 0x00, /* 5 subclass */
226 0x00, /* 6 protocol */
227 64, /* 7 max pack size */
228 0x01, /* 8 number of other-speed configuration */
229 0x00, /* 9 reserved */
232 const u8 config_full[] = {
233 0x09, /* 0 desc size */
234 0x07, /* 1 desc type (other speed) */
235 0x20, /* 2 Total length of data returned */
237 0x01, /* 4 Number of interfaces */
238 0x01, /* 5 value to use to select configuration */
239 0x00, /* 6 index of string desc */
240 /* 7 same as configuration desc */
241 CONF_ATTR_DEFAULT | CONF_ATTR_SELFPOWERED,
242 0x19, /* 8 same as configuration desc */
246 const u8 config_full_total[] = {
247 0x09, 0x07, 0x20, 0x00, 0x01, 0x01, 0x00, 0xC0, 0x19,
248 0x09, 0x04, 0x00, 0x00, 0x02, 0xff, 0x00, 0x00, 0x00,
249 0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x00,
250 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00
253 const u8 config_high[] = {
254 0x09, /* 0 desc size */
255 0x07, /* 1 desc type (other speed) */
256 0x20, /* 2 Total length of data returned */
258 0x01, /* 4 Number of interfaces */
259 0x01, /* 5 value to use to select configuration */
260 0x00, /* 6 index of string desc */
261 /* 7 same as configuration desc */
262 CONF_ATTR_DEFAULT | CONF_ATTR_SELFPOWERED,
263 0x19, /* 8 same as configuration desc */
267 const u8 config_high_total[] = {
268 0x09, 0x07, 0x20, 0x00, 0x01, 0x01, 0x00, 0xC0, 0x19,
269 0x09, 0x04, 0x00, 0x00, 0x02, 0xff, 0x00, 0x00, 0x00,
270 0x07, 0x05, 0x81, 0x02, 0x00, 0x02, 0x00,
271 0x07, 0x05, 0x02, 0x02, 0x00, 0x02, 0x00
274 /* Descriptor size */
275 enum DESCRIPTOR_SIZE {
276 DEVICE_DESC_SIZE = sizeof(device_desc_t),
277 STRING_DESC0_SIZE = sizeof(string_desc0),
278 STRING_DESC1_SIZE = sizeof(string_desc1),
279 STRING_DESC2_SIZE = sizeof(string_desc2),
280 CONFIG_DESC_SIZE = sizeof(config_desc_t),
281 INTERFACE_DESC_SIZE = sizeof(intf_desc_t),
282 ENDPOINT_DESC_SIZE = sizeof(ep_desc_t),
283 DEVICE_QUALIFIER_SIZE = sizeof(qualifier_desc),
284 OTHER_SPEED_CFG_SIZE = 9
287 /*32 <cfg desc>+<if desc>+<endp0 desc>+<endp1 desc>*/
288 #define CONFIG_DESC_TOTAL_SIZE \
289 (CONFIG_DESC_SIZE+INTERFACE_DESC_SIZE+ENDPOINT_DESC_SIZE*2)
291 static unsigned int phy_base;
292 static unsigned int otg_base;
294 static inline void s5p_usb_init_base(void)
296 if (cpu_is_s5pc110()) {
297 phy_base = S5PC110_PHY_BASE;
298 otg_base = S5PC110_OTG_BASE;
300 phy_base = S5PC100_PHY_BASE;
301 otg_base = S5PC100_OTG_BASE;
305 static inline int s5pc1xx_phy_read_reg(int offset)
307 return readl(phy_base + offset);
310 static inline void s5pc1xx_phy_write_reg(int value, int offset)
312 writel(value, phy_base + offset);
315 static inline int s5pc1xx_otg_read_reg(int offset)
317 return readl(otg_base + offset);
320 static inline void s5pc1xx_otg_write_reg(int value, int offset)
322 writel(value, otg_base + offset);
325 static void s5p_usb_init_phy(void)
327 if (cpu_is_s5pc110()) {
328 s5pc1xx_phy_write_reg(0xA0, OTG_PHYPWR);
329 s5pc1xx_phy_write_reg(0x3, OTG_PHYCTRL);
331 s5pc1xx_phy_write_reg(0x0, OTG_PHYPWR);
332 #ifdef CONFIG_OTG_CLK_OSCC
333 s5pc1xx_phy_write_reg(0x22, OTG_PHYCTRL);
335 s5pc1xx_phy_write_reg(0x2, OTG_PHYCTRL);
339 s5pc1xx_phy_write_reg(0x1, OTG_RSTCON);
341 s5pc1xx_phy_write_reg(0x0, OTG_RSTCON);
345 int s5p_usb_detect_irq(void)
348 status = s5pc1xx_otg_read_reg(OTG_GINTSTS);
349 return (status & 0x800c3810);
352 void s5p_usb_clear_irq(void)
354 s5pc1xx_otg_write_reg(0xffffffff, OTG_GINTSTS);
357 static void s5p_usb_core_soft_reset(void)
361 s5pc1xx_otg_write_reg(CORE_SOFT_RESET, OTG_GRSTCTL);
364 tmp = s5pc1xx_otg_read_reg(OTG_GRSTCTL);
365 } while (!(tmp & AHB_MASTER_IDLE));
368 static void s5p_usb_wait_cable_insert(void)
376 tmp = s5pc1xx_otg_read_reg(OTG_GOTGCTL);
378 if (tmp & (B_SESSION_VALID | A_SESSION_VALID)) {
380 } else if (ucFirst == 1) {
381 printf("Insert a OTG cable into the connector!\n");
387 static void s5p_usb_init_core(void)
389 s5pc1xx_otg_write_reg(PTXFE_HALF | NPTXFE_HALF | MODE_SLAVE |
390 BURST_SINGLE | GBL_INT_UNMASK, OTG_GAHBCFG);
392 s5pc1xx_otg_write_reg(
393 0x0 << 15 /* PHY Low Power Clock sel */
394 | 0x1 << 14 /* Non-Periodic TxFIFO Rewind Enable */
395 | 0x5 << 10 /* Turnaround time */
396 | 0x0 << 9 /* 0:HNP disable, 1:HNP enable */
397 | 0x0 << 8 /* 0:SRP disable, 1:SRP enable */
398 | 0x0 << 7 /* ULPI DDR sel */
399 | 0x0 << 6 /* 0: high speed utmi+, 1: full speed serial */
400 | 0x0 << 4 /* 0: utmi+, 1:ulpi */
401 | 0x1 << 3 /* phy i/f 0:8bit, 1:16bit */
402 | 0x7 << 0, /* HS/FS Timeout* */
406 static void s5p_usb_check_current_mode(u8 *pucMode)
410 tmp = s5pc1xx_otg_read_reg(OTG_GINTSTS);
411 *pucMode = tmp & 0x1;
414 static void s5p_usb_soft_disconnect(int set)
418 tmp = s5pc1xx_otg_read_reg(OTG_DCTL);
420 tmp |= SOFT_DISCONNECT;
422 tmp &= ~SOFT_DISCONNECT;
423 s5pc1xx_otg_write_reg(tmp, OTG_DCTL);
426 static void s5p_usb_init_device(void)
428 s5pc1xx_otg_write_reg(1 << 18 | otg.speed << 0, OTG_DCFG);
430 s5pc1xx_otg_write_reg(INT_RESUME | INT_OUT_EP | INT_IN_EP |
431 INT_ENUMDONE | INT_RESET | INT_SUSPEND |
432 INT_RX_FIFO_NOT_EMPTY, OTG_GINTMSK);
435 int s5p_usbctl_init(void)
442 if (cpu_is_s5pc110()) {
443 reg = readl(S5PC110_USB_PHY_CON);
444 reg |= (1 << 0); /* USB PHY0 enable */
445 writel(reg, S5PC110_USB_PHY_CON);
447 reg = readl(S5PC100_OTHERS);
448 reg |= (1 << 16); /* unmask usb signal */
449 writel(reg, S5PC100_OTHERS);
454 otg.ep0_state = EP0_STATE_INIT;
455 otg.ep0_substate = 0;
458 s5p_usb_core_soft_reset();
459 s5p_usb_wait_cable_insert();
461 s5p_usb_check_current_mode(&ucMode);
463 if (ucMode == INT_DEV_MODE) {
464 s5p_usb_soft_disconnect(1);
466 s5p_usb_soft_disconnect(0);
467 s5p_usb_init_device();
470 printf("Error : Current Mode is Host\n");
475 static void s5p_usb_set_inep_xfersize(EP_TYPE type, u32 pktcnt, u32 xfersize)
477 if (type == EP_TYPE_CONTROL) {
478 s5pc1xx_otg_write_reg((pktcnt << 19) | (xfersize << 0),
480 } else if (type == EP_TYPE_BULK) {
481 s5pc1xx_otg_write_reg((1 << 29) | (pktcnt << 19) |
482 (xfersize << 0), OTG_DIEPTSIZ_IN);
486 static void s5p_usb_set_outep_xfersize(EP_TYPE type, u32 pktcnt, u32 xfersize)
488 if (type == EP_TYPE_CONTROL) {
489 s5pc1xx_otg_write_reg((1 << 29) | (pktcnt << 19) |
490 (xfersize << 0), OTG_DOEPTSIZ0);
491 } else if (type == EP_TYPE_BULK) {
492 s5pc1xx_otg_write_reg((pktcnt << 19) | (xfersize << 0),
497 /* works on both aligned and unaligned buffers */
498 static void s5p_usb_write_ep0_fifo(u8 *buf, int num)
503 for (i = 0; i < num; i += 4) {
504 Wr_Data = ((*(buf + 3)) << 24) |
505 ((*(buf + 2)) << 16) |
506 ((*(buf + 1)) << 8) |
508 s5pc1xx_otg_write_reg(Wr_Data, OTG_EP0_FIFO);
513 /* optimized fifo access routines, warning: only aligned buffers are supported */
514 static inline void s5p_usb_write_in_fifo(u8 *buf, int num)
516 u32 fifo = otg_base + OTG_IN_FIFO;
520 for (i = 0; i < num; i += 4)
524 static inline void s5p_usb_read_out_fifo(u8 *buf, int num)
526 u32 fifo = otg_base + OTG_OUT_FIFO;
530 for (i = 0; i < num; i += 4)
534 static void s5p_usb_get_desc(void)
536 switch (otg.dev_req.wValue_H) {
537 case DEVICE_DESCRIPTOR:
538 otg.req_length = (u32)((otg.dev_req.wLength_H << 8) |
539 otg.dev_req.wLength_L);
540 otg.ep0_state = EP0_STATE_GD_DEV_0;
543 case CONFIGURATION_DESCRIPTOR:
544 otg.req_length = (u32)((otg.dev_req.wLength_H << 8) |
545 otg.dev_req.wLength_L);
547 if (otg.req_length > CONFIG_DESC_SIZE)
548 otg.ep0_state = EP0_STATE_GD_CFG_0;
550 otg.ep0_state = EP0_STATE_GD_CFG_ONLY_0;
553 case STRING_DESCRIPTOR:
554 switch (otg.dev_req.wValue_L) {
556 otg.ep0_state = EP0_STATE_GD_STR_I0;
559 otg.ep0_state = EP0_STATE_GD_STR_I1;
562 otg.ep0_state = EP0_STATE_GD_STR_I2;
569 case ENDPOINT_DESCRIPTOR:
570 switch (otg.dev_req.wValue_L & 0xf) {
572 otg.ep0_state = EP0_STATE_GD_EP0_ONLY_0;
575 otg.ep0_state = EP0_STATE_GD_EP1_ONLY_0;
582 case DEVICE_QUALIFIER:
583 otg.req_length = (u32)((otg.dev_req.wLength_H << 8) |
584 otg.dev_req.wLength_L);
585 otg.ep0_state = EP0_STATE_GD_DEV_QUALIFIER;
588 case OTHER_SPEED_CONFIGURATION:
589 otg.req_length = (u32)((otg.dev_req.wLength_H << 8) |
590 otg.dev_req.wLength_L);
591 otg.ep0_state = EP0_STATE_GD_OTHER_SPEED;
596 static void s5p_usb_clear_feature(void)
598 switch (otg.dev_req.bmRequestType) {
599 case DEVICE_RECIPIENT:
600 if (otg.dev_req.wValue_L == 1)
604 case ENDPOINT_RECIPIENT:
605 if (otg.dev_req.wValue_L == 0) {
606 if ((otg.dev_req.wIndex_L & 0x7f) == CONTROL_EP)
607 get_status.ep_ctrl = 0;
610 if ((otg.dev_req.wIndex_L & 0x7f) == BULK_IN_EP)
611 get_status.ep_in = 0;
614 if ((otg.dev_req.wIndex_L & 0x7f) == BULK_OUT_EP)
615 get_status.ep_out = 0;
622 otg.ep0_state = EP0_STATE_INIT;
625 static void s5p_usb_set_feature(void)
627 switch (otg.dev_req.bmRequestType) {
628 case DEVICE_RECIPIENT:
629 if (otg.dev_req.wValue_L == 1)
633 case ENDPOINT_RECIPIENT:
634 if (otg.dev_req.wValue_L == 0) {
635 if ((otg.dev_req.wIndex_L & 0x7f) == CONTROL_EP)
636 get_status.ep_ctrl = 1;
638 if ((otg.dev_req.wIndex_L & 0x7f) == BULK_IN_EP)
639 get_status.ep_in = 1;
641 if ((otg.dev_req.wIndex_L & 0x7f) == BULK_OUT_EP)
642 get_status.ep_out = 1;
650 otg.ep0_state = EP0_STATE_INIT;
653 static void s5p_usb_get_status(void)
655 switch (otg.dev_req.bmRequestType) {
656 case (0x80): /*device */
657 get_status.Device = ((u8) remode_wakeup << 1) | 0x1;
658 otg.ep0_state = EP0_STATE_GET_STATUS0;
661 case (0x81): /*interface */
662 get_status.Interface = 0;
663 otg.ep0_state = EP0_STATE_GET_STATUS1;
666 case (0x82): /*endpoint */
667 if ((otg.dev_req.wIndex_L & 0x7f) == CONTROL_EP)
668 otg.ep0_state = EP0_STATE_GET_STATUS2;
670 if ((otg.dev_req.wIndex_L & 0x7f) == BULK_IN_EP)
671 otg.ep0_state = EP0_STATE_GET_STATUS3;
673 if ((otg.dev_req.wIndex_L & 0x7f) == BULK_OUT_EP)
674 otg.ep0_state = EP0_STATE_GET_STATUS4;
682 static void s5p_usb_ep0_int_hndlr(void)
685 u32 buf[2] = {0x0000, };
688 if (otg.ep0_state == EP0_STATE_INIT) {
689 for (i = 0; i < 2; i++)
690 buf[i] = s5pc1xx_otg_read_reg(OTG_EP0_FIFO);
692 otg.dev_req.bmRequestType = buf[0];
693 otg.dev_req.bRequest = buf[0] >> 8;
694 otg.dev_req.wValue_L = buf[0] >> 16;
695 otg.dev_req.wValue_H = buf[0] >> 24;
696 otg.dev_req.wIndex_L = buf[1];
697 otg.dev_req.wIndex_H = buf[1] >> 8;
698 otg.dev_req.wLength_L = buf[1] >> 16;
699 otg.dev_req.wLength_H = buf[1] >> 24;
701 switch (otg.dev_req.bRequest) {
702 case STANDARD_SET_ADDRESS:
703 /* Set Address Update bit */
704 addr = (otg.dev_req.wValue_L);
705 s5pc1xx_otg_write_reg(1 << 18 | addr << 4 | otg.speed << 0,
707 otg.ep0_state = EP0_STATE_INIT;
710 case STANDARD_SET_DESCRIPTOR:
713 case STANDARD_SET_CONFIGURATION:
714 /* Configuration value in configuration descriptor */
715 config_value = otg.dev_req.wValue_L;
717 otg.ep0_state = EP0_STATE_INIT;
719 s5p_usb_connected = 1;
722 case STANDARD_GET_CONFIGURATION:
723 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
725 /*ep0 enable, clear nak, next ep0, 8byte */
726 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
727 s5pc1xx_otg_write_reg(config_value, OTG_EP0_FIFO);
728 otg.ep0_state = EP0_STATE_INIT;
731 case STANDARD_GET_DESCRIPTOR:
735 case STANDARD_CLEAR_FEATURE:
736 s5p_usb_clear_feature();
739 case STANDARD_SET_FEATURE:
740 s5p_usb_set_feature();
743 case STANDARD_GET_STATUS:
744 s5p_usb_get_status();
747 case STANDARD_GET_INTERFACE:
748 otg.ep0_state = EP0_STATE_INTERFACE_GET;
751 case STANDARD_SET_INTERFACE:
752 get_intf.AlternateSetting = otg.dev_req.wValue_L;
753 otg.ep0_state = EP0_STATE_INIT;
756 case STANDARD_SYNCH_FRAME:
757 otg.ep0_state = EP0_STATE_INIT;
765 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, otg.ctrl_max_pktsize);
767 /*clear nak, next ep0, 64byte */
768 s5pc1xx_otg_write_reg(((1 << 26) | (CONTROL_EP << 11) | (0 << 0)),
772 static void s5p_usb_set_otherspeed_conf_desc(u32 length)
774 /* Standard device descriptor */
776 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 9);
777 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
778 s5p_usb_write_ep0_fifo((u8 *) &config_full, 9);
779 } else if (length == 32) {
780 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 32);
781 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
782 s5p_usb_write_ep0_fifo((u8 *) &config_full_total, 32);
784 otg.ep0_state = EP0_STATE_INIT;
787 static void s5p_usb_transfer_ep0(void)
789 switch (otg.ep0_state) {
791 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 0);
793 /*ep0 enable, clear nak, next ep0, 8byte */
794 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
797 case EP0_STATE_GD_DEV_0:
798 /*ep0 enable, clear nak, next ep0, max 64byte */
799 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
800 if (otg.req_length < DEVICE_DESC_SIZE) {
801 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
803 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.dev)),
806 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
808 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.dev)),
811 otg.ep0_state = EP0_STATE_INIT;
814 case EP0_STATE_GD_DEV_1:
815 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
816 if (otg.req_length < (2 * FS_CTRL_PKT_SIZE)) {
817 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.dev)) +
819 otg.req_length - FS_CTRL_PKT_SIZE);
820 otg.ep0_state = EP0_STATE_INIT;
822 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.dev)) +
823 FS_CTRL_PKT_SIZE, FS_CTRL_PKT_SIZE);
824 otg.ep0_state = EP0_STATE_GD_DEV_2;
828 case EP0_STATE_GD_DEV_2:
829 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
830 if (otg.req_length < DEVICE_DESC_SIZE) {
831 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.dev)) +
832 (2 * FS_CTRL_PKT_SIZE),
833 otg.req_length - 2 * FS_CTRL_PKT_SIZE);
835 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.dev)) +
836 (2 * FS_CTRL_PKT_SIZE),
837 DEVICE_DESC_SIZE - 2 * FS_CTRL_PKT_SIZE);
839 otg.ep0_state = EP0_STATE_INIT;
842 case EP0_STATE_GD_CFG_0:
843 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
844 if (otg.req_length < CONFIG_DESC_TOTAL_SIZE) {
845 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
847 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)),
850 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
851 CONFIG_DESC_TOTAL_SIZE);
852 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)),
853 CONFIG_DESC_TOTAL_SIZE);
855 otg.ep0_state = EP0_STATE_INIT;
858 case EP0_STATE_GD_CFG_1:
859 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
860 if (otg.req_length < (2 * FS_CTRL_PKT_SIZE)) {
861 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)) +
863 (otg.req_length - FS_CTRL_PKT_SIZE));
864 otg.ep0_state = EP0_STATE_INIT;
866 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)) +
867 FS_CTRL_PKT_SIZE, FS_CTRL_PKT_SIZE);
868 otg.ep0_state = EP0_STATE_GD_CFG_2;
872 case EP0_STATE_GD_CFG_2:
873 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
874 if (otg.req_length < (3 * FS_CTRL_PKT_SIZE)) {
875 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)) +
876 (2 * FS_CTRL_PKT_SIZE),
877 otg.req_length - 2 * FS_CTRL_PKT_SIZE);
878 otg.ep0_state = EP0_STATE_INIT;
880 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)) +
881 (2 * FS_CTRL_PKT_SIZE), FS_CTRL_PKT_SIZE);
882 otg.ep0_state = EP0_STATE_GD_CFG_3;
886 case EP0_STATE_GD_CFG_3:
887 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
888 if (otg.req_length < (4 * FS_CTRL_PKT_SIZE)) {
889 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)) +
890 (3 * FS_CTRL_PKT_SIZE),
891 otg.req_length - 3 * FS_CTRL_PKT_SIZE);
892 otg.ep0_state = EP0_STATE_INIT;
894 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)) +
895 (3 * FS_CTRL_PKT_SIZE), FS_CTRL_PKT_SIZE);
896 otg.ep0_state = EP0_STATE_GD_CFG_4;
900 case EP0_STATE_GD_CFG_4:
901 otg.ep0_state = EP0_STATE_INIT;
904 case EP0_STATE_GD_DEV_QUALIFIER:
905 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
906 if (otg.req_length < 10) {
907 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
909 s5p_usb_write_ep0_fifo((u8 *)qualifier_desc,
912 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 10);
913 s5p_usb_write_ep0_fifo((u8 *)qualifier_desc, 10);
915 otg.ep0_state = EP0_STATE_INIT;
918 case EP0_STATE_GD_OTHER_SPEED:
919 s5p_usb_set_otherspeed_conf_desc(otg.req_length);
922 case EP0_STATE_GD_OTHER_SPEED_HIGH_1:
923 if (otg.req_length == 9) {
924 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
925 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
926 s5p_usb_write_ep0_fifo(((u8 *) &config_high) + 8, 1);
927 otg.ep0_state = EP0_STATE_INIT;
929 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 8);
930 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
931 s5p_usb_write_ep0_fifo(((u8 *) &config_high) + 8, 8);
932 otg.ep0_state = EP0_STATE_GD_OTHER_SPEED_HIGH_2;
936 case EP0_STATE_GD_OTHER_SPEED_HIGH_2:
937 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 8);
938 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
939 s5p_usb_write_ep0_fifo(((u8 *) &config_high) + 16, 8);
940 otg.ep0_state = EP0_STATE_GD_OTHER_SPEED_HIGH_3;
943 case EP0_STATE_GD_OTHER_SPEED_HIGH_3:
944 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 8);
945 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
946 s5p_usb_write_ep0_fifo(((u8 *) &config_high) + 24, 8);
947 otg.ep0_state = EP0_STATE_INIT;
950 case EP0_STATE_GD_CFG_ONLY_0:
951 if (otg.req_length < CONFIG_DESC_SIZE) {
952 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
954 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
955 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)),
958 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
960 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
961 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)),
964 otg.ep0_state = EP0_STATE_INIT;
967 case EP0_STATE_GD_CFG_ONLY_1:
968 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
969 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)) +
971 CONFIG_DESC_SIZE - FS_CTRL_PKT_SIZE);
972 otg.ep0_state = EP0_STATE_INIT;
975 case EP0_STATE_GD_IF_ONLY_0:
976 if (otg.req_length < INTERFACE_DESC_SIZE) {
977 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
979 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
980 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.intf)),
983 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
984 INTERFACE_DESC_SIZE);
985 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
986 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.intf)),
987 INTERFACE_DESC_SIZE);
989 otg.ep0_state = EP0_STATE_INIT;
992 case EP0_STATE_GD_IF_ONLY_1:
993 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
994 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.intf)) +
996 INTERFACE_DESC_SIZE - FS_CTRL_PKT_SIZE);
997 otg.ep0_state = EP0_STATE_INIT;
1000 case EP0_STATE_GD_EP0_ONLY_0:
1001 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
1002 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, ENDPOINT_DESC_SIZE);
1003 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.ep1)),
1004 ENDPOINT_DESC_SIZE);
1005 otg.ep0_state = EP0_STATE_INIT;
1008 case EP0_STATE_GD_EP1_ONLY_0:
1009 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, ENDPOINT_DESC_SIZE);
1010 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
1011 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.ep2)),
1012 ENDPOINT_DESC_SIZE);
1013 otg.ep0_state = EP0_STATE_INIT;
1016 case EP0_STATE_GD_STR_I0:
1017 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, STRING_DESC0_SIZE);
1018 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
1019 s5p_usb_write_ep0_fifo((u8 *)string_desc0, STRING_DESC0_SIZE);
1020 otg.ep0_state = EP0_STATE_INIT;
1023 case EP0_STATE_GD_STR_I1:
1024 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, sizeof(string_desc1));
1025 if ((otg.ep0_substate * otg.ctrl_max_pktsize +
1026 otg.ctrl_max_pktsize) < sizeof(string_desc1)) {
1027 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
1029 s5p_usb_write_ep0_fifo((u8 *)string_desc1 +
1030 (otg.ep0_substate * otg.ctrl_max_pktsize),
1031 otg.ctrl_max_pktsize);
1032 otg.ep0_state = EP0_STATE_GD_STR_I1;
1035 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
1037 s5p_usb_write_ep0_fifo((u8 *)string_desc1 +
1038 (otg.ep0_substate * otg.ctrl_max_pktsize),
1039 sizeof(string_desc1) - (otg.ep0_substate *
1040 otg.ctrl_max_pktsize));
1041 otg.ep0_state = EP0_STATE_INIT;
1042 otg.ep0_substate = 0;
1046 case EP0_STATE_GD_STR_I2:
1047 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, sizeof(string_desc2));
1048 if ((otg.ep0_substate * otg.ctrl_max_pktsize +
1049 otg.ctrl_max_pktsize) < sizeof(string_desc2)) {
1050 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
1052 s5p_usb_write_ep0_fifo((u8 *) string_desc2 +
1053 (otg.ep0_substate * otg.ctrl_max_pktsize),
1054 otg.ctrl_max_pktsize);
1055 otg.ep0_state = EP0_STATE_GD_STR_I2;
1058 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
1059 s5p_usb_write_ep0_fifo((u8 *) string_desc2 +
1060 (otg.ep0_substate * otg.ctrl_max_pktsize),
1061 sizeof(string_desc2) - (otg.ep0_substate *
1062 otg.ctrl_max_pktsize));
1063 otg.ep0_state = EP0_STATE_INIT;
1064 otg.ep0_substate = 0;
1068 case EP0_STATE_INTERFACE_GET:
1069 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
1070 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
1071 s5p_usb_write_ep0_fifo((u8 *) &get_intf, 1);
1072 otg.ep0_state = EP0_STATE_INIT;
1075 case EP0_STATE_GET_STATUS0:
1076 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
1077 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
1078 s5p_usb_write_ep0_fifo((u8 *) &get_status, 1);
1079 otg.ep0_state = EP0_STATE_INIT;
1082 case EP0_STATE_GET_STATUS1:
1083 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
1084 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
1085 s5p_usb_write_ep0_fifo((u8 *) &get_status + 1, 1);
1086 otg.ep0_state = EP0_STATE_INIT;
1089 case EP0_STATE_GET_STATUS2:
1090 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
1091 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
1092 s5p_usb_write_ep0_fifo((u8 *) &get_status + 2, 1);
1093 otg.ep0_state = EP0_STATE_INIT;
1096 case EP0_STATE_GET_STATUS3:
1097 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
1098 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
1099 s5p_usb_write_ep0_fifo((u8 *) &get_status + 3, 1);
1100 otg.ep0_state = EP0_STATE_INIT;
1103 case EP0_STATE_GET_STATUS4:
1104 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
1105 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
1106 s5p_usb_write_ep0_fifo((u8 *) &get_status + 4, 1);
1107 otg.ep0_state = EP0_STATE_INIT;
1115 void s5p_usb_tx(char *tx_data, int tx_size)
1117 otg.up_ptr = (u8 *) tx_data;
1118 otg.up_addr = (u32) tx_data;
1119 otg.up_size = tx_size;
1121 if (otg.op_mode == USB_CPU) {
1122 if (otg.up_size > otg.bulkin_max_pktsize) {
1123 s5p_usb_set_inep_xfersize(EP_TYPE_BULK, 1,
1124 otg.bulkin_max_pktsize);
1126 s5p_usb_set_inep_xfersize(EP_TYPE_BULK, 1, otg.up_size);
1129 /*ep1 enable, clear nak, bulk, usb active, max pkt */
1130 s5pc1xx_otg_write_reg(1u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
1131 otg.bulkin_max_pktsize << 0, OTG_DIEPCTL_IN);
1133 s5p_usb_write_in_fifo(otg.up_ptr, otg.up_size);
1134 } else if ((otg.op_mode == USB_DMA) && (otg.up_size > 0)) {
1135 u32 pktcnt, remainder;
1137 s5pc1xx_otg_write_reg(MODE_DMA | BURST_INCR4 | GBL_INT_UNMASK,
1139 s5pc1xx_otg_write_reg(INT_RESUME | INT_OUT_EP | INT_IN_EP |
1140 INT_ENUMDONE | INT_RESET | INT_SUSPEND,
1143 s5pc1xx_otg_write_reg((u32) otg.up_ptr, OTG_DIEPDMA_IN);
1145 pktcnt = (u32) (otg.up_size / otg.bulkin_max_pktsize);
1146 remainder = (u32) (otg.up_size % otg.bulkin_max_pktsize);
1150 if (pktcnt > 1023) {
1151 s5p_usb_set_inep_xfersize(EP_TYPE_BULK, 1023,
1152 otg.bulkin_max_pktsize * 1023);
1154 s5p_usb_set_inep_xfersize(EP_TYPE_BULK, pktcnt,
1158 /*ep1 enable, clear nak, bulk, usb active, next ep1, max pkt */
1159 s5pc1xx_otg_write_reg(1u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
1160 BULK_IN_EP << 11 | otg.bulkin_max_pktsize << 0,
1165 static void s5p_usb_rx(u32 fifo_cnt_byte)
1167 if (otg.op_mode == USB_CPU) {
1168 s5p_usb_read_out_fifo((u8 *)otg.dn_ptr, fifo_cnt_byte);
1169 otg.dn_ptr += fifo_cnt_byte;
1171 s5p_usb_set_outep_xfersize(EP_TYPE_BULK, 1,
1172 otg.bulkout_max_pktsize);
1174 /*ep3 enable, clear nak, bulk, usb active, next ep3, max pkt */
1175 s5pc1xx_otg_write_reg(1u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
1176 otg.bulkout_max_pktsize << 0, OTG_DOEPCTL_OUT);
1178 if (((u32)otg.dn_ptr - otg.dn_addr) >= (otg.dn_filesize))
1179 s5p_receive_done = 1;
1180 } else if (otg.dn_filesize > otg.bulkout_max_pktsize) {
1181 u32 pkt_cnt, remain_cnt;
1183 s5pc1xx_otg_write_reg(INT_RESUME | INT_OUT_EP | INT_IN_EP |
1184 INT_ENUMDONE | INT_RESET | INT_SUSPEND,
1186 s5pc1xx_otg_write_reg(MODE_DMA | BURST_INCR4 | GBL_INT_UNMASK,
1188 s5pc1xx_otg_write_reg((u32) otg.dn_ptr, OTG_DOEPDMA_OUT);
1189 pkt_cnt = (u32)(otg.dn_filesize - otg.bulkout_max_pktsize) /
1190 otg.bulkout_max_pktsize;
1191 remain_cnt = (u32)((otg.dn_filesize - otg.bulkout_max_pktsize) %
1192 otg.bulkout_max_pktsize);
1194 if (remain_cnt != 0)
1197 if (pkt_cnt > 1023) {
1198 s5p_usb_set_outep_xfersize(EP_TYPE_BULK, 1023,
1199 otg.bulkout_max_pktsize * 1023);
1201 s5p_usb_set_outep_xfersize(EP_TYPE_BULK, pkt_cnt,
1202 otg.dn_filesize - otg.bulkout_max_pktsize);
1205 /*ep3 enable, clear nak, bulk, usb active, next ep3, max pkt */
1206 s5pc1xx_otg_write_reg(1u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
1207 otg.bulkout_max_pktsize << 0, OTG_DOEPCTL_OUT);
1211 static void s5p_usb_int_bulkout(u32 fifo_cnt_byte)
1213 s5p_usb_rx(fifo_cnt_byte);
1216 static void s5p_usb_dma_in_done(void)
1220 otg.up_ptr = (u8 *)s5pc1xx_otg_read_reg(OTG_DIEPDMA_IN);
1221 remain_cnt = otg.up_size - ((u32) otg.up_ptr - otg.up_addr);
1223 if (remain_cnt > 0) {
1224 u32 pktcnt, remainder;
1225 pktcnt = (u32)(remain_cnt / otg.bulkin_max_pktsize);
1226 remainder = (u32)(remain_cnt % otg.bulkin_max_pktsize);
1231 if (pktcnt > 1023) {
1232 s5p_usb_set_inep_xfersize(EP_TYPE_BULK, 1023,
1233 otg.bulkin_max_pktsize * 1023);
1235 s5p_usb_set_inep_xfersize(EP_TYPE_BULK, pktcnt,
1239 /*ep1 enable, clear nak, bulk, usb active, next ep1, max pkt */
1240 s5pc1xx_otg_write_reg(1u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
1241 BULK_IN_EP << 11 | otg.bulkin_max_pktsize << 0,
1244 s5p_receive_done = 1;
1248 static void s5p_usb_dma_out_done(void)
1252 otg.dn_ptr = (u8 *)s5pc1xx_otg_read_reg(OTG_DOEPDMA_OUT);
1254 remain_cnt = otg.dn_filesize - ((u32) otg.dn_ptr - otg.dn_addr + 8);
1256 if (remain_cnt > 0) {
1257 u32 pktcnt, remainder;
1258 pktcnt = (u32)(remain_cnt / otg.bulkout_max_pktsize);
1259 remainder = (u32)(remain_cnt % otg.bulkout_max_pktsize);
1264 if (pktcnt > 1023) {
1265 s5p_usb_set_outep_xfersize(EP_TYPE_BULK, 1023,
1266 otg.bulkout_max_pktsize * 1023);
1268 s5p_usb_set_outep_xfersize(EP_TYPE_BULK, pktcnt,
1272 /*ep3 enable, clear nak, bulk, usb active, next ep3, max pkt 64 */
1273 s5pc1xx_otg_write_reg(1u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
1274 otg.bulkout_max_pktsize << 0, OTG_DOEPCTL_OUT);
1276 udelay(500); /*for FPGA ??? */
1280 static void s5p_usb_set_all_outep_nak(int set)
1285 for (i = 0; i < 16; i++) {
1286 tmp = s5pc1xx_otg_read_reg(OTG_DOEPCTL0 + 0x20 * i);
1290 tmp |= (DEPCTL_EPENA | DEPCTL_CNAK);
1291 s5pc1xx_otg_write_reg(tmp, OTG_DOEPCTL0 + 0x20 * i);
1295 static void s5p_usb_set_max_pktsize(USB_SPEED speed)
1297 otg.speed = USB_HIGH;
1298 otg.ctrl_max_pktsize = HS_CTRL_PKT_SIZE;
1299 otg.bulkin_max_pktsize = HS_BULK_PKT_SIZE;
1300 otg.bulkout_max_pktsize = HS_BULK_PKT_SIZE;
1303 static void s5p_usb_set_endpoint(void)
1305 /* Unmask OTG_DAINT source */
1306 s5pc1xx_otg_write_reg(0xff, OTG_DIEPINT0);
1307 s5pc1xx_otg_write_reg(0xff, OTG_DOEPINT0);
1308 s5pc1xx_otg_write_reg(0xff, OTG_DIEPINT_IN);
1309 s5pc1xx_otg_write_reg(0xff, OTG_DOEPINT_OUT);
1313 s5pc1xx_otg_write_reg(((1 << 26) | (CONTROL_EP << 11) | (0 << 0)),
1315 /*ep0 enable, clear nak */
1316 s5pc1xx_otg_write_reg((1u << 31) | (1 << 26) | (0 << 0),
1320 static void s5p_usb_set_descriptors(void)
1322 #if defined (CONFIG_SAMSUNG_USB)
1323 otg.desc.dev.bLength = DEVICE_DESC_SIZE;
1324 otg.desc.dev.bDescriptorType = DEVICE_DESCRIPTOR;
1325 otg.desc.dev.bDeviceClass = 0xFF;
1326 otg.desc.dev.bDeviceSubClass = 0x0;
1327 otg.desc.dev.bDeviceProtocol = 0x0;
1328 otg.desc.dev.bMaxPacketSize0 = otg.ctrl_max_pktsize;
1329 otg.desc.dev.idVendorL = 0xE8;
1330 otg.desc.dev.idVendorH = 0x04;
1331 otg.desc.dev.idProductL = 0x04;
1332 otg.desc.dev.idProductH = 0x12;
1333 otg.desc.dev.iManufacturer = 0x0;
1334 otg.desc.dev.iProduct = 0x2;
1335 otg.desc.dev.iSerialNumber = 0x0;
1336 otg.desc.dev.bNumConfigurations = 0x1;
1337 otg.desc.dev.bcdUSBL = 0x00;
1338 otg.desc.dev.bcdUSBH = 0x02;
1340 otg.desc.config.bLength = CONFIG_DESC_SIZE;
1341 otg.desc.config.bDescriptorType = CONFIGURATION_DESCRIPTOR;
1342 otg.desc.config.wTotalLengthL = CONFIG_DESC_TOTAL_SIZE;
1343 otg.desc.config.wTotalLengthH = 0;
1344 otg.desc.config.bNumInterfaces = 1;
1345 otg.desc.config.bConfigurationValue = 1;
1346 otg.desc.config.iConfiguration = 0;
1347 otg.desc.config.bmAttributes = CONF_ATTR_DEFAULT | CONF_ATTR_SELFPOWERED;
1348 otg.desc.config.maxPower = 50;
1350 otg.desc.dev.bLength = DEVICE_DESC_SIZE;
1351 otg.desc.dev.bDescriptorType = DEVICE_DESCRIPTOR;
1352 otg.desc.dev.bDeviceClass = 0xFF;
1353 otg.desc.dev.bDeviceSubClass = 0x0;
1354 otg.desc.dev.bDeviceProtocol = 0x0;
1355 otg.desc.dev.bMaxPacketSize0 = otg.ctrl_max_pktsize;
1356 otg.desc.dev.idVendorL = 0xE8;
1357 otg.desc.dev.idVendorH = 0x04;
1358 otg.desc.dev.idProductL = 0x34;
1359 otg.desc.dev.idProductH = 0x12;
1360 otg.desc.dev.bcdDeviceL = 0x00;
1361 otg.desc.dev.bcdDeviceH = 0x01;
1362 otg.desc.dev.iManufacturer = 0x1;
1363 otg.desc.dev.iProduct = 0x2;
1364 otg.desc.dev.iSerialNumber = 0x0;
1365 otg.desc.dev.bNumConfigurations = 0x1;
1366 otg.desc.dev.bcdUSBL = 0x00;
1367 otg.desc.dev.bcdUSBH = 0x02;
1369 otg.desc.config.bLength = CONFIG_DESC_SIZE;
1370 otg.desc.config.bDescriptorType = CONFIGURATION_DESCRIPTOR;
1371 otg.desc.config.wTotalLengthL = CONFIG_DESC_TOTAL_SIZE;
1372 otg.desc.config.wTotalLengthH = 0;
1373 otg.desc.config.bNumInterfaces = 1;
1374 otg.desc.config.bConfigurationValue = 1;
1375 otg.desc.config.iConfiguration = 0;
1376 otg.desc.config.bmAttributes = CONF_ATTR_DEFAULT | CONF_ATTR_SELFPOWERED;
1377 otg.desc.config.maxPower = 25;
1379 otg.desc.intf.bLength = INTERFACE_DESC_SIZE;
1380 otg.desc.intf.bDescriptorType = INTERFACE_DESCRIPTOR;
1381 otg.desc.intf.bInterfaceNumber = 0x0;
1382 otg.desc.intf.bAlternateSetting = 0x0;
1383 otg.desc.intf.bNumEndpoints = 2;
1384 otg.desc.intf.bInterfaceClass = 0xff;
1385 otg.desc.intf.bInterfaceSubClass = 0xff;
1386 otg.desc.intf.bInterfaceProtocol = 0xff;
1387 otg.desc.intf.iInterface = 0x0;
1389 otg.desc.ep1.bLength = ENDPOINT_DESC_SIZE;
1390 otg.desc.ep1.bDescriptorType = ENDPOINT_DESCRIPTOR;
1391 otg.desc.ep1.bEndpointAddress = BULK_IN_EP | EP_ADDR_IN;
1392 otg.desc.ep1.bmAttributes = EP_ATTR_BULK;
1393 otg.desc.ep1.wMaxPacketSizeL = (u8)otg.bulkin_max_pktsize;
1394 otg.desc.ep1.wMaxPacketSizeH = (u8)(otg.bulkin_max_pktsize >> 8);
1395 otg.desc.ep1.bInterval = 0x0;
1397 otg.desc.ep2.bLength = ENDPOINT_DESC_SIZE;
1398 otg.desc.ep2.bDescriptorType = ENDPOINT_DESCRIPTOR;
1399 otg.desc.ep2.bEndpointAddress = BULK_OUT_EP | EP_ADDR_OUT;
1400 otg.desc.ep2.bmAttributes = EP_ATTR_BULK;
1401 otg.desc.ep2.wMaxPacketSizeL = (u8)otg.bulkout_max_pktsize;
1402 otg.desc.ep2.wMaxPacketSizeH = (u8)(otg.bulkout_max_pktsize >> 8);
1403 otg.desc.ep2.bInterval = 0x0;
1406 static void s5p_usb_set_opmode(USB_OPMODE mode)
1410 s5pc1xx_otg_write_reg(INT_RESUME | INT_OUT_EP | INT_IN_EP | INT_ENUMDONE |
1411 INT_RESET | INT_SUSPEND | INT_RX_FIFO_NOT_EMPTY,
1414 s5pc1xx_otg_write_reg(MODE_SLAVE | BURST_SINGLE | GBL_INT_UNMASK,
1417 s5p_usb_set_outep_xfersize(EP_TYPE_BULK, 1, otg.bulkout_max_pktsize);
1418 s5p_usb_set_inep_xfersize(EP_TYPE_BULK, 1, 0);
1420 /*bulk out ep enable, clear nak, bulk, usb active, next ep3, max pkt */
1421 s5pc1xx_otg_write_reg(1u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
1422 otg.bulkout_max_pktsize << 0, OTG_DOEPCTL_OUT);
1424 /*bulk in ep enable, clear nak, bulk, usb active, next ep1, max pkt */
1425 s5pc1xx_otg_write_reg(0u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
1426 otg.bulkin_max_pktsize << 0, OTG_DIEPCTL_IN);
1429 static void s5p_usb_reset(void)
1431 s5p_usb_set_all_outep_nak(1);
1433 otg.ep0_state = EP0_STATE_INIT;
1434 s5pc1xx_otg_write_reg(((1 << BULK_OUT_EP) | (1 << CONTROL_EP)) << 16 |
1435 ((1 << BULK_IN_EP) | (1 << CONTROL_EP)), OTG_DAINTMSK);
1436 s5pc1xx_otg_write_reg(CTRL_OUT_EP_SETUP_PHASE_DONE | AHB_ERROR |
1437 TRANSFER_DONE, OTG_DOEPMSK);
1438 s5pc1xx_otg_write_reg(INTKN_TXFEMP | NON_ISO_IN_EP_TIMEOUT | AHB_ERROR |
1439 TRANSFER_DONE, OTG_DIEPMSK);
1442 s5pc1xx_otg_write_reg(RX_FIFO_SIZE, OTG_GRXFSIZ);
1444 /* Non Periodic Tx FIFO Size */
1445 s5pc1xx_otg_write_reg(NPTX_FIFO_SIZE << 16 | NPTX_FIFO_START_ADDR << 0,
1448 s5p_usb_set_all_outep_nak(0);
1450 /*clear device address */
1451 s5pc1xx_otg_write_reg(s5pc1xx_otg_read_reg(OTG_DCFG) & ~(0x7f << 4),
1455 static int s5p_usb_set_init(void)
1459 status = s5pc1xx_otg_read_reg(OTG_DSTS);
1461 /* Set if Device is High speed or Full speed */
1462 if (((status & 0x6) >> 1) == USB_HIGH) {
1463 s5p_usb_set_max_pktsize(USB_HIGH);
1464 } else if (((status & 0x6) >> 1) == USB_FULL) {
1465 printf("Error: Don't support Full_Speed\n");
1468 printf("Error: Neither High_Speed nor Full_Speed\n");
1472 s5p_usb_set_endpoint();
1473 s5p_usb_set_descriptors();
1474 s5p_usb_set_opmode(op_mode);
1479 static void s5p_usb_pkt_receive(void)
1484 rx_status = s5pc1xx_otg_read_reg(OTG_GRXSTSP);
1486 if ((rx_status & (0xf << 17)) == SETUP_PKT_RECEIVED) {
1487 s5p_usb_ep0_int_hndlr();
1488 } else if ((rx_status & (0xf << 17)) == OUT_PKT_RECEIVED) {
1489 fifo_cnt_byte = (rx_status & 0x7ff0) >> 4;
1491 if ((rx_status & BULK_OUT_EP) && (fifo_cnt_byte)) {
1492 s5p_usb_int_bulkout(fifo_cnt_byte);
1493 if (otg.op_mode == USB_CPU) {
1494 s5pc1xx_otg_write_reg(INT_RESUME | INT_OUT_EP |
1495 INT_IN_EP | INT_ENUMDONE | INT_RESET |
1496 INT_SUSPEND | INT_RX_FIFO_NOT_EMPTY,
1505 static void s5p_usb_transfer(void)
1511 ep_int = s5pc1xx_otg_read_reg(OTG_DAINT);
1513 if (ep_int & (1 << CONTROL_EP)) {
1514 ep_int_status = s5pc1xx_otg_read_reg(OTG_DIEPINT0);
1516 if (ep_int_status & INTKN_TXFEMP) {
1519 uNTxFifoSpace = s5pc1xx_otg_read_reg(OTG_GNPTXSTS)
1521 } while (uNTxFifoSpace < otg.ctrl_max_pktsize);
1523 s5p_usb_transfer_ep0();
1526 s5pc1xx_otg_write_reg(ep_int_status, OTG_DIEPINT0);
1529 if (ep_int & ((1 << CONTROL_EP) << 16)) {
1530 ep_int_status = s5pc1xx_otg_read_reg(OTG_DOEPINT0);
1532 s5p_usb_set_outep_xfersize(EP_TYPE_CONTROL, 1, 8);
1533 s5pc1xx_otg_write_reg(1u << 31 | 1 << 26, OTG_DOEPCTL0);
1535 s5pc1xx_otg_write_reg(ep_int_status, OTG_DOEPINT0);
1538 if (ep_int & (1 << BULK_IN_EP)) {
1539 ep_int_status = s5pc1xx_otg_read_reg(OTG_DIEPINT_IN);
1541 s5pc1xx_otg_write_reg(ep_int_status, OTG_DIEPINT_IN);
1542 check_dma = s5pc1xx_otg_read_reg(OTG_GAHBCFG);
1544 if ((check_dma & MODE_DMA) && (ep_int_status & TRANSFER_DONE))
1545 s5p_usb_dma_in_done();
1548 if (ep_int & ((1 << BULK_OUT_EP) << 16)) {
1549 ep_int_status = s5pc1xx_otg_read_reg(OTG_DOEPINT_OUT);
1551 s5pc1xx_otg_write_reg(ep_int_status, OTG_DOEPINT_OUT);
1552 check_dma = s5pc1xx_otg_read_reg(OTG_GAHBCFG);
1554 if ((check_dma & MODE_DMA) && (ep_int_status & TRANSFER_DONE))
1555 s5p_usb_dma_out_done();
1559 void s5p_udc_int_hndlr(void)
1564 int_status = s5pc1xx_otg_read_reg(OTG_GINTSTS);
1565 s5pc1xx_otg_write_reg(int_status, OTG_GINTSTS);
1567 if (int_status & INT_RESET) {
1568 s5pc1xx_otg_write_reg(INT_RESET, OTG_GINTSTS);
1572 if (int_status & INT_ENUMDONE) {
1573 s5pc1xx_otg_write_reg(INT_ENUMDONE, OTG_GINTSTS);
1575 tmp = s5p_usb_set_init();
1580 if (int_status & INT_RESUME)
1581 s5pc1xx_otg_write_reg(INT_RESUME, OTG_GINTSTS);
1583 if (int_status & INT_SUSPEND)
1584 s5pc1xx_otg_write_reg(INT_SUSPEND, OTG_GINTSTS);
1586 if (int_status & INT_RX_FIFO_NOT_EMPTY) {
1587 s5pc1xx_otg_write_reg(INT_RESUME | INT_OUT_EP | INT_IN_EP |
1588 INT_ENUMDONE | INT_RESET | INT_SUSPEND,
1591 s5p_usb_pkt_receive();
1593 s5pc1xx_otg_write_reg(INT_RESUME | INT_OUT_EP | INT_IN_EP |
1594 INT_ENUMDONE | INT_RESET | INT_SUSPEND |
1595 INT_RX_FIFO_NOT_EMPTY, OTG_GINTMSK);
1598 if ((int_status & INT_IN_EP) || (int_status & INT_OUT_EP))