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"
28 #define SUSPEND_RESUME_ON 0
35 int s5p_usb_connected;
37 USB_OPMODE op_mode = USB_CPU;
38 USB_SPEED speed = USB_HIGH;
40 USB_OPMODE op_mode = USB_DMA;
41 USB_SPEED speed = USB_FULL;
45 get_status_t get_status;
49 EP0, EP1, EP2, EP3, EP4
52 /*------------------------------------------------*/
56 EP0_STATE_GD_DEV_0 = 11,
57 EP0_STATE_GD_DEV_1 = 12,
58 EP0_STATE_GD_DEV_2 = 13,
59 EP0_STATE_GD_CFG_0 = 21,
60 EP0_STATE_GD_CFG_1 = 22,
61 EP0_STATE_GD_CFG_2 = 23,
62 EP0_STATE_GD_CFG_3 = 24,
63 EP0_STATE_GD_CFG_4 = 25,
64 EP0_STATE_GD_STR_I0 = 30,
65 EP0_STATE_GD_STR_I1 = 31,
66 EP0_STATE_GD_STR_I2 = 32,
67 EP0_STATE_GD_DEV_QUALIFIER = 33,
68 EP0_STATE_INTERFACE_GET = 34,
69 EP0_STATE_GET_STATUS0 = 35,
70 EP0_STATE_GET_STATUS1 = 36,
71 EP0_STATE_GET_STATUS2 = 37,
72 EP0_STATE_GET_STATUS3 = 38,
73 EP0_STATE_GET_STATUS4 = 39,
74 EP0_STATE_GD_OTHER_SPEED = 40,
75 EP0_STATE_GD_CFG_ONLY_0 = 41,
76 EP0_STATE_GD_CFG_ONLY_1 = 42,
77 EP0_STATE_GD_IF_ONLY_0 = 44,
78 EP0_STATE_GD_IF_ONLY_1 = 45,
79 EP0_STATE_GD_EP0_ONLY_0 = 46,
80 EP0_STATE_GD_EP1_ONLY_0 = 47,
81 EP0_STATE_GD_EP2_ONLY_0 = 48,
82 EP0_STATE_GD_EP3_ONLY_0 = 49,
83 EP0_STATE_GD_OTHER_SPEED_HIGH_1 = 51,
84 EP0_STATE_GD_OTHER_SPEED_HIGH_2 = 52,
85 EP0_STATE_GD_OTHER_SPEED_HIGH_3 = 53
88 /*definitions related to CSR setting */
91 #define B_SESSION_VALID (0x1 << 19)
92 #define A_SESSION_VALID (0x1 << 18)
95 #define PTXFE_HALF (0<<8)
96 #define PTXFE_ZERO (1<<8)
97 #define NPTXFE_HALF (0<<7)
98 #define NPTXFE_ZERO (1<<7)
99 #define MODE_SLAVE (0<<5)
100 #define MODE_DMA (1<<5)
101 #define BURST_SINGLE (0<<1)
102 #define BURST_INCR (1<<1)
103 #define BURST_INCR4 (3<<1)
104 #define BURST_INCR8 (5<<1)
105 #define BURST_INCR16 (7<<1)
106 #define GBL_INT_UNMASK (1<<0)
107 #define GBL_INT_MASK (0<<0)
110 #define AHB_MASTER_IDLE (1u<<31)
111 #define CORE_SOFT_RESET (0x1<<0)
113 /* OTG_GINTSTS/OTG_GINTMSK core interrupt register */
114 #define INT_RESUME (1u<<31)
115 #define INT_DISCONN (0x1<<29)
116 #define INT_CONN_ID_STS_CNG (0x1<<28)
117 #define INT_OUT_EP (0x1<<19)
118 #define INT_IN_EP (0x1<<18)
119 #define INT_ENUMDONE (0x1<<13)
120 #define INT_RESET (0x1<<12)
121 #define INT_SUSPEND (0x1<<11)
122 #define INT_TX_FIFO_EMPTY (0x1<<5)
123 #define INT_RX_FIFO_NOT_EMPTY (0x1<<4)
124 #define INT_SOF (0x1<<3)
125 #define INT_DEV_MODE (0x0<<0)
126 #define INT_HOST_MODE (0x1<<1)
127 #define INT_OTG (0x1<<2)
129 /* OTG_GRXSTSP STATUS*/
130 #define GLOBAL_OUT_NAK (0x1<<17)
131 #define OUT_PKT_RECEIVED (0x2<<17)
132 #define OUT_TRNASFER_COMPLETED (0x3<<17)
133 #define SETUP_TRANSACTION_COMPLETED (0x4<<17)
134 #define SETUP_PKT_RECEIVED (0x6<<17)
136 /* OTG_DCTL device control register */
137 #define NORMAL_OPERATION (0x1<<0)
138 #define SOFT_DISCONNECT (0x1<<1)
139 #define TEST_J_MODE (TEST_J<<4)
140 #define TEST_K_MODE (TEST_K<<4)
141 #define TEST_SE0_NAK_MODE (TEST_SE0_NAK<<4)
142 #define TEST_PACKET_MODE (TEST_PACKET<<4)
143 #define TEST_FORCE_ENABLE_MODE (TEST_FORCE_ENABLE<<4)
144 #define TEST_CONTROL_FIELD (0x7<<4)
146 /* OTG_DAINT device all endpoint interrupt register */
147 #define INT_IN_EP0 (0x1<<0)
148 #define INT_IN_EP1 (0x1<<1)
149 #define INT_IN_EP3 (0x1<<3)
150 #define INT_OUT_EP0 (0x1<<16)
151 #define INT_OUT_EP2 (0x1<<18)
152 #define INT_OUT_EP4 (0x1<<20)
154 /* OTG_DIEPCTL0/OTG_DOEPCTL0 */
155 #define DEPCTL_EPENA (0x1<<31)
156 #define DEPCTL_EPDIS (0x1<<30)
157 #define DEPCTL_SNAK (0x1<<27)
158 #define DEPCTL_CNAK (0x1<<26)
159 #define DEPCTL_CTRL_TYPE (EP_TYPE_CONTROL<<18)
160 #define DEPCTL_ISO_TYPE (EP_TYPE_ISOCHRONOUS<<18)
161 #define DEPCTL_BULK_TYPE (EP_TYPE_BULK<<18)
162 #define DEPCTL_INTR_TYPE (EP_TYPE_INTERRUPT<<18)
163 #define DEPCTL_USBACTEP (0x1<<15)
165 /*ep0 enable, clear nak, next ep0, max 64byte */
166 #define EPEN_CNAK_EP0_64 (DEPCTL_EPENA|DEPCTL_CNAK|(CONTROL_EP<<11)|(0<<0))
168 /*ep0 enable, clear nak, next ep0, 8byte */
169 #define EPEN_CNAK_EP0_8 (DEPCTL_EPENA|DEPCTL_CNAK|(CONTROL_EP<<11)|(3<<0))
171 /* DIEPCTLn/DOEPCTLn */
172 #define BACK2BACK_SETUP_RECEIVED (0x1<<6)
173 #define INTKN_TXFEMP (0x1<<4)
174 #define NON_ISO_IN_EP_TIMEOUT (0x1<<3)
175 #define CTRL_OUT_EP_SETUP_PHASE_DONE (0x1<<3)
176 #define AHB_ERROR (0x1<<2)
177 #define TRANSFER_DONE (0x1<<0)
179 /* codes representing languages */
180 const u8 string_desc0[] = {
181 4, STRING_DESCRIPTOR, LANGID_US_L, LANGID_US_H,
184 #ifdef CONFIG_SAMSUNG_USB
185 const u8 string_desc1[] = /* Manufacturer */
187 (0x14 + 2), STRING_DESCRIPTOR,
188 'S', 0x0, '/', 0x0, 'W', 0x0, ' ', 0x0, 'C', 0x0,
189 'e', 0x0, 'n', 0x0, 't', 0x0, 'e', 0x0, 'r', 0x0,
192 const u8 string_desc1[] = /* Manufacturer */
194 (0x14 + 2), STRING_DESCRIPTOR,
195 'S', 0x0, 'y', 0x0, 's', 0x0, 't', 0x0, 'e', 0x0,
196 'm', 0x0, ' ', 0x0, 'M', 0x0, 'C', 0x0, 'U', 0x0,
200 #ifdef CONFIG_SAMSUNG_USB
201 const u8 string_desc2[] = /* Product */
203 (0x22 + 2), STRING_DESCRIPTOR,
204 'S', 0x0, 'A', 0x0, 'M', 0x0, 'S', 0x0, 'U', 0x0,
205 'N', 0x0, 'G', 0x0, ' ', 0x0, 'X', 0x0, 'O', 0x0,
206 ' ', 0x0, 'D', 0x0, 'R', 0x0, 'I', 0x0, 'V', 0x0,
210 const u8 string_desc2[] = /* Product */
212 (0x2a + 2), STRING_DESCRIPTOR,
213 'S', 0x0, 'E', 0x0, 'C', 0x0, ' ', 0x0, 'S', 0x0,
214 '3', 0x0, 'C', 0x0, '6', 0x0, '4', 0x0, '0', 0x0,
215 '0', 0x0, 'X', 0x0, ' ', 0x0, 'T', 0x0, 'e', 0x0,
216 's', 0x0, 't', 0x0, ' ', 0x0, 'B', 0x0, '/', 0x0,
221 /* setting the device qualifier descriptor and a string descriptor */
222 const u8 qualifier_desc[] = {
223 0x0a, /* 0 desc size */
224 0x06, /* 1 desc type (DEVICE_QUALIFIER) */
225 0x00, /* 2 USB release */
226 0x02, /* 3 => 2.00 */
228 0x00, /* 5 subclass */
229 0x00, /* 6 protocol */
230 64, /* 7 max pack size */
231 0x01, /* 8 number of other-speed configuration */
232 0x00, /* 9 reserved */
235 const u8 config_full[] = {
236 0x09, /* 0 desc size */
237 0x07, /* 1 desc type (other speed) */
238 0x20, /* 2 Total length of data returned */
240 0x01, /* 4 Number of interfaces */
241 0x01, /* 5 value to use to select configuration */
242 0x00, /* 6 index of string desc */
243 /* 7 same as configuration desc */
244 CONF_ATTR_DEFAULT | CONF_ATTR_SELFPOWERED,
245 0x19, /* 8 same as configuration desc */
249 const u8 config_full_total[] = {
250 0x09, 0x07, 0x20, 0x00, 0x01, 0x01, 0x00, 0xC0, 0x19,
251 0x09, 0x04, 0x00, 0x00, 0x02, 0xff, 0x00, 0x00, 0x00,
252 0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x00,
253 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00
256 const u8 config_high[] = {
257 0x09, /* 0 desc size */
258 0x07, /* 1 desc type (other speed) */
259 0x20, /* 2 Total length of data returned */
261 0x01, /* 4 Number of interfaces */
262 0x01, /* 5 value to use to select configuration */
263 0x00, /* 6 index of string desc */
264 /* 7 same as configuration desc */
265 CONF_ATTR_DEFAULT | CONF_ATTR_SELFPOWERED,
266 0x19, /* 8 same as configuration desc */
270 const u8 config_high_total[] = {
271 0x09, 0x07, 0x20, 0x00, 0x01, 0x01, 0x00, 0xC0, 0x19,
272 0x09, 0x04, 0x00, 0x00, 0x02, 0xff, 0x00, 0x00, 0x00,
273 0x07, 0x05, 0x81, 0x02, 0x00, 0x02, 0x00,
274 0x07, 0x05, 0x02, 0x02, 0x00, 0x02, 0x00
277 /* Descriptor size */
278 enum DESCRIPTOR_SIZE {
279 DEVICE_DESC_SIZE = sizeof(device_desc_t),
280 STRING_DESC0_SIZE = sizeof(string_desc0),
281 STRING_DESC1_SIZE = sizeof(string_desc1),
282 STRING_DESC2_SIZE = sizeof(string_desc2),
283 CONFIG_DESC_SIZE = sizeof(config_desc_t),
284 INTERFACE_DESC_SIZE = sizeof(intf_desc_t),
285 ENDPOINT_DESC_SIZE = sizeof(ep_desc_t),
286 DEVICE_QUALIFIER_SIZE = sizeof(qualifier_desc),
287 OTHER_SPEED_CFG_SIZE = 9
290 /*32 <cfg desc>+<if desc>+<endp0 desc>+<endp1 desc>*/
291 #define CONFIG_DESC_TOTAL_SIZE \
292 (CONFIG_DESC_SIZE+INTERFACE_DESC_SIZE+ENDPOINT_DESC_SIZE*2)
294 static unsigned int phy_base;
295 static unsigned int otg_base;
297 static inline void s5p_usb_init_base(void)
299 if (cpu_is_s5pc110()) {
300 phy_base = S5PC110_PHY_BASE;
301 otg_base = S5PC110_OTG_BASE;
303 phy_base = S5PC100_PHY_BASE;
304 otg_base = S5PC100_OTG_BASE;
308 static inline int s5pc1xx_phy_read_reg(int offset)
310 return readl(phy_base + offset);
313 static inline void s5pc1xx_phy_write_reg(int value, int offset)
315 writel(value, phy_base + offset);
318 static inline int s5pc1xx_otg_read_reg(int offset)
320 return readl(otg_base + offset);
323 static inline void s5pc1xx_otg_write_reg(int value, int offset)
325 writel(value, otg_base + offset);
328 void s5p_usb_init_phy(void)
330 if (cpu_is_s5pc110()) {
331 s5pc1xx_phy_write_reg(0xA0, OTG_PHYPWR);
332 s5pc1xx_phy_write_reg(0x3, OTG_PHYCTRL);
334 s5pc1xx_phy_write_reg(0x0, OTG_PHYPWR);
335 #ifdef CONFIG_OTG_CLK_OSCC
336 s5pc1xx_phy_write_reg(0x22, OTG_PHYCTRL);
338 s5pc1xx_phy_write_reg(0x2, OTG_PHYCTRL);
342 s5pc1xx_phy_write_reg(0x1, OTG_RSTCON);
344 s5pc1xx_phy_write_reg(0x0, OTG_RSTCON);
348 int s5p_usb_detect_irq(void)
351 status = s5pc1xx_otg_read_reg(OTG_GINTSTS);
352 return (status & 0x800c3810);
355 void s5p_usb_clear_irq(void)
357 s5pc1xx_otg_write_reg(0xffffffff, OTG_GINTSTS);
360 void s5p_usb_core_soft_reset(void)
364 s5pc1xx_otg_write_reg(CORE_SOFT_RESET, OTG_GRSTCTL);
367 tmp = s5pc1xx_otg_read_reg(OTG_GRSTCTL);
368 } while (!(tmp & AHB_MASTER_IDLE));
371 void s5p_usb_wait_cable_insert(void)
379 tmp = s5pc1xx_otg_read_reg(OTG_GOTGCTL);
381 if (tmp & (B_SESSION_VALID | A_SESSION_VALID)) {
383 } else if (ucFirst == 1) {
384 printf("Insert a OTG cable into the connector!\n");
390 void s5p_usb_init_core(void)
392 s5pc1xx_otg_write_reg(PTXFE_HALF | NPTXFE_HALF | MODE_SLAVE |
393 BURST_SINGLE | GBL_INT_UNMASK, OTG_GAHBCFG);
395 s5pc1xx_otg_write_reg(
396 0x0 << 15 /* PHY Low Power Clock sel */
397 | 0x1 << 14 /* Non-Periodic TxFIFO Rewind Enable */
398 | 0x5 << 10 /* Turnaround time */
399 | 0x0 << 9 /* 0:HNP disable, 1:HNP enable */
400 | 0x0 << 8 /* 0:SRP disable, 1:SRP enable */
401 | 0x0 << 7 /* ULPI DDR sel */
402 | 0x0 << 6 /* 0: high speed utmi+, 1: full speed serial */
403 | 0x0 << 4 /* 0: utmi+, 1:ulpi */
404 | 0x1 << 3 /* phy i/f 0:8bit, 1:16bit */
405 | 0x7 << 0, /* HS/FS Timeout* */
409 void s5p_usb_check_current_mode(u8 *pucMode)
413 tmp = s5pc1xx_otg_read_reg(OTG_GINTSTS);
414 *pucMode = tmp & 0x1;
417 void s5p_usb_soft_disconnect(int set)
421 tmp = s5pc1xx_otg_read_reg(OTG_DCTL);
423 tmp |= SOFT_DISCONNECT;
425 tmp &= ~SOFT_DISCONNECT;
426 s5pc1xx_otg_write_reg(tmp, OTG_DCTL);
429 void s5p_usb_init_device(void)
431 s5pc1xx_otg_write_reg(1 << 18 | otg.speed << 0, OTG_DCFG);
433 s5pc1xx_otg_write_reg(INT_RESUME | INT_OUT_EP | INT_IN_EP |
434 INT_ENUMDONE | INT_RESET | INT_SUSPEND |
435 INT_RX_FIFO_NOT_EMPTY, OTG_GINTMSK);
438 int s5p_usbctl_init(void)
445 if (cpu_is_s5pc110()) {
446 reg = readl(S5PC110_USB_PHY_CON);
447 reg |= (1 << 0); /* USB PHY0 enable */
448 writel(reg, S5PC110_USB_PHY_CON);
450 reg = readl(S5PC100_OTHERS);
451 reg |= (1 << 16); /* unmask usb signal */
452 writel(reg, S5PC100_OTHERS);
457 otg.ep0_state = EP0_STATE_INIT;
458 otg.ep0_substate = 0;
461 s5p_usb_core_soft_reset();
462 s5p_usb_wait_cable_insert();
464 s5p_usb_check_current_mode(&ucMode);
466 if (ucMode == INT_DEV_MODE) {
467 s5p_usb_soft_disconnect(1);
469 s5p_usb_soft_disconnect(0);
470 s5p_usb_init_device();
473 printf("Error : Current Mode is Host\n");
478 int s5p_usbc_activate(void)
483 void s5p_usb_stop(void)
487 void s5p_usb_set_inep_xfersize(EP_TYPE type, u32 pktcnt, u32 xfersize)
489 if (type == EP_TYPE_CONTROL) {
490 s5pc1xx_otg_write_reg((pktcnt << 19) | (xfersize << 0),
492 } else if (type == EP_TYPE_BULK) {
493 s5pc1xx_otg_write_reg((1 << 29) | (pktcnt << 19) |
494 (xfersize << 0), OTG_DIEPTSIZ_IN);
498 void s5p_usb_set_outep_xfersize(EP_TYPE type, u32 pktcnt, u32 xfersize)
500 if (type == EP_TYPE_CONTROL) {
501 s5pc1xx_otg_write_reg((1 << 29) | (pktcnt << 19) |
502 (xfersize << 0), OTG_DOEPTSIZ0);
503 } else if (type == EP_TYPE_BULK) {
504 s5pc1xx_otg_write_reg((pktcnt << 19) | (xfersize << 0),
509 /* works on both aligned and unaligned buffers */
510 void s5p_usb_write_ep0_fifo(u8 *buf, int num)
515 for (i = 0; i < num; i += 4) {
516 Wr_Data = ((*(buf + 3)) << 24) |
517 ((*(buf + 2)) << 16) |
518 ((*(buf + 1)) << 8) |
520 s5pc1xx_otg_write_reg(Wr_Data, OTG_EP0_FIFO);
525 /* optimized fifo access routines, warning: only aligned buffers are supported */
526 static inline void s5p_usb_write_in_fifo(u8 *buf, int num)
528 u32 fifo = otg_base + OTG_IN_FIFO;
532 for (i = 0; i < num; i += 4)
536 static inline void s5p_usb_read_out_fifo(u8 *buf, int num)
538 u32 fifo = otg_base + OTG_OUT_FIFO;
542 for (i = 0; i < num; i += 4)
546 void s5p_usb_get_desc(void)
548 switch (otg.dev_req.wValue_H) {
549 case DEVICE_DESCRIPTOR:
550 otg.req_length = (u32)((otg.dev_req.wLength_H << 8) |
551 otg.dev_req.wLength_L);
552 otg.ep0_state = EP0_STATE_GD_DEV_0;
555 case CONFIGURATION_DESCRIPTOR:
556 otg.req_length = (u32)((otg.dev_req.wLength_H << 8) |
557 otg.dev_req.wLength_L);
559 if (otg.req_length > CONFIG_DESC_SIZE)
560 otg.ep0_state = EP0_STATE_GD_CFG_0;
562 otg.ep0_state = EP0_STATE_GD_CFG_ONLY_0;
565 case STRING_DESCRIPTOR:
566 switch (otg.dev_req.wValue_L) {
568 otg.ep0_state = EP0_STATE_GD_STR_I0;
571 otg.ep0_state = EP0_STATE_GD_STR_I1;
574 otg.ep0_state = EP0_STATE_GD_STR_I2;
581 case ENDPOINT_DESCRIPTOR:
582 switch (otg.dev_req.wValue_L & 0xf) {
584 otg.ep0_state = EP0_STATE_GD_EP0_ONLY_0;
587 otg.ep0_state = EP0_STATE_GD_EP1_ONLY_0;
594 case DEVICE_QUALIFIER:
595 otg.req_length = (u32)((otg.dev_req.wLength_H << 8) |
596 otg.dev_req.wLength_L);
597 otg.ep0_state = EP0_STATE_GD_DEV_QUALIFIER;
600 case OTHER_SPEED_CONFIGURATION:
601 otg.req_length = (u32)((otg.dev_req.wLength_H << 8) |
602 otg.dev_req.wLength_L);
603 otg.ep0_state = EP0_STATE_GD_OTHER_SPEED;
608 void s5p_usb_clear_feature(void)
610 switch (otg.dev_req.bmRequestType) {
611 case DEVICE_RECIPIENT:
612 if (otg.dev_req.wValue_L == 1)
616 case ENDPOINT_RECIPIENT:
617 if (otg.dev_req.wValue_L == 0) {
618 if ((otg.dev_req.wIndex_L & 0x7f) == CONTROL_EP)
619 get_status.ep_ctrl = 0;
622 if ((otg.dev_req.wIndex_L & 0x7f) == BULK_IN_EP)
623 get_status.ep_in = 0;
626 if ((otg.dev_req.wIndex_L & 0x7f) == BULK_OUT_EP)
627 get_status.ep_out = 0;
634 otg.ep0_state = EP0_STATE_INIT;
637 void s5p_usb_set_feature(void)
639 switch (otg.dev_req.bmRequestType) {
640 case DEVICE_RECIPIENT:
641 if (otg.dev_req.wValue_L == 1)
645 case ENDPOINT_RECIPIENT:
646 if (otg.dev_req.wValue_L == 0) {
647 if ((otg.dev_req.wIndex_L & 0x7f) == CONTROL_EP)
648 get_status.ep_ctrl = 1;
650 if ((otg.dev_req.wIndex_L & 0x7f) == BULK_IN_EP)
651 get_status.ep_in = 1;
653 if ((otg.dev_req.wIndex_L & 0x7f) == BULK_OUT_EP)
654 get_status.ep_out = 1;
662 switch (otg.dev_req.wValue_L) {
664 /* TBD: additional processing if required */
674 otg.ep0_state = EP0_STATE_INIT;
677 void s5p_usb_get_status(void)
679 switch (otg.dev_req.bmRequestType) {
680 case (0x80): /*device */
681 get_status.Device = ((u8) remode_wakeup << 1) | 0x1;
682 otg.ep0_state = EP0_STATE_GET_STATUS0;
685 case (0x81): /*interface */
686 get_status.Interface = 0;
687 otg.ep0_state = EP0_STATE_GET_STATUS1;
690 case (0x82): /*endpoint */
691 if ((otg.dev_req.wIndex_L & 0x7f) == CONTROL_EP)
692 otg.ep0_state = EP0_STATE_GET_STATUS2;
694 if ((otg.dev_req.wIndex_L & 0x7f) == BULK_IN_EP)
695 otg.ep0_state = EP0_STATE_GET_STATUS3;
697 if ((otg.dev_req.wIndex_L & 0x7f) == BULK_OUT_EP)
698 otg.ep0_state = EP0_STATE_GET_STATUS4;
706 void s5p_usb_ep0_int_hndlr(void)
709 u32 buf[2] = {0x0000, };
712 if (otg.ep0_state == EP0_STATE_INIT) {
713 for (i = 0; i < 2; i++)
714 buf[i] = s5pc1xx_otg_read_reg(OTG_EP0_FIFO);
716 otg.dev_req.bmRequestType = buf[0];
717 otg.dev_req.bRequest = buf[0] >> 8;
718 otg.dev_req.wValue_L = buf[0] >> 16;
719 otg.dev_req.wValue_H = buf[0] >> 24;
720 otg.dev_req.wIndex_L = buf[1];
721 otg.dev_req.wIndex_H = buf[1] >> 8;
722 otg.dev_req.wLength_L = buf[1] >> 16;
723 otg.dev_req.wLength_H = buf[1] >> 24;
725 switch (otg.dev_req.bRequest) {
726 case STANDARD_SET_ADDRESS:
727 /* Set Address Update bit */
728 addr = (otg.dev_req.wValue_L);
729 s5pc1xx_otg_write_reg(1 << 18 | addr << 4 | otg.speed << 0,
731 otg.ep0_state = EP0_STATE_INIT;
734 case STANDARD_SET_DESCRIPTOR:
737 case STANDARD_SET_CONFIGURATION:
738 /* Configuration value in configuration descriptor */
739 config_value = otg.dev_req.wValue_L;
741 otg.ep0_state = EP0_STATE_INIT;
743 s5p_usb_connected = 1;
746 case STANDARD_GET_CONFIGURATION:
747 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
749 /*ep0 enable, clear nak, next ep0, 8byte */
750 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
751 s5pc1xx_otg_write_reg(config_value, OTG_EP0_FIFO);
752 otg.ep0_state = EP0_STATE_INIT;
755 case STANDARD_GET_DESCRIPTOR:
759 case STANDARD_CLEAR_FEATURE:
760 s5p_usb_clear_feature();
763 case STANDARD_SET_FEATURE:
764 s5p_usb_set_feature();
767 case STANDARD_GET_STATUS:
768 s5p_usb_get_status();
771 case STANDARD_GET_INTERFACE:
772 otg.ep0_state = EP0_STATE_INTERFACE_GET;
775 case STANDARD_SET_INTERFACE:
776 get_intf.AlternateSetting = otg.dev_req.wValue_L;
777 otg.ep0_state = EP0_STATE_INIT;
780 case STANDARD_SYNCH_FRAME:
781 otg.ep0_state = EP0_STATE_INIT;
789 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, otg.ctrl_max_pktsize);
791 /*clear nak, next ep0, 64byte */
792 s5pc1xx_otg_write_reg(((1 << 26) | (CONTROL_EP << 11) | (0 << 0)),
796 void s5p_usb_set_otherspeed_conf_desc(u32 length)
798 /* Standard device descriptor */
800 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 9);
801 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
802 s5p_usb_write_ep0_fifo((u8 *) &config_full, 9);
803 } else if (length == 32) {
804 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 32);
805 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
806 s5p_usb_write_ep0_fifo((u8 *) &config_full_total, 32);
808 otg.ep0_state = EP0_STATE_INIT;
811 void s5p_usb_transfer_ep0(void)
813 switch (otg.ep0_state) {
815 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 0);
817 /*ep0 enable, clear nak, next ep0, 8byte */
818 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
821 case EP0_STATE_GD_DEV_0:
822 /*ep0 enable, clear nak, next ep0, max 64byte */
823 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
824 if (otg.req_length < DEVICE_DESC_SIZE) {
825 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
827 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.dev)),
830 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
832 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.dev)),
835 otg.ep0_state = EP0_STATE_INIT;
838 case EP0_STATE_GD_DEV_1:
839 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
840 if (otg.req_length < (2 * FS_CTRL_PKT_SIZE)) {
841 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.dev)) +
843 otg.req_length - FS_CTRL_PKT_SIZE);
844 otg.ep0_state = EP0_STATE_INIT;
846 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.dev)) +
847 FS_CTRL_PKT_SIZE, FS_CTRL_PKT_SIZE);
848 otg.ep0_state = EP0_STATE_GD_DEV_2;
852 case EP0_STATE_GD_DEV_2:
853 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
854 if (otg.req_length < DEVICE_DESC_SIZE) {
855 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.dev)) +
856 (2 * FS_CTRL_PKT_SIZE),
857 otg.req_length - 2 * FS_CTRL_PKT_SIZE);
859 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.dev)) +
860 (2 * FS_CTRL_PKT_SIZE),
861 DEVICE_DESC_SIZE - 2 * FS_CTRL_PKT_SIZE);
863 otg.ep0_state = EP0_STATE_INIT;
866 case EP0_STATE_GD_CFG_0:
867 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
868 if (otg.req_length < CONFIG_DESC_TOTAL_SIZE) {
869 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
871 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)),
874 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
875 CONFIG_DESC_TOTAL_SIZE);
876 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)),
877 CONFIG_DESC_TOTAL_SIZE);
879 otg.ep0_state = EP0_STATE_INIT;
882 case EP0_STATE_GD_CFG_1:
883 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
884 if (otg.req_length < (2 * FS_CTRL_PKT_SIZE)) {
885 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)) +
887 (otg.req_length - FS_CTRL_PKT_SIZE));
888 otg.ep0_state = EP0_STATE_INIT;
890 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)) +
891 FS_CTRL_PKT_SIZE, FS_CTRL_PKT_SIZE);
892 otg.ep0_state = EP0_STATE_GD_CFG_2;
896 case EP0_STATE_GD_CFG_2:
897 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
898 if (otg.req_length < (3 * FS_CTRL_PKT_SIZE)) {
899 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)) +
900 (2 * FS_CTRL_PKT_SIZE),
901 otg.req_length - 2 * FS_CTRL_PKT_SIZE);
902 otg.ep0_state = EP0_STATE_INIT;
904 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)) +
905 (2 * FS_CTRL_PKT_SIZE), FS_CTRL_PKT_SIZE);
906 otg.ep0_state = EP0_STATE_GD_CFG_3;
910 case EP0_STATE_GD_CFG_3:
911 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
912 if (otg.req_length < (4 * FS_CTRL_PKT_SIZE)) {
913 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)) +
914 (3 * FS_CTRL_PKT_SIZE),
915 otg.req_length - 3 * FS_CTRL_PKT_SIZE);
916 otg.ep0_state = EP0_STATE_INIT;
918 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)) +
919 (3 * FS_CTRL_PKT_SIZE), FS_CTRL_PKT_SIZE);
920 otg.ep0_state = EP0_STATE_GD_CFG_4;
924 case EP0_STATE_GD_CFG_4:
925 otg.ep0_state = EP0_STATE_INIT;
928 case EP0_STATE_GD_DEV_QUALIFIER:
929 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
930 if (otg.req_length < 10) {
931 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
933 s5p_usb_write_ep0_fifo((u8 *)qualifier_desc,
936 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 10);
937 s5p_usb_write_ep0_fifo((u8 *)qualifier_desc, 10);
939 otg.ep0_state = EP0_STATE_INIT;
942 case EP0_STATE_GD_OTHER_SPEED:
943 s5p_usb_set_otherspeed_conf_desc(otg.req_length);
946 case EP0_STATE_GD_OTHER_SPEED_HIGH_1:
947 if (otg.req_length == 9) {
948 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
949 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
950 s5p_usb_write_ep0_fifo(((u8 *) &config_high) + 8, 1);
951 otg.ep0_state = EP0_STATE_INIT;
953 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 8);
954 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
955 s5p_usb_write_ep0_fifo(((u8 *) &config_high) + 8, 8);
956 otg.ep0_state = EP0_STATE_GD_OTHER_SPEED_HIGH_2;
960 case EP0_STATE_GD_OTHER_SPEED_HIGH_2:
961 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 8);
962 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
963 s5p_usb_write_ep0_fifo(((u8 *) &config_high) + 16, 8);
964 otg.ep0_state = EP0_STATE_GD_OTHER_SPEED_HIGH_3;
967 case EP0_STATE_GD_OTHER_SPEED_HIGH_3:
968 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 8);
969 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
970 s5p_usb_write_ep0_fifo(((u8 *) &config_high) + 24, 8);
971 otg.ep0_state = EP0_STATE_INIT;
974 case EP0_STATE_GD_CFG_ONLY_0:
975 if (otg.req_length < CONFIG_DESC_SIZE) {
976 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
978 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
979 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)),
982 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
984 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
985 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)),
988 otg.ep0_state = EP0_STATE_INIT;
991 case EP0_STATE_GD_CFG_ONLY_1:
992 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
993 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.config)) +
995 CONFIG_DESC_SIZE - FS_CTRL_PKT_SIZE);
996 otg.ep0_state = EP0_STATE_INIT;
999 case EP0_STATE_GD_IF_ONLY_0:
1000 if (otg.req_length < INTERFACE_DESC_SIZE) {
1001 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
1003 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
1004 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.intf)),
1007 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1,
1008 INTERFACE_DESC_SIZE);
1009 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
1010 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.intf)),
1011 INTERFACE_DESC_SIZE);
1013 otg.ep0_state = EP0_STATE_INIT;
1016 case EP0_STATE_GD_IF_ONLY_1:
1017 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
1018 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.intf)) +
1020 INTERFACE_DESC_SIZE - FS_CTRL_PKT_SIZE);
1021 otg.ep0_state = EP0_STATE_INIT;
1024 case EP0_STATE_GD_EP0_ONLY_0:
1025 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
1026 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, ENDPOINT_DESC_SIZE);
1027 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.ep1)),
1028 ENDPOINT_DESC_SIZE);
1029 otg.ep0_state = EP0_STATE_INIT;
1032 case EP0_STATE_GD_EP1_ONLY_0:
1033 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, ENDPOINT_DESC_SIZE);
1034 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
1035 s5p_usb_write_ep0_fifo(((u8 *) &(otg.desc.ep2)),
1036 ENDPOINT_DESC_SIZE);
1037 otg.ep0_state = EP0_STATE_INIT;
1040 case EP0_STATE_GD_STR_I0:
1041 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, STRING_DESC0_SIZE);
1042 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
1043 s5p_usb_write_ep0_fifo((u8 *)string_desc0, STRING_DESC0_SIZE);
1044 otg.ep0_state = EP0_STATE_INIT;
1047 case EP0_STATE_GD_STR_I1:
1048 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, sizeof(string_desc1));
1049 if ((otg.ep0_substate * otg.ctrl_max_pktsize +
1050 otg.ctrl_max_pktsize) < sizeof(string_desc1)) {
1051 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
1053 s5p_usb_write_ep0_fifo((u8 *)string_desc1 +
1054 (otg.ep0_substate * otg.ctrl_max_pktsize),
1055 otg.ctrl_max_pktsize);
1056 otg.ep0_state = EP0_STATE_GD_STR_I1;
1059 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
1061 s5p_usb_write_ep0_fifo((u8 *)string_desc1 +
1062 (otg.ep0_substate * otg.ctrl_max_pktsize),
1063 sizeof(string_desc1) - (otg.ep0_substate *
1064 otg.ctrl_max_pktsize));
1065 otg.ep0_state = EP0_STATE_INIT;
1066 otg.ep0_substate = 0;
1070 case EP0_STATE_GD_STR_I2:
1071 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, sizeof(string_desc2));
1072 if ((otg.ep0_substate * otg.ctrl_max_pktsize +
1073 otg.ctrl_max_pktsize) < sizeof(string_desc2)) {
1074 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
1076 s5p_usb_write_ep0_fifo((u8 *) string_desc2 +
1077 (otg.ep0_substate * otg.ctrl_max_pktsize),
1078 otg.ctrl_max_pktsize);
1079 otg.ep0_state = EP0_STATE_GD_STR_I2;
1082 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_64, OTG_DIEPCTL0);
1083 s5p_usb_write_ep0_fifo((u8 *) string_desc2 +
1084 (otg.ep0_substate * otg.ctrl_max_pktsize),
1085 sizeof(string_desc2) - (otg.ep0_substate *
1086 otg.ctrl_max_pktsize));
1087 otg.ep0_state = EP0_STATE_INIT;
1088 otg.ep0_substate = 0;
1092 case EP0_STATE_INTERFACE_GET:
1093 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
1094 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
1095 s5p_usb_write_ep0_fifo((u8 *) &get_intf, 1);
1096 otg.ep0_state = EP0_STATE_INIT;
1099 case EP0_STATE_GET_STATUS0:
1100 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
1101 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
1102 s5p_usb_write_ep0_fifo((u8 *) &get_status, 1);
1103 otg.ep0_state = EP0_STATE_INIT;
1106 case EP0_STATE_GET_STATUS1:
1107 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
1108 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
1109 s5p_usb_write_ep0_fifo((u8 *) &get_status + 1, 1);
1110 otg.ep0_state = EP0_STATE_INIT;
1113 case EP0_STATE_GET_STATUS2:
1114 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
1115 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
1116 s5p_usb_write_ep0_fifo((u8 *) &get_status + 2, 1);
1117 otg.ep0_state = EP0_STATE_INIT;
1120 case EP0_STATE_GET_STATUS3:
1121 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
1122 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
1123 s5p_usb_write_ep0_fifo((u8 *) &get_status + 3, 1);
1124 otg.ep0_state = EP0_STATE_INIT;
1127 case EP0_STATE_GET_STATUS4:
1128 s5p_usb_set_inep_xfersize(EP_TYPE_CONTROL, 1, 1);
1129 s5pc1xx_otg_write_reg(EPEN_CNAK_EP0_8, OTG_DIEPCTL0);
1130 s5p_usb_write_ep0_fifo((u8 *) &get_status + 4, 1);
1131 otg.ep0_state = EP0_STATE_INIT;
1139 void s5p_usb_tx(char *tx_data, int tx_size)
1141 otg.up_ptr = (u8 *) tx_data;
1142 otg.up_addr = (u32) tx_data;
1143 otg.up_size = tx_size;
1145 if (otg.op_mode == USB_CPU) {
1146 if (otg.up_size > otg.bulkin_max_pktsize) {
1147 s5p_usb_set_inep_xfersize(EP_TYPE_BULK, 1,
1148 otg.bulkin_max_pktsize);
1150 s5p_usb_set_inep_xfersize(EP_TYPE_BULK, 1, otg.up_size);
1153 /*ep1 enable, clear nak, bulk, usb active, max pkt */
1154 s5pc1xx_otg_write_reg(1u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
1155 otg.bulkin_max_pktsize << 0, OTG_DIEPCTL_IN);
1157 s5p_usb_write_in_fifo(otg.up_ptr, otg.up_size);
1158 } else if ((otg.op_mode == USB_DMA) && (otg.up_size > 0)) {
1159 u32 pktcnt, remainder;
1161 s5pc1xx_otg_write_reg(MODE_DMA | BURST_INCR4 | GBL_INT_UNMASK,
1163 s5pc1xx_otg_write_reg(INT_RESUME | INT_OUT_EP | INT_IN_EP |
1164 INT_ENUMDONE | INT_RESET | INT_SUSPEND,
1167 s5pc1xx_otg_write_reg((u32) otg.up_ptr, OTG_DIEPDMA_IN);
1169 pktcnt = (u32) (otg.up_size / otg.bulkin_max_pktsize);
1170 remainder = (u32) (otg.up_size % otg.bulkin_max_pktsize);
1174 if (pktcnt > 1023) {
1175 s5p_usb_set_inep_xfersize(EP_TYPE_BULK, 1023,
1176 otg.bulkin_max_pktsize * 1023);
1178 s5p_usb_set_inep_xfersize(EP_TYPE_BULK, pktcnt,
1182 /*ep1 enable, clear nak, bulk, usb active, next ep1, max pkt */
1183 s5pc1xx_otg_write_reg(1u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
1184 BULK_IN_EP << 11 | otg.bulkin_max_pktsize << 0,
1189 void s5p_usb_rx(u32 fifo_cnt_byte)
1191 if (otg.op_mode == USB_CPU) {
1192 s5p_usb_read_out_fifo((u8 *)otg.dn_ptr, fifo_cnt_byte);
1193 otg.dn_ptr += fifo_cnt_byte;
1195 s5p_usb_set_outep_xfersize(EP_TYPE_BULK, 1,
1196 otg.bulkout_max_pktsize);
1198 /*ep3 enable, clear nak, bulk, usb active, next ep3, max pkt */
1199 s5pc1xx_otg_write_reg(1u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
1200 otg.bulkout_max_pktsize << 0, OTG_DOEPCTL_OUT);
1202 if (((u32)otg.dn_ptr - otg.dn_addr) >= (otg.dn_filesize))
1203 s5p_receive_done = 1;
1204 } else if (otg.dn_filesize > otg.bulkout_max_pktsize) {
1205 u32 pkt_cnt, remain_cnt;
1207 s5pc1xx_otg_write_reg(INT_RESUME | INT_OUT_EP | INT_IN_EP |
1208 INT_ENUMDONE | INT_RESET | INT_SUSPEND,
1210 s5pc1xx_otg_write_reg(MODE_DMA | BURST_INCR4 | GBL_INT_UNMASK,
1212 s5pc1xx_otg_write_reg((u32) otg.dn_ptr, OTG_DOEPDMA_OUT);
1213 pkt_cnt = (u32)(otg.dn_filesize - otg.bulkout_max_pktsize) /
1214 otg.bulkout_max_pktsize;
1215 remain_cnt = (u32)((otg.dn_filesize - otg.bulkout_max_pktsize) %
1216 otg.bulkout_max_pktsize);
1218 if (remain_cnt != 0)
1221 if (pkt_cnt > 1023) {
1222 s5p_usb_set_outep_xfersize(EP_TYPE_BULK, 1023,
1223 otg.bulkout_max_pktsize * 1023);
1225 s5p_usb_set_outep_xfersize(EP_TYPE_BULK, pkt_cnt,
1226 otg.dn_filesize - otg.bulkout_max_pktsize);
1229 /*ep3 enable, clear nak, bulk, usb active, next ep3, max pkt */
1230 s5pc1xx_otg_write_reg(1u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
1231 otg.bulkout_max_pktsize << 0, OTG_DOEPCTL_OUT);
1235 void s5p_usb_int_bulkout(u32 fifo_cnt_byte)
1237 s5p_usb_rx(fifo_cnt_byte);
1240 void s5p_usb_dma_in_done(void)
1244 otg.up_ptr = (u8 *)s5pc1xx_otg_read_reg(OTG_DIEPDMA_IN);
1245 remain_cnt = otg.up_size - ((u32) otg.up_ptr - otg.up_addr);
1247 if (remain_cnt > 0) {
1248 u32 pktcnt, remainder;
1249 pktcnt = (u32)(remain_cnt / otg.bulkin_max_pktsize);
1250 remainder = (u32)(remain_cnt % otg.bulkin_max_pktsize);
1255 if (pktcnt > 1023) {
1256 s5p_usb_set_inep_xfersize(EP_TYPE_BULK, 1023,
1257 otg.bulkin_max_pktsize * 1023);
1259 s5p_usb_set_inep_xfersize(EP_TYPE_BULK, pktcnt,
1263 /*ep1 enable, clear nak, bulk, usb active, next ep1, max pkt */
1264 s5pc1xx_otg_write_reg(1u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
1265 BULK_IN_EP << 11 | otg.bulkin_max_pktsize << 0,
1268 s5p_receive_done = 1;
1272 void s5p_usb_dma_out_done(void)
1276 otg.dn_ptr = (u8 *)s5pc1xx_otg_read_reg(OTG_DOEPDMA_OUT);
1278 remain_cnt = otg.dn_filesize - ((u32) otg.dn_ptr - otg.dn_addr + 8);
1280 if (remain_cnt > 0) {
1281 u32 pktcnt, remainder;
1282 pktcnt = (u32)(remain_cnt / otg.bulkout_max_pktsize);
1283 remainder = (u32)(remain_cnt % otg.bulkout_max_pktsize);
1288 if (pktcnt > 1023) {
1289 s5p_usb_set_outep_xfersize(EP_TYPE_BULK, 1023,
1290 otg.bulkout_max_pktsize * 1023);
1292 s5p_usb_set_outep_xfersize(EP_TYPE_BULK, pktcnt,
1296 /*ep3 enable, clear nak, bulk, usb active, next ep3, max pkt 64 */
1297 s5pc1xx_otg_write_reg(1u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
1298 otg.bulkout_max_pktsize << 0, OTG_DOEPCTL_OUT);
1300 udelay(500); /*for FPGA ??? */
1304 void s5p_usb_set_all_outep_nak(void)
1309 for (i = 0; i < 16; i++) {
1310 tmp = s5pc1xx_otg_read_reg(OTG_DOEPCTL0 + 0x20 * i);
1312 s5pc1xx_otg_write_reg(tmp, OTG_DOEPCTL0 + 0x20 * i);
1316 void s5p_usb_clear_all_outep_nak(void)
1321 for (i = 0; i < 16; i++) {
1322 tmp = s5pc1xx_otg_read_reg(OTG_DOEPCTL0 + 0x20 * i);
1323 tmp |= (DEPCTL_EPENA | DEPCTL_CNAK);
1324 s5pc1xx_otg_write_reg(tmp, OTG_DOEPCTL0 + 0x20 * i);
1328 void s5p_usb_set_max_pktsize(USB_SPEED speed)
1330 otg.speed = USB_HIGH;
1331 otg.ctrl_max_pktsize = HS_CTRL_PKT_SIZE;
1332 otg.bulkin_max_pktsize = HS_BULK_PKT_SIZE;
1333 otg.bulkout_max_pktsize = HS_BULK_PKT_SIZE;
1336 void s5p_usb_set_endpoint(void)
1338 /* Unmask OTG_DAINT source */
1339 s5pc1xx_otg_write_reg(0xff, OTG_DIEPINT0);
1340 s5pc1xx_otg_write_reg(0xff, OTG_DOEPINT0);
1341 s5pc1xx_otg_write_reg(0xff, OTG_DIEPINT_IN);
1342 s5pc1xx_otg_write_reg(0xff, OTG_DOEPINT_OUT);
1346 s5pc1xx_otg_write_reg(((1 << 26) | (CONTROL_EP << 11) | (0 << 0)),
1348 /*ep0 enable, clear nak */
1349 s5pc1xx_otg_write_reg((1u << 31) | (1 << 26) | (0 << 0),
1353 void s5p_usb_set_descriptors(void)
1355 #if defined (CONFIG_SAMSUNG_USB)
1356 otg.desc.dev.bLength = DEVICE_DESC_SIZE;
1357 otg.desc.dev.bDescriptorType = DEVICE_DESCRIPTOR;
1358 otg.desc.dev.bDeviceClass = 0xFF;
1359 otg.desc.dev.bDeviceSubClass = 0x0;
1360 otg.desc.dev.bDeviceProtocol = 0x0;
1361 otg.desc.dev.bMaxPacketSize0 = otg.ctrl_max_pktsize;
1362 otg.desc.dev.idVendorL = 0xE8;
1363 otg.desc.dev.idVendorH = 0x04;
1364 otg.desc.dev.idProductL = 0x04;
1365 otg.desc.dev.idProductH = 0x12;
1366 otg.desc.dev.iManufacturer = 0x0;
1367 otg.desc.dev.iProduct = 0x2;
1368 otg.desc.dev.iSerialNumber = 0x0;
1369 otg.desc.dev.bNumConfigurations = 0x1;
1370 otg.desc.dev.bcdUSBL = 0x00;
1371 otg.desc.dev.bcdUSBH = 0x02;
1373 otg.desc.config.bLength = CONFIG_DESC_SIZE;
1374 otg.desc.config.bDescriptorType = CONFIGURATION_DESCRIPTOR;
1375 otg.desc.config.wTotalLengthL = CONFIG_DESC_TOTAL_SIZE;
1376 otg.desc.config.wTotalLengthH = 0;
1377 otg.desc.config.bNumInterfaces = 1;
1378 otg.desc.config.bConfigurationValue = 1;
1379 otg.desc.config.iConfiguration = 0;
1380 otg.desc.config.bmAttributes = CONF_ATTR_DEFAULT | CONF_ATTR_SELFPOWERED;
1381 otg.desc.config.maxPower = 50;
1383 otg.desc.dev.bLength = DEVICE_DESC_SIZE;
1384 otg.desc.dev.bDescriptorType = DEVICE_DESCRIPTOR;
1385 otg.desc.dev.bDeviceClass = 0xFF;
1386 otg.desc.dev.bDeviceSubClass = 0x0;
1387 otg.desc.dev.bDeviceProtocol = 0x0;
1388 otg.desc.dev.bMaxPacketSize0 = otg.ctrl_max_pktsize;
1389 otg.desc.dev.idVendorL = 0xE8;
1390 otg.desc.dev.idVendorH = 0x04;
1391 otg.desc.dev.idProductL = 0x34;
1392 otg.desc.dev.idProductH = 0x12;
1393 otg.desc.dev.bcdDeviceL = 0x00;
1394 otg.desc.dev.bcdDeviceH = 0x01;
1395 otg.desc.dev.iManufacturer = 0x1;
1396 otg.desc.dev.iProduct = 0x2;
1397 otg.desc.dev.iSerialNumber = 0x0;
1398 otg.desc.dev.bNumConfigurations = 0x1;
1399 otg.desc.dev.bcdUSBL = 0x00;
1400 otg.desc.dev.bcdUSBH = 0x02;
1402 otg.desc.config.bLength = CONFIG_DESC_SIZE;
1403 otg.desc.config.bDescriptorType = CONFIGURATION_DESCRIPTOR;
1404 otg.desc.config.wTotalLengthL = CONFIG_DESC_TOTAL_SIZE;
1405 otg.desc.config.wTotalLengthH = 0;
1406 otg.desc.config.bNumInterfaces = 1;
1407 otg.desc.config.bConfigurationValue = 1;
1408 otg.desc.config.iConfiguration = 0;
1409 otg.desc.config.bmAttributes = CONF_ATTR_DEFAULT | CONF_ATTR_SELFPOWERED;
1410 otg.desc.config.maxPower = 25;
1412 otg.desc.intf.bLength = INTERFACE_DESC_SIZE;
1413 otg.desc.intf.bDescriptorType = INTERFACE_DESCRIPTOR;
1414 otg.desc.intf.bInterfaceNumber = 0x0;
1415 otg.desc.intf.bAlternateSetting = 0x0;
1416 otg.desc.intf.bNumEndpoints = 2;
1417 otg.desc.intf.bInterfaceClass = 0xff;
1418 otg.desc.intf.bInterfaceSubClass = 0xff;
1419 otg.desc.intf.bInterfaceProtocol = 0xff;
1420 otg.desc.intf.iInterface = 0x0;
1422 otg.desc.ep1.bLength = ENDPOINT_DESC_SIZE;
1423 otg.desc.ep1.bDescriptorType = ENDPOINT_DESCRIPTOR;
1424 otg.desc.ep1.bEndpointAddress = BULK_IN_EP | EP_ADDR_IN;
1425 otg.desc.ep1.bmAttributes = EP_ATTR_BULK;
1426 otg.desc.ep1.wMaxPacketSizeL = (u8)otg.bulkin_max_pktsize;
1427 otg.desc.ep1.wMaxPacketSizeH = (u8)(otg.bulkin_max_pktsize >> 8);
1428 otg.desc.ep1.bInterval = 0x0;
1430 otg.desc.ep2.bLength = ENDPOINT_DESC_SIZE;
1431 otg.desc.ep2.bDescriptorType = ENDPOINT_DESCRIPTOR;
1432 otg.desc.ep2.bEndpointAddress = BULK_OUT_EP | EP_ADDR_OUT;
1433 otg.desc.ep2.bmAttributes = EP_ATTR_BULK;
1434 otg.desc.ep2.wMaxPacketSizeL = (u8)otg.bulkout_max_pktsize;
1435 otg.desc.ep2.wMaxPacketSizeH = (u8)(otg.bulkout_max_pktsize >> 8);
1436 otg.desc.ep2.bInterval = 0x0;
1439 void s5p_usb_check_speed(USB_SPEED *speed)
1443 status = s5pc1xx_otg_read_reg(OTG_DSTS);
1445 *speed = (USB_SPEED)((status & 0x6) >> 1);
1448 int s5p_usb_check_setconf(void)
1450 return otg.set_config;
1453 void s5p_usb_set_opmode(USB_OPMODE mode)
1457 s5pc1xx_otg_write_reg(INT_RESUME | INT_OUT_EP | INT_IN_EP | INT_ENUMDONE |
1458 INT_RESET | INT_SUSPEND | INT_RX_FIFO_NOT_EMPTY,
1461 s5pc1xx_otg_write_reg(MODE_SLAVE | BURST_SINGLE | GBL_INT_UNMASK,
1464 s5p_usb_set_outep_xfersize(EP_TYPE_BULK, 1, otg.bulkout_max_pktsize);
1465 s5p_usb_set_inep_xfersize(EP_TYPE_BULK, 1, 0);
1467 /*bulk out ep enable, clear nak, bulk, usb active, next ep3, max pkt */
1468 s5pc1xx_otg_write_reg(1u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
1469 otg.bulkout_max_pktsize << 0, OTG_DOEPCTL_OUT);
1471 /*bulk in ep enable, clear nak, bulk, usb active, next ep1, max pkt */
1472 s5pc1xx_otg_write_reg(0u << 31 | 1 << 26 | 2 << 18 | 1 << 15 |
1473 otg.bulkin_max_pktsize << 0, OTG_DIEPCTL_IN);
1476 void s5p_usb_reset(void)
1478 s5p_usb_set_all_outep_nak();
1480 otg.ep0_state = EP0_STATE_INIT;
1481 s5pc1xx_otg_write_reg(((1 << BULK_OUT_EP) | (1 << CONTROL_EP)) << 16 |
1482 ((1 << BULK_IN_EP) | (1 << CONTROL_EP)), OTG_DAINTMSK);
1483 s5pc1xx_otg_write_reg(CTRL_OUT_EP_SETUP_PHASE_DONE | AHB_ERROR |
1484 TRANSFER_DONE, OTG_DOEPMSK);
1485 s5pc1xx_otg_write_reg(INTKN_TXFEMP | NON_ISO_IN_EP_TIMEOUT | AHB_ERROR |
1486 TRANSFER_DONE, OTG_DIEPMSK);
1489 s5pc1xx_otg_write_reg(RX_FIFO_SIZE, OTG_GRXFSIZ);
1491 /* Non Periodic Tx FIFO Size */
1492 s5pc1xx_otg_write_reg(NPTX_FIFO_SIZE << 16 | NPTX_FIFO_START_ADDR << 0,
1495 s5p_usb_clear_all_outep_nak();
1497 /*clear device address */
1498 s5pc1xx_otg_write_reg(s5pc1xx_otg_read_reg(OTG_DCFG) & ~(0x7f << 4),
1501 if (SUSPEND_RESUME_ON) {
1502 s5pc1xx_otg_write_reg(s5pc1xx_otg_read_reg(OTG_PCGCCTRL) & ~(1 << 0),
1507 int s5p_usb_set_init(void)
1511 status = s5pc1xx_otg_read_reg(OTG_DSTS);
1513 /* Set if Device is High speed or Full speed */
1514 if (((status & 0x6) >> 1) == USB_HIGH) {
1515 s5p_usb_set_max_pktsize(USB_HIGH);
1516 } else if (((status & 0x6) >> 1) == USB_FULL) {
1517 printf("Error: Don't support Full_Speed\n");
1520 printf("Error: Neither High_Speed nor Full_Speed\n");
1524 s5p_usb_set_endpoint();
1525 s5p_usb_set_descriptors();
1526 s5p_usb_set_opmode(op_mode);
1531 void s5p_usb_pkt_receive(void)
1536 rx_status = s5pc1xx_otg_read_reg(OTG_GRXSTSP);
1538 if ((rx_status & (0xf << 17)) == SETUP_PKT_RECEIVED) {
1539 s5p_usb_ep0_int_hndlr();
1540 } else if ((rx_status & (0xf << 17)) == OUT_PKT_RECEIVED) {
1541 fifo_cnt_byte = (rx_status & 0x7ff0) >> 4;
1543 if ((rx_status & BULK_OUT_EP) && (fifo_cnt_byte)) {
1544 s5p_usb_int_bulkout(fifo_cnt_byte);
1545 if (otg.op_mode == USB_CPU) {
1546 s5pc1xx_otg_write_reg(INT_RESUME | INT_OUT_EP |
1547 INT_IN_EP | INT_ENUMDONE | INT_RESET |
1548 INT_SUSPEND | INT_RX_FIFO_NOT_EMPTY,
1554 } else if ((rx_status & (0xf << 17)) == GLOBAL_OUT_NAK) {
1556 } else if ((rx_status & (0xf << 17)) == OUT_TRNASFER_COMPLETED) {
1558 } else if ((rx_status & (0xf << 17)) == SETUP_TRANSACTION_COMPLETED) {
1565 void s5p_usb_transfer(void)
1571 ep_int = s5pc1xx_otg_read_reg(OTG_DAINT);
1573 if (ep_int & (1 << CONTROL_EP)) {
1574 ep_int_status = s5pc1xx_otg_read_reg(OTG_DIEPINT0);
1576 if (ep_int_status & INTKN_TXFEMP) {
1579 uNTxFifoSpace = s5pc1xx_otg_read_reg(OTG_GNPTXSTS)
1581 } while (uNTxFifoSpace < otg.ctrl_max_pktsize);
1583 s5p_usb_transfer_ep0();
1586 s5pc1xx_otg_write_reg(ep_int_status, OTG_DIEPINT0);
1589 if (ep_int & ((1 << CONTROL_EP) << 16)) {
1590 ep_int_status = s5pc1xx_otg_read_reg(OTG_DOEPINT0);
1592 s5p_usb_set_outep_xfersize(EP_TYPE_CONTROL, 1, 8);
1593 s5pc1xx_otg_write_reg(1u << 31 | 1 << 26, OTG_DOEPCTL0);
1595 s5pc1xx_otg_write_reg(ep_int_status, OTG_DOEPINT0);
1598 if (ep_int & (1 << BULK_IN_EP)) {
1599 ep_int_status = s5pc1xx_otg_read_reg(OTG_DIEPINT_IN);
1601 s5pc1xx_otg_write_reg(ep_int_status, OTG_DIEPINT_IN);
1602 check_dma = s5pc1xx_otg_read_reg(OTG_GAHBCFG);
1604 if ((check_dma & MODE_DMA) && (ep_int_status & TRANSFER_DONE))
1605 s5p_usb_dma_in_done();
1608 if (ep_int & ((1 << BULK_OUT_EP) << 16)) {
1609 ep_int_status = s5pc1xx_otg_read_reg(OTG_DOEPINT_OUT);
1611 s5pc1xx_otg_write_reg(ep_int_status, OTG_DOEPINT_OUT);
1612 check_dma = s5pc1xx_otg_read_reg(OTG_GAHBCFG);
1614 if ((check_dma & MODE_DMA) && (ep_int_status & TRANSFER_DONE))
1615 s5p_usb_dma_out_done();
1619 void s5p_udc_int_hndlr(void)
1624 int_status = s5pc1xx_otg_read_reg(OTG_GINTSTS);
1625 s5pc1xx_otg_write_reg(int_status, OTG_GINTSTS);
1627 if (int_status & INT_RESET) {
1628 s5pc1xx_otg_write_reg(INT_RESET, OTG_GINTSTS);
1632 if (int_status & INT_ENUMDONE) {
1633 s5pc1xx_otg_write_reg(INT_ENUMDONE, OTG_GINTSTS);
1635 tmp = s5p_usb_set_init();
1640 if (int_status & INT_RESUME) {
1641 s5pc1xx_otg_write_reg(INT_RESUME, OTG_GINTSTS);
1643 if (SUSPEND_RESUME_ON) {
1644 s5pc1xx_otg_write_reg(s5pc1xx_otg_read_reg(OTG_PCGCCTRL) &
1645 ~(1 << 0), OTG_PCGCCTRL);
1649 if (int_status & INT_SUSPEND) {
1650 s5pc1xx_otg_write_reg(INT_SUSPEND, OTG_GINTSTS);
1652 if (SUSPEND_RESUME_ON) {
1653 s5pc1xx_otg_write_reg(s5pc1xx_otg_read_reg(OTG_PCGCCTRL) |
1654 (1 << 0), OTG_PCGCCTRL);
1658 if (int_status & INT_RX_FIFO_NOT_EMPTY) {
1659 s5pc1xx_otg_write_reg(INT_RESUME | INT_OUT_EP | INT_IN_EP |
1660 INT_ENUMDONE | INT_RESET | INT_SUSPEND,
1663 s5p_usb_pkt_receive();
1665 s5pc1xx_otg_write_reg(INT_RESUME | INT_OUT_EP | INT_IN_EP |
1666 INT_ENUMDONE | INT_RESET | INT_SUSPEND |
1667 INT_RX_FIFO_NOT_EMPTY, OTG_GINTMSK);
1670 if ((int_status & INT_IN_EP) || (int_status & INT_OUT_EP))