diff options
author | Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> | 2007-11-22 07:00:30 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2008-02-01 17:34:48 -0500 |
commit | 8c73aff6d3b772e5f373d78bc34fd47b10b35fef (patch) | |
tree | c6829760527dd59c27acf86b3f935b3659b2c6fa /drivers/usb/gadget/m66592-udc.c | |
parent | 9da0068a4964540d8d1caa8455fe193b544d846d (diff) |
USB: m66592-udc: Add support for SH7722 USBF
Add support for SuperH SH7722 USB Function.
M66592 is similar to SH7722 USBF. It can support SH7722 USBF by
changing several M66592 code.
Signed-off-by: Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
Acked-by: David Brownell <david-b@pacbell.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget/m66592-udc.c')
-rw-r--r-- | drivers/usb/gadget/m66592-udc.c | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index ebc5536aa271..154007aa8d30 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c | |||
@@ -36,9 +36,14 @@ MODULE_DESCRIPTION("M66592 USB gadget driver"); | |||
36 | MODULE_LICENSE("GPL"); | 36 | MODULE_LICENSE("GPL"); |
37 | MODULE_AUTHOR("Yoshihiro Shimoda"); | 37 | MODULE_AUTHOR("Yoshihiro Shimoda"); |
38 | 38 | ||
39 | #define DRIVER_VERSION "29 May 2007" | 39 | #define DRIVER_VERSION "18 Oct 2007" |
40 | 40 | ||
41 | /* module parameters */ | 41 | /* module parameters */ |
42 | #if defined(CONFIG_SUPERH_BUILT_IN_M66592) | ||
43 | static unsigned short endian = M66592_LITTLE; | ||
44 | module_param(endian, ushort, 0644); | ||
45 | MODULE_PARM_DESC(endian, "data endian: big=0, little=0 (default=0)"); | ||
46 | #else | ||
42 | static unsigned short clock = M66592_XTAL24; | 47 | static unsigned short clock = M66592_XTAL24; |
43 | module_param(clock, ushort, 0644); | 48 | module_param(clock, ushort, 0644); |
44 | MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 " | 49 | MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 " |
@@ -56,6 +61,7 @@ static unsigned short irq_sense = M66592_INTL; | |||
56 | module_param(irq_sense, ushort, 0644); | 61 | module_param(irq_sense, ushort, 0644); |
57 | MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=2, falling edge=0 " | 62 | MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=2, falling edge=0 " |
58 | "(default=2)"); | 63 | "(default=2)"); |
64 | #endif | ||
59 | 65 | ||
60 | static const char udc_name[] = "m66592_udc"; | 66 | static const char udc_name[] = "m66592_udc"; |
61 | static const char *m66592_ep_name[] = { | 67 | static const char *m66592_ep_name[] = { |
@@ -360,6 +366,7 @@ static void m66592_ep_setting(struct m66592 *m66592, struct m66592_ep *ep, | |||
360 | ep->fifosel = M66592_D0FIFOSEL; | 366 | ep->fifosel = M66592_D0FIFOSEL; |
361 | ep->fifoctr = M66592_D0FIFOCTR; | 367 | ep->fifoctr = M66592_D0FIFOCTR; |
362 | ep->fifotrn = M66592_D0FIFOTRN; | 368 | ep->fifotrn = M66592_D0FIFOTRN; |
369 | #if !defined(CONFIG_SUPERH_BUILT_IN_M66592) | ||
363 | } else if (m66592->num_dma == 1) { | 370 | } else if (m66592->num_dma == 1) { |
364 | m66592->num_dma++; | 371 | m66592->num_dma++; |
365 | ep->use_dma = 1; | 372 | ep->use_dma = 1; |
@@ -367,6 +374,7 @@ static void m66592_ep_setting(struct m66592 *m66592, struct m66592_ep *ep, | |||
367 | ep->fifosel = M66592_D1FIFOSEL; | 374 | ep->fifosel = M66592_D1FIFOSEL; |
368 | ep->fifoctr = M66592_D1FIFOCTR; | 375 | ep->fifoctr = M66592_D1FIFOCTR; |
369 | ep->fifotrn = M66592_D1FIFOTRN; | 376 | ep->fifotrn = M66592_D1FIFOTRN; |
377 | #endif | ||
370 | } else { | 378 | } else { |
371 | ep->use_dma = 0; | 379 | ep->use_dma = 0; |
372 | ep->fifoaddr = M66592_CFIFO; | 380 | ep->fifoaddr = M66592_CFIFO; |
@@ -611,6 +619,28 @@ static void start_ep0(struct m66592_ep *ep, struct m66592_request *req) | |||
611 | } | 619 | } |
612 | } | 620 | } |
613 | 621 | ||
622 | #if defined(CONFIG_SUPERH_BUILT_IN_M66592) | ||
623 | static void init_controller(struct m66592 *m66592) | ||
624 | { | ||
625 | usbf_start_clock(); | ||
626 | m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */ | ||
627 | m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG); | ||
628 | m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG); | ||
629 | m66592_bset(m66592, M66592_USBE, M66592_SYSCFG); | ||
630 | |||
631 | /* This is a workaound for SH7722 2nd cut */ | ||
632 | m66592_bset(m66592, 0x8000, M66592_DVSTCTR); | ||
633 | m66592_bset(m66592, 0x1000, M66592_TESTMODE); | ||
634 | m66592_bclr(m66592, 0x8000, M66592_DVSTCTR); | ||
635 | |||
636 | m66592_bset(m66592, M66592_INTL, M66592_INTENB1); | ||
637 | |||
638 | m66592_write(m66592, 0, M66592_CFBCFG); | ||
639 | m66592_write(m66592, 0, M66592_D0FBCFG); | ||
640 | m66592_bset(m66592, endian, M66592_CFBCFG); | ||
641 | m66592_bset(m66592, endian, M66592_D0FBCFG); | ||
642 | } | ||
643 | #else /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */ | ||
614 | static void init_controller(struct m66592 *m66592) | 644 | static void init_controller(struct m66592 *m66592) |
615 | { | 645 | { |
616 | m66592_bset(m66592, (vif & M66592_LDRV) | (endian & M66592_BIGEND), | 646 | m66592_bset(m66592, (vif & M66592_LDRV) | (endian & M66592_BIGEND), |
@@ -636,9 +666,13 @@ static void init_controller(struct m66592 *m66592) | |||
636 | m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR, | 666 | m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR, |
637 | M66592_DMA0CFG); | 667 | M66592_DMA0CFG); |
638 | } | 668 | } |
669 | #endif /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */ | ||
639 | 670 | ||
640 | static void disable_controller(struct m66592 *m66592) | 671 | static void disable_controller(struct m66592 *m66592) |
641 | { | 672 | { |
673 | #if defined(CONFIG_SUPERH_BUILT_IN_M66592) | ||
674 | usbf_stop_clock(); | ||
675 | #else | ||
642 | m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG); | 676 | m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG); |
643 | udelay(1); | 677 | udelay(1); |
644 | m66592_bclr(m66592, M66592_PLLC, M66592_SYSCFG); | 678 | m66592_bclr(m66592, M66592_PLLC, M66592_SYSCFG); |
@@ -646,15 +680,20 @@ static void disable_controller(struct m66592 *m66592) | |||
646 | m66592_bclr(m66592, M66592_RCKE, M66592_SYSCFG); | 680 | m66592_bclr(m66592, M66592_RCKE, M66592_SYSCFG); |
647 | udelay(1); | 681 | udelay(1); |
648 | m66592_bclr(m66592, M66592_XCKE, M66592_SYSCFG); | 682 | m66592_bclr(m66592, M66592_XCKE, M66592_SYSCFG); |
683 | #endif | ||
649 | } | 684 | } |
650 | 685 | ||
651 | static void m66592_start_xclock(struct m66592 *m66592) | 686 | static void m66592_start_xclock(struct m66592 *m66592) |
652 | { | 687 | { |
688 | #if defined(CONFIG_SUPERH_BUILT_IN_M66592) | ||
689 | usbf_start_clock(); | ||
690 | #else | ||
653 | u16 tmp; | 691 | u16 tmp; |
654 | 692 | ||
655 | tmp = m66592_read(m66592, M66592_SYSCFG); | 693 | tmp = m66592_read(m66592, M66592_SYSCFG); |
656 | if (!(tmp & M66592_XCKE)) | 694 | if (!(tmp & M66592_XCKE)) |
657 | m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG); | 695 | m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG); |
696 | #endif | ||
658 | } | 697 | } |
659 | 698 | ||
660 | /*-------------------------------------------------------------------------*/ | 699 | /*-------------------------------------------------------------------------*/ |
@@ -1142,6 +1181,19 @@ static irqreturn_t m66592_irq(int irq, void *_m66592) | |||
1142 | intsts0 = m66592_read(m66592, M66592_INTSTS0); | 1181 | intsts0 = m66592_read(m66592, M66592_INTSTS0); |
1143 | intenb0 = m66592_read(m66592, M66592_INTENB0); | 1182 | intenb0 = m66592_read(m66592, M66592_INTENB0); |
1144 | 1183 | ||
1184 | #if defined(CONFIG_SUPERH_BUILT_IN_M66592) | ||
1185 | if (!intsts0 && !intenb0) { | ||
1186 | /* | ||
1187 | * When USB clock stops, it cannot read register. Even if a | ||
1188 | * clock stops, the interrupt occurs. So this driver turn on | ||
1189 | * a clock by this timing and do re-reading of register. | ||
1190 | */ | ||
1191 | m66592_start_xclock(m66592); | ||
1192 | intsts0 = m66592_read(m66592, M66592_INTSTS0); | ||
1193 | intenb0 = m66592_read(m66592, M66592_INTENB0); | ||
1194 | } | ||
1195 | #endif | ||
1196 | |||
1145 | savepipe = m66592_read(m66592, M66592_CFIFOSEL); | 1197 | savepipe = m66592_read(m66592, M66592_CFIFOSEL); |
1146 | 1198 | ||
1147 | mask0 = intsts0 & intenb0; | 1199 | mask0 = intsts0 & intenb0; |
@@ -1485,6 +1537,7 @@ static int __exit m66592_remove(struct platform_device *pdev) | |||
1485 | iounmap(m66592->reg); | 1537 | iounmap(m66592->reg); |
1486 | free_irq(platform_get_irq(pdev, 0), m66592); | 1538 | free_irq(platform_get_irq(pdev, 0), m66592); |
1487 | m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req); | 1539 | m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req); |
1540 | usbf_stop_clock(); | ||
1488 | kfree(m66592); | 1541 | kfree(m66592); |
1489 | return 0; | 1542 | return 0; |
1490 | } | 1543 | } |