aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-shmobile/board-ap4evb.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-shmobile/board-ap4evb.c')
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c326
1 files changed, 215 insertions, 111 deletions
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index 14923989ea05..f5d55efda386 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -30,7 +30,6 @@
30#include <linux/mtd/mtd.h> 30#include <linux/mtd/mtd.h>
31#include <linux/mtd/partitions.h> 31#include <linux/mtd/partitions.h>
32#include <linux/mtd/physmap.h> 32#include <linux/mtd/physmap.h>
33#include <linux/mmc/host.h>
34#include <linux/mmc/sh_mmcif.h> 33#include <linux/mmc/sh_mmcif.h>
35#include <linux/i2c.h> 34#include <linux/i2c.h>
36#include <linux/i2c/tsc2007.h> 35#include <linux/i2c/tsc2007.h>
@@ -44,6 +43,10 @@
44#include <linux/input/sh_keysc.h> 43#include <linux/input/sh_keysc.h>
45#include <linux/usb/r8a66597.h> 44#include <linux/usb/r8a66597.h>
46 45
46#include <media/sh_mobile_ceu.h>
47#include <media/sh_mobile_csi2.h>
48#include <media/soc_camera.h>
49
47#include <sound/sh_fsi.h> 50#include <sound/sh_fsi.h>
48 51
49#include <video/sh_mobile_hdmi.h> 52#include <video/sh_mobile_hdmi.h>
@@ -238,7 +241,7 @@ static struct platform_device smc911x_device = {
238/* SH_MMCIF */ 241/* SH_MMCIF */
239static struct resource sh_mmcif_resources[] = { 242static struct resource sh_mmcif_resources[] = {
240 [0] = { 243 [0] = {
241 .name = "SH_MMCIF", 244 .name = "MMCIF",
242 .start = 0xE6BD0000, 245 .start = 0xE6BD0000,
243 .end = 0xE6BD00FF, 246 .end = 0xE6BD00FF,
244 .flags = IORESOURCE_MEM, 247 .flags = IORESOURCE_MEM,
@@ -375,10 +378,40 @@ static struct platform_device usb1_host_device = {
375 .resource = usb1_host_resources, 378 .resource = usb1_host_resources,
376}; 379};
377 380
381const static struct fb_videomode ap4evb_lcdc_modes[] = {
382 {
383#ifdef CONFIG_AP4EVB_QHD
384 .name = "R63302(QHD)",
385 .xres = 544,
386 .yres = 961,
387 .left_margin = 72,
388 .right_margin = 600,
389 .hsync_len = 16,
390 .upper_margin = 8,
391 .lower_margin = 8,
392 .vsync_len = 2,
393 .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
394#else
395 .name = "WVGA Panel",
396 .xres = 800,
397 .yres = 480,
398 .left_margin = 220,
399 .right_margin = 110,
400 .hsync_len = 70,
401 .upper_margin = 20,
402 .lower_margin = 5,
403 .vsync_len = 5,
404 .sync = 0,
405#endif
406 },
407};
408
378static struct sh_mobile_lcdc_info lcdc_info = { 409static struct sh_mobile_lcdc_info lcdc_info = {
379 .ch[0] = { 410 .ch[0] = {
380 .chan = LCDC_CHAN_MAINLCD, 411 .chan = LCDC_CHAN_MAINLCD,
381 .bpp = 16, 412 .bpp = 16,
413 .lcd_cfg = ap4evb_lcdc_modes,
414 .num_cfg = ARRAY_SIZE(ap4evb_lcdc_modes),
382 } 415 }
383}; 416};
384 417
@@ -517,27 +550,6 @@ static struct platform_device *qhd_devices[] __initdata = {
517 550
518/* FSI */ 551/* FSI */
519#define IRQ_FSI evt2irq(0x1840) 552#define IRQ_FSI evt2irq(0x1840)
520#define FSIACKCR 0xE6150018
521static void fsiackcr_init(struct clk *clk)
522{
523 u32 status = __raw_readl(clk->enable_reg);
524
525 /* use external clock */
526 status &= ~0x000000ff;
527 status |= 0x00000080;
528 __raw_writel(status, clk->enable_reg);
529}
530
531static struct clk_ops fsiackcr_clk_ops = {
532 .init = fsiackcr_init,
533};
534
535static struct clk fsiackcr_clk = {
536 .ops = &fsiackcr_clk_ops,
537 .enable_reg = (void __iomem *)FSIACKCR,
538 .rate = 0, /* unknown */
539};
540
541static struct sh_fsi_platform_info fsi_info = { 553static struct sh_fsi_platform_info fsi_info = {
542 .porta_flags = SH_FSI_BRS_INV | 554 .porta_flags = SH_FSI_BRS_INV |
543 SH_FSI_OUT_SLAVE_MODE | 555 SH_FSI_OUT_SLAVE_MODE |
@@ -577,26 +589,6 @@ static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = {
577 .interface_type = RGB24, 589 .interface_type = RGB24,
578 .clock_divider = 1, 590 .clock_divider = 1,
579 .flags = LCDC_FLAGS_DWPOL, 591 .flags = LCDC_FLAGS_DWPOL,
580 .lcd_cfg = {
581 .name = "HDMI",
582 /* So far only 720p is supported */
583 .xres = 1280,
584 .yres = 720,
585 /*
586 * If left and right margins are not multiples of 8,
587 * LDHAJR will be adjusted accordingly by the LCDC
588 * driver. Until we start using EDID, these values
589 * might have to be adjusted for different monitors.
590 */
591 .left_margin = 200,
592 .right_margin = 88,
593 .hsync_len = 48,
594 .upper_margin = 20,
595 .lower_margin = 5,
596 .vsync_len = 5,
597 .pixclock = 13468,
598 .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
599 },
600 } 592 }
601}; 593};
602 594
@@ -608,7 +600,7 @@ static struct resource lcdc1_resources[] = {
608 .flags = IORESOURCE_MEM, 600 .flags = IORESOURCE_MEM,
609 }, 601 },
610 [1] = { 602 [1] = {
611 .start = intcs_evt2irq(0x17a0), 603 .start = intcs_evt2irq(0x1780),
612 .flags = IORESOURCE_IRQ, 604 .flags = IORESOURCE_IRQ,
613 }, 605 },
614}; 606};
@@ -689,6 +681,95 @@ static struct platform_device leds_device = {
689 }, 681 },
690}; 682};
691 683
684static struct i2c_board_info imx074_info = {
685 I2C_BOARD_INFO("imx074", 0x1a),
686};
687
688struct soc_camera_link imx074_link = {
689 .bus_id = 0,
690 .board_info = &imx074_info,
691 .i2c_adapter_id = 0,
692 .module_name = "imx074",
693};
694
695static struct platform_device ap4evb_camera = {
696 .name = "soc-camera-pdrv",
697 .id = 0,
698 .dev = {
699 .platform_data = &imx074_link,
700 },
701};
702
703static struct sh_csi2_client_config csi2_clients[] = {
704 {
705 .phy = SH_CSI2_PHY_MAIN,
706 .lanes = 3,
707 .channel = 0,
708 .pdev = &ap4evb_camera,
709 },
710};
711
712static struct sh_csi2_pdata csi2_info = {
713 .type = SH_CSI2C,
714 .clients = csi2_clients,
715 .num_clients = ARRAY_SIZE(csi2_clients),
716 .flags = SH_CSI2_ECC | SH_CSI2_CRC,
717};
718
719static struct resource csi2_resources[] = {
720 [0] = {
721 .name = "CSI2",
722 .start = 0xffc90000,
723 .end = 0xffc90fff,
724 .flags = IORESOURCE_MEM,
725 },
726 [1] = {
727 .start = intcs_evt2irq(0x17a0),
728 .flags = IORESOURCE_IRQ,
729 },
730};
731
732static struct platform_device csi2_device = {
733 .name = "sh-mobile-csi2",
734 .id = 0,
735 .num_resources = ARRAY_SIZE(csi2_resources),
736 .resource = csi2_resources,
737 .dev = {
738 .platform_data = &csi2_info,
739 },
740};
741
742static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
743 .flags = SH_CEU_FLAG_USE_8BIT_BUS,
744 .csi2_dev = &csi2_device.dev,
745};
746
747static struct resource ceu_resources[] = {
748 [0] = {
749 .name = "CEU",
750 .start = 0xfe910000,
751 .end = 0xfe91009f,
752 .flags = IORESOURCE_MEM,
753 },
754 [1] = {
755 .start = intcs_evt2irq(0x880),
756 .flags = IORESOURCE_IRQ,
757 },
758 [2] = {
759 /* place holder for contiguous memory */
760 },
761};
762
763static struct platform_device ceu_device = {
764 .name = "sh_mobile_ceu",
765 .id = 0, /* "ceu0" clock */
766 .num_resources = ARRAY_SIZE(ceu_resources),
767 .resource = ceu_resources,
768 .dev = {
769 .platform_data = &sh_mobile_ceu_info,
770 },
771};
772
692static struct platform_device *ap4evb_devices[] __initdata = { 773static struct platform_device *ap4evb_devices[] __initdata = {
693 &leds_device, 774 &leds_device,
694 &nor_flash_device, 775 &nor_flash_device,
@@ -701,6 +782,9 @@ static struct platform_device *ap4evb_devices[] __initdata = {
701 &lcdc1_device, 782 &lcdc1_device,
702 &lcdc_device, 783 &lcdc_device,
703 &hdmi_device, 784 &hdmi_device,
785 &csi2_device,
786 &ceu_device,
787 &ap4evb_camera,
704}; 788};
705 789
706static int __init hdmi_init_pm_clock(void) 790static int __init hdmi_init_pm_clock(void)
@@ -715,22 +799,22 @@ static int __init hdmi_init_pm_clock(void)
715 goto out; 799 goto out;
716 } 800 }
717 801
718 ret = clk_set_parent(&pllc2_clk, &dv_clki_div2_clk); 802 ret = clk_set_parent(&sh7372_pllc2_clk, &sh7372_dv_clki_div2_clk);
719 if (ret < 0) { 803 if (ret < 0) {
720 pr_err("Cannot set PLLC2 parent: %d, %d users\n", ret, pllc2_clk.usecount); 804 pr_err("Cannot set PLLC2 parent: %d, %d users\n", ret, sh7372_pllc2_clk.usecount);
721 goto out; 805 goto out;
722 } 806 }
723 807
724 pr_debug("PLLC2 initial frequency %lu\n", clk_get_rate(&pllc2_clk)); 808 pr_debug("PLLC2 initial frequency %lu\n", clk_get_rate(&sh7372_pllc2_clk));
725 809
726 rate = clk_round_rate(&pllc2_clk, 594000000); 810 rate = clk_round_rate(&sh7372_pllc2_clk, 594000000);
727 if (rate < 0) { 811 if (rate < 0) {
728 pr_err("Cannot get suitable rate: %ld\n", rate); 812 pr_err("Cannot get suitable rate: %ld\n", rate);
729 ret = rate; 813 ret = rate;
730 goto out; 814 goto out;
731 } 815 }
732 816
733 ret = clk_set_rate(&pllc2_clk, rate); 817 ret = clk_set_rate(&sh7372_pllc2_clk, rate);
734 if (ret < 0) { 818 if (ret < 0) {
735 pr_err("Cannot set rate %ld: %d\n", rate, ret); 819 pr_err("Cannot set rate %ld: %d\n", rate, ret);
736 goto out; 820 goto out;
@@ -738,7 +822,7 @@ static int __init hdmi_init_pm_clock(void)
738 822
739 pr_debug("PLLC2 set frequency %lu\n", rate); 823 pr_debug("PLLC2 set frequency %lu\n", rate);
740 824
741 ret = clk_set_parent(hdmi_ick, &pllc2_clk); 825 ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk);
742 if (ret < 0) { 826 if (ret < 0) {
743 pr_err("Cannot set HDMI parent: %d\n", ret); 827 pr_err("Cannot set HDMI parent: %d\n", ret);
744 goto out; 828 goto out;
@@ -752,11 +836,51 @@ out:
752 836
753device_initcall(hdmi_init_pm_clock); 837device_initcall(hdmi_init_pm_clock);
754 838
839#define FSIACK_DUMMY_RATE 48000
840static int __init fsi_init_pm_clock(void)
841{
842 struct clk *fsia_ick;
843 int ret;
844
845 /*
846 * FSIACK is connected to AK4642,
847 * and the rate is depend on playing sound rate.
848 * So, set dummy rate (= 48k) here
849 */
850 ret = clk_set_rate(&sh7372_fsiack_clk, FSIACK_DUMMY_RATE);
851 if (ret < 0) {
852 pr_err("Cannot set FSIACK dummy rate: %d\n", ret);
853 return ret;
854 }
855
856 fsia_ick = clk_get(&fsi_device.dev, "icka");
857 if (IS_ERR(fsia_ick)) {
858 ret = PTR_ERR(fsia_ick);
859 pr_err("Cannot get FSI ICK: %d\n", ret);
860 return ret;
861 }
862
863 ret = clk_set_parent(fsia_ick, &sh7372_fsiack_clk);
864 if (ret < 0) {
865 pr_err("Cannot set FSI-A parent: %d\n", ret);
866 goto out;
867 }
868
869 ret = clk_set_rate(fsia_ick, FSIACK_DUMMY_RATE);
870 if (ret < 0)
871 pr_err("Cannot set FSI-A rate: %d\n", ret);
872
873out:
874 clk_put(fsia_ick);
875
876 return ret;
877}
878device_initcall(fsi_init_pm_clock);
879
755/* 880/*
756 * FIXME !! 881 * FIXME !!
757 * 882 *
758 * gpio_no_direction 883 * gpio_no_direction
759 * gpio_pull_up
760 * are quick_hack. 884 * are quick_hack.
761 * 885 *
762 * current gpio frame work doesn't have 886 * current gpio frame work doesn't have
@@ -768,49 +892,37 @@ static void __init gpio_no_direction(u32 addr)
768 __raw_writeb(0x00, addr); 892 __raw_writeb(0x00, addr);
769} 893}
770 894
771static void __init gpio_pull_up(u32 addr)
772{
773 u8 data = __raw_readb(addr);
774
775 data &= 0x0F;
776 data |= 0xC0;
777 __raw_writeb(data, addr);
778}
779
780/* TouchScreen */ 895/* TouchScreen */
896#ifdef CONFIG_AP4EVB_QHD
897# define GPIO_TSC_IRQ GPIO_FN_IRQ28_123
898# define GPIO_TSC_PORT GPIO_PORT123
899#else /* WVGA */
900# define GPIO_TSC_IRQ GPIO_FN_IRQ7_40
901# define GPIO_TSC_PORT GPIO_PORT40
902#endif
903
781#define IRQ28 evt2irq(0x3380) /* IRQ28A */ 904#define IRQ28 evt2irq(0x3380) /* IRQ28A */
782#define IRQ7 evt2irq(0x02e0) /* IRQ7A */ 905#define IRQ7 evt2irq(0x02e0) /* IRQ7A */
783static int ts_get_pendown_state(void) 906static int ts_get_pendown_state(void)
784{ 907{
785 int val1, val2; 908 int val;
786 909
787 gpio_free(GPIO_FN_IRQ28_123); 910 gpio_free(GPIO_TSC_IRQ);
788 gpio_free(GPIO_FN_IRQ7_40);
789 911
790 gpio_request(GPIO_PORT123, NULL); 912 gpio_request(GPIO_TSC_PORT, NULL);
791 gpio_request(GPIO_PORT40, NULL);
792 913
793 gpio_direction_input(GPIO_PORT123); 914 gpio_direction_input(GPIO_TSC_PORT);
794 gpio_direction_input(GPIO_PORT40);
795 915
796 val1 = gpio_get_value(GPIO_PORT123); 916 val = gpio_get_value(GPIO_TSC_PORT);
797 val2 = gpio_get_value(GPIO_PORT40);
798 917
799 gpio_request(GPIO_FN_IRQ28_123, NULL); /* for QHD */ 918 gpio_request(GPIO_TSC_IRQ, NULL);
800 gpio_request(GPIO_FN_IRQ7_40, NULL); /* for WVGA */
801 919
802 return val1 ^ val2; 920 return !val;
803} 921}
804 922
805#define PORT40CR 0xE6051028
806#define PORT123CR 0xE605007B
807static int ts_init(void) 923static int ts_init(void)
808{ 924{
809 gpio_request(GPIO_FN_IRQ28_123, NULL); /* for QHD */ 925 gpio_request(GPIO_TSC_IRQ, NULL);
810 gpio_request(GPIO_FN_IRQ7_40, NULL); /* for WVGA */
811
812 gpio_pull_up(PORT40CR);
813 gpio_pull_up(PORT123CR);
814 926
815 return 0; 927 return 0;
816} 928}
@@ -955,14 +1067,6 @@ static void __init ap4evb_init(void)
955 clk_put(clk); 1067 clk_put(clk);
956 } 1068 }
957 1069
958 /* change parent of FSI A */
959 clk = clk_get(NULL, "fsia_clk");
960 if (!IS_ERR(clk)) {
961 clk_register(&fsiackcr_clk);
962 clk_set_parent(clk, &fsiackcr_clk);
963 clk_put(clk);
964 }
965
966 /* 1070 /*
967 * set irq priority, to avoid sound chopping 1071 * set irq priority, to avoid sound chopping
968 * when NFS rootfs is used 1072 * when NFS rootfs is used
@@ -977,8 +1081,10 @@ static void __init ap4evb_init(void)
977 ARRAY_SIZE(i2c1_devices)); 1081 ARRAY_SIZE(i2c1_devices));
978 1082
979#ifdef CONFIG_AP4EVB_QHD 1083#ifdef CONFIG_AP4EVB_QHD
1084
980 /* 1085 /*
981 * QHD 1086 * For QHD Panel (MIPI-DSI, CONFIG_AP4EVB_QHD=y) and
1087 * IRQ28 for Touch Panel, set dip switches S3, S43 as OFF, ON.
982 */ 1088 */
983 1089
984 /* enable KEYSC */ 1090 /* enable KEYSC */
@@ -1004,17 +1110,6 @@ static void __init ap4evb_init(void)
1004 lcdc_info.ch[0].interface_type = RGB24; 1110 lcdc_info.ch[0].interface_type = RGB24;
1005 lcdc_info.ch[0].clock_divider = 1; 1111 lcdc_info.ch[0].clock_divider = 1;
1006 lcdc_info.ch[0].flags = LCDC_FLAGS_DWPOL; 1112 lcdc_info.ch[0].flags = LCDC_FLAGS_DWPOL;
1007 lcdc_info.ch[0].lcd_cfg.name = "R63302(QHD)";
1008 lcdc_info.ch[0].lcd_cfg.xres = 544;
1009 lcdc_info.ch[0].lcd_cfg.yres = 961;
1010 lcdc_info.ch[0].lcd_cfg.left_margin = 72;
1011 lcdc_info.ch[0].lcd_cfg.right_margin = 600;
1012 lcdc_info.ch[0].lcd_cfg.hsync_len = 16;
1013 lcdc_info.ch[0].lcd_cfg.upper_margin = 8;
1014 lcdc_info.ch[0].lcd_cfg.lower_margin = 8;
1015 lcdc_info.ch[0].lcd_cfg.vsync_len = 2;
1016 lcdc_info.ch[0].lcd_cfg.sync = FB_SYNC_VERT_HIGH_ACT |
1017 FB_SYNC_HOR_HIGH_ACT;
1018 lcdc_info.ch[0].lcd_size_cfg.width = 44; 1113 lcdc_info.ch[0].lcd_size_cfg.width = 44;
1019 lcdc_info.ch[0].lcd_size_cfg.height = 79; 1114 lcdc_info.ch[0].lcd_size_cfg.height = 79;
1020 1115
@@ -1022,8 +1117,10 @@ static void __init ap4evb_init(void)
1022 1117
1023#else 1118#else
1024 /* 1119 /*
1025 * WVGA 1120 * For WVGA Panel (18-bit RGB, CONFIG_AP4EVB_WVGA=y) and
1121 * IRQ7 for Touch Panel, set dip switches S3, S43 to ON, OFF.
1026 */ 1122 */
1123
1027 gpio_request(GPIO_FN_LCDD17, NULL); 1124 gpio_request(GPIO_FN_LCDD17, NULL);
1028 gpio_request(GPIO_FN_LCDD16, NULL); 1125 gpio_request(GPIO_FN_LCDD16, NULL);
1029 gpio_request(GPIO_FN_LCDD15, NULL); 1126 gpio_request(GPIO_FN_LCDD15, NULL);
@@ -1055,16 +1152,6 @@ static void __init ap4evb_init(void)
1055 lcdc_info.ch[0].interface_type = RGB18; 1152 lcdc_info.ch[0].interface_type = RGB18;
1056 lcdc_info.ch[0].clock_divider = 2; 1153 lcdc_info.ch[0].clock_divider = 2;
1057 lcdc_info.ch[0].flags = 0; 1154 lcdc_info.ch[0].flags = 0;
1058 lcdc_info.ch[0].lcd_cfg.name = "WVGA Panel";
1059 lcdc_info.ch[0].lcd_cfg.xres = 800;
1060 lcdc_info.ch[0].lcd_cfg.yres = 480;
1061 lcdc_info.ch[0].lcd_cfg.left_margin = 220;
1062 lcdc_info.ch[0].lcd_cfg.right_margin = 110;
1063 lcdc_info.ch[0].lcd_cfg.hsync_len = 70;
1064 lcdc_info.ch[0].lcd_cfg.upper_margin = 20;
1065 lcdc_info.ch[0].lcd_cfg.lower_margin = 5;
1066 lcdc_info.ch[0].lcd_cfg.vsync_len = 5;
1067 lcdc_info.ch[0].lcd_cfg.sync = 0;
1068 lcdc_info.ch[0].lcd_size_cfg.width = 152; 1155 lcdc_info.ch[0].lcd_size_cfg.width = 152;
1069 lcdc_info.ch[0].lcd_size_cfg.height = 91; 1156 lcdc_info.ch[0].lcd_size_cfg.height = 91;
1070 1157
@@ -1075,6 +1162,23 @@ static void __init ap4evb_init(void)
1075 i2c_register_board_info(0, &tsc_device, 1); 1162 i2c_register_board_info(0, &tsc_device, 1);
1076#endif /* CONFIG_AP4EVB_QHD */ 1163#endif /* CONFIG_AP4EVB_QHD */
1077 1164
1165 /* CEU */
1166
1167 /*
1168 * TODO: reserve memory for V4L2 DMA buffers, when a suitable API
1169 * becomes available
1170 */
1171
1172 /* MIPI-CSI stuff */
1173 gpio_request(GPIO_FN_VIO_CKO, NULL);
1174
1175 clk = clk_get(NULL, "vck1_clk");
1176 if (!IS_ERR(clk)) {
1177 clk_set_rate(clk, clk_round_rate(clk, 13000000));
1178 clk_enable(clk);
1179 clk_put(clk);
1180 }
1181
1078 sh7372_add_standard_devices(); 1182 sh7372_add_standard_devices();
1079 1183
1080 /* HDMI */ 1184 /* HDMI */
@@ -1097,7 +1201,7 @@ static void __init ap4evb_timer_init(void)
1097 shmobile_timer.init(); 1201 shmobile_timer.init();
1098 1202
1099 /* External clock source */ 1203 /* External clock source */
1100 clk_set_rate(&dv_clki_clk, 27000000); 1204 clk_set_rate(&sh7372_dv_clki_clk, 27000000);
1101} 1205}
1102 1206
1103static struct sys_timer ap4evb_timer = { 1207static struct sys_timer ap4evb_timer = {