aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-shmobile/board-mackerel.c
diff options
context:
space:
mode:
authorMagnus Damm <damm@opensource.se>2011-06-09 03:03:37 -0400
committerPaul Mundt <lethal@linux-sh.org>2011-06-14 02:11:49 -0400
commite2a53b7c5bcfb63114c02c32117ed62eae463dc2 (patch)
treedf0fa061ee9ebe86200bb4af141ed5d0b4123f98 /arch/arm/mach-shmobile/board-mackerel.c
parent5294206053f9ab522fbd6bfde1cf7629dc564d5e (diff)
ARM: mach-shmobile: Mackerel USB platform data update
This patch updates the board specific USB support code for the sh7372 Mackerel board. With this patch applied port CN22 is driven by the recently added renesas_usbhs driver using the first USB controller included in sh7372 aka USBHS0. Hotplugging of USBHS0 unfortunately has to be handled by software polling. The sh7372 SoC itself obviously supports hotplug notification by IRQ but on the Mackerel board this IRQ happens to be used for the touch screen. Also fix the pinmux configuration to avoid setting up unused pins and fix minor spelling errors. Signed-off-by: Magnus Damm <damm@opensource.se> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/arm/mach-shmobile/board-mackerel.c')
-rw-r--r--arch/arm/mach-shmobile/board-mackerel.c225
1 files changed, 160 insertions, 65 deletions
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 776f20560e72..1037bd2ffdb9 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -126,7 +126,7 @@
126 * ------+--------------------+--------------------+------- 126 * ------+--------------------+--------------------+-------
127 * IRQ0 | ICR1A.IRQ0SA=0010 | SDHI2 card detect | Low 127 * IRQ0 | ICR1A.IRQ0SA=0010 | SDHI2 card detect | Low
128 * IRQ6 | ICR1A.IRQ6SA=0011 | Ether(LAN9220) | High 128 * IRQ6 | ICR1A.IRQ6SA=0011 | Ether(LAN9220) | High
129 * IRQ7 | ICR1A.IRQ7SA=0010 | LCD Tuch Panel | Low 129 * IRQ7 | ICR1A.IRQ7SA=0010 | LCD Touch Panel | Low
130 * IRQ8 | ICR2A.IRQ8SA=0010 | MMC/SD card detect | Low 130 * IRQ8 | ICR2A.IRQ8SA=0010 | MMC/SD card detect | Low
131 * IRQ9 | ICR2A.IRQ9SA=0010 | KEY(TCA6408) | Low 131 * IRQ9 | ICR2A.IRQ9SA=0010 | KEY(TCA6408) | Low
132 * IRQ21 | ICR4A.IRQ21SA=0011 | Sensor(ADXL345) | High 132 * IRQ21 | ICR4A.IRQ21SA=0011 | Sensor(ADXL345) | High
@@ -165,10 +165,10 @@
165 * USB1 can become Host by r8a66597, and become Function by renesas_usbhs. 165 * USB1 can become Host by r8a66597, and become Function by renesas_usbhs.
166 * But don't select both drivers in same time. 166 * But don't select both drivers in same time.
167 * These uses same IRQ number for request_irq(), and aren't supporting 167 * These uses same IRQ number for request_irq(), and aren't supporting
168 * IRQF_SHARD / IORESOURCE_IRQ_SHAREABLE. 168 * IRQF_SHARED / IORESOURCE_IRQ_SHAREABLE.
169 * 169 *
170 * Actually these are old/new version of USB driver. 170 * Actually these are old/new version of USB driver.
171 * This mean its register will be broken if it supports SHARD IRQ, 171 * This mean its register will be broken if it supports shared IRQ,
172 */ 172 */
173 173
174/* 174/*
@@ -562,7 +562,136 @@ out:
562 clk_put(hdmi_ick); 562 clk_put(hdmi_ick);
563} 563}
564 564
565/* USB1 (Host) */ 565/* USBHS0 is connected to CN22 which takes a USB Mini-B plug
566 *
567 * The sh7372 SoC has IRQ7 set aside for USBHS0 hotplug,
568 * but on this particular board IRQ7 is already used by
569 * the touch screen. This leaves us with software polling.
570 */
571#define USBHS0_POLL_INTERVAL (HZ * 5)
572
573struct usbhs_private {
574 unsigned int usbphyaddr;
575 unsigned int usbcrcaddr;
576 struct renesas_usbhs_platform_info info;
577 struct delayed_work work;
578 struct platform_device *pdev;
579};
580
581#define usbhs_get_priv(pdev) \
582 container_of(renesas_usbhs_get_info(pdev), \
583 struct usbhs_private, info)
584
585#define usbhs_is_connected(priv) \
586 (!((1 << 7) & __raw_readw(priv->usbcrcaddr)))
587
588static int usbhs_get_vbus(struct platform_device *pdev)
589{
590 return usbhs_is_connected(usbhs_get_priv(pdev));
591}
592
593static void usbhs_phy_reset(struct platform_device *pdev)
594{
595 struct usbhs_private *priv = usbhs_get_priv(pdev);
596
597 /* init phy */
598 __raw_writew(0x8a0a, priv->usbcrcaddr);
599}
600
601static int usbhs0_get_id(struct platform_device *pdev)
602{
603 return USBHS_GADGET;
604}
605
606static void usbhs0_work_function(struct work_struct *work)
607{
608 struct usbhs_private *priv = container_of(work, struct usbhs_private,
609 work.work);
610
611 renesas_usbhs_call_notify_hotplug(priv->pdev);
612 schedule_delayed_work(&priv->work, USBHS0_POLL_INTERVAL);
613}
614
615static int usbhs0_hardware_init(struct platform_device *pdev)
616{
617 struct usbhs_private *priv = usbhs_get_priv(pdev);
618
619 priv->pdev = pdev;
620 INIT_DELAYED_WORK(&priv->work, usbhs0_work_function);
621 schedule_delayed_work(&priv->work, USBHS0_POLL_INTERVAL);
622 return 0;
623}
624
625static void usbhs0_hardware_exit(struct platform_device *pdev)
626{
627 struct usbhs_private *priv = usbhs_get_priv(pdev);
628
629 cancel_delayed_work_sync(&priv->work);
630}
631
632static u32 usbhs0_pipe_cfg[] = {
633 USB_ENDPOINT_XFER_CONTROL,
634 USB_ENDPOINT_XFER_ISOC,
635 USB_ENDPOINT_XFER_ISOC,
636 USB_ENDPOINT_XFER_BULK,
637 USB_ENDPOINT_XFER_BULK,
638 USB_ENDPOINT_XFER_BULK,
639 USB_ENDPOINT_XFER_INT,
640 USB_ENDPOINT_XFER_INT,
641 USB_ENDPOINT_XFER_INT,
642 USB_ENDPOINT_XFER_BULK,
643};
644
645static struct usbhs_private usbhs0_private = {
646 .usbcrcaddr = 0xe605810c, /* USBCR2 */
647 .info = {
648 .platform_callback = {
649 .hardware_init = usbhs0_hardware_init,
650 .hardware_exit = usbhs0_hardware_exit,
651 .phy_reset = usbhs_phy_reset,
652 .get_id = usbhs0_get_id,
653 .get_vbus = usbhs_get_vbus,
654 },
655 .driver_param = {
656 .buswait_bwait = 4,
657 .pipe_type = usbhs0_pipe_cfg,
658 .pipe_size = ARRAY_SIZE(usbhs0_pipe_cfg),
659 },
660 },
661};
662
663static struct resource usbhs0_resources[] = {
664 [0] = {
665 .name = "USBHS0",
666 .start = 0xe6890000,
667 .end = 0xe68900e6 - 1,
668 .flags = IORESOURCE_MEM,
669 },
670 [1] = {
671 .start = evt2irq(0x1ca0) /* USB0_USB0I0 */,
672 .flags = IORESOURCE_IRQ,
673 },
674};
675
676static struct platform_device usbhs0_device = {
677 .name = "renesas_usbhs",
678 .id = 0,
679 .dev = {
680 .platform_data = &usbhs0_private.info,
681 },
682 .num_resources = ARRAY_SIZE(usbhs0_resources),
683 .resource = usbhs0_resources,
684};
685
686/* USBHS1 is connected to CN31 which takes a USB Mini-AB plug
687 *
688 * Use J30 to select between Host and Function. This setting
689 * can however not be detected by software. Hotplug of USBHS1
690 * is provided via IRQ8.
691 */
692#define IRQ8 evt2irq(0x0300)
693
694/* USBHS1 USB Host support via r8a66597_hcd */
566static void usb1_host_port_power(int port, int power) 695static void usb1_host_port_power(int port, int power)
567{ 696{
568 if (!power) /* only power-on is supported for now */ 697 if (!power) /* only power-on is supported for now */
@@ -579,9 +708,9 @@ static struct r8a66597_platdata usb1_host_data = {
579 708
580static struct resource usb1_host_resources[] = { 709static struct resource usb1_host_resources[] = {
581 [0] = { 710 [0] = {
582 .name = "USBHS", 711 .name = "USBHS1",
583 .start = 0xE68B0000, 712 .start = 0xe68b0000,
584 .end = 0xE68B00E6 - 1, 713 .end = 0xe68b00e6 - 1,
585 .flags = IORESOURCE_MEM, 714 .flags = IORESOURCE_MEM,
586 }, 715 },
587 [1] = { 716 [1] = {
@@ -602,37 +731,14 @@ static struct platform_device usb1_host_device = {
602 .resource = usb1_host_resources, 731 .resource = usb1_host_resources,
603}; 732};
604 733
605/* USB1 (Function) */ 734/* USBHS1 USB Function support via renesas_usbhs */
735
606#define USB_PHY_MODE (1 << 4) 736#define USB_PHY_MODE (1 << 4)
607#define USB_PHY_INT_EN ((1 << 3) | (1 << 2)) 737#define USB_PHY_INT_EN ((1 << 3) | (1 << 2))
608#define USB_PHY_ON (1 << 1) 738#define USB_PHY_ON (1 << 1)
609#define USB_PHY_OFF (1 << 0) 739#define USB_PHY_OFF (1 << 0)
610#define USB_PHY_INT_CLR (USB_PHY_ON | USB_PHY_OFF) 740#define USB_PHY_INT_CLR (USB_PHY_ON | USB_PHY_OFF)
611 741
612struct usbhs_private {
613 unsigned int irq;
614 unsigned int usbphyaddr;
615 unsigned int usbcrcaddr;
616 struct renesas_usbhs_platform_info info;
617};
618
619#define usbhs_get_priv(pdev) \
620 container_of(renesas_usbhs_get_info(pdev), \
621 struct usbhs_private, info)
622
623#define usbhs_is_connected(priv) \
624 (!((1 << 7) & __raw_readw(priv->usbcrcaddr)))
625
626static int usbhs1_get_id(struct platform_device *pdev)
627{
628 return USBHS_GADGET;
629}
630
631static int usbhs1_get_vbus(struct platform_device *pdev)
632{
633 return usbhs_is_connected(usbhs_get_priv(pdev));
634}
635
636static irqreturn_t usbhs1_interrupt(int irq, void *data) 742static irqreturn_t usbhs1_interrupt(int irq, void *data)
637{ 743{
638 struct platform_device *pdev = data; 744 struct platform_device *pdev = data;
@@ -654,12 +760,10 @@ static int usbhs1_hardware_init(struct platform_device *pdev)
654 struct usbhs_private *priv = usbhs_get_priv(pdev); 760 struct usbhs_private *priv = usbhs_get_priv(pdev);
655 int ret; 761 int ret;
656 762
657 irq_set_irq_type(priv->irq, IRQ_TYPE_LEVEL_HIGH);
658
659 /* clear interrupt status */ 763 /* clear interrupt status */
660 __raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->usbphyaddr); 764 __raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->usbphyaddr);
661 765
662 ret = request_irq(priv->irq, usbhs1_interrupt, 0, 766 ret = request_irq(IRQ8, usbhs1_interrupt, IRQF_TRIGGER_HIGH,
663 dev_name(&pdev->dev), pdev); 767 dev_name(&pdev->dev), pdev);
664 if (ret) { 768 if (ret) {
665 dev_err(&pdev->dev, "request_irq err\n"); 769 dev_err(&pdev->dev, "request_irq err\n");
@@ -679,15 +783,7 @@ static void usbhs1_hardware_exit(struct platform_device *pdev)
679 /* clear interrupt status */ 783 /* clear interrupt status */
680 __raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->usbphyaddr); 784 __raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->usbphyaddr);
681 785
682 free_irq(priv->irq, pdev); 786 free_irq(IRQ8, pdev);
683}
684
685static void usbhs1_phy_reset(struct platform_device *pdev)
686{
687 struct usbhs_private *priv = usbhs_get_priv(pdev);
688
689 /* init phy */
690 __raw_writew(0x8a0a, priv->usbcrcaddr);
691} 787}
692 788
693static u32 usbhs1_pipe_cfg[] = { 789static u32 usbhs1_pipe_cfg[] = {
@@ -710,16 +806,14 @@ static u32 usbhs1_pipe_cfg[] = {
710}; 806};
711 807
712static struct usbhs_private usbhs1_private = { 808static struct usbhs_private usbhs1_private = {
713 .irq = evt2irq(0x0300), /* IRQ8 */ 809 .usbphyaddr = 0xe60581e2, /* USBPHY1INTAP */
714 .usbphyaddr = 0xE60581E2, /* USBPHY1INTAP */ 810 .usbcrcaddr = 0xe6058130, /* USBCR4 */
715 .usbcrcaddr = 0xE6058130, /* USBCR4 */
716 .info = { 811 .info = {
717 .platform_callback = { 812 .platform_callback = {
718 .hardware_init = usbhs1_hardware_init, 813 .hardware_init = usbhs1_hardware_init,
719 .hardware_exit = usbhs1_hardware_exit, 814 .hardware_exit = usbhs1_hardware_exit,
720 .phy_reset = usbhs1_phy_reset, 815 .phy_reset = usbhs_phy_reset,
721 .get_id = usbhs1_get_id, 816 .get_vbus = usbhs_get_vbus,
722 .get_vbus = usbhs1_get_vbus,
723 }, 817 },
724 .driver_param = { 818 .driver_param = {
725 .buswait_bwait = 4, 819 .buswait_bwait = 4,
@@ -731,9 +825,9 @@ static struct usbhs_private usbhs1_private = {
731 825
732static struct resource usbhs1_resources[] = { 826static struct resource usbhs1_resources[] = {
733 [0] = { 827 [0] = {
734 .name = "USBHS", 828 .name = "USBHS1",
735 .start = 0xE68B0000, 829 .start = 0xe68b0000,
736 .end = 0xE68B00E6 - 1, 830 .end = 0xe68b00e6 - 1,
737 .flags = IORESOURCE_MEM, 831 .flags = IORESOURCE_MEM,
738 }, 832 },
739 [1] = { 833 [1] = {
@@ -752,7 +846,6 @@ static struct platform_device usbhs1_device = {
752 .resource = usbhs1_resources, 846 .resource = usbhs1_resources,
753}; 847};
754 848
755
756/* LED */ 849/* LED */
757static struct gpio_led mackerel_leds[] = { 850static struct gpio_led mackerel_leds[] = {
758 { 851 {
@@ -1203,6 +1296,7 @@ static struct platform_device *mackerel_devices[] __initdata = {
1203 &nor_flash_device, 1296 &nor_flash_device,
1204 &smc911x_device, 1297 &smc911x_device,
1205 &lcdc_device, 1298 &lcdc_device,
1299 &usbhs0_device,
1206 &usb1_host_device, 1300 &usb1_host_device,
1207 &usbhs1_device, 1301 &usbhs1_device,
1208 &leds_device, 1302 &leds_device,
@@ -1301,6 +1395,7 @@ static void __init mackerel_map_io(void)
1301 1395
1302#define GPIO_PORT9CR 0xE6051009 1396#define GPIO_PORT9CR 0xE6051009
1303#define GPIO_PORT10CR 0xE605100A 1397#define GPIO_PORT10CR 0xE605100A
1398#define GPIO_PORT167CR 0xE60520A7
1304#define GPIO_PORT168CR 0xE60520A8 1399#define GPIO_PORT168CR 0xE60520A8
1305#define SRCR4 0xe61580bc 1400#define SRCR4 0xe61580bc
1306#define USCCR1 0xE6058144 1401#define USCCR1 0xE6058144
@@ -1354,17 +1449,17 @@ static void __init mackerel_init(void)
1354 gpio_request(GPIO_PORT151, NULL); /* LCDDON */ 1449 gpio_request(GPIO_PORT151, NULL); /* LCDDON */
1355 gpio_direction_output(GPIO_PORT151, 1); 1450 gpio_direction_output(GPIO_PORT151, 1);
1356 1451
1357 /* USB enable */ 1452 /* USBHS0 */
1358 gpio_request(GPIO_FN_VBUS0_1, NULL); 1453 gpio_request(GPIO_FN_VBUS0_0, NULL);
1359 gpio_request(GPIO_FN_IDIN_1_18, NULL); 1454 gpio_pull_down(GPIO_PORT168CR); /* VBUS0_0 pull down */
1360 gpio_request(GPIO_FN_PWEN_1_115, NULL); 1455
1361 gpio_request(GPIO_FN_OVCN_1_114, NULL); 1456 /* USBHS1 */
1362 gpio_request(GPIO_FN_EXTLP_1, NULL); 1457 gpio_request(GPIO_FN_VBUS0_1, NULL);
1363 gpio_request(GPIO_FN_OVCN2_1, NULL); 1458 gpio_pull_down(GPIO_PORT167CR); /* VBUS0_1 pull down */
1364 gpio_pull_down(GPIO_PORT168CR); 1459 gpio_request(GPIO_FN_IDIN_1_113, NULL);
1365 1460
1366 /* setup USB phy */ 1461 /* USB phy tweak to make the r8a66597_hcd host driver work */
1367 __raw_writew(0x8a0a, 0xE6058130); /* USBCR4 */ 1462 __raw_writew(0x8a0a, 0xe6058130); /* USBCR4 */
1368 1463
1369 /* enable FSI2 port A (ak4643) */ 1464 /* enable FSI2 port A (ak4643) */
1370 gpio_request(GPIO_FN_FSIAIBT, NULL); 1465 gpio_request(GPIO_FN_FSIAIBT, NULL);