Lines Matching +full:ast2600 +full:- +full:udc
1 // SPDX-License-Identifier: GPL-2.0+
8 #include <linux/dma-mapping.h>
29 * UDC register definitions *
110 * per-endpoint register definitions *
182 struct ast_udc_dev *udc; member
241 dev_dbg(&(u)->pdev->dev, "%s() " fmt, __func__, ##__VA_ARGS__)
248 dev_dbg(&(e)->udc->pdev->dev, "%s():%s " fmt, __func__, \
249 (e)->ep.name, ##__VA_ARGS__)
256 dev_dbg(&(u)->pdev->dev, "%s() " fmt, __func__, ##__VA_ARGS__)
263 dev_dbg(&(u)->pdev->dev, "%s() " fmt, __func__, ##__VA_ARGS__)
268 /*-------------------------------------------------------------------------*/
269 #define ast_udc_read(udc, offset) \ argument
270 readl((udc)->reg + (offset))
271 #define ast_udc_write(udc, val, offset) \ argument
272 writel((val), (udc)->reg + (offset))
275 readl((ep)->ep_reg + (reg))
277 writel((val), (ep)->ep_reg + (reg))
279 /*-------------------------------------------------------------------------*/
284 struct ast_udc_dev *udc = ep->udc; in ast_udc_done() local
287 req, req->req.actual, req->req.length, in ast_udc_done()
288 (u32)req->req.buf, ep->dir_in); in ast_udc_done()
290 list_del(&req->queue); in ast_udc_done()
292 if (req->req.status == -EINPROGRESS) in ast_udc_done()
293 req->req.status = status; in ast_udc_done()
295 status = req->req.status; in ast_udc_done()
297 if (status && status != -ESHUTDOWN) in ast_udc_done()
300 spin_unlock(&udc->lock); in ast_udc_done()
301 usb_gadget_giveback_request(&ep->ep, &req->req); in ast_udc_done()
302 spin_lock(&udc->lock); in ast_udc_done()
309 while (!list_empty(&ep->queue)) { in ast_udc_nuke()
312 req = list_entry(ep->queue.next, struct ast_udc_request, in ast_udc_nuke()
329 static void ast_udc_stop_activity(struct ast_udc_dev *udc) in ast_udc_stop_activity() argument
335 ep = &udc->ep[i]; in ast_udc_stop_activity()
336 ep->stopped = 1; in ast_udc_stop_activity()
337 ast_udc_nuke(ep, -ESHUTDOWN); in ast_udc_stop_activity()
346 struct ast_udc_dev *udc = ep->udc; in ast_udc_ep_enable() local
353 if (!_ep || !ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT || in ast_udc_ep_enable()
354 maxpacket == 0 || maxpacket > ep->ep.maxpacket) { in ast_udc_ep_enable()
356 return -EINVAL; in ast_udc_ep_enable()
359 if (!udc->driver) { in ast_udc_ep_enable()
361 return -ESHUTDOWN; in ast_udc_ep_enable()
366 spin_lock_irqsave(&udc->lock, flags); in ast_udc_ep_enable()
368 ep->desc = desc; in ast_udc_ep_enable()
369 ep->stopped = 0; in ast_udc_ep_enable()
370 ep->ep.maxpacket = maxpacket; in ast_udc_ep_enable()
371 ep->chunk_max = AST_EP_DMA_DESC_MAX_LEN; in ast_udc_ep_enable()
380 ep->dir_in = dir_in; in ast_udc_ep_enable()
381 if (!ep->dir_in) in ast_udc_ep_enable()
399 ep->desc_mode = udc->desc_mode && ep->descs_dma && ep->dir_in; in ast_udc_ep_enable()
400 if (ep->desc_mode) { in ast_udc_ep_enable()
403 ast_ep_write(ep, ep->descs_dma, AST_UDC_EP_DMA_BUFF); in ast_udc_ep_enable()
409 ep->descs_wptr = 0; in ast_udc_ep_enable()
418 ast_udc_write(udc, EP_TOGGLE_SET_EPNUM(epnum), AST_VHUB_EP_DATA); in ast_udc_ep_enable()
425 spin_unlock_irqrestore(&udc->lock, flags); in ast_udc_ep_enable()
433 struct ast_udc_dev *udc = ep->udc; in ast_udc_ep_disable() local
436 spin_lock_irqsave(&udc->lock, flags); in ast_udc_ep_disable()
438 ep->ep.desc = NULL; in ast_udc_ep_disable()
439 ep->stopped = 1; in ast_udc_ep_disable()
441 ast_udc_nuke(ep, -ESHUTDOWN); in ast_udc_ep_disable()
444 spin_unlock_irqrestore(&udc->lock, flags); in ast_udc_ep_disable()
461 INIT_LIST_HEAD(&req->queue); in ast_udc_ep_alloc_request()
463 return &req->req; in ast_udc_ep_alloc_request()
477 struct ast_udc_dev *udc = ep->udc; in ast_dma_descriptor_setup() local
478 struct device *dev = &udc->pdev->dev; in ast_dma_descriptor_setup()
483 if (!ep->descs) { in ast_dma_descriptor_setup()
485 ep->ep.name); in ast_dma_descriptor_setup()
486 return -EINVAL; in ast_dma_descriptor_setup()
493 "wptr", ep->descs_wptr, "dma_buf", dma_buf, in ast_dma_descriptor_setup()
499 ep->descs[ep->descs_wptr].des_0 = dma_buf + offset; in ast_dma_descriptor_setup()
501 if (chunk > ep->chunk_max) { in ast_dma_descriptor_setup()
502 ep->descs[ep->descs_wptr].des_1 = ep->chunk_max; in ast_dma_descriptor_setup()
504 ep->descs[ep->descs_wptr].des_1 = chunk; in ast_dma_descriptor_setup()
508 chunk -= ep->chunk_max; in ast_dma_descriptor_setup()
511 ep->descs_wptr, in ast_dma_descriptor_setup()
512 ep->descs[ep->descs_wptr].des_0, in ast_dma_descriptor_setup()
513 ep->descs[ep->descs_wptr].des_1); in ast_dma_descriptor_setup()
516 req->saved_dma_wptr = ep->descs_wptr; in ast_dma_descriptor_setup()
518 ep->descs_wptr++; in ast_dma_descriptor_setup()
521 if (ep->descs_wptr >= AST_UDC_DESCS_COUNT) in ast_dma_descriptor_setup()
522 ep->descs_wptr = 0; in ast_dma_descriptor_setup()
524 offset = ep->chunk_max * count; in ast_dma_descriptor_setup()
535 last = req->req.length - req->req.actual; in ast_udc_epn_kick()
536 tx_len = last > ep->ep.maxpacket ? ep->ep.maxpacket : last; in ast_udc_epn_kick()
539 req, tx_len, ep->dir_in); in ast_udc_epn_kick()
541 ast_ep_write(ep, req->req.dma + req->req.actual, AST_UDC_EP_DMA_BUFF); in ast_udc_epn_kick()
558 last = req->req.length - req->req.actual; in ast_udc_epn_kick_desc()
562 req, "tx_len", tx_len, "dir_in", ep->dir_in, in ast_udc_epn_kick_desc()
563 "dma", req->req.dma + req->req.actual, in ast_udc_epn_kick_desc()
564 req->req.actual, req->req.length, in ast_udc_epn_kick_desc()
567 if (!ast_dma_descriptor_setup(ep, req->req.dma + req->req.actual, in ast_udc_epn_kick_desc()
569 req->actual_dma_length += tx_len; in ast_udc_epn_kick_desc()
574 ast_ep_write(ep, ep->descs_wptr, AST_UDC_EP_DMA_STS); in ast_udc_epn_kick_desc()
577 ep->descs_wptr, in ast_udc_epn_kick_desc()
585 struct ast_udc_dev *udc = ep->udc; in ast_udc_ep0_queue() local
589 last = req->req.length - req->req.actual; in ast_udc_ep0_queue()
590 tx_len = last > ep->ep.maxpacket ? ep->ep.maxpacket : last; in ast_udc_ep0_queue()
592 ast_udc_write(udc, req->req.dma + req->req.actual, in ast_udc_ep0_queue()
595 if (ep->dir_in) { in ast_udc_ep0_queue()
597 SETUP_DBG(udc, "IN: %s:0x%x, %s:0x%x, %s:%d (%d/%d), %s:%d\n", in ast_udc_ep0_queue()
598 "buf", (u32)req->req.buf, in ast_udc_ep0_queue()
599 "dma", req->req.dma + req->req.actual, in ast_udc_ep0_queue()
601 req->req.actual, req->req.length, in ast_udc_ep0_queue()
602 "dir_in", ep->dir_in); in ast_udc_ep0_queue()
604 req->req.actual += tx_len; in ast_udc_ep0_queue()
605 ast_udc_write(udc, EP0_TX_LEN(tx_len), AST_UDC_EP0_CTRL); in ast_udc_ep0_queue()
606 ast_udc_write(udc, EP0_TX_LEN(tx_len) | EP0_TX_BUFF_RDY, in ast_udc_ep0_queue()
611 SETUP_DBG(udc, "OUT: %s:%x, %s:%x, %s:(%d/%d), %s:%d\n", in ast_udc_ep0_queue()
612 "buf", (u32)req->req.buf, in ast_udc_ep0_queue()
613 "dma", req->req.dma + req->req.actual, in ast_udc_ep0_queue()
614 "len", req->req.actual, req->req.length, in ast_udc_ep0_queue()
615 "dir_in", ep->dir_in); in ast_udc_ep0_queue()
617 if (!req->req.length) { in ast_udc_ep0_queue()
619 ast_udc_write(udc, EP0_TX_BUFF_RDY, AST_UDC_EP0_CTRL); in ast_udc_ep0_queue()
620 ep->dir_in = 0x1; in ast_udc_ep0_queue()
622 ast_udc_write(udc, EP0_RX_BUFF_RDY, AST_UDC_EP0_CTRL); in ast_udc_ep0_queue()
631 struct ast_udc_dev *udc = ep->udc; in ast_udc_ep_queue() local
632 struct device *dev = &udc->pdev->dev; in ast_udc_ep_queue()
636 if (unlikely(!_req || !_req->complete || !_req->buf || !_ep)) { in ast_udc_ep_queue()
638 return -EINVAL; in ast_udc_ep_queue()
641 if (ep->stopped) { in ast_udc_ep_queue()
642 dev_warn(dev, "%s is already stopped !\n", _ep->name); in ast_udc_ep_queue()
643 return -ESHUTDOWN; in ast_udc_ep_queue()
646 spin_lock_irqsave(&udc->lock, flags); in ast_udc_ep_queue()
648 list_add_tail(&req->queue, &ep->queue); in ast_udc_ep_queue()
650 req->req.actual = 0; in ast_udc_ep_queue()
651 req->req.status = -EINPROGRESS; in ast_udc_ep_queue()
652 req->actual_dma_length = 0; in ast_udc_ep_queue()
654 rc = usb_gadget_map_request(&udc->gadget, &req->req, ep->dir_in); in ast_udc_ep_queue()
663 _req->length, _req->dma, _req->zero, ep->dir_in); in ast_udc_ep_queue()
666 if (ep->ep.desc == NULL) { in ast_udc_ep_queue()
667 if ((req->req.dma % 4) != 0) { in ast_udc_ep_queue()
669 rc = -ESHUTDOWN; in ast_udc_ep_queue()
678 if (list_is_singular(&ep->queue)) { in ast_udc_ep_queue()
679 if (ep->desc_mode) in ast_udc_ep_queue()
686 spin_unlock_irqrestore(&udc->lock, flags); in ast_udc_ep_queue()
694 struct ast_udc_dev *udc = ep->udc; in ast_udc_ep_dequeue() local
699 spin_lock_irqsave(&udc->lock, flags); in ast_udc_ep_dequeue()
702 list_for_each_entry(req, &ep->queue, queue) { in ast_udc_ep_dequeue()
703 if (&req->req == _req) { in ast_udc_ep_dequeue()
704 list_del_init(&req->queue); in ast_udc_ep_dequeue()
705 ast_udc_done(ep, req, -ESHUTDOWN); in ast_udc_ep_dequeue()
706 _req->status = -ECONNRESET; in ast_udc_ep_dequeue()
712 if (&req->req != _req) in ast_udc_ep_dequeue()
713 rc = -EINVAL; in ast_udc_ep_dequeue()
715 spin_unlock_irqrestore(&udc->lock, flags); in ast_udc_ep_dequeue()
723 struct ast_udc_dev *udc = ep->udc; in ast_udc_ep_set_halt() local
730 spin_lock_irqsave(&udc->lock, flags); in ast_udc_ep_set_halt()
732 epnum = usb_endpoint_num(ep->desc); in ast_udc_ep_set_halt()
736 ctrl = ast_udc_read(udc, AST_UDC_EP0_CTRL); in ast_udc_ep_set_halt()
742 ast_udc_write(udc, ctrl, AST_UDC_EP0_CTRL); in ast_udc_ep_set_halt()
746 ctrl = ast_udc_read(udc, AST_UDC_EP_CONFIG); in ast_udc_ep_set_halt()
755 ep->stopped = value ? 1 : 0; in ast_udc_ep_set_halt()
758 spin_unlock_irqrestore(&udc->lock, flags); in ast_udc_ep_set_halt()
774 static void ast_udc_ep0_rx(struct ast_udc_dev *udc) in ast_udc_ep0_rx() argument
776 ast_udc_write(udc, udc->ep0_buf_dma, AST_UDC_EP0_DATA_BUFF); in ast_udc_ep0_rx()
777 ast_udc_write(udc, EP0_RX_BUFF_RDY, AST_UDC_EP0_CTRL); in ast_udc_ep0_rx()
780 static void ast_udc_ep0_tx(struct ast_udc_dev *udc) in ast_udc_ep0_tx() argument
782 ast_udc_write(udc, udc->ep0_buf_dma, AST_UDC_EP0_DATA_BUFF); in ast_udc_ep0_tx()
783 ast_udc_write(udc, EP0_TX_BUFF_RDY, AST_UDC_EP0_CTRL); in ast_udc_ep0_tx()
786 static void ast_udc_ep0_out(struct ast_udc_dev *udc) in ast_udc_ep0_out() argument
788 struct device *dev = &udc->pdev->dev; in ast_udc_ep0_out()
789 struct ast_udc_ep *ep = &udc->ep[0]; in ast_udc_ep0_out()
793 if (list_empty(&ep->queue)) in ast_udc_ep0_out()
796 req = list_entry(ep->queue.next, struct ast_udc_request, queue); in ast_udc_ep0_out()
798 rx_len = EP0_GET_RX_LEN(ast_udc_read(udc, AST_UDC_EP0_CTRL)); in ast_udc_ep0_out()
799 req->req.actual += rx_len; in ast_udc_ep0_out()
801 SETUP_DBG(udc, "req %p (%d/%d)\n", req, in ast_udc_ep0_out()
802 req->req.actual, req->req.length); in ast_udc_ep0_out()
804 if ((rx_len < ep->ep.maxpacket) || in ast_udc_ep0_out()
805 (req->req.actual == req->req.length)) { in ast_udc_ep0_out()
806 ast_udc_ep0_tx(udc); in ast_udc_ep0_out()
807 if (!ep->dir_in) in ast_udc_ep0_out()
811 if (rx_len > req->req.length) { in ast_udc_ep0_out()
814 req->req.actual, req->req.length); in ast_udc_ep0_out()
815 ast_udc_ep0_tx(udc); in ast_udc_ep0_out()
820 ep->dir_in = 0; in ast_udc_ep0_out()
827 static void ast_udc_ep0_in(struct ast_udc_dev *udc) in ast_udc_ep0_in() argument
829 struct ast_udc_ep *ep = &udc->ep[0]; in ast_udc_ep0_in()
832 if (list_empty(&ep->queue)) { in ast_udc_ep0_in()
833 if (udc->is_control_tx) { in ast_udc_ep0_in()
834 ast_udc_ep0_rx(udc); in ast_udc_ep0_in()
835 udc->is_control_tx = 0; in ast_udc_ep0_in()
841 req = list_entry(ep->queue.next, struct ast_udc_request, queue); in ast_udc_ep0_in()
843 SETUP_DBG(udc, "req %p (%d/%d)\n", req, in ast_udc_ep0_in()
844 req->req.actual, req->req.length); in ast_udc_ep0_in()
846 if (req->req.length == req->req.actual) { in ast_udc_ep0_in()
847 if (req->req.length) in ast_udc_ep0_in()
848 ast_udc_ep0_rx(udc); in ast_udc_ep0_in()
850 if (ep->dir_in) in ast_udc_ep0_in()
859 static void ast_udc_epn_handle(struct ast_udc_dev *udc, u16 ep_num) in ast_udc_epn_handle() argument
861 struct ast_udc_ep *ep = &udc->ep[ep_num]; in ast_udc_epn_handle()
865 if (list_empty(&ep->queue)) in ast_udc_epn_handle()
868 req = list_first_entry(&ep->queue, struct ast_udc_request, queue); in ast_udc_epn_handle()
871 req->req.actual += len; in ast_udc_epn_handle()
874 req->req.actual, req->req.length, "len", len); in ast_udc_epn_handle()
877 if (req->req.length == req->req.actual) { in ast_udc_epn_handle()
879 req = list_first_entry_or_null(&ep->queue, in ast_udc_epn_handle()
885 if (len < ep->ep.maxpacket) { in ast_udc_epn_handle()
887 req = list_first_entry_or_null(&ep->queue, in ast_udc_epn_handle()
898 static void ast_udc_epn_handle_desc(struct ast_udc_dev *udc, u16 ep_num) in ast_udc_epn_handle_desc() argument
900 struct ast_udc_ep *ep = &udc->ep[ep_num]; in ast_udc_epn_handle_desc()
901 struct device *dev = &udc->pdev->dev; in ast_udc_epn_handle_desc()
908 if (list_empty(&ep->queue)) { in ast_udc_epn_handle_desc()
909 dev_warn(dev, "%s request queue empty!\n", ep->ep.name); in ast_udc_epn_handle_desc()
913 req = list_first_entry(&ep->queue, struct ast_udc_request, queue); in ast_udc_epn_handle_desc()
938 i = req->saved_dma_wptr; in ast_udc_epn_handle_desc()
941 len_in_desc = EP_DESC1_IN_LEN(ep->descs[i].des_1); in ast_udc_epn_handle_desc()
950 req->req.actual += total_len; in ast_udc_epn_handle_desc()
953 req->req.actual, req->req.length, "len", total_len); in ast_udc_epn_handle_desc()
956 if (req->req.length == req->req.actual) { in ast_udc_epn_handle_desc()
958 req = list_first_entry_or_null(&ep->queue, in ast_udc_epn_handle_desc()
964 if (total_len < ep->ep.maxpacket) { in ast_udc_epn_handle_desc()
966 req = list_first_entry_or_null(&ep->queue, in ast_udc_epn_handle_desc()
973 if (req && (req->actual_dma_length == req->req.actual)) { in ast_udc_epn_handle_desc()
979 static void ast_udc_ep0_data_tx(struct ast_udc_dev *udc, u8 *tx_data, u32 len) in ast_udc_ep0_data_tx() argument
982 memcpy(udc->ep0_buf, tx_data, len); in ast_udc_ep0_data_tx()
984 ast_udc_write(udc, udc->ep0_buf_dma, AST_UDC_EP0_DATA_BUFF); in ast_udc_ep0_data_tx()
985 ast_udc_write(udc, EP0_TX_LEN(len), AST_UDC_EP0_CTRL); in ast_udc_ep0_data_tx()
986 ast_udc_write(udc, EP0_TX_LEN(len) | EP0_TX_BUFF_RDY, in ast_udc_ep0_data_tx()
988 udc->is_control_tx = 1; in ast_udc_ep0_data_tx()
991 ast_udc_write(udc, EP0_TX_BUFF_RDY, AST_UDC_EP0_CTRL); in ast_udc_ep0_data_tx()
994 static void ast_udc_getstatus(struct ast_udc_dev *udc) in ast_udc_getstatus() argument
1001 memcpy_fromio(&crq, udc->creq, sizeof(crq)); in ast_udc_getstatus()
1012 status = udc->ep[epnum].stopped; in ast_udc_getstatus()
1018 ep = &udc->ep[epnum]; in ast_udc_getstatus()
1020 ast_udc_ep0_data_tx(udc, (u8 *)&status, sizeof(status)); in ast_udc_getstatus()
1026 ast_udc_write(udc, ast_udc_read(udc, AST_UDC_EP0_CTRL) | EP0_STALL, in ast_udc_getstatus()
1030 static void ast_udc_ep0_handle_setup(struct ast_udc_dev *udc) in ast_udc_ep0_handle_setup() argument
1032 struct ast_udc_ep *ep = &udc->ep[0]; in ast_udc_ep0_handle_setup()
1039 memcpy_fromio(&crq, udc->creq, sizeof(crq)); in ast_udc_ep0_handle_setup()
1041 SETUP_DBG(udc, "SETUP packet: %02x/%02x/%04x/%04x/%04x\n", in ast_udc_ep0_handle_setup()
1049 list_for_each_entry(req, &udc->ep[0].queue, queue) { in ast_udc_ep0_handle_setup()
1055 ast_udc_nuke(&udc->ep[0], -ETIMEDOUT); in ast_udc_ep0_handle_setup()
1057 udc->ep[0].dir_in = crq.bRequestType & USB_DIR_IN; in ast_udc_ep0_handle_setup()
1062 if (ast_udc_read(udc, AST_UDC_STS) & UDC_STS_HIGHSPEED) in ast_udc_ep0_handle_setup()
1063 udc->gadget.speed = USB_SPEED_HIGH; in ast_udc_ep0_handle_setup()
1065 udc->gadget.speed = USB_SPEED_FULL; in ast_udc_ep0_handle_setup()
1067 SETUP_DBG(udc, "set addr: 0x%x\n", crq.wValue); in ast_udc_ep0_handle_setup()
1068 reg = ast_udc_read(udc, AST_UDC_CONFIG); in ast_udc_ep0_handle_setup()
1071 ast_udc_write(udc, reg, AST_UDC_CONFIG); in ast_udc_ep0_handle_setup()
1075 SETUP_DBG(udc, "ep0: CLEAR FEATURE\n"); in ast_udc_ep0_handle_setup()
1079 SETUP_DBG(udc, "ep0: SET FEATURE\n"); in ast_udc_ep0_handle_setup()
1083 ast_udc_getstatus(udc); in ast_udc_ep0_handle_setup()
1093 if (udc->driver) { in ast_udc_ep0_handle_setup()
1094 SETUP_DBG(udc, "Forwarding %s to gadget...\n", in ast_udc_ep0_handle_setup()
1095 udc->gadget.name); in ast_udc_ep0_handle_setup()
1097 spin_unlock(&udc->lock); in ast_udc_ep0_handle_setup()
1098 rc = udc->driver->setup(&udc->gadget, &crq); in ast_udc_ep0_handle_setup()
1099 spin_lock(&udc->lock); in ast_udc_ep0_handle_setup()
1102 SETUP_DBG(udc, "No gadget for request !\n"); in ast_udc_ep0_handle_setup()
1109 SETUP_DBG(udc, "Stalling, rc:0x%x\n", rc); in ast_udc_ep0_handle_setup()
1110 ast_udc_write(udc, ast_udc_read(udc, AST_UDC_EP0_CTRL) | EP0_STALL, in ast_udc_ep0_handle_setup()
1115 SETUP_DBG(udc, "ep0: Sending IN status without data\n"); in ast_udc_ep0_handle_setup()
1116 ast_udc_write(udc, EP0_TX_BUFF_RDY, AST_UDC_EP0_CTRL); in ast_udc_ep0_handle_setup()
1121 struct ast_udc_dev *udc = (struct ast_udc_dev *)data; in ast_udc_isr() local
1126 spin_lock(&udc->lock); in ast_udc_isr()
1128 isr = ast_udc_read(udc, AST_UDC_ISR); in ast_udc_isr()
1133 ast_udc_write(udc, isr, AST_UDC_ISR); in ast_udc_isr()
1136 ISR_DBG(udc, "UDC_IRQ_BUS_RESET\n"); in ast_udc_isr()
1137 udc->gadget.speed = USB_SPEED_UNKNOWN; in ast_udc_isr()
1139 ep = &udc->ep[1]; in ast_udc_isr()
1143 if (udc->driver && udc->driver->reset) { in ast_udc_isr()
1144 spin_unlock(&udc->lock); in ast_udc_isr()
1145 udc->driver->reset(&udc->gadget); in ast_udc_isr()
1146 spin_lock(&udc->lock); in ast_udc_isr()
1151 ISR_DBG(udc, "UDC_IRQ_BUS_SUSPEND\n"); in ast_udc_isr()
1152 udc->suspended_from = udc->gadget.state; in ast_udc_isr()
1153 usb_gadget_set_state(&udc->gadget, USB_STATE_SUSPENDED); in ast_udc_isr()
1155 if (udc->driver && udc->driver->suspend) { in ast_udc_isr()
1156 spin_unlock(&udc->lock); in ast_udc_isr()
1157 udc->driver->suspend(&udc->gadget); in ast_udc_isr()
1158 spin_lock(&udc->lock); in ast_udc_isr()
1163 ISR_DBG(udc, "UDC_IRQ_BUS_RESUME\n"); in ast_udc_isr()
1164 usb_gadget_set_state(&udc->gadget, udc->suspended_from); in ast_udc_isr()
1166 if (udc->driver && udc->driver->resume) { in ast_udc_isr()
1167 spin_unlock(&udc->lock); in ast_udc_isr()
1168 udc->driver->resume(&udc->gadget); in ast_udc_isr()
1169 spin_lock(&udc->lock); in ast_udc_isr()
1174 ISR_DBG(udc, "UDC_IRQ_EP0_IN_ACK_STALL\n"); in ast_udc_isr()
1175 ast_udc_ep0_in(udc); in ast_udc_isr()
1179 ISR_DBG(udc, "UDC_IRQ_EP0_OUT_ACK_STALL\n"); in ast_udc_isr()
1180 ast_udc_ep0_out(udc); in ast_udc_isr()
1184 ISR_DBG(udc, "UDC_IRQ_EP0_SETUP\n"); in ast_udc_isr()
1185 ast_udc_ep0_handle_setup(udc); in ast_udc_isr()
1189 ISR_DBG(udc, "UDC_IRQ_EP_POOL_ACK_STALL\n"); in ast_udc_isr()
1190 ep_isr = ast_udc_read(udc, AST_UDC_EP_ACK_ISR); in ast_udc_isr()
1193 ast_udc_write(udc, ep_isr, AST_UDC_EP_ACK_ISR); in ast_udc_isr()
1196 for (i = 0; i < AST_UDC_NUM_ENDPOINTS - 1; i++) { in ast_udc_isr()
1198 ep = &udc->ep[i + 1]; in ast_udc_isr()
1199 if (ep->desc_mode) in ast_udc_isr()
1200 ast_udc_epn_handle_desc(udc, i + 1); in ast_udc_isr()
1202 ast_udc_epn_handle(udc, i + 1); in ast_udc_isr()
1208 spin_unlock(&udc->lock); in ast_udc_isr()
1214 struct ast_udc_dev *udc = to_ast_dev(gadget); in ast_udc_gadget_getframe() local
1216 return (ast_udc_read(udc, AST_UDC_STS) >> 16) & 0x7ff; in ast_udc_gadget_getframe()
1221 struct ast_udc_dev *udc = container_of(work, struct ast_udc_dev, in ast_udc_wake_work() local
1226 spin_lock_irqsave(&udc->lock, flags); in ast_udc_wake_work()
1228 UDC_DBG(udc, "Wakeup Host !\n"); in ast_udc_wake_work()
1229 ctrl = ast_udc_read(udc, AST_UDC_FUNC_CTRL); in ast_udc_wake_work()
1230 ast_udc_write(udc, ctrl | USB_REMOTE_WAKEUP_EN, AST_UDC_FUNC_CTRL); in ast_udc_wake_work()
1232 spin_unlock_irqrestore(&udc->lock, flags); in ast_udc_wake_work()
1235 static void ast_udc_wakeup_all(struct ast_udc_dev *udc) in ast_udc_wakeup_all() argument
1242 schedule_work(&udc->wake_work); in ast_udc_wakeup_all()
1247 struct ast_udc_dev *udc = to_ast_dev(gadget); in ast_udc_wakeup() local
1251 spin_lock_irqsave(&udc->lock, flags); in ast_udc_wakeup()
1253 if (!udc->wakeup_en) { in ast_udc_wakeup()
1254 UDC_DBG(udc, "Remote Wakeup is disabled\n"); in ast_udc_wakeup()
1255 rc = -EINVAL; in ast_udc_wakeup()
1259 UDC_DBG(udc, "Device initiated wakeup\n"); in ast_udc_wakeup()
1260 ast_udc_wakeup_all(udc); in ast_udc_wakeup()
1263 spin_unlock_irqrestore(&udc->lock, flags); in ast_udc_wakeup()
1272 struct ast_udc_dev *udc = to_ast_dev(gadget); in ast_udc_pullup() local
1276 spin_lock_irqsave(&udc->lock, flags); in ast_udc_pullup()
1278 UDC_DBG(udc, "is_on: %d\n", is_on); in ast_udc_pullup()
1280 ctrl = ast_udc_read(udc, AST_UDC_FUNC_CTRL) | USB_UPSTREAM_EN; in ast_udc_pullup()
1282 ctrl = ast_udc_read(udc, AST_UDC_FUNC_CTRL) & ~USB_UPSTREAM_EN; in ast_udc_pullup()
1284 ast_udc_write(udc, ctrl, AST_UDC_FUNC_CTRL); in ast_udc_pullup()
1286 spin_unlock_irqrestore(&udc->lock, flags); in ast_udc_pullup()
1294 struct ast_udc_dev *udc = to_ast_dev(gadget); in ast_udc_start() local
1299 spin_lock_irqsave(&udc->lock, flags); in ast_udc_start()
1301 UDC_DBG(udc, "\n"); in ast_udc_start()
1302 udc->driver = driver; in ast_udc_start()
1303 udc->gadget.dev.of_node = udc->pdev->dev.of_node; in ast_udc_start()
1306 ep = &udc->ep[i]; in ast_udc_start()
1307 ep->stopped = 0; in ast_udc_start()
1310 spin_unlock_irqrestore(&udc->lock, flags); in ast_udc_start()
1317 struct ast_udc_dev *udc = to_ast_dev(gadget); in ast_udc_stop() local
1321 spin_lock_irqsave(&udc->lock, flags); in ast_udc_stop()
1323 UDC_DBG(udc, "\n"); in ast_udc_stop()
1324 ctrl = ast_udc_read(udc, AST_UDC_FUNC_CTRL) & ~USB_UPSTREAM_EN; in ast_udc_stop()
1325 ast_udc_write(udc, ctrl, AST_UDC_FUNC_CTRL); in ast_udc_stop()
1327 udc->gadget.speed = USB_SPEED_UNKNOWN; in ast_udc_stop()
1328 udc->driver = NULL; in ast_udc_stop()
1330 ast_udc_stop_activity(udc); in ast_udc_stop()
1331 usb_gadget_set_state(&udc->gadget, USB_STATE_NOTATTACHED); in ast_udc_stop()
1333 spin_unlock_irqrestore(&udc->lock, flags); in ast_udc_stop()
1351 static void ast_udc_init_ep(struct ast_udc_dev *udc) in ast_udc_init_ep() argument
1357 ep = &udc->ep[i]; in ast_udc_init_ep()
1358 ep->ep.name = ast_ep_name[i]; in ast_udc_init_ep()
1360 ep->ep.caps.type_control = true; in ast_udc_init_ep()
1362 ep->ep.caps.type_iso = true; in ast_udc_init_ep()
1363 ep->ep.caps.type_bulk = true; in ast_udc_init_ep()
1364 ep->ep.caps.type_int = true; in ast_udc_init_ep()
1366 ep->ep.caps.dir_in = true; in ast_udc_init_ep()
1367 ep->ep.caps.dir_out = true; in ast_udc_init_ep()
1369 ep->ep.ops = &ast_udc_ep_ops; in ast_udc_init_ep()
1370 ep->udc = udc; in ast_udc_init_ep()
1372 INIT_LIST_HEAD(&ep->queue); in ast_udc_init_ep()
1375 usb_ep_set_maxpacket_limit(&ep->ep, in ast_udc_init_ep()
1380 ep->ep_reg = udc->reg + AST_UDC_EP_BASE + in ast_udc_init_ep()
1381 (AST_UDC_EP_OFFSET * (i - 1)); in ast_udc_init_ep()
1383 ep->epn_buf = udc->ep0_buf + (i * AST_UDC_EP_DMA_SIZE); in ast_udc_init_ep()
1384 ep->epn_buf_dma = udc->ep0_buf_dma + (i * AST_UDC_EP_DMA_SIZE); in ast_udc_init_ep()
1385 usb_ep_set_maxpacket_limit(&ep->ep, AST_UDC_EPn_MAX_PACKET); in ast_udc_init_ep()
1387 ep->descs = ep->epn_buf + AST_UDC_EPn_MAX_PACKET; in ast_udc_init_ep()
1388 ep->descs_dma = ep->epn_buf_dma + AST_UDC_EPn_MAX_PACKET; in ast_udc_init_ep()
1389 ep->descs_wptr = 0; in ast_udc_init_ep()
1391 list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list); in ast_udc_init_ep()
1395 static void ast_udc_init_dev(struct ast_udc_dev *udc) in ast_udc_init_dev() argument
1397 INIT_WORK(&udc->wake_work, ast_udc_wake_work); in ast_udc_init_dev()
1400 static void ast_udc_init_hw(struct ast_udc_dev *udc) in ast_udc_init_hw() argument
1406 ast_udc_write(udc, ctrl, AST_UDC_FUNC_CTRL); in ast_udc_init_hw()
1409 ast_udc_write(udc, 0, AST_UDC_DEV_RESET); in ast_udc_init_hw()
1414 ast_udc_write(udc, ctrl, AST_UDC_FUNC_CTRL); in ast_udc_init_hw()
1418 ast_udc_write(udc, 0, AST_UDC_IER); in ast_udc_init_hw()
1419 ast_udc_write(udc, UDC_IRQ_ACK_ALL, AST_UDC_ISR); in ast_udc_init_hw()
1426 ast_udc_write(udc, ctrl, AST_UDC_IER); in ast_udc_init_hw()
1429 ast_udc_write(udc, UDC_IRQ_EP_ACK_ALL, AST_UDC_EP_ACK_IER); in ast_udc_init_hw()
1430 ast_udc_write(udc, UDC_IRQ_EP_ACK_ALL, AST_UDC_EP_ACK_ISR); in ast_udc_init_hw()
1432 ast_udc_write(udc, 0, AST_UDC_EP0_CTRL); in ast_udc_init_hw()
1437 struct ast_udc_dev *udc = platform_get_drvdata(pdev); in ast_udc_remove() local
1441 usb_del_gadget_udc(&udc->gadget); in ast_udc_remove()
1442 if (udc->driver) { in ast_udc_remove()
1449 dev_alert(&pdev->dev, in ast_udc_remove()
1454 spin_lock_irqsave(&udc->lock, flags); in ast_udc_remove()
1457 ctrl = ast_udc_read(udc, AST_UDC_FUNC_CTRL) & ~USB_UPSTREAM_EN; in ast_udc_remove()
1458 ast_udc_write(udc, ctrl, AST_UDC_FUNC_CTRL); in ast_udc_remove()
1460 clk_disable_unprepare(udc->clk); in ast_udc_remove()
1462 spin_unlock_irqrestore(&udc->lock, flags); in ast_udc_remove()
1464 if (udc->ep0_buf) in ast_udc_remove()
1465 dma_free_coherent(&pdev->dev, in ast_udc_remove()
1467 udc->ep0_buf, in ast_udc_remove()
1468 udc->ep0_buf_dma); in ast_udc_remove()
1470 udc->ep0_buf = NULL; in ast_udc_remove()
1476 struct device *dev = &pdev->dev; in ast_udc_probe()
1477 struct ast_udc_dev *udc; in ast_udc_probe() local
1480 udc = devm_kzalloc(&pdev->dev, sizeof(struct ast_udc_dev), GFP_KERNEL); in ast_udc_probe()
1481 if (!udc) in ast_udc_probe()
1482 return -ENOMEM; in ast_udc_probe()
1484 udc->gadget.dev.parent = dev; in ast_udc_probe()
1485 udc->pdev = pdev; in ast_udc_probe()
1486 spin_lock_init(&udc->lock); in ast_udc_probe()
1488 udc->gadget.ops = &ast_udc_ops; in ast_udc_probe()
1489 udc->gadget.ep0 = &udc->ep[0].ep; in ast_udc_probe()
1490 udc->gadget.name = "aspeed-udc"; in ast_udc_probe()
1491 udc->gadget.dev.init_name = "gadget"; in ast_udc_probe()
1493 udc->reg = devm_platform_ioremap_resource(pdev, 0); in ast_udc_probe()
1494 if (IS_ERR(udc->reg)) { in ast_udc_probe()
1495 dev_err(&pdev->dev, "Failed to map resources\n"); in ast_udc_probe()
1496 return PTR_ERR(udc->reg); in ast_udc_probe()
1499 platform_set_drvdata(pdev, udc); in ast_udc_probe()
1501 udc->clk = devm_clk_get(&pdev->dev, NULL); in ast_udc_probe()
1502 if (IS_ERR(udc->clk)) { in ast_udc_probe()
1503 rc = PTR_ERR(udc->clk); in ast_udc_probe()
1506 rc = clk_prepare_enable(udc->clk); in ast_udc_probe()
1508 dev_err(&pdev->dev, "Failed to enable clock (0x%x)\n", rc); in ast_udc_probe()
1513 max_speed = usb_get_maximum_speed(&pdev->dev); in ast_udc_probe()
1515 udc->force_usb1 = true; in ast_udc_probe()
1520 udc->ep0_buf = dma_alloc_coherent(&pdev->dev, in ast_udc_probe()
1523 &udc->ep0_buf_dma, GFP_KERNEL); in ast_udc_probe()
1525 udc->gadget.speed = USB_SPEED_UNKNOWN; in ast_udc_probe()
1526 udc->gadget.max_speed = USB_SPEED_HIGH; in ast_udc_probe()
1527 udc->creq = udc->reg + AST_UDC_SETUP0; in ast_udc_probe()
1533 udc->desc_mode = AST_UDC_DESC_MODE; in ast_udc_probe()
1535 dev_info(&pdev->dev, "DMA %s\n", udc->desc_mode ? in ast_udc_probe()
1538 INIT_LIST_HEAD(&udc->gadget.ep_list); in ast_udc_probe()
1539 INIT_LIST_HEAD(&udc->gadget.ep0->ep_list); in ast_udc_probe()
1541 /* Initialized udc ep */ in ast_udc_probe()
1542 ast_udc_init_ep(udc); in ast_udc_probe()
1544 /* Initialized udc device */ in ast_udc_probe()
1545 ast_udc_init_dev(udc); in ast_udc_probe()
1547 /* Initialized udc hardware */ in ast_udc_probe()
1548 ast_udc_init_hw(udc); in ast_udc_probe()
1551 udc->irq = platform_get_irq(pdev, 0); in ast_udc_probe()
1552 if (udc->irq < 0) { in ast_udc_probe()
1553 rc = udc->irq; in ast_udc_probe()
1557 rc = devm_request_irq(&pdev->dev, udc->irq, ast_udc_isr, 0, in ast_udc_probe()
1558 KBUILD_MODNAME, udc); in ast_udc_probe()
1560 dev_err(&pdev->dev, "Failed to request interrupt\n"); in ast_udc_probe()
1564 rc = usb_add_gadget_udc(&pdev->dev, &udc->gadget); in ast_udc_probe()
1566 dev_err(&pdev->dev, "Failed to add gadget udc\n"); in ast_udc_probe()
1570 dev_info(&pdev->dev, "Initialized udc in USB%s mode\n", in ast_udc_probe()
1571 udc->force_usb1 ? "1" : "2"); in ast_udc_probe()
1576 dev_err(&pdev->dev, "Failed to udc probe, rc:0x%x\n", rc); in ast_udc_probe()
1583 { .compatible = "aspeed,ast2600-udc", },
1600 MODULE_DESCRIPTION("ASPEED UDC driver");