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 22a2b44ddb7b..46ca4d4abf91 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>
@@ -250,7 +253,7 @@ static int slot_cn7_get_cd(struct platform_device *pdev)
250/* SH_MMCIF */ 253/* SH_MMCIF */
251static struct resource sh_mmcif_resources[] = { 254static struct resource sh_mmcif_resources[] = {
252 [0] = { 255 [0] = {
253 .name = "SH_MMCIF", 256 .name = "MMCIF",
254 .start = 0xE6BD0000, 257 .start = 0xE6BD0000,
255 .end = 0xE6BD00FF, 258 .end = 0xE6BD00FF,
256 .flags = IORESOURCE_MEM, 259 .flags = IORESOURCE_MEM,
@@ -390,10 +393,40 @@ static struct platform_device usb1_host_device = {
390 .resource = usb1_host_resources, 393 .resource = usb1_host_resources,
391}; 394};
392 395
396const static struct fb_videomode ap4evb_lcdc_modes[] = {
397 {
398#ifdef CONFIG_AP4EVB_QHD
399 .name = "R63302(QHD)",
400 .xres = 544,
401 .yres = 961,
402 .left_margin = 72,
403 .right_margin = 600,
404 .hsync_len = 16,
405 .upper_margin = 8,
406 .lower_margin = 8,
407 .vsync_len = 2,
408 .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
409#else
410 .name = "WVGA Panel",
411 .xres = 800,
412 .yres = 480,
413 .left_margin = 220,
414 .right_margin = 110,
415 .hsync_len = 70,
416 .upper_margin = 20,
417 .lower_margin = 5,
418 .vsync_len = 5,
419 .sync = 0,
420#endif
421 },
422};
423
393static struct sh_mobile_lcdc_info lcdc_info = { 424static struct sh_mobile_lcdc_info lcdc_info = {
394 .ch[0] = { 425 .ch[0] = {
395 .chan = LCDC_CHAN_MAINLCD, 426 .chan = LCDC_CHAN_MAINLCD,
396 .bpp = 16, 427 .bpp = 16,
428 .lcd_cfg = ap4evb_lcdc_modes,
429 .num_cfg = ARRAY_SIZE(ap4evb_lcdc_modes),
397 } 430 }
398}; 431};
399 432
@@ -532,27 +565,6 @@ static struct platform_device *qhd_devices[] __initdata = {
532 565
533/* FSI */ 566/* FSI */
534#define IRQ_FSI evt2irq(0x1840) 567#define IRQ_FSI evt2irq(0x1840)
535#define FSIACKCR 0xE6150018
536static void fsiackcr_init(struct clk *clk)
537{
538 u32 status = __raw_readl(clk->enable_reg);
539
540 /* use external clock */
541 status &= ~0x000000ff;
542 status |= 0x00000080;
543 __raw_writel(status, clk->enable_reg);
544}
545
546static struct clk_ops fsiackcr_clk_ops = {
547 .init = fsiackcr_init,
548};
549
550static struct clk fsiackcr_clk = {
551 .ops = &fsiackcr_clk_ops,
552 .enable_reg = (void __iomem *)FSIACKCR,
553 .rate = 0, /* unknown */
554};
555
556static struct sh_fsi_platform_info fsi_info = { 568static struct sh_fsi_platform_info fsi_info = {
557 .porta_flags = SH_FSI_BRS_INV | 569 .porta_flags = SH_FSI_BRS_INV |
558 SH_FSI_OUT_SLAVE_MODE | 570 SH_FSI_OUT_SLAVE_MODE |
@@ -592,26 +604,6 @@ static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = {
592 .interface_type = RGB24, 604 .interface_type = RGB24,
593 .clock_divider = 1, 605 .clock_divider = 1,
594 .flags = LCDC_FLAGS_DWPOL, 606 .flags = LCDC_FLAGS_DWPOL,
595 .lcd_cfg = {
596 .name = "HDMI",
597 /* So far only 720p is supported */
598 .xres = 1280,
599 .yres = 720,
600 /*
601 * If left and right margins are not multiples of 8,
602 * LDHAJR will be adjusted accordingly by the LCDC
603 * driver. Until we start using EDID, these values
604 * might have to be adjusted for different monitors.
605 */
606 .left_margin = 200,
607 .right_margin = 88,
608 .hsync_len = 48,
609 .upper_margin = 20,
610 .lower_margin = 5,
611 .vsync_len = 5,
612 .pixclock = 13468,
613 .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
614 },
615 } 607 }
616}; 608};
617 609
@@ -623,7 +615,7 @@ static struct resource lcdc1_resources[] = {
623 .flags = IORESOURCE_MEM, 615 .flags = IORESOURCE_MEM,
624 }, 616 },
625 [1] = { 617 [1] = {
626 .start = intcs_evt2irq(0x17a0), 618 .start = intcs_evt2irq(0x1780),
627 .flags = IORESOURCE_IRQ, 619 .flags = IORESOURCE_IRQ,
628 }, 620 },
629}; 621};
@@ -704,6 +696,95 @@ static struct platform_device leds_device = {
704 }, 696 },
705}; 697};
706 698
699static struct i2c_board_info imx074_info = {
700 I2C_BOARD_INFO("imx074", 0x1a),
701};
702
703struct soc_camera_link imx074_link = {
704 .bus_id = 0,
705 .board_info = &imx074_info,
706 .i2c_adapter_id = 0,
707 .module_name = "imx074",
708};
709
710static struct platform_device ap4evb_camera = {
711 .name = "soc-camera-pdrv",
712 .id = 0,
713 .dev = {
714 .platform_data = &imx074_link,
715 },
716};
717
718static struct sh_csi2_client_config csi2_clients[] = {
719 {
720 .phy = SH_CSI2_PHY_MAIN,
721 .lanes = 3,
722 .channel = 0,
723 .pdev = &ap4evb_camera,
724 },
725};
726
727static struct sh_csi2_pdata csi2_info = {
728 .type = SH_CSI2C,
729 .clients = csi2_clients,
730 .num_clients = ARRAY_SIZE(csi2_clients),
731 .flags = SH_CSI2_ECC | SH_CSI2_CRC,
732};
733
734static struct resource csi2_resources[] = {
735 [0] = {
736 .name = "CSI2",
737 .start = 0xffc90000,
738 .end = 0xffc90fff,
739 .flags = IORESOURCE_MEM,
740 },
741 [1] = {
742 .start = intcs_evt2irq(0x17a0),
743 .flags = IORESOURCE_IRQ,
744 },
745};
746
747static struct platform_device csi2_device = {
748 .name = "sh-mobile-csi2",
749 .id = 0,
750 .num_resources = ARRAY_SIZE(csi2_resources),
751 .resource = csi2_resources,
752 .dev = {
753 .platform_data = &csi2_info,
754 },
755};
756
757static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
758 .flags = SH_CEU_FLAG_USE_8BIT_BUS,
759 .csi2_dev = &csi2_device.dev,
760};
761
762static struct resource ceu_resources[] = {
763 [0] = {
764 .name = "CEU",
765 .start = 0xfe910000,
766 .end = 0xfe91009f,
767 .flags = IORESOURCE_MEM,
768 },
769 [1] = {
770 .start = intcs_evt2irq(0x880),
771 .flags = IORESOURCE_IRQ,
772 },
773 [2] = {
774 /* place holder for contiguous memory */
775 },
776};
777
778static struct platform_device ceu_device = {
779 .name = "sh_mobile_ceu",
780 .id = 0, /* "ceu0" clock */
781 .num_resources = ARRAY_SIZE(ceu_resources),
782 .resource = ceu_resources,
783 .dev = {
784 .platform_data = &sh_mobile_ceu_info,
785 },
786};
787
707static struct platform_device *ap4evb_devices[] __initdata = { 788static struct platform_device *ap4evb_devices[] __initdata = {
708 &leds_device, 789 &leds_device,
709 &nor_flash_device, 790 &nor_flash_device,
@@ -716,6 +797,9 @@ static struct platform_device *ap4evb_devices[] __initdata = {
716 &lcdc1_device, 797 &lcdc1_device,
717 &lcdc_device, 798 &lcdc_device,
718 &hdmi_device, 799 &hdmi_device,
800 &csi2_device,
801 &ceu_device,
802 &ap4evb_camera,
719}; 803};
720 804
721static int __init hdmi_init_pm_clock(void) 805static int __init hdmi_init_pm_clock(void)
@@ -730,22 +814,22 @@ static int __init hdmi_init_pm_clock(void)
730 goto out; 814 goto out;
731 } 815 }
732 816
733 ret = clk_set_parent(&pllc2_clk, &dv_clki_div2_clk); 817 ret = clk_set_parent(&sh7372_pllc2_clk, &sh7372_dv_clki_div2_clk);
734 if (ret < 0) { 818 if (ret < 0) {
735 pr_err("Cannot set PLLC2 parent: %d, %d users\n", ret, pllc2_clk.usecount); 819 pr_err("Cannot set PLLC2 parent: %d, %d users\n", ret, sh7372_pllc2_clk.usecount);
736 goto out; 820 goto out;
737 } 821 }
738 822
739 pr_debug("PLLC2 initial frequency %lu\n", clk_get_rate(&pllc2_clk)); 823 pr_debug("PLLC2 initial frequency %lu\n", clk_get_rate(&sh7372_pllc2_clk));
740 824
741 rate = clk_round_rate(&pllc2_clk, 594000000); 825 rate = clk_round_rate(&sh7372_pllc2_clk, 594000000);
742 if (rate < 0) { 826 if (rate < 0) {
743 pr_err("Cannot get suitable rate: %ld\n", rate); 827 pr_err("Cannot get suitable rate: %ld\n", rate);
744 ret = rate; 828 ret = rate;
745 goto out; 829 goto out;
746 } 830 }
747 831
748 ret = clk_set_rate(&pllc2_clk, rate); 832 ret = clk_set_rate(&sh7372_pllc2_clk, rate);
749 if (ret < 0) { 833 if (ret < 0) {
750 pr_err("Cannot set rate %ld: %d\n", rate, ret); 834 pr_err("Cannot set rate %ld: %d\n", rate, ret);
751 goto out; 835 goto out;
@@ -753,7 +837,7 @@ static int __init hdmi_init_pm_clock(void)
753 837
754 pr_debug("PLLC2 set frequency %lu\n", rate); 838 pr_debug("PLLC2 set frequency %lu\n", rate);
755 839
756 ret = clk_set_parent(hdmi_ick, &pllc2_clk); 840 ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk);
757 if (ret < 0) { 841 if (ret < 0) {
758 pr_err("Cannot set HDMI parent: %d\n", ret); 842 pr_err("Cannot set HDMI parent: %d\n", ret);
759 goto out; 843 goto out;
@@ -767,11 +851,51 @@ out:
767 851
768device_initcall(hdmi_init_pm_clock); 852device_initcall(hdmi_init_pm_clock);
769 853
854#define FSIACK_DUMMY_RATE 48000
855static int __init fsi_init_pm_clock(void)
856{
857 struct clk *fsia_ick;
858 int ret;
859
860 /*
861 * FSIACK is connected to AK4642,
862 * and the rate is depend on playing sound rate.
863 * So, set dummy rate (= 48k) here
864 */
865 ret = clk_set_rate(&sh7372_fsiack_clk, FSIACK_DUMMY_RATE);
866 if (ret < 0) {
867 pr_err("Cannot set FSIACK dummy rate: %d\n", ret);
868 return ret;
869 }
870
871 fsia_ick = clk_get(&fsi_device.dev, "icka");
872 if (IS_ERR(fsia_ick)) {
873 ret = PTR_ERR(fsia_ick);
874 pr_err("Cannot get FSI ICK: %d\n", ret);
875 return ret;
876 }
877
878 ret = clk_set_parent(fsia_ick, &sh7372_fsiack_clk);
879 if (ret < 0) {
880 pr_err("Cannot set FSI-A parent: %d\n", ret);
881 goto out;
882 }
883
884 ret = clk_set_rate(fsia_ick, FSIACK_DUMMY_RATE);
885 if (ret < 0)
886 pr_err("Cannot set FSI-A rate: %d\n", ret);
887
888out:
889 clk_put(fsia_ick);
890
891 return ret;
892}
893device_initcall(fsi_init_pm_clock);
894
770/* 895/*
771 * FIXME !! 896 * FIXME !!
772 * 897 *
773 * gpio_no_direction 898 * gpio_no_direction
774 * gpio_pull_up
775 * are quick_hack. 899 * are quick_hack.
776 * 900 *
777 * current gpio frame work doesn't have 901 * current gpio frame work doesn't have
@@ -783,49 +907,37 @@ static void __init gpio_no_direction(u32 addr)
783 __raw_writeb(0x00, addr); 907 __raw_writeb(0x00, addr);
784} 908}
785 909
786static void __init gpio_pull_up(u32 addr)
787{
788 u8 data = __raw_readb(addr);
789
790 data &= 0x0F;
791 data |= 0xC0;
792 __raw_writeb(data, addr);
793}
794
795/* TouchScreen */ 910/* TouchScreen */
911#ifdef CONFIG_AP4EVB_QHD
912# define GPIO_TSC_IRQ GPIO_FN_IRQ28_123
913# define GPIO_TSC_PORT GPIO_PORT123
914#else /* WVGA */
915# define GPIO_TSC_IRQ GPIO_FN_IRQ7_40
916# define GPIO_TSC_PORT GPIO_PORT40
917#endif
918
796#define IRQ28 evt2irq(0x3380) /* IRQ28A */ 919#define IRQ28 evt2irq(0x3380) /* IRQ28A */
797#define IRQ7 evt2irq(0x02e0) /* IRQ7A */ 920#define IRQ7 evt2irq(0x02e0) /* IRQ7A */
798static int ts_get_pendown_state(void) 921static int ts_get_pendown_state(void)
799{ 922{
800 int val1, val2; 923 int val;
801 924
802 gpio_free(GPIO_FN_IRQ28_123); 925 gpio_free(GPIO_TSC_IRQ);
803 gpio_free(GPIO_FN_IRQ7_40);
804 926
805 gpio_request(GPIO_PORT123, NULL); 927 gpio_request(GPIO_TSC_PORT, NULL);
806 gpio_request(GPIO_PORT40, NULL);
807 928
808 gpio_direction_input(GPIO_PORT123); 929 gpio_direction_input(GPIO_TSC_PORT);
809 gpio_direction_input(GPIO_PORT40);
810 930
811 val1 = gpio_get_value(GPIO_PORT123); 931 val = gpio_get_value(GPIO_TSC_PORT);
812 val2 = gpio_get_value(GPIO_PORT40);
813 932
814 gpio_request(GPIO_FN_IRQ28_123, NULL); /* for QHD */ 933 gpio_request(GPIO_TSC_IRQ, NULL);
815 gpio_request(GPIO_FN_IRQ7_40, NULL); /* for WVGA */
816 934
817 return val1 ^ val2; 935 return !val;
818} 936}
819 937
820#define PORT40CR 0xE6051028
821#define PORT123CR 0xE605007B
822static int ts_init(void) 938static int ts_init(void)
823{ 939{
824 gpio_request(GPIO_FN_IRQ28_123, NULL); /* for QHD */ 940 gpio_request(GPIO_TSC_IRQ, NULL);
825 gpio_request(GPIO_FN_IRQ7_40, NULL); /* for WVGA */
826
827 gpio_pull_up(PORT40CR);
828 gpio_pull_up(PORT123CR);
829 941
830 return 0; 942 return 0;
831} 943}
@@ -974,14 +1086,6 @@ static void __init ap4evb_init(void)
974 clk_put(clk); 1086 clk_put(clk);
975 } 1087 }
976 1088
977 /* change parent of FSI A */
978 clk = clk_get(NULL, "fsia_clk");
979 if (!IS_ERR(clk)) {
980 clk_register(&fsiackcr_clk);
981 clk_set_parent(clk, &fsiackcr_clk);
982 clk_put(clk);
983 }
984
985 /* 1089 /*
986 * set irq priority, to avoid sound chopping 1090 * set irq priority, to avoid sound chopping
987 * when NFS rootfs is used 1091 * when NFS rootfs is used
@@ -996,8 +1100,10 @@ static void __init ap4evb_init(void)
996 ARRAY_SIZE(i2c1_devices)); 1100 ARRAY_SIZE(i2c1_devices));
997 1101
998#ifdef CONFIG_AP4EVB_QHD 1102#ifdef CONFIG_AP4EVB_QHD
1103
999 /* 1104 /*
1000 * QHD 1105 * For QHD Panel (MIPI-DSI, CONFIG_AP4EVB_QHD=y) and
1106 * IRQ28 for Touch Panel, set dip switches S3, S43 as OFF, ON.
1001 */ 1107 */
1002 1108
1003 /* enable KEYSC */ 1109 /* enable KEYSC */
@@ -1023,17 +1129,6 @@ static void __init ap4evb_init(void)
1023 lcdc_info.ch[0].interface_type = RGB24; 1129 lcdc_info.ch[0].interface_type = RGB24;
1024 lcdc_info.ch[0].clock_divider = 1; 1130 lcdc_info.ch[0].clock_divider = 1;
1025 lcdc_info.ch[0].flags = LCDC_FLAGS_DWPOL; 1131 lcdc_info.ch[0].flags = LCDC_FLAGS_DWPOL;
1026 lcdc_info.ch[0].lcd_cfg.name = "R63302(QHD)";
1027 lcdc_info.ch[0].lcd_cfg.xres = 544;
1028 lcdc_info.ch[0].lcd_cfg.yres = 961;
1029 lcdc_info.ch[0].lcd_cfg.left_margin = 72;
1030 lcdc_info.ch[0].lcd_cfg.right_margin = 600;
1031 lcdc_info.ch[0].lcd_cfg.hsync_len = 16;
1032 lcdc_info.ch[0].lcd_cfg.upper_margin = 8;
1033 lcdc_info.ch[0].lcd_cfg.lower_margin = 8;
1034 lcdc_info.ch[0].lcd_cfg.vsync_len = 2;
1035 lcdc_info.ch[0].lcd_cfg.sync = FB_SYNC_VERT_HIGH_ACT |
1036 FB_SYNC_HOR_HIGH_ACT;
1037 lcdc_info.ch[0].lcd_size_cfg.width = 44; 1132 lcdc_info.ch[0].lcd_size_cfg.width = 44;
1038 lcdc_info.ch[0].lcd_size_cfg.height = 79; 1133 lcdc_info.ch[0].lcd_size_cfg.height = 79;
1039 1134
@@ -1041,8 +1136,10 @@ static void __init ap4evb_init(void)
1041 1136
1042#else 1137#else
1043 /* 1138 /*
1044 * WVGA 1139 * For WVGA Panel (18-bit RGB, CONFIG_AP4EVB_WVGA=y) and
1140 * IRQ7 for Touch Panel, set dip switches S3, S43 to ON, OFF.
1045 */ 1141 */
1142
1046 gpio_request(GPIO_FN_LCDD17, NULL); 1143 gpio_request(GPIO_FN_LCDD17, NULL);
1047 gpio_request(GPIO_FN_LCDD16, NULL); 1144 gpio_request(GPIO_FN_LCDD16, NULL);
1048 gpio_request(GPIO_FN_LCDD15, NULL); 1145 gpio_request(GPIO_FN_LCDD15, NULL);
@@ -1074,16 +1171,6 @@ static void __init ap4evb_init(void)
1074 lcdc_info.ch[0].interface_type = RGB18; 1171 lcdc_info.ch[0].interface_type = RGB18;
1075 lcdc_info.ch[0].clock_divider = 2; 1172 lcdc_info.ch[0].clock_divider = 2;
1076 lcdc_info.ch[0].flags = 0; 1173 lcdc_info.ch[0].flags = 0;
1077 lcdc_info.ch[0].lcd_cfg.name = "WVGA Panel";
1078 lcdc_info.ch[0].lcd_cfg.xres = 800;
1079 lcdc_info.ch[0].lcd_cfg.yres = 480;
1080 lcdc_info.ch[0].lcd_cfg.left_margin = 220;
1081 lcdc_info.ch[0].lcd_cfg.right_margin = 110;
1082 lcdc_info.ch[0].lcd_cfg.hsync_len = 70;
1083 lcdc_info.ch[0].lcd_cfg.upper_margin = 20;
1084 lcdc_info.ch[0].lcd_cfg.lower_margin = 5;
1085 lcdc_info.ch[0].lcd_cfg.vsync_len = 5;
1086 lcdc_info.ch[0].lcd_cfg.sync = 0;
1087 lcdc_info.ch[0].lcd_size_cfg.width = 152; 1174 lcdc_info.ch[0].lcd_size_cfg.width = 152;
1088 lcdc_info.ch[0].lcd_size_cfg.height = 91; 1175 lcdc_info.ch[0].lcd_size_cfg.height = 91;
1089 1176
@@ -1094,6 +1181,23 @@ static void __init ap4evb_init(void)
1094 i2c_register_board_info(0, &tsc_device, 1); 1181 i2c_register_board_info(0, &tsc_device, 1);
1095#endif /* CONFIG_AP4EVB_QHD */ 1182#endif /* CONFIG_AP4EVB_QHD */
1096 1183
1184 /* CEU */
1185
1186 /*
1187 * TODO: reserve memory for V4L2 DMA buffers, when a suitable API
1188 * becomes available
1189 */
1190
1191 /* MIPI-CSI stuff */
1192 gpio_request(GPIO_FN_VIO_CKO, NULL);
1193
1194 clk = clk_get(NULL, "vck1_clk");
1195 if (!IS_ERR(clk)) {
1196 clk_set_rate(clk, clk_round_rate(clk, 13000000));
1197 clk_enable(clk);
1198 clk_put(clk);
1199 }
1200
1097 sh7372_add_standard_devices(); 1201 sh7372_add_standard_devices();
1098 1202
1099 /* HDMI */ 1203 /* HDMI */
@@ -1116,7 +1220,7 @@ static void __init ap4evb_timer_init(void)
1116 shmobile_timer.init(); 1220 shmobile_timer.init();
1117 1221
1118 /* External clock source */ 1222 /* External clock source */
1119 clk_set_rate(&dv_clki_clk, 27000000); 1223 clk_set_rate(&sh7372_dv_clki_clk, 27000000);
1120} 1224}
1121 1225
1122static struct sys_timer ap4evb_timer = { 1226static struct sys_timer ap4evb_timer = {