diff options
Diffstat (limited to 'drivers/usb/gadget/r8a66597-udc.c')
-rw-r--r-- | drivers/usb/gadget/r8a66597-udc.c | 71 |
1 files changed, 58 insertions, 13 deletions
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index 6dcc1f68fa60..50991e5bd5e8 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2006-2009 Renesas Solutions Corp. | 4 | * Copyright (C) 2006-2009 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 |
@@ -576,7 +576,11 @@ static void init_controller(struct r8a66597 *r8a66597) | |||
576 | u16 endian = r8a66597->pdata->endian ? BIGEND : 0; | 576 | u16 endian = r8a66597->pdata->endian ? BIGEND : 0; |
577 | 577 | ||
578 | if (r8a66597->pdata->on_chip) { | 578 | if (r8a66597->pdata->on_chip) { |
579 | r8a66597_bset(r8a66597, 0x04, SYSCFG1); | 579 | if (r8a66597->pdata->buswait) |
580 | r8a66597_write(r8a66597, r8a66597->pdata->buswait, | ||
581 | SYSCFG1); | ||
582 | else | ||
583 | r8a66597_write(r8a66597, 0x0f, SYSCFG1); | ||
580 | r8a66597_bset(r8a66597, HSE, SYSCFG0); | 584 | r8a66597_bset(r8a66597, HSE, SYSCFG0); |
581 | 585 | ||
582 | r8a66597_bclr(r8a66597, USBE, SYSCFG0); | 586 | r8a66597_bclr(r8a66597, USBE, SYSCFG0); |
@@ -618,6 +622,7 @@ static void disable_controller(struct r8a66597 *r8a66597) | |||
618 | { | 622 | { |
619 | if (r8a66597->pdata->on_chip) { | 623 | if (r8a66597->pdata->on_chip) { |
620 | r8a66597_bset(r8a66597, SCKE, SYSCFG0); | 624 | r8a66597_bset(r8a66597, SCKE, SYSCFG0); |
625 | r8a66597_bclr(r8a66597, UTST, TESTMODE); | ||
621 | 626 | ||
622 | /* disable interrupts */ | 627 | /* disable interrupts */ |
623 | r8a66597_write(r8a66597, 0, INTENB0); | 628 | r8a66597_write(r8a66597, 0, INTENB0); |
@@ -635,6 +640,7 @@ static void disable_controller(struct r8a66597 *r8a66597) | |||
635 | r8a66597_bclr(r8a66597, SCKE, SYSCFG0); | 640 | r8a66597_bclr(r8a66597, SCKE, SYSCFG0); |
636 | 641 | ||
637 | } else { | 642 | } else { |
643 | r8a66597_bclr(r8a66597, UTST, TESTMODE); | ||
638 | r8a66597_bclr(r8a66597, SCKE, SYSCFG0); | 644 | r8a66597_bclr(r8a66597, SCKE, SYSCFG0); |
639 | udelay(1); | 645 | udelay(1); |
640 | r8a66597_bclr(r8a66597, PLLC, SYSCFG0); | 646 | r8a66597_bclr(r8a66597, PLLC, SYSCFG0); |
@@ -999,10 +1005,29 @@ static void clear_feature(struct r8a66597 *r8a66597, | |||
999 | 1005 | ||
1000 | static void set_feature(struct r8a66597 *r8a66597, struct usb_ctrlrequest *ctrl) | 1006 | static void set_feature(struct r8a66597 *r8a66597, struct usb_ctrlrequest *ctrl) |
1001 | { | 1007 | { |
1008 | u16 tmp; | ||
1009 | int timeout = 3000; | ||
1002 | 1010 | ||
1003 | switch (ctrl->bRequestType & USB_RECIP_MASK) { | 1011 | switch (ctrl->bRequestType & USB_RECIP_MASK) { |
1004 | case USB_RECIP_DEVICE: | 1012 | case USB_RECIP_DEVICE: |
1005 | control_end(r8a66597, 1); | 1013 | switch (le16_to_cpu(ctrl->wValue)) { |
1014 | case USB_DEVICE_TEST_MODE: | ||
1015 | control_end(r8a66597, 1); | ||
1016 | /* Wait for the completion of status stage */ | ||
1017 | do { | ||
1018 | tmp = r8a66597_read(r8a66597, INTSTS0) & CTSQ; | ||
1019 | udelay(1); | ||
1020 | } while (tmp != CS_IDST || timeout-- > 0); | ||
1021 | |||
1022 | if (tmp == CS_IDST) | ||
1023 | r8a66597_bset(r8a66597, | ||
1024 | le16_to_cpu(ctrl->wIndex >> 8), | ||
1025 | TESTMODE); | ||
1026 | break; | ||
1027 | default: | ||
1028 | pipe_stall(r8a66597, 0); | ||
1029 | break; | ||
1030 | } | ||
1006 | break; | 1031 | break; |
1007 | case USB_RECIP_INTERFACE: | 1032 | case USB_RECIP_INTERFACE: |
1008 | control_end(r8a66597, 1); | 1033 | control_end(r8a66597, 1); |
@@ -1410,7 +1435,7 @@ static struct usb_ep_ops r8a66597_ep_ops = { | |||
1410 | /*-------------------------------------------------------------------------*/ | 1435 | /*-------------------------------------------------------------------------*/ |
1411 | static struct r8a66597 *the_controller; | 1436 | static struct r8a66597 *the_controller; |
1412 | 1437 | ||
1413 | int usb_gadget_probe_driver(struct usb_gadget_driver *driver, | 1438 | static int r8a66597_start(struct usb_gadget_driver *driver, |
1414 | int (*bind)(struct usb_gadget *)) | 1439 | int (*bind)(struct usb_gadget *)) |
1415 | { | 1440 | { |
1416 | struct r8a66597 *r8a66597 = the_controller; | 1441 | struct r8a66597 *r8a66597 = the_controller; |
@@ -1444,6 +1469,7 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, | |||
1444 | goto error; | 1469 | goto error; |
1445 | } | 1470 | } |
1446 | 1471 | ||
1472 | init_controller(r8a66597); | ||
1447 | r8a66597_bset(r8a66597, VBSE, INTENB0); | 1473 | r8a66597_bset(r8a66597, VBSE, INTENB0); |
1448 | if (r8a66597_read(r8a66597, INTSTS0) & VBSTS) { | 1474 | if (r8a66597_read(r8a66597, INTSTS0) & VBSTS) { |
1449 | r8a66597_start_xclock(r8a66597); | 1475 | r8a66597_start_xclock(r8a66597); |
@@ -1462,9 +1488,8 @@ error: | |||
1462 | 1488 | ||
1463 | return retval; | 1489 | return retval; |
1464 | } | 1490 | } |
1465 | EXPORT_SYMBOL(usb_gadget_probe_driver); | ||
1466 | 1491 | ||
1467 | int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | 1492 | static int r8a66597_stop(struct usb_gadget_driver *driver) |
1468 | { | 1493 | { |
1469 | struct r8a66597 *r8a66597 = the_controller; | 1494 | struct r8a66597 *r8a66597 = the_controller; |
1470 | unsigned long flags; | 1495 | unsigned long flags; |
@@ -1475,20 +1500,16 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
1475 | spin_lock_irqsave(&r8a66597->lock, flags); | 1500 | spin_lock_irqsave(&r8a66597->lock, flags); |
1476 | if (r8a66597->gadget.speed != USB_SPEED_UNKNOWN) | 1501 | if (r8a66597->gadget.speed != USB_SPEED_UNKNOWN) |
1477 | r8a66597_usb_disconnect(r8a66597); | 1502 | r8a66597_usb_disconnect(r8a66597); |
1478 | spin_unlock_irqrestore(&r8a66597->lock, flags); | ||
1479 | |||
1480 | r8a66597_bclr(r8a66597, VBSE, INTENB0); | 1503 | r8a66597_bclr(r8a66597, VBSE, INTENB0); |
1504 | disable_controller(r8a66597); | ||
1505 | spin_unlock_irqrestore(&r8a66597->lock, flags); | ||
1481 | 1506 | ||
1482 | driver->unbind(&r8a66597->gadget); | 1507 | driver->unbind(&r8a66597->gadget); |
1483 | 1508 | ||
1484 | init_controller(r8a66597); | ||
1485 | disable_controller(r8a66597); | ||
1486 | |||
1487 | device_del(&r8a66597->gadget.dev); | 1509 | device_del(&r8a66597->gadget.dev); |
1488 | r8a66597->driver = NULL; | 1510 | r8a66597->driver = NULL; |
1489 | return 0; | 1511 | return 0; |
1490 | } | 1512 | } |
1491 | EXPORT_SYMBOL(usb_gadget_unregister_driver); | ||
1492 | 1513 | ||
1493 | /*-------------------------------------------------------------------------*/ | 1514 | /*-------------------------------------------------------------------------*/ |
1494 | static int r8a66597_get_frame(struct usb_gadget *_gadget) | 1515 | static int r8a66597_get_frame(struct usb_gadget *_gadget) |
@@ -1497,14 +1518,33 @@ static int r8a66597_get_frame(struct usb_gadget *_gadget) | |||
1497 | return r8a66597_read(r8a66597, FRMNUM) & 0x03FF; | 1518 | return r8a66597_read(r8a66597, FRMNUM) & 0x03FF; |
1498 | } | 1519 | } |
1499 | 1520 | ||
1521 | static int r8a66597_pullup(struct usb_gadget *gadget, int is_on) | ||
1522 | { | ||
1523 | struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget); | ||
1524 | unsigned long flags; | ||
1525 | |||
1526 | spin_lock_irqsave(&r8a66597->lock, flags); | ||
1527 | if (is_on) | ||
1528 | r8a66597_bset(r8a66597, DPRPU, SYSCFG0); | ||
1529 | else | ||
1530 | r8a66597_bclr(r8a66597, DPRPU, SYSCFG0); | ||
1531 | spin_unlock_irqrestore(&r8a66597->lock, flags); | ||
1532 | |||
1533 | return 0; | ||
1534 | } | ||
1535 | |||
1500 | static struct usb_gadget_ops r8a66597_gadget_ops = { | 1536 | static struct usb_gadget_ops r8a66597_gadget_ops = { |
1501 | .get_frame = r8a66597_get_frame, | 1537 | .get_frame = r8a66597_get_frame, |
1538 | .start = r8a66597_start, | ||
1539 | .stop = r8a66597_stop, | ||
1540 | .pullup = r8a66597_pullup, | ||
1502 | }; | 1541 | }; |
1503 | 1542 | ||
1504 | static int __exit r8a66597_remove(struct platform_device *pdev) | 1543 | static int __exit r8a66597_remove(struct platform_device *pdev) |
1505 | { | 1544 | { |
1506 | struct r8a66597 *r8a66597 = dev_get_drvdata(&pdev->dev); | 1545 | struct r8a66597 *r8a66597 = dev_get_drvdata(&pdev->dev); |
1507 | 1546 | ||
1547 | usb_del_gadget_udc(&r8a66597->gadget); | ||
1508 | del_timer_sync(&r8a66597->timer); | 1548 | del_timer_sync(&r8a66597->timer); |
1509 | iounmap(r8a66597->reg); | 1549 | iounmap(r8a66597->reg); |
1510 | free_irq(platform_get_irq(pdev, 0), r8a66597); | 1550 | free_irq(platform_get_irq(pdev, 0), r8a66597); |
@@ -1645,11 +1685,15 @@ static int __init r8a66597_probe(struct platform_device *pdev) | |||
1645 | goto clean_up3; | 1685 | goto clean_up3; |
1646 | r8a66597->ep0_req->complete = nop_completion; | 1686 | r8a66597->ep0_req->complete = nop_completion; |
1647 | 1687 | ||
1648 | init_controller(r8a66597); | 1688 | ret = usb_add_gadget_udc(&pdev->dev, &r8a66597->gadget); |
1689 | if (ret) | ||
1690 | goto err_add_udc; | ||
1649 | 1691 | ||
1650 | dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION); | 1692 | dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION); |
1651 | return 0; | 1693 | return 0; |
1652 | 1694 | ||
1695 | err_add_udc: | ||
1696 | r8a66597_free_request(&r8a66597->ep[0].ep, r8a66597->ep0_req); | ||
1653 | clean_up3: | 1697 | clean_up3: |
1654 | free_irq(irq, r8a66597); | 1698 | free_irq(irq, r8a66597); |
1655 | clean_up2: | 1699 | clean_up2: |
@@ -1679,6 +1723,7 @@ static struct platform_driver r8a66597_driver = { | |||
1679 | .name = (char *) udc_name, | 1723 | .name = (char *) udc_name, |
1680 | }, | 1724 | }, |
1681 | }; | 1725 | }; |
1726 | MODULE_ALIAS("platform:r8a66597_udc"); | ||
1682 | 1727 | ||
1683 | static int __init r8a66597_udc_init(void) | 1728 | static int __init r8a66597_udc_init(void) |
1684 | { | 1729 | { |