aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);