Lines Matching +full:vddi +full:- +full:supply
1 // SPDX-License-Identifier: GPL-2.0
2 /* linux/drivers/usb/gadget/s3c-hsudc.c
7 * S3C24XX USB 2.0 High-speed USB controller gadget driver
9 * The S3C24XX USB 2.0 high-speed USB controller supports upto 9 endpoints.
19 #include <linux/dma-mapping.h>
29 #include <linux/platform_data/s3c-hsudc.h>
35 /* Non-Indexed Registers */
89 "vdda", /* analog phy supply, 3.3V */
90 "vddi", /* digital phy supply, 1.2V */
91 "vddosc", /* oscillator supply, 1.8V - 3.3V */
95 * struct s3c_hsudc_ep - Endpoint representation used by driver.
117 * struct s3c_hsudc_req - Driver encapsulation of USB gadget transfer request.
127 * struct s3c_hsudc - Driver's abstraction of the device controller.
153 #define ep_maxpacket(_ep) ((_ep)->ep.maxpacket)
154 #define ep_is_in(_ep) ((_ep)->bEndpointAddress & USB_DIR_IN)
155 #define ep_index(_ep) ((_ep)->bEndpointAddress & \
158 static const char driver_name[] = "s3c-udc";
159 static const char ep0name[] = "ep0-control";
179 writel(ep_addr, hsudc->regs + S3C_IR); in set_index()
188 * s3c_hsudc_complete_request - Complete a transfer request.
196 unsigned int stopped = hsep->stopped; in s3c_hsudc_complete_request()
197 struct s3c_hsudc *hsudc = hsep->dev; in s3c_hsudc_complete_request()
199 list_del_init(&hsreq->queue); in s3c_hsudc_complete_request()
200 hsreq->req.status = status; in s3c_hsudc_complete_request()
203 hsudc->ep0state = WAIT_FOR_SETUP; in s3c_hsudc_complete_request()
204 hsep->bEndpointAddress &= ~USB_DIR_IN; in s3c_hsudc_complete_request()
207 hsep->stopped = 1; in s3c_hsudc_complete_request()
208 spin_unlock(&hsudc->lock); in s3c_hsudc_complete_request()
209 usb_gadget_giveback_request(&hsep->ep, &hsreq->req); in s3c_hsudc_complete_request()
210 spin_lock(&hsudc->lock); in s3c_hsudc_complete_request()
211 hsep->stopped = stopped; in s3c_hsudc_complete_request()
215 * s3c_hsudc_nuke_ep - Terminate all requests queued for a endpoint.
223 while (!list_empty(&hsep->queue)) { in s3c_hsudc_nuke_ep()
224 hsreq = list_entry(hsep->queue.next, in s3c_hsudc_nuke_ep()
231 * s3c_hsudc_stop_activity - Stop activity on all endpoints.
242 hsudc->gadget.speed = USB_SPEED_UNKNOWN; in s3c_hsudc_stop_activity()
244 for (epnum = 0; epnum < hsudc->pd->epnum; epnum++) { in s3c_hsudc_stop_activity()
245 hsep = &hsudc->ep[epnum]; in s3c_hsudc_stop_activity()
246 hsep->stopped = 1; in s3c_hsudc_stop_activity()
247 s3c_hsudc_nuke_ep(hsep, -ESHUTDOWN); in s3c_hsudc_stop_activity()
252 * s3c_hsudc_read_setup_pkt - Read the received setup packet from EP0 fifo.
264 count = readl(hsudc->regs + S3C_BRCR); in s3c_hsudc_read_setup_pkt()
265 while (count--) in s3c_hsudc_read_setup_pkt()
266 *buf++ = (u16)readl(hsudc->regs + S3C_BR(0)); in s3c_hsudc_read_setup_pkt()
268 writel(S3C_EP0SR_RX_SUCCESS, hsudc->regs + S3C_EP0SR); in s3c_hsudc_read_setup_pkt()
272 * s3c_hsudc_write_fifo - Write next chunk of transfer data to EP fifo.
286 void __iomem *fifo = hsep->fifo; in s3c_hsudc_write_fifo()
288 buf = hsreq->req.buf + hsreq->req.actual; in s3c_hsudc_write_fifo()
291 length = hsreq->req.length - hsreq->req.actual; in s3c_hsudc_write_fifo()
293 hsreq->req.actual += length; in s3c_hsudc_write_fifo()
295 writel(length, hsep->dev->regs + S3C_BWCR); in s3c_hsudc_write_fifo()
302 if (hsreq->req.length != hsreq->req.actual || hsreq->req.zero) in s3c_hsudc_write_fifo()
317 * s3c_hsudc_read_fifo - Read the next chunk of data from EP fifo.
328 struct s3c_hsudc *hsudc = hsep->dev; in s3c_hsudc_read_fifo()
332 void __iomem *fifo = hsep->fifo; in s3c_hsudc_read_fifo()
336 csr = readl(hsudc->regs + offset); in s3c_hsudc_read_fifo()
338 return -EINVAL; in s3c_hsudc_read_fifo()
340 buf = hsreq->req.buf + hsreq->req.actual; in s3c_hsudc_read_fifo()
342 buflen = hsreq->req.length - hsreq->req.actual; in s3c_hsudc_read_fifo()
344 rcnt = readl(hsudc->regs + S3C_BRCR); in s3c_hsudc_read_fifo()
345 rlen = (csr & S3C_ESR_LWO) ? (rcnt * 2 - 1) : (rcnt * 2); in s3c_hsudc_read_fifo()
347 hsreq->req.actual += min(rlen, buflen); in s3c_hsudc_read_fifo()
348 is_short = (rlen < hsep->ep.maxpacket); in s3c_hsudc_read_fifo()
350 while (rcnt-- != 0) { in s3c_hsudc_read_fifo()
354 buflen--; in s3c_hsudc_read_fifo()
356 hsreq->req.status = -EOVERFLOW; in s3c_hsudc_read_fifo()
360 writel(S3C_ESR_RX_SUCCESS, hsudc->regs + offset); in s3c_hsudc_read_fifo()
362 if (is_short || hsreq->req.actual == hsreq->req.length) { in s3c_hsudc_read_fifo()
371 * s3c_hsudc_epin_intr - Handle in-endpoint interrupt.
372 * @hsudc - Device controller for which the interrupt is to be handled.
373 * @ep_idx - Endpoint number on which an interrupt is pending.
375 * Handles interrupt for a in-endpoint. The interrupts that are handled are
380 struct s3c_hsudc_ep *hsep = &hsudc->ep[ep_idx]; in s3c_hsudc_epin_intr()
384 csr = readl(hsudc->regs + S3C_ESR); in s3c_hsudc_epin_intr()
386 writel(S3C_ESR_STALL, hsudc->regs + S3C_ESR); in s3c_hsudc_epin_intr()
391 writel(S3C_ESR_TX_SUCCESS, hsudc->regs + S3C_ESR); in s3c_hsudc_epin_intr()
392 if (list_empty(&hsep->queue)) in s3c_hsudc_epin_intr()
395 hsreq = list_entry(hsep->queue.next, in s3c_hsudc_epin_intr()
404 * s3c_hsudc_epout_intr - Handle out-endpoint interrupt.
405 * @hsudc - Device controller for which the interrupt is to be handled.
406 * @ep_idx - Endpoint number on which an interrupt is pending.
408 * Handles interrupt for a out-endpoint. The interrupts that are handled are
413 struct s3c_hsudc_ep *hsep = &hsudc->ep[ep_idx]; in s3c_hsudc_epout_intr()
417 csr = readl(hsudc->regs + S3C_ESR); in s3c_hsudc_epout_intr()
419 writel(S3C_ESR_STALL, hsudc->regs + S3C_ESR); in s3c_hsudc_epout_intr()
424 __orr32(hsudc->regs + S3C_ECR, S3C_ECR_FLUSH); in s3c_hsudc_epout_intr()
429 if (list_empty(&hsep->queue)) in s3c_hsudc_epout_intr()
432 hsreq = list_entry(hsep->queue.next, in s3c_hsudc_epout_intr()
440 /** s3c_hsudc_set_halt - Set or clear a endpoint halt.
445 * If halt is cleared, for in-endpoints, if there are any pending
451 struct s3c_hsudc *hsudc = hsep->dev; in s3c_hsudc_set_halt()
457 if (value && ep_is_in(hsep) && !list_empty(&hsep->queue)) in s3c_hsudc_set_halt()
458 return -EAGAIN; in s3c_hsudc_set_halt()
460 spin_lock_irqsave(&hsudc->lock, irqflags); in s3c_hsudc_set_halt()
463 ecr = readl(hsudc->regs + offset); in s3c_hsudc_set_halt()
469 hsep->stopped = 1; in s3c_hsudc_set_halt()
472 hsep->stopped = hsep->wedge = 0; in s3c_hsudc_set_halt()
474 writel(ecr, hsudc->regs + offset); in s3c_hsudc_set_halt()
476 if (ep_is_in(hsep) && !list_empty(&hsep->queue) && !value) { in s3c_hsudc_set_halt()
477 hsreq = list_entry(hsep->queue.next, in s3c_hsudc_set_halt()
483 spin_unlock_irqrestore(&hsudc->lock, irqflags); in s3c_hsudc_set_halt()
487 /** s3c_hsudc_set_wedge - Sets the halt feature with the clear requests ignored
497 return -EINVAL; in s3c_hsudc_set_wedge()
499 hsep->wedge = 1; in s3c_hsudc_set_wedge()
503 /** s3c_hsudc_handle_reqfeat - Handle set feature or clear feature requests.
513 bool set = (ctrl->bRequest == USB_REQ_SET_FEATURE); in s3c_hsudc_handle_reqfeat()
514 u8 ep_num = ctrl->wIndex & USB_ENDPOINT_NUMBER_MASK; in s3c_hsudc_handle_reqfeat()
516 if (ctrl->bRequestType == USB_RECIP_ENDPOINT) { in s3c_hsudc_handle_reqfeat()
517 hsep = &hsudc->ep[ep_num]; in s3c_hsudc_handle_reqfeat()
518 switch (le16_to_cpu(ctrl->wValue)) { in s3c_hsudc_handle_reqfeat()
520 if (set || !hsep->wedge) in s3c_hsudc_handle_reqfeat()
521 s3c_hsudc_set_halt(&hsep->ep, set); in s3c_hsudc_handle_reqfeat()
526 return -ENOENT; in s3c_hsudc_handle_reqfeat()
530 * s3c_hsudc_process_req_status - Handle get status control request.
539 struct s3c_hsudc_ep *hsep0 = &hsudc->ep[0]; in s3c_hsudc_process_req_status()
545 switch (ctrl->bRequestType & USB_RECIP_MASK) { in s3c_hsudc_process_req_status()
555 epnum = le16_to_cpu(ctrl->wIndex) & USB_ENDPOINT_NUMBER_MASK; in s3c_hsudc_process_req_status()
556 hsep = &hsudc->ep[epnum]; in s3c_hsudc_process_req_status()
557 reply = cpu_to_le16(hsep->stopped ? 1 : 0); in s3c_hsudc_process_req_status()
570 * s3c_hsudc_process_setup - Process control request received on endpoint 0.
578 struct s3c_hsudc_ep *hsep = &hsudc->ep[0]; in s3c_hsudc_process_setup()
582 s3c_hsudc_nuke_ep(hsep, -EPROTO); in s3c_hsudc_process_setup()
586 hsep->bEndpointAddress |= USB_DIR_IN; in s3c_hsudc_process_setup()
587 hsudc->ep0state = DATA_STATE_XMIT; in s3c_hsudc_process_setup()
589 hsep->bEndpointAddress &= ~USB_DIR_IN; in s3c_hsudc_process_setup()
590 hsudc->ep0state = DATA_STATE_RECV; in s3c_hsudc_process_setup()
597 hsudc->ep0state = WAIT_FOR_SETUP; in s3c_hsudc_process_setup()
611 hsudc->ep0state = WAIT_FOR_SETUP; in s3c_hsudc_process_setup()
615 if (hsudc->driver) { in s3c_hsudc_process_setup()
616 spin_unlock(&hsudc->lock); in s3c_hsudc_process_setup()
617 ret = hsudc->driver->setup(&hsudc->gadget, &ctrl); in s3c_hsudc_process_setup()
618 spin_lock(&hsudc->lock); in s3c_hsudc_process_setup()
621 hsep->bEndpointAddress &= ~USB_DIR_IN; in s3c_hsudc_process_setup()
622 hsudc->ep0state = WAIT_FOR_SETUP; in s3c_hsudc_process_setup()
626 dev_err(hsudc->dev, "setup failed, returned %d\n", in s3c_hsudc_process_setup()
628 s3c_hsudc_set_halt(&hsep->ep, 1); in s3c_hsudc_process_setup()
629 hsudc->ep0state = WAIT_FOR_SETUP; in s3c_hsudc_process_setup()
630 hsep->bEndpointAddress &= ~USB_DIR_IN; in s3c_hsudc_process_setup()
635 /** s3c_hsudc_handle_ep0_intr - Handle endpoint 0 interrupt.
644 struct s3c_hsudc_ep *hsep = &hsudc->ep[0]; in s3c_hsudc_handle_ep0_intr()
646 u32 csr = readl(hsudc->regs + S3C_EP0SR); in s3c_hsudc_handle_ep0_intr()
650 ecr = readl(hsudc->regs + S3C_EP0CR); in s3c_hsudc_handle_ep0_intr()
652 writel(ecr, hsudc->regs + S3C_EP0CR); in s3c_hsudc_handle_ep0_intr()
654 writel(S3C_EP0SR_STALL, hsudc->regs + S3C_EP0SR); in s3c_hsudc_handle_ep0_intr()
655 hsep->stopped = 0; in s3c_hsudc_handle_ep0_intr()
657 s3c_hsudc_nuke_ep(hsep, -ECONNABORTED); in s3c_hsudc_handle_ep0_intr()
658 hsudc->ep0state = WAIT_FOR_SETUP; in s3c_hsudc_handle_ep0_intr()
659 hsep->bEndpointAddress &= ~USB_DIR_IN; in s3c_hsudc_handle_ep0_intr()
664 writel(S3C_EP0SR_TX_SUCCESS, hsudc->regs + S3C_EP0SR); in s3c_hsudc_handle_ep0_intr()
666 if (list_empty(&hsep->queue)) in s3c_hsudc_handle_ep0_intr()
669 hsreq = list_entry(hsep->queue.next, in s3c_hsudc_handle_ep0_intr()
676 if (hsudc->ep0state == WAIT_FOR_SETUP) in s3c_hsudc_handle_ep0_intr()
680 if (list_empty(&hsep->queue)) in s3c_hsudc_handle_ep0_intr()
682 hsreq = list_entry(hsep->queue.next, in s3c_hsudc_handle_ep0_intr()
691 * s3c_hsudc_ep_enable - Enable a endpoint.
708 if (!_ep || !desc || _ep->name == ep0name in s3c_hsudc_ep_enable()
709 || desc->bDescriptorType != USB_DT_ENDPOINT in s3c_hsudc_ep_enable()
710 || hsep->bEndpointAddress != desc->bEndpointAddress in s3c_hsudc_ep_enable()
712 return -EINVAL; in s3c_hsudc_ep_enable()
714 if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK in s3c_hsudc_ep_enable()
716 || !desc->wMaxPacketSize) in s3c_hsudc_ep_enable()
717 return -ERANGE; in s3c_hsudc_ep_enable()
719 hsudc = hsep->dev; in s3c_hsudc_ep_enable()
720 if (!hsudc->driver || hsudc->gadget.speed == USB_SPEED_UNKNOWN) in s3c_hsudc_ep_enable()
721 return -ESHUTDOWN; in s3c_hsudc_ep_enable()
723 spin_lock_irqsave(&hsudc->lock, flags); in s3c_hsudc_ep_enable()
725 set_index(hsudc, hsep->bEndpointAddress); in s3c_hsudc_ep_enable()
727 writel(ecr, hsudc->regs + S3C_ECR); in s3c_hsudc_ep_enable()
729 hsep->stopped = hsep->wedge = 0; in s3c_hsudc_ep_enable()
730 hsep->ep.desc = desc; in s3c_hsudc_ep_enable()
731 hsep->ep.maxpacket = usb_endpoint_maxp(desc); in s3c_hsudc_ep_enable()
734 __set_bit(ep_index(hsep), hsudc->regs + S3C_EIER); in s3c_hsudc_ep_enable()
736 spin_unlock_irqrestore(&hsudc->lock, flags); in s3c_hsudc_ep_enable()
741 * s3c_hsudc_ep_disable - Disable a endpoint.
750 struct s3c_hsudc *hsudc = hsep->dev; in s3c_hsudc_ep_disable()
753 if (!_ep || !hsep->ep.desc) in s3c_hsudc_ep_disable()
754 return -EINVAL; in s3c_hsudc_ep_disable()
756 spin_lock_irqsave(&hsudc->lock, flags); in s3c_hsudc_ep_disable()
758 set_index(hsudc, hsep->bEndpointAddress); in s3c_hsudc_ep_disable()
759 __clear_bit(ep_index(hsep), hsudc->regs + S3C_EIER); in s3c_hsudc_ep_disable()
761 s3c_hsudc_nuke_ep(hsep, -ESHUTDOWN); in s3c_hsudc_ep_disable()
763 hsep->ep.desc = NULL; in s3c_hsudc_ep_disable()
764 hsep->stopped = 1; in s3c_hsudc_ep_disable()
766 spin_unlock_irqrestore(&hsudc->lock, flags); in s3c_hsudc_ep_disable()
771 * s3c_hsudc_alloc_request - Allocate a new request.
786 INIT_LIST_HEAD(&hsreq->queue); in s3c_hsudc_alloc_request()
787 return &hsreq->req; in s3c_hsudc_alloc_request()
791 * s3c_hsudc_free_request - Deallocate a request.
802 WARN_ON(!list_empty(&hsreq->queue)); in s3c_hsudc_free_request()
807 * s3c_hsudc_queue - Queue a transfer request for the endpoint.
825 if ((!_req || !_req->complete || !_req->buf || in s3c_hsudc_queue()
826 !list_empty(&hsreq->queue))) in s3c_hsudc_queue()
827 return -EINVAL; in s3c_hsudc_queue()
830 hsudc = hsep->dev; in s3c_hsudc_queue()
831 if (!hsudc->driver || hsudc->gadget.speed == USB_SPEED_UNKNOWN) in s3c_hsudc_queue()
832 return -ESHUTDOWN; in s3c_hsudc_queue()
834 spin_lock_irqsave(&hsudc->lock, flags); in s3c_hsudc_queue()
835 set_index(hsudc, hsep->bEndpointAddress); in s3c_hsudc_queue()
837 _req->status = -EINPROGRESS; in s3c_hsudc_queue()
838 _req->actual = 0; in s3c_hsudc_queue()
840 if (!ep_index(hsep) && _req->length == 0) { in s3c_hsudc_queue()
841 hsudc->ep0state = WAIT_FOR_SETUP; in s3c_hsudc_queue()
843 spin_unlock_irqrestore(&hsudc->lock, flags); in s3c_hsudc_queue()
847 if (list_empty(&hsep->queue) && !hsep->stopped) { in s3c_hsudc_queue()
850 csr = readl(hsudc->regs + offset); in s3c_hsudc_queue()
855 csr = readl(hsudc->regs + offset); in s3c_hsudc_queue()
863 list_add_tail(&hsreq->queue, &hsep->queue); in s3c_hsudc_queue()
865 spin_unlock_irqrestore(&hsudc->lock, flags); in s3c_hsudc_queue()
870 * s3c_hsudc_dequeue - Dequeue a transfer request from an endpoint.
879 struct s3c_hsudc *hsudc = hsep->dev; in s3c_hsudc_dequeue()
884 if (!_ep || hsep->ep.name == ep0name) in s3c_hsudc_dequeue()
885 return -EINVAL; in s3c_hsudc_dequeue()
887 spin_lock_irqsave(&hsudc->lock, flags); in s3c_hsudc_dequeue()
889 list_for_each_entry(hsreq, &hsep->queue, queue) { in s3c_hsudc_dequeue()
890 if (&hsreq->req == _req) in s3c_hsudc_dequeue()
893 if (&hsreq->req != _req) { in s3c_hsudc_dequeue()
894 spin_unlock_irqrestore(&hsudc->lock, flags); in s3c_hsudc_dequeue()
895 return -EINVAL; in s3c_hsudc_dequeue()
898 set_index(hsudc, hsep->bEndpointAddress); in s3c_hsudc_dequeue()
899 s3c_hsudc_complete_request(hsep, hsreq, -ECONNRESET); in s3c_hsudc_dequeue()
901 spin_unlock_irqrestore(&hsudc->lock, flags); in s3c_hsudc_dequeue()
917 * s3c_hsudc_initep - Initialize a endpoint to default state.
918 * @hsudc - Reference to the device controller.
919 * @hsep - Endpoint to be initialized.
920 * @epnum - Address to be assigned to the endpoint.
933 hsep->bEndpointAddress = USB_DIR_IN; in s3c_hsudc_initep()
936 hsep->bEndpointAddress |= epnum; in s3c_hsudc_initep()
938 snprintf(hsep->name, sizeof(hsep->name), "ep%d%s", epnum, dir); in s3c_hsudc_initep()
940 snprintf(hsep->name, sizeof(hsep->name), "%s", ep0name); in s3c_hsudc_initep()
942 INIT_LIST_HEAD(&hsep->queue); in s3c_hsudc_initep()
943 INIT_LIST_HEAD(&hsep->ep.ep_list); in s3c_hsudc_initep()
945 list_add_tail(&hsep->ep.ep_list, &hsudc->gadget.ep_list); in s3c_hsudc_initep()
947 hsep->dev = hsudc; in s3c_hsudc_initep()
948 hsep->ep.name = hsep->name; in s3c_hsudc_initep()
949 usb_ep_set_maxpacket_limit(&hsep->ep, epnum ? 512 : 64); in s3c_hsudc_initep()
950 hsep->ep.ops = &s3c_hsudc_ep_ops; in s3c_hsudc_initep()
951 hsep->fifo = hsudc->regs + S3C_BR(epnum); in s3c_hsudc_initep()
952 hsep->ep.desc = NULL; in s3c_hsudc_initep()
953 hsep->stopped = 0; in s3c_hsudc_initep()
954 hsep->wedge = 0; in s3c_hsudc_initep()
957 hsep->ep.caps.type_control = true; in s3c_hsudc_initep()
958 hsep->ep.caps.dir_in = true; in s3c_hsudc_initep()
959 hsep->ep.caps.dir_out = true; in s3c_hsudc_initep()
961 hsep->ep.caps.type_iso = true; in s3c_hsudc_initep()
962 hsep->ep.caps.type_bulk = true; in s3c_hsudc_initep()
963 hsep->ep.caps.type_int = true; in s3c_hsudc_initep()
967 hsep->ep.caps.dir_in = true; in s3c_hsudc_initep()
969 hsep->ep.caps.dir_out = true; in s3c_hsudc_initep()
972 writel(hsep->ep.maxpacket, hsudc->regs + S3C_MPR); in s3c_hsudc_initep()
976 * s3c_hsudc_setup_ep - Configure all endpoints to default state.
985 hsudc->ep0state = WAIT_FOR_SETUP; in s3c_hsudc_setup_ep()
986 INIT_LIST_HEAD(&hsudc->gadget.ep_list); in s3c_hsudc_setup_ep()
987 for (epnum = 0; epnum < hsudc->pd->epnum; epnum++) in s3c_hsudc_setup_ep()
988 s3c_hsudc_initep(hsudc, &hsudc->ep[epnum], epnum); in s3c_hsudc_setup_ep()
992 * s3c_hsudc_reconfig - Reconfigure the device controller to default state.
999 writel(0xAA, hsudc->regs + S3C_EDR); in s3c_hsudc_reconfig()
1000 writel(1, hsudc->regs + S3C_EIER); in s3c_hsudc_reconfig()
1001 writel(0, hsudc->regs + S3C_TR); in s3c_hsudc_reconfig()
1003 S3C_SCR_RST_EN, hsudc->regs + S3C_SCR); in s3c_hsudc_reconfig()
1004 writel(0, hsudc->regs + S3C_EP0CR); in s3c_hsudc_reconfig()
1010 * s3c_hsudc_irq - Interrupt handler for device controller.
1025 spin_lock(&hsudc->lock); in s3c_hsudc_irq()
1027 sys_status = readl(hsudc->regs + S3C_SSR); in s3c_hsudc_irq()
1028 ep_intr = readl(hsudc->regs + S3C_EIR) & 0x3FF; in s3c_hsudc_irq()
1031 spin_unlock(&hsudc->lock); in s3c_hsudc_irq()
1037 writel(S3C_SSR_VBUSON, hsudc->regs + S3C_SSR); in s3c_hsudc_irq()
1040 writel(S3C_SSR_ERR, hsudc->regs + S3C_SSR); in s3c_hsudc_irq()
1043 writel(S3C_SSR_SDE, hsudc->regs + S3C_SSR); in s3c_hsudc_irq()
1044 hsudc->gadget.speed = (sys_status & S3C_SSR_HSP) ? in s3c_hsudc_irq()
1049 writel(S3C_SSR_SUSPEND, hsudc->regs + S3C_SSR); in s3c_hsudc_irq()
1050 if (hsudc->gadget.speed != USB_SPEED_UNKNOWN in s3c_hsudc_irq()
1051 && hsudc->driver && hsudc->driver->suspend) in s3c_hsudc_irq()
1052 hsudc->driver->suspend(&hsudc->gadget); in s3c_hsudc_irq()
1056 writel(S3C_SSR_RESUME, hsudc->regs + S3C_SSR); in s3c_hsudc_irq()
1057 if (hsudc->gadget.speed != USB_SPEED_UNKNOWN in s3c_hsudc_irq()
1058 && hsudc->driver && hsudc->driver->resume) in s3c_hsudc_irq()
1059 hsudc->driver->resume(&hsudc->gadget); in s3c_hsudc_irq()
1063 writel(S3C_SSR_RESET, hsudc->regs + S3C_SSR); in s3c_hsudc_irq()
1064 for (ep_idx = 0; ep_idx < hsudc->pd->epnum; ep_idx++) { in s3c_hsudc_irq()
1065 hsep = &hsudc->ep[ep_idx]; in s3c_hsudc_irq()
1066 hsep->stopped = 1; in s3c_hsudc_irq()
1067 s3c_hsudc_nuke_ep(hsep, -ECONNRESET); in s3c_hsudc_irq()
1070 hsudc->ep0state = WAIT_FOR_SETUP; in s3c_hsudc_irq()
1075 writel(S3C_EIR_EP0, hsudc->regs + S3C_EIR); in s3c_hsudc_irq()
1084 hsep = &hsudc->ep[ep_idx]; in s3c_hsudc_irq()
1086 writel(1 << ep_idx, hsudc->regs + S3C_EIR); in s3c_hsudc_irq()
1096 spin_unlock(&hsudc->lock); in s3c_hsudc_irq()
1107 || driver->max_speed < USB_SPEED_FULL in s3c_hsudc_start()
1108 || !driver->setup) in s3c_hsudc_start()
1109 return -EINVAL; in s3c_hsudc_start()
1112 return -ENODEV; in s3c_hsudc_start()
1114 if (hsudc->driver) in s3c_hsudc_start()
1115 return -EBUSY; in s3c_hsudc_start()
1117 hsudc->driver = driver; in s3c_hsudc_start()
1119 ret = regulator_bulk_enable(ARRAY_SIZE(hsudc->supplies), in s3c_hsudc_start()
1120 hsudc->supplies); in s3c_hsudc_start()
1122 dev_err(hsudc->dev, "failed to enable supplies: %d\n", ret); in s3c_hsudc_start()
1127 if (!IS_ERR_OR_NULL(hsudc->transceiver)) { in s3c_hsudc_start()
1128 ret = otg_set_peripheral(hsudc->transceiver->otg, in s3c_hsudc_start()
1129 &hsudc->gadget); in s3c_hsudc_start()
1131 dev_err(hsudc->dev, "%s: can't bind to transceiver\n", in s3c_hsudc_start()
1132 hsudc->gadget.name); in s3c_hsudc_start()
1137 enable_irq(hsudc->irq); in s3c_hsudc_start()
1140 pm_runtime_get_sync(hsudc->dev); in s3c_hsudc_start()
1142 if (hsudc->pd->phy_init) in s3c_hsudc_start()
1143 hsudc->pd->phy_init(); in s3c_hsudc_start()
1144 if (hsudc->pd->gpio_init) in s3c_hsudc_start()
1145 hsudc->pd->gpio_init(); in s3c_hsudc_start()
1149 regulator_bulk_disable(ARRAY_SIZE(hsudc->supplies), hsudc->supplies); in s3c_hsudc_start()
1151 hsudc->driver = NULL; in s3c_hsudc_start()
1161 return -ENODEV; in s3c_hsudc_stop()
1163 spin_lock_irqsave(&hsudc->lock, flags); in s3c_hsudc_stop()
1164 hsudc->gadget.speed = USB_SPEED_UNKNOWN; in s3c_hsudc_stop()
1165 if (hsudc->pd->phy_uninit) in s3c_hsudc_stop()
1166 hsudc->pd->phy_uninit(); in s3c_hsudc_stop()
1168 pm_runtime_put(hsudc->dev); in s3c_hsudc_stop()
1170 if (hsudc->pd->gpio_uninit) in s3c_hsudc_stop()
1171 hsudc->pd->gpio_uninit(); in s3c_hsudc_stop()
1173 spin_unlock_irqrestore(&hsudc->lock, flags); in s3c_hsudc_stop()
1175 if (!IS_ERR_OR_NULL(hsudc->transceiver)) in s3c_hsudc_stop()
1176 (void) otg_set_peripheral(hsudc->transceiver->otg, NULL); in s3c_hsudc_stop()
1178 disable_irq(hsudc->irq); in s3c_hsudc_stop()
1180 regulator_bulk_disable(ARRAY_SIZE(hsudc->supplies), hsudc->supplies); in s3c_hsudc_stop()
1181 hsudc->driver = NULL; in s3c_hsudc_stop()
1188 return readl(hsudc->regs + S3C_FNR) & 0x3FF; in s3c_hsudc_read_frameno()
1201 return -ENODEV; in s3c_hsudc_vbus_draw()
1203 if (!IS_ERR_OR_NULL(hsudc->transceiver)) in s3c_hsudc_vbus_draw()
1204 return usb_phy_set_power(hsudc->transceiver, mA); in s3c_hsudc_vbus_draw()
1206 return -EOPNOTSUPP; in s3c_hsudc_vbus_draw()
1218 struct device *dev = &pdev->dev; in s3c_hsudc_probe()
1220 struct s3c24xx_hsudc_platdata *pd = dev_get_platdata(&pdev->dev); in s3c_hsudc_probe()
1223 hsudc = devm_kzalloc(&pdev->dev, sizeof(struct s3c_hsudc) + in s3c_hsudc_probe()
1224 sizeof(struct s3c_hsudc_ep) * pd->epnum, in s3c_hsudc_probe()
1227 return -ENOMEM; in s3c_hsudc_probe()
1230 hsudc->dev = dev; in s3c_hsudc_probe()
1231 hsudc->pd = dev_get_platdata(&pdev->dev); in s3c_hsudc_probe()
1233 hsudc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2); in s3c_hsudc_probe()
1235 for (i = 0; i < ARRAY_SIZE(hsudc->supplies); i++) in s3c_hsudc_probe()
1236 hsudc->supplies[i].supply = s3c_hsudc_supply_names[i]; in s3c_hsudc_probe()
1238 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(hsudc->supplies), in s3c_hsudc_probe()
1239 hsudc->supplies); in s3c_hsudc_probe()
1241 if (ret != -EPROBE_DEFER) in s3c_hsudc_probe()
1246 hsudc->regs = devm_platform_ioremap_resource(pdev, 0); in s3c_hsudc_probe()
1247 if (IS_ERR(hsudc->regs)) { in s3c_hsudc_probe()
1248 ret = PTR_ERR(hsudc->regs); in s3c_hsudc_probe()
1252 spin_lock_init(&hsudc->lock); in s3c_hsudc_probe()
1254 hsudc->gadget.max_speed = USB_SPEED_HIGH; in s3c_hsudc_probe()
1255 hsudc->gadget.ops = &s3c_hsudc_gadget_ops; in s3c_hsudc_probe()
1256 hsudc->gadget.name = dev_name(dev); in s3c_hsudc_probe()
1257 hsudc->gadget.ep0 = &hsudc->ep[0].ep; in s3c_hsudc_probe()
1258 hsudc->gadget.is_otg = 0; in s3c_hsudc_probe()
1259 hsudc->gadget.is_a_peripheral = 0; in s3c_hsudc_probe()
1260 hsudc->gadget.speed = USB_SPEED_UNKNOWN; in s3c_hsudc_probe()
1267 hsudc->irq = ret; in s3c_hsudc_probe()
1269 ret = devm_request_irq(&pdev->dev, hsudc->irq, s3c_hsudc_irq, 0, in s3c_hsudc_probe()
1276 hsudc->uclk = devm_clk_get(&pdev->dev, "usb-device"); in s3c_hsudc_probe()
1277 if (IS_ERR(hsudc->uclk)) { in s3c_hsudc_probe()
1278 dev_err(dev, "failed to find usb-device clock source\n"); in s3c_hsudc_probe()
1279 ret = PTR_ERR(hsudc->uclk); in s3c_hsudc_probe()
1282 clk_enable(hsudc->uclk); in s3c_hsudc_probe()
1286 disable_irq(hsudc->irq); in s3c_hsudc_probe()
1289 ret = usb_add_gadget_udc(&pdev->dev, &hsudc->gadget); in s3c_hsudc_probe()
1297 clk_disable(hsudc->uclk); in s3c_hsudc_probe()
1299 if (!IS_ERR_OR_NULL(hsudc->transceiver)) in s3c_hsudc_probe()
1300 usb_put_phy(hsudc->transceiver); in s3c_hsudc_probe()
1308 .name = "s3c-hsudc",
1315 MODULE_DESCRIPTION("Samsung S3C24XX USB high-speed controller driver");
1318 MODULE_ALIAS("platform:s3c-hsudc");