diff options
Diffstat (limited to 'drivers/usb/gadget/m66592-udc.c')
-rw-r--r-- | drivers/usb/gadget/m66592-udc.c | 62 |
1 files changed, 54 insertions, 8 deletions
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index 084aa080a2d5..491f825ed5c9 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2006-2007 Renesas Solutions Corp. | 4 | * Copyright (C) 2006-2007 Renesas Solutions Corp. |
5 | * | 5 | * |
6 | * Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> | 6 | * Author : Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
@@ -691,6 +691,7 @@ static void init_controller(struct m66592 *m66592) | |||
691 | 691 | ||
692 | static void disable_controller(struct m66592 *m66592) | 692 | static void disable_controller(struct m66592 *m66592) |
693 | { | 693 | { |
694 | m66592_bclr(m66592, M66592_UTST, M66592_TESTMODE); | ||
694 | if (!m66592->pdata->on_chip) { | 695 | if (!m66592->pdata->on_chip) { |
695 | m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG); | 696 | m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG); |
696 | udelay(1); | 697 | udelay(1); |
@@ -780,7 +781,7 @@ static void irq_ep0_write(struct m66592_ep *ep, struct m66592_request *req) | |||
780 | /* write fifo */ | 781 | /* write fifo */ |
781 | if (req->req.buf) { | 782 | if (req->req.buf) { |
782 | if (size > 0) | 783 | if (size > 0) |
783 | m66592_write_fifo(m66592, ep->fifoaddr, buf, size); | 784 | m66592_write_fifo(m66592, ep, buf, size); |
784 | if ((size == 0) || ((size % ep->ep.maxpacket) != 0)) | 785 | if ((size == 0) || ((size % ep->ep.maxpacket) != 0)) |
785 | m66592_bset(m66592, M66592_BVAL, ep->fifoctr); | 786 | m66592_bset(m66592, M66592_BVAL, ep->fifoctr); |
786 | } | 787 | } |
@@ -826,7 +827,7 @@ static void irq_packet_write(struct m66592_ep *ep, struct m66592_request *req) | |||
826 | 827 | ||
827 | /* write fifo */ | 828 | /* write fifo */ |
828 | if (req->req.buf) { | 829 | if (req->req.buf) { |
829 | m66592_write_fifo(m66592, ep->fifoaddr, buf, size); | 830 | m66592_write_fifo(m66592, ep, buf, size); |
830 | if ((size == 0) | 831 | if ((size == 0) |
831 | || ((size % ep->ep.maxpacket) != 0) | 832 | || ((size % ep->ep.maxpacket) != 0) |
832 | || ((bufsize != ep->ep.maxpacket) | 833 | || ((bufsize != ep->ep.maxpacket) |
@@ -1048,10 +1049,30 @@ static void clear_feature(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) | |||
1048 | 1049 | ||
1049 | static void set_feature(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) | 1050 | static void set_feature(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) |
1050 | { | 1051 | { |
1052 | u16 tmp; | ||
1053 | int timeout = 3000; | ||
1051 | 1054 | ||
1052 | switch (ctrl->bRequestType & USB_RECIP_MASK) { | 1055 | switch (ctrl->bRequestType & USB_RECIP_MASK) { |
1053 | case USB_RECIP_DEVICE: | 1056 | case USB_RECIP_DEVICE: |
1054 | control_end(m66592, 1); | 1057 | switch (le16_to_cpu(ctrl->wValue)) { |
1058 | case USB_DEVICE_TEST_MODE: | ||
1059 | control_end(m66592, 1); | ||
1060 | /* Wait for the completion of status stage */ | ||
1061 | do { | ||
1062 | tmp = m66592_read(m66592, M66592_INTSTS0) & | ||
1063 | M66592_CTSQ; | ||
1064 | udelay(1); | ||
1065 | } while (tmp != M66592_CS_IDST || timeout-- > 0); | ||
1066 | |||
1067 | if (tmp == M66592_CS_IDST) | ||
1068 | m66592_bset(m66592, | ||
1069 | le16_to_cpu(ctrl->wIndex >> 8), | ||
1070 | M66592_TESTMODE); | ||
1071 | break; | ||
1072 | default: | ||
1073 | pipe_stall(m66592, 0); | ||
1074 | break; | ||
1075 | } | ||
1055 | break; | 1076 | break; |
1056 | case USB_RECIP_INTERFACE: | 1077 | case USB_RECIP_INTERFACE: |
1057 | control_end(m66592, 1); | 1078 | control_end(m66592, 1); |
@@ -1454,7 +1475,7 @@ static struct usb_ep_ops m66592_ep_ops = { | |||
1454 | /*-------------------------------------------------------------------------*/ | 1475 | /*-------------------------------------------------------------------------*/ |
1455 | static struct m66592 *the_controller; | 1476 | static struct m66592 *the_controller; |
1456 | 1477 | ||
1457 | int usb_gadget_probe_driver(struct usb_gadget_driver *driver, | 1478 | static int m66592_start(struct usb_gadget_driver *driver, |
1458 | int (*bind)(struct usb_gadget *)) | 1479 | int (*bind)(struct usb_gadget *)) |
1459 | { | 1480 | { |
1460 | struct m66592 *m66592 = the_controller; | 1481 | struct m66592 *m66592 = the_controller; |
@@ -1506,9 +1527,8 @@ error: | |||
1506 | 1527 | ||
1507 | return retval; | 1528 | return retval; |
1508 | } | 1529 | } |
1509 | EXPORT_SYMBOL(usb_gadget_probe_driver); | ||
1510 | 1530 | ||
1511 | int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | 1531 | static int m66592_stop(struct usb_gadget_driver *driver) |
1512 | { | 1532 | { |
1513 | struct m66592 *m66592 = the_controller; | 1533 | struct m66592 *m66592 = the_controller; |
1514 | unsigned long flags; | 1534 | unsigned long flags; |
@@ -1533,7 +1553,6 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
1533 | m66592->driver = NULL; | 1553 | m66592->driver = NULL; |
1534 | return 0; | 1554 | return 0; |
1535 | } | 1555 | } |
1536 | EXPORT_SYMBOL(usb_gadget_unregister_driver); | ||
1537 | 1556 | ||
1538 | /*-------------------------------------------------------------------------*/ | 1557 | /*-------------------------------------------------------------------------*/ |
1539 | static int m66592_get_frame(struct usb_gadget *_gadget) | 1558 | static int m66592_get_frame(struct usb_gadget *_gadget) |
@@ -1542,14 +1561,34 @@ static int m66592_get_frame(struct usb_gadget *_gadget) | |||
1542 | return m66592_read(m66592, M66592_FRMNUM) & 0x03FF; | 1561 | return m66592_read(m66592, M66592_FRMNUM) & 0x03FF; |
1543 | } | 1562 | } |
1544 | 1563 | ||
1564 | static int m66592_pullup(struct usb_gadget *gadget, int is_on) | ||
1565 | { | ||
1566 | struct m66592 *m66592 = gadget_to_m66592(gadget); | ||
1567 | unsigned long flags; | ||
1568 | |||
1569 | spin_lock_irqsave(&m66592->lock, flags); | ||
1570 | if (is_on) | ||
1571 | m66592_bset(m66592, M66592_DPRPU, M66592_SYSCFG); | ||
1572 | else | ||
1573 | m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG); | ||
1574 | spin_unlock_irqrestore(&m66592->lock, flags); | ||
1575 | |||
1576 | return 0; | ||
1577 | } | ||
1578 | |||
1545 | static struct usb_gadget_ops m66592_gadget_ops = { | 1579 | static struct usb_gadget_ops m66592_gadget_ops = { |
1546 | .get_frame = m66592_get_frame, | 1580 | .get_frame = m66592_get_frame, |
1581 | .start = m66592_start, | ||
1582 | .stop = m66592_stop, | ||
1583 | .pullup = m66592_pullup, | ||
1547 | }; | 1584 | }; |
1548 | 1585 | ||
1549 | static int __exit m66592_remove(struct platform_device *pdev) | 1586 | static int __exit m66592_remove(struct platform_device *pdev) |
1550 | { | 1587 | { |
1551 | struct m66592 *m66592 = dev_get_drvdata(&pdev->dev); | 1588 | struct m66592 *m66592 = dev_get_drvdata(&pdev->dev); |
1552 | 1589 | ||
1590 | usb_del_gadget_udc(&m66592->gadget); | ||
1591 | |||
1553 | del_timer_sync(&m66592->timer); | 1592 | del_timer_sync(&m66592->timer); |
1554 | iounmap(m66592->reg); | 1593 | iounmap(m66592->reg); |
1555 | free_irq(platform_get_irq(pdev, 0), m66592); | 1594 | free_irq(platform_get_irq(pdev, 0), m66592); |
@@ -1691,9 +1730,16 @@ static int __init m66592_probe(struct platform_device *pdev) | |||
1691 | 1730 | ||
1692 | init_controller(m66592); | 1731 | init_controller(m66592); |
1693 | 1732 | ||
1733 | ret = usb_add_gadget_udc(&pdev->dev, &m66592->gadget); | ||
1734 | if (ret) | ||
1735 | goto err_add_udc; | ||
1736 | |||
1694 | dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION); | 1737 | dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION); |
1695 | return 0; | 1738 | return 0; |
1696 | 1739 | ||
1740 | err_add_udc: | ||
1741 | m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req); | ||
1742 | |||
1697 | clean_up3: | 1743 | clean_up3: |
1698 | #ifdef CONFIG_HAVE_CLK | 1744 | #ifdef CONFIG_HAVE_CLK |
1699 | if (m66592->pdata->on_chip) { | 1745 | if (m66592->pdata->on_chip) { |