diff options
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r-- | drivers/usb/gadget/at91_udc.c | 42 | ||||
-rw-r--r-- | drivers/usb/gadget/at91_udc.h | 6 |
2 files changed, 42 insertions, 6 deletions
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index b53b93700ca8..c8954a6ddf8c 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c | |||
@@ -51,6 +51,8 @@ | |||
51 | 51 | ||
52 | #include <asm/arch/gpio.h> | 52 | #include <asm/arch/gpio.h> |
53 | #include <asm/arch/board.h> | 53 | #include <asm/arch/board.h> |
54 | #include <asm/arch/cpu.h> | ||
55 | #include <asm/arch/at91sam9261_matrix.h> | ||
54 | 56 | ||
55 | #include "at91_udc.h" | 57 | #include "at91_udc.h" |
56 | 58 | ||
@@ -909,11 +911,37 @@ static void pullup(struct at91_udc *udc, int is_on) | |||
909 | if (is_on) { | 911 | if (is_on) { |
910 | clk_on(udc); | 912 | clk_on(udc); |
911 | at91_udp_write(udc, AT91_UDP_TXVC, 0); | 913 | at91_udp_write(udc, AT91_UDP_TXVC, 0); |
912 | at91_set_gpio_value(udc->board.pullup_pin, 1); | 914 | if (cpu_is_at91rm9200()) |
915 | at91_set_gpio_value(udc->board.pullup_pin, 1); | ||
916 | else if (cpu_is_at91sam9260()) { | ||
917 | u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC); | ||
918 | |||
919 | txvc |= AT91_UDP_TXVC_PUON; | ||
920 | at91_udp_write(udc, AT91_UDP_TXVC, txvc); | ||
921 | } else if (cpu_is_at91sam9261()) { | ||
922 | u32 usbpucr; | ||
923 | |||
924 | usbpucr = at91_sys_read(AT91_MATRIX_USBPUCR); | ||
925 | usbpucr |= AT91_MATRIX_USBPUCR_PUON; | ||
926 | at91_sys_write(AT91_MATRIX_USBPUCR, usbpucr); | ||
927 | } | ||
913 | } else { | 928 | } else { |
914 | stop_activity(udc); | 929 | stop_activity(udc); |
915 | at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); | 930 | at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); |
916 | at91_set_gpio_value(udc->board.pullup_pin, 0); | 931 | if (cpu_is_at91rm9200()) |
932 | at91_set_gpio_value(udc->board.pullup_pin, 0); | ||
933 | else if (cpu_is_at91sam9260()) { | ||
934 | u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC); | ||
935 | |||
936 | txvc &= ~AT91_UDP_TXVC_PUON; | ||
937 | at91_udp_write(udc, AT91_UDP_TXVC, txvc); | ||
938 | } else if (cpu_is_at91sam9261()) { | ||
939 | u32 usbpucr; | ||
940 | |||
941 | usbpucr = at91_sys_read(AT91_MATRIX_USBPUCR); | ||
942 | usbpucr &= ~AT91_MATRIX_USBPUCR_PUON; | ||
943 | at91_sys_write(AT91_MATRIX_USBPUCR, usbpucr); | ||
944 | } | ||
917 | clk_off(udc); | 945 | clk_off(udc); |
918 | } | 946 | } |
919 | } | 947 | } |
@@ -1668,7 +1696,8 @@ static int __devinit at91udc_probe(struct platform_device *pdev) | |||
1668 | udc->fclk = clk_get(dev, "udpck"); | 1696 | udc->fclk = clk_get(dev, "udpck"); |
1669 | if (IS_ERR(udc->iclk) || IS_ERR(udc->fclk)) { | 1697 | if (IS_ERR(udc->iclk) || IS_ERR(udc->fclk)) { |
1670 | DBG("clocks missing\n"); | 1698 | DBG("clocks missing\n"); |
1671 | return -ENODEV; | 1699 | retval = -ENODEV; |
1700 | goto fail0; | ||
1672 | } | 1701 | } |
1673 | 1702 | ||
1674 | retval = device_register(&udc->gadget.dev); | 1703 | retval = device_register(&udc->gadget.dev); |
@@ -1679,6 +1708,8 @@ static int __devinit at91udc_probe(struct platform_device *pdev) | |||
1679 | clk_enable(udc->iclk); | 1708 | clk_enable(udc->iclk); |
1680 | at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); | 1709 | at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); |
1681 | at91_udp_write(udc, AT91_UDP_IDR, 0xffffffff); | 1710 | at91_udp_write(udc, AT91_UDP_IDR, 0xffffffff); |
1711 | /* Clear all pending interrupts - UDP may be used by bootloader. */ | ||
1712 | at91_udp_write(udc, AT91_UDP_ICR, 0xffffffff); | ||
1682 | clk_disable(udc->iclk); | 1713 | clk_disable(udc->iclk); |
1683 | 1714 | ||
1684 | /* request UDC and maybe VBUS irqs */ | 1715 | /* request UDC and maybe VBUS irqs */ |
@@ -1690,6 +1721,11 @@ static int __devinit at91udc_probe(struct platform_device *pdev) | |||
1690 | goto fail1; | 1721 | goto fail1; |
1691 | } | 1722 | } |
1692 | if (udc->board.vbus_pin > 0) { | 1723 | if (udc->board.vbus_pin > 0) { |
1724 | /* | ||
1725 | * Get the initial state of VBUS - we cannot expect | ||
1726 | * a pending interrupt. | ||
1727 | */ | ||
1728 | udc->vbus = at91_get_gpio_value(udc->board.vbus_pin); | ||
1693 | if (request_irq(udc->board.vbus_pin, at91_vbus_irq, | 1729 | if (request_irq(udc->board.vbus_pin, at91_vbus_irq, |
1694 | IRQF_DISABLED, driver_name, udc)) { | 1730 | IRQF_DISABLED, driver_name, udc)) { |
1695 | DBG("request vbus irq %d failed\n", | 1731 | DBG("request vbus irq %d failed\n", |
diff --git a/drivers/usb/gadget/at91_udc.h b/drivers/usb/gadget/at91_udc.h index a35f3b627d3c..677089baa59d 100644 --- a/drivers/usb/gadget/at91_udc.h +++ b/drivers/usb/gadget/at91_udc.h | |||
@@ -51,10 +51,10 @@ | |||
51 | #define AT91_UDP_EP(n) (1 << (n)) /* Endpoint Interrupt Status */ | 51 | #define AT91_UDP_EP(n) (1 << (n)) /* Endpoint Interrupt Status */ |
52 | #define AT91_UDP_RXSUSP (1 << 8) /* USB Suspend Interrupt Status */ | 52 | #define AT91_UDP_RXSUSP (1 << 8) /* USB Suspend Interrupt Status */ |
53 | #define AT91_UDP_RXRSM (1 << 9) /* USB Resume Interrupt Status */ | 53 | #define AT91_UDP_RXRSM (1 << 9) /* USB Resume Interrupt Status */ |
54 | #define AT91_UDP_EXTRSM (1 << 10) /* External Resume Interrupt Status */ | 54 | #define AT91_UDP_EXTRSM (1 << 10) /* External Resume Interrupt Status [AT91RM9200 only] */ |
55 | #define AT91_UDP_SOFINT (1 << 11) /* Start of Frame Interrupt Status */ | 55 | #define AT91_UDP_SOFINT (1 << 11) /* Start of Frame Interrupt Status */ |
56 | #define AT91_UDP_ENDBUSRES (1 << 12) /* End of Bus Reset Interrpt Status */ | 56 | #define AT91_UDP_ENDBUSRES (1 << 12) /* End of Bus Reset Interrpt Status */ |
57 | #define AT91_UDP_WAKEUP (1 << 13) /* USB Wakeup Interrupt Status */ | 57 | #define AT91_UDP_WAKEUP (1 << 13) /* USB Wakeup Interrupt Status [AT91RM9200 only] */ |
58 | 58 | ||
59 | #define AT91_UDP_ICR 0x20 /* Interrupt Clear Register */ | 59 | #define AT91_UDP_ICR 0x20 /* Interrupt Clear Register */ |
60 | #define AT91_UDP_RST_EP 0x28 /* Reset Endpoint Register */ | 60 | #define AT91_UDP_RST_EP 0x28 /* Reset Endpoint Register */ |
@@ -84,7 +84,7 @@ | |||
84 | 84 | ||
85 | #define AT91_UDP_TXVC 0x74 /* Transceiver Control Register */ | 85 | #define AT91_UDP_TXVC 0x74 /* Transceiver Control Register */ |
86 | #define AT91_UDP_TXVC_TXVDIS (1 << 8) /* Transceiver Disable */ | 86 | #define AT91_UDP_TXVC_TXVDIS (1 << 8) /* Transceiver Disable */ |
87 | 87 | #define AT91_UDP_TXVC_PUON (1 << 9) /* PullUp On [AT91SAM9260 only] */ | |
88 | 88 | ||
89 | /*-------------------------------------------------------------------------*/ | 89 | /*-------------------------------------------------------------------------*/ |
90 | 90 | ||