aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/m66592-udc.c
diff options
context:
space:
mode:
authorMagnus Damm <damm@igel.co.jp>2009-07-22 10:41:35 -0400
committerPaul Mundt <lethal@linux-sh.org>2009-07-23 00:04:15 -0400
commit2c59b0b70b9d5d61c726f179724660c4c2423f31 (patch)
treedc7629d1ed0627f3651669d8b483f88a8cd4955e /drivers/usb/gadget/m66592-udc.c
parentcf4f1e76c49dacfde0680b170b9a9b6a42f296bb (diff)
usb: m66592-udc platform data on_chip support
Convert the m66592-udc driver to use the on_chip flag from platform data to enable on chip behaviour instead of relying on CONFIG_SUPERH_BUILT_IN_M66592 ugliness. This makes the code cleaner and also allows us to support both external and internal m66592 with the same kernel. It also makes the Kconfig part more future proof since we with this patch can add support for new processors with on-chip m66592 without modifying the Kconfig. The patch adds a m66592 header file for platform data and ties in platform data to the existing m66592 devices. Signed-off-by: Magnus Damm <damm@igel.co.jp> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/usb/gadget/m66592-udc.c')
-rw-r--r--drivers/usb/gadget/m66592-udc.c252
1 files changed, 147 insertions, 105 deletions
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c
index 0dddd2f8ff35..a61c70caff12 100644
--- a/drivers/usb/gadget/m66592-udc.c
+++ b/drivers/usb/gadget/m66592-udc.c
@@ -31,38 +31,12 @@
31 31
32#include "m66592-udc.h" 32#include "m66592-udc.h"
33 33
34
35MODULE_DESCRIPTION("M66592 USB gadget driver"); 34MODULE_DESCRIPTION("M66592 USB gadget driver");
36MODULE_LICENSE("GPL"); 35MODULE_LICENSE("GPL");
37MODULE_AUTHOR("Yoshihiro Shimoda"); 36MODULE_AUTHOR("Yoshihiro Shimoda");
38MODULE_ALIAS("platform:m66592_udc"); 37MODULE_ALIAS("platform:m66592_udc");
39 38
40#define DRIVER_VERSION "26 Jun 2009" 39#define DRIVER_VERSION "21 July 2009"
41
42/* module parameters */
43#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
44static unsigned short endian = M66592_LITTLE;
45module_param(endian, ushort, 0644);
46MODULE_PARM_DESC(endian, "data endian: big=0, little=0 (default=0)");
47#else
48static unsigned short clock = M66592_XTAL24;
49module_param(clock, ushort, 0644);
50MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 "
51 "(default=16384)");
52
53static unsigned short vif = M66592_LDRV;
54module_param(vif, ushort, 0644);
55MODULE_PARM_DESC(vif, "input VIF: 3.3V=32768, 1.5V=0 (default=32768)");
56
57static unsigned short endian;
58module_param(endian, ushort, 0644);
59MODULE_PARM_DESC(endian, "data endian: big=256, little=0 (default=0)");
60
61static unsigned short irq_sense = M66592_INTL;
62module_param(irq_sense, ushort, 0644);
63MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=2, falling edge=0 "
64 "(default=2)");
65#endif
66 40
67static const char udc_name[] = "m66592_udc"; 41static const char udc_name[] = "m66592_udc";
68static const char *m66592_ep_name[] = { 42static const char *m66592_ep_name[] = {
@@ -244,6 +218,7 @@ static inline int get_buffer_size(struct m66592 *m66592, u16 pipenum)
244static inline void pipe_change(struct m66592 *m66592, u16 pipenum) 218static inline void pipe_change(struct m66592 *m66592, u16 pipenum)
245{ 219{
246 struct m66592_ep *ep = m66592->pipenum2ep[pipenum]; 220 struct m66592_ep *ep = m66592->pipenum2ep[pipenum];
221 unsigned short mbw;
247 222
248 if (ep->use_dma) 223 if (ep->use_dma)
249 return; 224 return;
@@ -252,7 +227,12 @@ static inline void pipe_change(struct m66592 *m66592, u16 pipenum)
252 227
253 ndelay(450); 228 ndelay(450);
254 229
255 m66592_bset(m66592, M66592_MBW, ep->fifosel); 230 if (m66592->pdata->on_chip)
231 mbw = M66592_MBW_32;
232 else
233 mbw = M66592_MBW_16;
234
235 m66592_bset(m66592, mbw, ep->fifosel);
256} 236}
257 237
258static int pipe_buffer_setting(struct m66592 *m66592, 238static int pipe_buffer_setting(struct m66592 *m66592,
@@ -332,6 +312,7 @@ static void pipe_buffer_release(struct m66592 *m66592,
332static void pipe_initialize(struct m66592_ep *ep) 312static void pipe_initialize(struct m66592_ep *ep)
333{ 313{
334 struct m66592 *m66592 = ep->m66592; 314 struct m66592 *m66592 = ep->m66592;
315 unsigned short mbw;
335 316
336 m66592_mdfy(m66592, 0, M66592_CURPIPE, ep->fifosel); 317 m66592_mdfy(m66592, 0, M66592_CURPIPE, ep->fifosel);
337 318
@@ -343,7 +324,12 @@ static void pipe_initialize(struct m66592_ep *ep)
343 324
344 ndelay(450); 325 ndelay(450);
345 326
346 m66592_bset(m66592, M66592_MBW, ep->fifosel); 327 if (m66592->pdata->on_chip)
328 mbw = M66592_MBW_32;
329 else
330 mbw = M66592_MBW_16;
331
332 m66592_bset(m66592, mbw, ep->fifosel);
347 } 333 }
348} 334}
349 335
@@ -359,15 +345,13 @@ static void m66592_ep_setting(struct m66592 *m66592, struct m66592_ep *ep,
359 ep->fifosel = M66592_D0FIFOSEL; 345 ep->fifosel = M66592_D0FIFOSEL;
360 ep->fifoctr = M66592_D0FIFOCTR; 346 ep->fifoctr = M66592_D0FIFOCTR;
361 ep->fifotrn = M66592_D0FIFOTRN; 347 ep->fifotrn = M66592_D0FIFOTRN;
362#if !defined(CONFIG_SUPERH_BUILT_IN_M66592) 348 } else if (!m66592->pdata->on_chip && m66592->num_dma == 1) {
363 } else if (m66592->num_dma == 1) {
364 m66592->num_dma++; 349 m66592->num_dma++;
365 ep->use_dma = 1; 350 ep->use_dma = 1;
366 ep->fifoaddr = M66592_D1FIFO; 351 ep->fifoaddr = M66592_D1FIFO;
367 ep->fifosel = M66592_D1FIFOSEL; 352 ep->fifosel = M66592_D1FIFOSEL;
368 ep->fifoctr = M66592_D1FIFOCTR; 353 ep->fifoctr = M66592_D1FIFOCTR;
369 ep->fifotrn = M66592_D1FIFOTRN; 354 ep->fifotrn = M66592_D1FIFOTRN;
370#endif
371 } else { 355 } else {
372 ep->use_dma = 0; 356 ep->use_dma = 0;
373 ep->fifoaddr = M66592_CFIFO; 357 ep->fifoaddr = M66592_CFIFO;
@@ -612,76 +596,120 @@ static void start_ep0(struct m66592_ep *ep, struct m66592_request *req)
612 } 596 }
613} 597}
614 598
615#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
616static void init_controller(struct m66592 *m66592) 599static void init_controller(struct m66592 *m66592)
617{ 600{
618 m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */ 601 unsigned int endian;
619 m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
620 m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
621 m66592_bset(m66592, M66592_USBE, M66592_SYSCFG);
622 602
623 /* This is a workaound for SH7722 2nd cut */ 603 if (m66592->pdata->on_chip) {
624 m66592_bset(m66592, 0x8000, M66592_DVSTCTR); 604 if (m66592->pdata->endian)
625 m66592_bset(m66592, 0x1000, M66592_TESTMODE); 605 endian = 0; /* big endian */
626 m66592_bclr(m66592, 0x8000, M66592_DVSTCTR); 606 else
607 endian = M66592_LITTLE; /* little endian */
627 608
628 m66592_bset(m66592, M66592_INTL, M66592_INTENB1); 609 m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */
610 m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
611 m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
612 m66592_bset(m66592, M66592_USBE, M66592_SYSCFG);
629 613
630 m66592_write(m66592, 0, M66592_CFBCFG); 614 /* This is a workaound for SH7722 2nd cut */
631 m66592_write(m66592, 0, M66592_D0FBCFG); 615 m66592_bset(m66592, 0x8000, M66592_DVSTCTR);
632 m66592_bset(m66592, endian, M66592_CFBCFG); 616 m66592_bset(m66592, 0x1000, M66592_TESTMODE);
633 m66592_bset(m66592, endian, M66592_D0FBCFG); 617 m66592_bclr(m66592, 0x8000, M66592_DVSTCTR);
634}
635#else /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
636static void init_controller(struct m66592 *m66592)
637{
638 m66592_bset(m66592, (vif & M66592_LDRV) | (endian & M66592_BIGEND),
639 M66592_PINCFG);
640 m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */
641 m66592_mdfy(m66592, clock & M66592_XTAL, M66592_XTAL, M66592_SYSCFG);
642 618
643 m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG); 619 m66592_bset(m66592, M66592_INTL, M66592_INTENB1);
644 m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG); 620
645 m66592_bset(m66592, M66592_USBE, M66592_SYSCFG); 621 m66592_write(m66592, 0, M66592_CFBCFG);
622 m66592_write(m66592, 0, M66592_D0FBCFG);
623 m66592_bset(m66592, endian, M66592_CFBCFG);
624 m66592_bset(m66592, endian, M66592_D0FBCFG);
625 } else {
626 unsigned int clock, vif, irq_sense;
627
628 if (m66592->pdata->endian)
629 endian = M66592_BIGEND; /* big endian */
630 else
631 endian = 0; /* little endian */
632
633 if (m66592->pdata->vif)
634 vif = M66592_LDRV; /* 3.3v */
635 else
636 vif = 0; /* 1.5v */
637
638 switch (m66592->pdata->xtal) {
639 case M66592_PLATDATA_XTAL_12MHZ:
640 clock = M66592_XTAL12;
641 break;
642 case M66592_PLATDATA_XTAL_24MHZ:
643 clock = M66592_XTAL24;
644 break;
645 case M66592_PLATDATA_XTAL_48MHZ:
646 clock = M66592_XTAL48;
647 break;
648 default:
649 pr_warning("m66592-udc: xtal configuration error\n");
650 clock = 0;
651 }
646 652
647 m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG); 653 switch (m66592->irq_trigger) {
654 case IRQF_TRIGGER_LOW:
655 irq_sense = M66592_INTL;
656 break;
657 case IRQF_TRIGGER_FALLING:
658 irq_sense = 0;
659 break;
660 default:
661 pr_warning("m66592-udc: irq trigger config error\n");
662 irq_sense = 0;
663 }
648 664
649 msleep(3); 665 m66592_bset(m66592,
666 (vif & M66592_LDRV) | (endian & M66592_BIGEND),
667 M66592_PINCFG);
668 m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */
669 m66592_mdfy(m66592, clock & M66592_XTAL, M66592_XTAL,
670 M66592_SYSCFG);
671 m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
672 m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
673 m66592_bset(m66592, M66592_USBE, M66592_SYSCFG);
650 674
651 m66592_bset(m66592, M66592_RCKE | M66592_PLLC, M66592_SYSCFG); 675 m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG);
676
677 msleep(3);
652 678
653 msleep(1); 679 m66592_bset(m66592, M66592_RCKE | M66592_PLLC, M66592_SYSCFG);
654 680
655 m66592_bset(m66592, M66592_SCKE, M66592_SYSCFG); 681 msleep(1);
656 682
657 m66592_bset(m66592, irq_sense & M66592_INTL, M66592_INTENB1); 683 m66592_bset(m66592, M66592_SCKE, M66592_SYSCFG);
658 m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR, 684
659 M66592_DMA0CFG); 685 m66592_bset(m66592, irq_sense & M66592_INTL, M66592_INTENB1);
686 m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR,
687 M66592_DMA0CFG);
688 }
660} 689}
661#endif /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
662 690
663static void disable_controller(struct m66592 *m66592) 691static void disable_controller(struct m66592 *m66592)
664{ 692{
665#if !defined(CONFIG_SUPERH_BUILT_IN_M66592) 693 if (!m66592->pdata->on_chip) {
666 m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG); 694 m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG);
667 udelay(1); 695 udelay(1);
668 m66592_bclr(m66592, M66592_PLLC, M66592_SYSCFG); 696 m66592_bclr(m66592, M66592_PLLC, M66592_SYSCFG);
669 udelay(1); 697 udelay(1);
670 m66592_bclr(m66592, M66592_RCKE, M66592_SYSCFG); 698 m66592_bclr(m66592, M66592_RCKE, M66592_SYSCFG);
671 udelay(1); 699 udelay(1);
672 m66592_bclr(m66592, M66592_XCKE, M66592_SYSCFG); 700 m66592_bclr(m66592, M66592_XCKE, M66592_SYSCFG);
673#endif 701 }
674} 702}
675 703
676static void m66592_start_xclock(struct m66592 *m66592) 704static void m66592_start_xclock(struct m66592 *m66592)
677{ 705{
678#if !defined(CONFIG_SUPERH_BUILT_IN_M66592)
679 u16 tmp; 706 u16 tmp;
680 707
681 tmp = m66592_read(m66592, M66592_SYSCFG); 708 if (!m66592->pdata->on_chip) {
682 if (!(tmp & M66592_XCKE)) 709 tmp = m66592_read(m66592, M66592_SYSCFG);
683 m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG); 710 if (!(tmp & M66592_XCKE))
684#endif 711 m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG);
712 }
685} 713}
686 714
687/*-------------------------------------------------------------------------*/ 715/*-------------------------------------------------------------------------*/
@@ -1169,8 +1197,7 @@ static irqreturn_t m66592_irq(int irq, void *_m66592)
1169 intsts0 = m66592_read(m66592, M66592_INTSTS0); 1197 intsts0 = m66592_read(m66592, M66592_INTSTS0);
1170 intenb0 = m66592_read(m66592, M66592_INTENB0); 1198 intenb0 = m66592_read(m66592, M66592_INTENB0);
1171 1199
1172#if defined(CONFIG_SUPERH_BUILT_IN_M66592) 1200 if (m66592->pdata->on_chip && !intsts0 && !intenb0) {
1173 if (!intsts0 && !intenb0) {
1174 /* 1201 /*
1175 * When USB clock stops, it cannot read register. Even if a 1202 * When USB clock stops, it cannot read register. Even if a
1176 * clock stops, the interrupt occurs. So this driver turn on 1203 * clock stops, the interrupt occurs. So this driver turn on
@@ -1180,7 +1207,6 @@ static irqreturn_t m66592_irq(int irq, void *_m66592)
1180 intsts0 = m66592_read(m66592, M66592_INTSTS0); 1207 intsts0 = m66592_read(m66592, M66592_INTSTS0);
1181 intenb0 = m66592_read(m66592, M66592_INTENB0); 1208 intenb0 = m66592_read(m66592, M66592_INTENB0);
1182 } 1209 }
1183#endif
1184 1210
1185 savepipe = m66592_read(m66592, M66592_CFIFOSEL); 1211 savepipe = m66592_read(m66592, M66592_CFIFOSEL);
1186 1212
@@ -1526,9 +1552,11 @@ static int __exit m66592_remove(struct platform_device *pdev)
1526 iounmap(m66592->reg); 1552 iounmap(m66592->reg);
1527 free_irq(platform_get_irq(pdev, 0), m66592); 1553 free_irq(platform_get_irq(pdev, 0), m66592);
1528 m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req); 1554 m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req);
1529#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK) 1555#ifdef CONFIG_HAVE_CLK
1530 clk_disable(m66592->clk); 1556 if (m66592->pdata->on_chip) {
1531 clk_put(m66592->clk); 1557 clk_disable(m66592->clk);
1558 clk_put(m66592->clk);
1559 }
1532#endif 1560#endif
1533 kfree(m66592); 1561 kfree(m66592);
1534 return 0; 1562 return 0;
@@ -1540,11 +1568,10 @@ static void nop_completion(struct usb_ep *ep, struct usb_request *r)
1540 1568
1541static int __init m66592_probe(struct platform_device *pdev) 1569static int __init m66592_probe(struct platform_device *pdev)
1542{ 1570{
1543 struct resource *res; 1571 struct resource *res, *ires;
1544 int irq;
1545 void __iomem *reg = NULL; 1572 void __iomem *reg = NULL;
1546 struct m66592 *m66592 = NULL; 1573 struct m66592 *m66592 = NULL;
1547#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK) 1574#ifdef CONFIG_HAVE_CLK
1548 char clk_name[8]; 1575 char clk_name[8];
1549#endif 1576#endif
1550 int ret = 0; 1577 int ret = 0;
@@ -1557,10 +1584,11 @@ static int __init m66592_probe(struct platform_device *pdev)
1557 goto clean_up; 1584 goto clean_up;
1558 } 1585 }
1559 1586
1560 irq = platform_get_irq(pdev, 0); 1587 ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1561 if (irq < 0) { 1588 if (!ires) {
1562 ret = -ENODEV; 1589 ret = -ENODEV;
1563 pr_err("platform_get_irq error.\n"); 1590 dev_err(&pdev->dev,
1591 "platform_get_resource IORESOURCE_IRQ error.\n");
1564 goto clean_up; 1592 goto clean_up;
1565 } 1593 }
1566 1594
@@ -1571,6 +1599,12 @@ static int __init m66592_probe(struct platform_device *pdev)
1571 goto clean_up; 1599 goto clean_up;
1572 } 1600 }
1573 1601
1602 if (pdev->dev.platform_data == NULL) {
1603 dev_err(&pdev->dev, "no platform data\n");
1604 ret = -ENODEV;
1605 goto clean_up;
1606 }
1607
1574 /* initialize ucd */ 1608 /* initialize ucd */
1575 m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL); 1609 m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL);
1576 if (m66592 == NULL) { 1610 if (m66592 == NULL) {
@@ -1578,6 +1612,9 @@ static int __init m66592_probe(struct platform_device *pdev)
1578 goto clean_up; 1612 goto clean_up;
1579 } 1613 }
1580 1614
1615 m66592->pdata = pdev->dev.platform_data;
1616 m66592->irq_trigger = ires->flags & IRQF_TRIGGER_MASK;
1617
1581 spin_lock_init(&m66592->lock); 1618 spin_lock_init(&m66592->lock);
1582 dev_set_drvdata(&pdev->dev, m66592); 1619 dev_set_drvdata(&pdev->dev, m66592);
1583 1620
@@ -1595,22 +1632,25 @@ static int __init m66592_probe(struct platform_device *pdev)
1595 m66592->timer.data = (unsigned long)m66592; 1632 m66592->timer.data = (unsigned long)m66592;
1596 m66592->reg = reg; 1633 m66592->reg = reg;
1597 1634
1598 ret = request_irq(irq, m66592_irq, IRQF_DISABLED | IRQF_SHARED, 1635 ret = request_irq(ires->start, m66592_irq, IRQF_DISABLED | IRQF_SHARED,
1599 udc_name, m66592); 1636 udc_name, m66592);
1600 if (ret < 0) { 1637 if (ret < 0) {
1601 pr_err("request_irq error (%d)\n", ret); 1638 pr_err("request_irq error (%d)\n", ret);
1602 goto clean_up; 1639 goto clean_up;
1603 } 1640 }
1604 1641
1605#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK) 1642#ifdef CONFIG_HAVE_CLK
1606 snprintf(clk_name, sizeof(clk_name), "usbf%d", pdev->id); 1643 if (m66592->pdata->on_chip) {
1607 m66592->clk = clk_get(&pdev->dev, clk_name); 1644 snprintf(clk_name, sizeof(clk_name), "usbf%d", pdev->id);
1608 if (IS_ERR(m66592->clk)) { 1645 m66592->clk = clk_get(&pdev->dev, clk_name);
1609 dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name); 1646 if (IS_ERR(m66592->clk)) {
1610 ret = PTR_ERR(m66592->clk); 1647 dev_err(&pdev->dev, "cannot get clock \"%s\"\n",
1611 goto clean_up2; 1648 clk_name);
1649 ret = PTR_ERR(m66592->clk);
1650 goto clean_up2;
1651 }
1652 clk_enable(m66592->clk);
1612 } 1653 }
1613 clk_enable(m66592->clk);
1614#endif 1654#endif
1615 INIT_LIST_HEAD(&m66592->gadget.ep_list); 1655 INIT_LIST_HEAD(&m66592->gadget.ep_list);
1616 m66592->gadget.ep0 = &m66592->ep[0].ep; 1656 m66592->gadget.ep0 = &m66592->ep[0].ep;
@@ -1652,12 +1692,14 @@ static int __init m66592_probe(struct platform_device *pdev)
1652 return 0; 1692 return 0;
1653 1693
1654clean_up3: 1694clean_up3:
1655#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK) 1695#ifdef CONFIG_HAVE_CLK
1656 clk_disable(m66592->clk); 1696 if (m66592->pdata->on_chip) {
1657 clk_put(m66592->clk); 1697 clk_disable(m66592->clk);
1698 clk_put(m66592->clk);
1699 }
1658clean_up2: 1700clean_up2:
1659#endif 1701#endif
1660 free_irq(irq, m66592); 1702 free_irq(ires->start, m66592);
1661clean_up: 1703clean_up:
1662 if (m66592) { 1704 if (m66592) {
1663 if (m66592->ep0_req) 1705 if (m66592->ep0_req)