aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/m66592-udc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/m66592-udc.c')
-rw-r--r--drivers/usb/gadget/m66592-udc.c62
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
692static void disable_controller(struct m66592 *m66592) 692static 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
1049static void set_feature(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) 1050static 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/*-------------------------------------------------------------------------*/
1455static struct m66592 *the_controller; 1476static struct m66592 *the_controller;
1456 1477
1457int usb_gadget_probe_driver(struct usb_gadget_driver *driver, 1478static 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}
1509EXPORT_SYMBOL(usb_gadget_probe_driver);
1510 1530
1511int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) 1531static 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}
1536EXPORT_SYMBOL(usb_gadget_unregister_driver);
1537 1556
1538/*-------------------------------------------------------------------------*/ 1557/*-------------------------------------------------------------------------*/
1539static int m66592_get_frame(struct usb_gadget *_gadget) 1558static 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
1564static 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
1545static struct usb_gadget_ops m66592_gadget_ops = { 1579static 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
1549static int __exit m66592_remove(struct platform_device *pdev) 1586static 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
1740err_add_udc:
1741 m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req);
1742
1697clean_up3: 1743clean_up3:
1698#ifdef CONFIG_HAVE_CLK 1744#ifdef CONFIG_HAVE_CLK
1699 if (m66592->pdata->on_chip) { 1745 if (m66592->pdata->on_chip) {